diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 72fd56f..a542a30 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -67,7 +67,7 @@ android {
dependencies {
implementation(project(":feature:home"))
- implementation(project(":feature:photolibrary"))
+ implementation(project(":feature:photo"))
// TODO Wei
// implementation(project(":feature:contactme"))
diff --git a/app/src/main/java/com/wei/picquest/navigation/PqNavHost.kt b/app/src/main/java/com/wei/picquest/navigation/PqNavHost.kt
index 4062567..68c21d6 100644
--- a/app/src/main/java/com/wei/picquest/navigation/PqNavHost.kt
+++ b/app/src/main/java/com/wei/picquest/navigation/PqNavHost.kt
@@ -7,7 +7,9 @@ import androidx.window.layout.DisplayFeature
import com.wei.picquest.core.designsystem.ui.DeviceOrientation
import com.wei.picquest.feature.home.home.navigation.homeGraph
import com.wei.picquest.feature.home.home.navigation.homeRoute
-import com.wei.picquest.feature.photolibrary.photolibrary.navigation.photoLibraryGraph
+import com.wei.picquest.feature.photo.photolibrary.navigation.navigateToPhotoLibrary
+import com.wei.picquest.feature.photo.photolibrary.navigation.photoLibraryGraph
+import com.wei.picquest.feature.photo.photosearch.navigation.photoSearchGraph
import com.wei.picquest.ui.PqAppState
/**
@@ -37,8 +39,12 @@ fun PqNavHost(
homeGraph(
navController = navController,
)
- photoLibraryGraph(
+ photoSearchGraph(
navController = navController,
+ onSearchClick = navController::navigateToPhotoLibrary,
+ nestedGraphs = {
+ photoLibraryGraph(navController = navController)
+ },
)
}
}
diff --git a/app/src/main/java/com/wei/picquest/navigation/TopLevelDestination.kt b/app/src/main/java/com/wei/picquest/navigation/TopLevelDestination.kt
index 7a22f9c..751c06e 100644
--- a/app/src/main/java/com/wei/picquest/navigation/TopLevelDestination.kt
+++ b/app/src/main/java/com/wei/picquest/navigation/TopLevelDestination.kt
@@ -21,11 +21,11 @@ enum class TopLevelDestination(
iconTextId = R.string.home,
titleTextId = R.string.home,
),
- PHOTO_LIBRARY(
+ PHOTO(
selectedIcon = PqIcons.PhotoLibrary,
unselectedIcon = PqIcons.PhotoLibraryBorder,
- iconTextId = R.string.photo_library,
- titleTextId = R.string.photo_library,
+ iconTextId = R.string.photo,
+ titleTextId = R.string.photo,
),
CONTACT_ME(
selectedIcon = PqIcons.ContactMe,
diff --git a/app/src/main/java/com/wei/picquest/ui/PqApp.kt b/app/src/main/java/com/wei/picquest/ui/PqApp.kt
index 23bd43f..088bb9a 100644
--- a/app/src/main/java/com/wei/picquest/ui/PqApp.kt
+++ b/app/src/main/java/com/wei/picquest/ui/PqApp.kt
@@ -58,6 +58,7 @@ import com.wei.picquest.core.manager.SnackbarState
import com.wei.picquest.core.utils.UiText
import com.wei.picquest.navigation.PqNavHost
import com.wei.picquest.navigation.TopLevelDestination
+import timber.log.Timber
@OptIn(
ExperimentalMaterial3Api::class,
@@ -294,6 +295,8 @@ private fun PqBottomBar(
private fun NavDestination?.isTopLevelDestinationInHierarchy(destination: TopLevelDestination) =
this?.hierarchy?.any {
+ Timber.e("PQ isTopLevelDestinationInHierarchy " + it.route.toString())
+ Timber.e("PQ destination " + destination.name.toString())
it.route?.contains(destination.name, true) ?: false
} ?: false
diff --git a/app/src/main/java/com/wei/picquest/ui/PqAppState.kt b/app/src/main/java/com/wei/picquest/ui/PqAppState.kt
index 15698f1..5eed23d 100644
--- a/app/src/main/java/com/wei/picquest/ui/PqAppState.kt
+++ b/app/src/main/java/com/wei/picquest/ui/PqAppState.kt
@@ -27,8 +27,8 @@ import com.wei.picquest.core.designsystem.ui.isBookPosture
import com.wei.picquest.core.designsystem.ui.isSeparating
import com.wei.picquest.feature.home.home.navigation.homeRoute
import com.wei.picquest.feature.home.home.navigation.navigateToHome
-import com.wei.picquest.feature.photolibrary.photolibrary.navigation.navigateToPhotoLibrary
-import com.wei.picquest.feature.photolibrary.photolibrary.navigation.photoLibraryRoute
+import com.wei.picquest.feature.photo.photosearch.navigation.navigateToPhotoSearch
+import com.wei.picquest.feature.photo.photosearch.navigation.photoSearchRoute
import com.wei.picquest.navigation.TopLevelDestination
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
@@ -151,7 +151,7 @@ class PqAppState(
val currentTopLevelDestination: TopLevelDestination?
@Composable get() = when (currentDestination?.route) {
homeRoute -> TopLevelDestination.HOME
- photoLibraryRoute -> TopLevelDestination.PHOTO_LIBRARY
+ photoSearchRoute -> TopLevelDestination.PHOTO
else -> null
}
@@ -199,7 +199,7 @@ class PqAppState(
topLevelNavOptions,
)
- TopLevelDestination.PHOTO_LIBRARY -> navController.navigateToPhotoLibrary(
+ TopLevelDestination.PHOTO -> navController.navigateToPhotoSearch(
topLevelNavOptions,
)
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index ec1279b..27cda33 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -2,7 +2,7 @@
PicQuest
⚠️ 您沒有網路連線
- 照片庫
+ 照片
首頁
聯絡我
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 503bf20..d34aeec 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,7 +1,7 @@
PicQuest
⚠️ You aren’t connected to the internet
- Photo Library
+ Photo
Home
Contact Me
diff --git a/core/designsystem/src/main/java/com/wei/picquest/core/designsystem/component/Navigation.kt b/core/designsystem/src/main/java/com/wei/picquest/core/designsystem/component/Navigation.kt
index fe4cf33..34cde89 100644
--- a/core/designsystem/src/main/java/com/wei/picquest/core/designsystem/component/Navigation.kt
+++ b/core/designsystem/src/main/java/com/wei/picquest/core/designsystem/component/Navigation.kt
@@ -335,14 +335,14 @@ object PqNavigationDefaults {
fun navigationIndicatorColor() = MaterialTheme.colorScheme.primaryContainer
}
-internal val previewItems = listOf("Schedule", "Home", "Contact Me")
+internal val previewItems = listOf("Home", "Photo", "Contact Me")
internal val previewIcons = listOf(
- PqIcons.ScheduleBorder,
PqIcons.HomeBorder,
+ PqIcons.PhotoLibraryBorder,
PqIcons.ContactMeBorder,
)
internal val previewSelectedIcons = listOf(
- PqIcons.Schedule,
PqIcons.Home,
+ PqIcons.PhotoLibrary,
PqIcons.ContactMe,
)
diff --git a/core/designsystem/src/main/java/com/wei/picquest/core/designsystem/icon/PqIcons.kt b/core/designsystem/src/main/java/com/wei/picquest/core/designsystem/icon/PqIcons.kt
index 3ef3b6f..1f4b5c5 100644
--- a/core/designsystem/src/main/java/com/wei/picquest/core/designsystem/icon/PqIcons.kt
+++ b/core/designsystem/src/main/java/com/wei/picquest/core/designsystem/icon/PqIcons.kt
@@ -1,7 +1,6 @@
package com.wei.picquest.core.designsystem.icon
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.outlined.CalendarMonth
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.PhotoLibrary
@@ -12,7 +11,6 @@ import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.rounded.ArrowBackIosNew
import androidx.compose.material.icons.rounded.ArrowForward
import androidx.compose.material.icons.rounded.ArrowForwardIos
-import androidx.compose.material.icons.rounded.CalendarMonth
import androidx.compose.material.icons.rounded.Close
import androidx.compose.material.icons.rounded.GridView
import androidx.compose.material.icons.rounded.Home
@@ -44,8 +42,6 @@ object PqIcons {
val InfoBorder = Icons.Outlined.Info
val Home = Icons.Rounded.Home
val HomeBorder = Icons.Outlined.Home
- val Schedule = Icons.Rounded.CalendarMonth
- val ScheduleBorder = Icons.Outlined.CalendarMonth
val ContactMe = Icons.Rounded.SupportAgent
val ContactMeBorder = Icons.Outlined.SupportAgent
val PhotoLibrary = Icons.Rounded.PhotoLibrary
diff --git a/feature/photolibrary/.gitignore b/feature/photo/.gitignore
similarity index 100%
rename from feature/photolibrary/.gitignore
rename to feature/photo/.gitignore
diff --git a/feature/photolibrary/build.gradle.kts b/feature/photo/build.gradle.kts
similarity index 75%
rename from feature/photolibrary/build.gradle.kts
rename to feature/photo/build.gradle.kts
index 85b8308..59a13a9 100644
--- a/feature/photolibrary/build.gradle.kts
+++ b/feature/photo/build.gradle.kts
@@ -5,7 +5,7 @@ plugins {
}
android {
- namespace = "com.wei.picquest.feature.photolibrary"
+ namespace = "com.wei.picquest.feature.photo"
}
dependencies {
diff --git a/feature/photolibrary/src/main/AndroidManifest.xml b/feature/photo/src/main/AndroidManifest.xml
similarity index 100%
rename from feature/photolibrary/src/main/AndroidManifest.xml
rename to feature/photo/src/main/AndroidManifest.xml
diff --git a/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/PhotoLibraryScreen.kt b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/PhotoLibraryScreen.kt
similarity index 89%
rename from feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/PhotoLibraryScreen.kt
rename to feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/PhotoLibraryScreen.kt
index 3d95f13..36060c4 100644
--- a/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/PhotoLibraryScreen.kt
+++ b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/PhotoLibraryScreen.kt
@@ -1,4 +1,4 @@
-package com.wei.picquest.feature.photolibrary.photolibrary
+package com.wei.picquest.feature.photo.photolibrary
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
@@ -54,13 +54,12 @@ import coil.compose.AsyncImagePainter
import coil.compose.SubcomposeAsyncImage
import coil.compose.SubcomposeAsyncImageContent
import com.wei.picquest.core.data.model.ImageDetail
-import com.wei.picquest.core.designsystem.component.FunctionalityNotAvailablePopup
import com.wei.picquest.core.designsystem.icon.PqIcons
import com.wei.picquest.core.designsystem.theme.SPACING_LARGE
import com.wei.picquest.core.designsystem.theme.SPACING_MEDIUM
import com.wei.picquest.core.designsystem.theme.SPACING_SMALL
-import com.wei.picquest.feature.photolibrary.R
-import com.wei.picquest.feature.photolibrary.photolibrary.component.LayoutSwitchWarningDialog
+import com.wei.picquest.feature.photo.R
+import com.wei.picquest.feature.photo.photolibrary.component.LayoutSwitchWarningDialog
/**
*
@@ -109,6 +108,7 @@ internal fun PhotoLibraryRoute(
TopBarActions(
layoutType = uiStates.layoutType,
+ onBackClick = navController::popBackStack,
onSwitchLayoutClick = {
viewModel.dispatch(PhotoLibraryViewAction.SwitchLayoutType)
},
@@ -120,12 +120,13 @@ internal fun PhotoLibraryRoute(
@Composable
fun TopBarActions(
layoutType: LayoutType,
+ onBackClick: () -> Unit,
onSwitchLayoutClick: () -> Unit,
) {
Column {
Spacer(Modifier.windowInsetsTopHeight(WindowInsets.safeDrawing))
Row(modifier = Modifier.padding(SPACING_MEDIUM.dp)) {
- BackButton()
+ BackButton(onBackClick = onBackClick)
Spacer(modifier = Modifier.weight(1f))
SwitchLayoutButton(
layoutType = layoutType,
@@ -136,22 +137,11 @@ fun TopBarActions(
}
@Composable
-fun BackButton() {
- val showPopup = remember { mutableStateOf(false) }
-
- if (showPopup.value) {
- FunctionalityNotAvailablePopup(
- onDismiss = {
- showPopup.value = false
- },
- )
- }
-
+fun BackButton(
+ onBackClick: () -> Unit,
+) {
IconButton(
- onClick = {
- /* TODO: Implement back button action */
- showPopup.value = true
- },
+ onClick = { onBackClick() },
modifier = Modifier
.clip(CircleShape)
.background(MaterialTheme.colorScheme.surfaceVariant)
@@ -208,12 +198,6 @@ fun PhotoLibraryListScreen(
Box(modifier = Modifier.fillMaxSize()) {
Column {
LazyColumn(modifier = Modifier.weight(1f)) {
- if (withTopSpacer) {
- item {
- Spacer(Modifier.windowInsetsTopHeight(WindowInsets.safeDrawing))
- }
- }
-
items(lazyPagingItems.itemCount) { index ->
lazyPagingItems[index]?.let {
ImageDetailItem(
@@ -222,15 +206,11 @@ fun PhotoLibraryListScreen(
)
}
}
-
- if (withBottomSpacer) {
- item {
- Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing))
- }
- }
}
-
PagingStateHandling(lazyPagingItems)
+ if (withBottomSpacer) {
+ Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing))
+ }
}
}
}
@@ -254,12 +234,6 @@ fun PhotoLibraryGridScreen(
verticalItemSpacing = 0.dp,
flingBehavior = ScrollableDefaults.flingBehavior(),
) {
- if (withTopSpacer) {
- item {
- Spacer(Modifier.windowInsetsTopHeight(WindowInsets.safeDrawing))
- }
- }
-
items(lazyPagingItems.itemCount) { index ->
lazyPagingItems[index]?.let {
ImageDetailItem(
@@ -268,15 +242,12 @@ fun PhotoLibraryGridScreen(
)
}
}
-
- if (withBottomSpacer) {
- item {
- Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing))
- }
- }
}
PagingStateHandling(lazyPagingItems)
+ if (withBottomSpacer) {
+ Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing))
+ }
}
}
}
diff --git a/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/PhotoLibraryViewModel.kt b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/PhotoLibraryViewModel.kt
similarity index 80%
rename from feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/PhotoLibraryViewModel.kt
rename to feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/PhotoLibraryViewModel.kt
index 7dee194..b20d491 100644
--- a/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/PhotoLibraryViewModel.kt
+++ b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/PhotoLibraryViewModel.kt
@@ -1,11 +1,13 @@
-package com.wei.picquest.feature.photolibrary.photolibrary
+package com.wei.picquest.feature.photo.photolibrary
+import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import androidx.paging.cachedIn
import com.wei.picquest.core.base.BaseViewModel
import com.wei.picquest.core.data.model.ImageDetail
import com.wei.picquest.core.data.repository.SearchImagesRepository
+import com.wei.picquest.feature.photo.photolibrary.navigation.PhotoLibraryArgs
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -14,19 +16,23 @@ import javax.inject.Inject
@HiltViewModel
class PhotoLibraryViewModel @Inject constructor(
+ savedStateHandle: SavedStateHandle,
private val searchImagesRepository: SearchImagesRepository,
) : BaseViewModel<
PhotoLibraryViewAction,
PhotoLibraryViewState,
>(PhotoLibraryViewState()) {
+ private val photoLibraryArgs: PhotoLibraryArgs = PhotoLibraryArgs(savedStateHandle)
+
+ val photoSearchKeyword = photoLibraryArgs.photoSearchKeyword
+
private val _imagesState: MutableStateFlow> =
MutableStateFlow(value = PagingData.empty())
val imagesState: MutableStateFlow> get() = _imagesState
init {
- // TODO Wei
- searchImages("")
+ searchImages(photoSearchKeyword)
}
private fun searchImages(query: String) {
@@ -50,7 +56,6 @@ class PhotoLibraryViewModel @Inject constructor(
override fun dispatch(action: PhotoLibraryViewAction) {
when (action) {
- is PhotoLibraryViewAction.SearchImages -> searchImages(action.query)
is PhotoLibraryViewAction.SwitchLayoutType -> switchLayoutType()
}
}
diff --git a/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/PhotoLibraryViewState.kt b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/PhotoLibraryViewState.kt
similarity index 68%
rename from feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/PhotoLibraryViewState.kt
rename to feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/PhotoLibraryViewState.kt
index 177d4cf..c84ca84 100644
--- a/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/PhotoLibraryViewState.kt
+++ b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/PhotoLibraryViewState.kt
@@ -1,4 +1,4 @@
-package com.wei.picquest.feature.photolibrary.photolibrary
+package com.wei.picquest.feature.photo.photolibrary
import com.wei.picquest.core.base.Action
import com.wei.picquest.core.base.State
@@ -8,9 +8,6 @@ enum class LayoutType {
}
sealed class PhotoLibraryViewAction : Action {
- data class SearchImages(
- val query: String,
- ) : PhotoLibraryViewAction()
object SwitchLayoutType : PhotoLibraryViewAction()
}
diff --git a/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/component/LayoutSwitchWarningDialog.kt b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/component/LayoutSwitchWarningDialog.kt
similarity index 91%
rename from feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/component/LayoutSwitchWarningDialog.kt
rename to feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/component/LayoutSwitchWarningDialog.kt
index 09b3527..f4713a9 100644
--- a/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/component/LayoutSwitchWarningDialog.kt
+++ b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/component/LayoutSwitchWarningDialog.kt
@@ -1,4 +1,4 @@
-package com.wei.picquest.feature.photolibrary.photolibrary.component
+package com.wei.picquest.feature.photo.photolibrary.component
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.MaterialTheme
@@ -9,7 +9,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
-import com.wei.picquest.feature.photolibrary.R
+import com.wei.picquest.feature.photo.R
@Composable
fun LayoutSwitchWarningDialog(onDismiss: () -> Unit) {
diff --git a/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/navigation/PhotoLibraryNavigation.kt b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/navigation/PhotoLibraryNavigation.kt
new file mode 100644
index 0000000..36bd8ad
--- /dev/null
+++ b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photolibrary/navigation/PhotoLibraryNavigation.kt
@@ -0,0 +1,50 @@
+package com.wei.picquest.feature.photo.photolibrary.navigation
+
+import androidx.annotation.VisibleForTesting
+import androidx.lifecycle.SavedStateHandle
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavType
+import androidx.navigation.compose.composable
+import androidx.navigation.navArgument
+import com.wei.picquest.feature.photo.photolibrary.PhotoLibraryRoute
+import com.wei.picquest.feature.photo.photosearch.navigation.photoSearchRoute
+import java.net.URLDecoder
+import java.net.URLEncoder
+
+private val URL_CHARACTER_ENCODING = Charsets.UTF_8.name()
+
+@VisibleForTesting
+internal const val photoSearchKeywordArg = "photoSearchKeyword"
+
+internal class PhotoLibraryArgs(val photoSearchKeyword: String) {
+ constructor(savedStateHandle: SavedStateHandle) :
+ this(
+ URLDecoder.decode(
+ checkNotNull(savedStateHandle[photoSearchKeywordArg]),
+ URL_CHARACTER_ENCODING,
+ ),
+ )
+}
+
+fun NavController.navigateToPhotoLibrary(photoSearchKeyword: String) {
+ val encodedKey = URLEncoder.encode(photoSearchKeyword, URL_CHARACTER_ENCODING)
+ this.navigate("$photoSearchRoute/$encodedKey") {
+ launchSingleTop = true
+ }
+}
+
+fun NavGraphBuilder.photoLibraryGraph(
+ navController: NavController,
+) {
+ composable(
+ route = "$photoSearchRoute/{$photoSearchKeywordArg}",
+ arguments = listOf(
+ navArgument(photoSearchKeywordArg) { type = NavType.StringType },
+ ),
+ ) {
+ PhotoLibraryRoute(
+ navController = navController,
+ )
+ }
+}
diff --git a/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/PhotoSearchScreen.kt b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/PhotoSearchScreen.kt
new file mode 100644
index 0000000..24e3dbb
--- /dev/null
+++ b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/PhotoSearchScreen.kt
@@ -0,0 +1,119 @@
+package com.wei.picquest.feature.photo.photosearch
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.WindowInsets
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.safeDrawing
+import androidx.compose.foundation.layout.windowInsetsBottomHeight
+import androidx.compose.foundation.layout.windowInsetsTopHeight
+import androidx.compose.material3.Button
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.semantics
+import androidx.navigation.NavController
+import com.wei.picquest.core.designsystem.component.FunctionalityNotAvailablePopup
+import com.wei.picquest.core.designsystem.component.ThemePreviews
+import com.wei.picquest.core.designsystem.theme.PqTheme
+
+/**
+ *
+ * UI 事件決策樹
+ * 下圖顯示了一個決策樹,用於查找處理特定事件用例的最佳方法。
+ *
+ * ┌───────┐
+ * │ Start │
+ * └───┬───┘
+ * ↓
+ * ┌───────────────────────────────────┐
+ * │ Where is event originated? │
+ * └──────┬─────────────────────┬──────┘
+ * ↓ ↓
+ * UI ViewModel
+ * │ │
+ * ┌─────────────────────────┐ ┌───────────────┐
+ * │ When the event requires │ │ Update the UI │
+ * │ ... │ │ State │
+ * └─┬─────────────────────┬─┘ └───────────────┘
+ * ↓ ↓
+ * Business logic UI behavior logic
+ * │ │
+ * ┌─────────────────────────────────┐ ┌──────────────────────────────────────┐
+ * │ Delegate the business logic to │ │ Modify the UI element state in the │
+ * │ the ViewModel │ │ UI directly │
+ * └─────────────────────────────────┘ └──────────────────────────────────────┘
+ *
+ *
+ */
+@Composable
+internal fun PhotoSearchRoute(
+ onSearchClick: (String) -> Unit,
+ navController: NavController,
+) {
+ PhotoSearchScreen(onSearchClick = onSearchClick)
+}
+
+@Composable
+internal fun PhotoSearchScreen(
+ onSearchClick: (String) -> Unit,
+ withTopSpacer: Boolean = true,
+ withBottomSpacer: Boolean = true,
+) {
+ val showPopup = remember { mutableStateOf(false) }
+
+ if (showPopup.value) {
+ FunctionalityNotAvailablePopup(
+ onDismiss = {
+ showPopup.value = false
+ },
+ )
+ }
+
+ Surface(
+ modifier = Modifier.fillMaxSize(),
+ color = MaterialTheme.colorScheme.background,
+ ) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ if (withTopSpacer) {
+ Spacer(Modifier.windowInsetsTopHeight(WindowInsets.safeDrawing))
+ }
+
+ Column {
+ Spacer(modifier = Modifier.weight(1f))
+ Text(
+ text = "Search Screen not available \uD83D\uDE48",
+ color = MaterialTheme.colorScheme.error,
+ style = MaterialTheme.typography.headlineMedium,
+ modifier = Modifier
+ .semantics { contentDescription = "" },
+ )
+ // TODO Wei
+ Button(onClick = { onSearchClick("kitten") }) {
+ Text(text = "Search [kitten] keyword")
+ }
+ Spacer(modifier = Modifier.weight(1f))
+ }
+
+ if (withBottomSpacer) {
+ Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing))
+ }
+ }
+ }
+}
+
+@ThemePreviews
+@Composable
+fun SearchPhotoScreenPreview() {
+ PqTheme {
+ PhotoSearchScreen(onSearchClick = {})
+ }
+}
diff --git a/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/PhotoSearchViewModel.kt b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/PhotoSearchViewModel.kt
new file mode 100644
index 0000000..210e1af
--- /dev/null
+++ b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/PhotoSearchViewModel.kt
@@ -0,0 +1,18 @@
+package com.wei.picquest.feature.photo.photosearch
+
+import com.wei.picquest.core.base.BaseViewModel
+import dagger.hilt.android.lifecycle.HiltViewModel
+import javax.inject.Inject
+
+@HiltViewModel
+class PhotoSearchViewModel @Inject constructor() : BaseViewModel<
+ PhotoSearchViewAction,
+ PhotoSearchViewState,
+ >(PhotoSearchViewState) {
+
+ override fun dispatch(action: PhotoSearchViewAction) {
+ when (action) {
+ is PhotoSearchViewAction.SearchPhotos -> TODO()
+ }
+ }
+}
diff --git a/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/PhotoSearchViewState.kt b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/PhotoSearchViewState.kt
new file mode 100644
index 0000000..aa6bdc3
--- /dev/null
+++ b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/PhotoSearchViewState.kt
@@ -0,0 +1,12 @@
+package com.wei.picquest.feature.photo.photosearch
+
+import com.wei.picquest.core.base.Action
+import com.wei.picquest.core.base.State
+
+sealed class PhotoSearchViewAction : Action {
+ data class SearchPhotos(
+ val query: String,
+ ) : PhotoSearchViewAction()
+}
+
+object PhotoSearchViewState : State
diff --git a/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/navigation/PhotoSearchNavigation.kt b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/navigation/PhotoSearchNavigation.kt
new file mode 100644
index 0000000..04734df
--- /dev/null
+++ b/feature/photo/src/main/java/com/wei/picquest/feature/photo/photosearch/navigation/PhotoSearchNavigation.kt
@@ -0,0 +1,27 @@
+package com.wei.picquest.feature.photo.photosearch.navigation
+
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavOptions
+import androidx.navigation.compose.composable
+import com.wei.picquest.feature.photo.photosearch.PhotoSearchRoute
+
+const val photoSearchRoute = "photo_search_route"
+
+fun NavController.navigateToPhotoSearch(navOptions: NavOptions? = null) {
+ this.navigate(photoSearchRoute, navOptions)
+}
+
+fun NavGraphBuilder.photoSearchGraph(
+ navController: NavController,
+ onSearchClick: (String) -> Unit,
+ nestedGraphs: NavGraphBuilder.() -> Unit,
+) {
+ composable(route = photoSearchRoute) {
+ PhotoSearchRoute(
+ onSearchClick = onSearchClick,
+ navController = navController,
+ )
+ }
+ nestedGraphs()
+}
diff --git a/feature/photolibrary/src/main/res/drawable/placeholder_image.png b/feature/photo/src/main/res/drawable/placeholder_image.png
similarity index 100%
rename from feature/photolibrary/src/main/res/drawable/placeholder_image.png
rename to feature/photo/src/main/res/drawable/placeholder_image.png
diff --git a/feature/photolibrary/src/main/res/values-zh-rTW/strings.xml b/feature/photo/src/main/res/values-zh-rTW/strings.xml
similarity index 100%
rename from feature/photolibrary/src/main/res/values-zh-rTW/strings.xml
rename to feature/photo/src/main/res/values-zh-rTW/strings.xml
diff --git a/feature/photolibrary/src/main/res/values/strings.xml b/feature/photo/src/main/res/values/strings.xml
similarity index 100%
rename from feature/photolibrary/src/main/res/values/strings.xml
rename to feature/photo/src/main/res/values/strings.xml
diff --git a/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/navigation/PhotoLibraryNavigation.kt b/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/navigation/PhotoLibraryNavigation.kt
deleted file mode 100644
index 910d257..0000000
--- a/feature/photolibrary/src/main/java/com/wei/picquest/feature/photolibrary/photolibrary/navigation/PhotoLibraryNavigation.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.wei.picquest.feature.photolibrary.photolibrary.navigation
-
-import androidx.navigation.NavController
-import androidx.navigation.NavGraphBuilder
-import androidx.navigation.NavOptions
-import androidx.navigation.compose.composable
-import com.wei.picquest.feature.photolibrary.photolibrary.PhotoLibraryRoute
-
-const val photoLibraryRoute = "photo_library_route"
-
-fun NavController.navigateToPhotoLibrary(navOptions: NavOptions? = null) {
- this.navigate(photoLibraryRoute, navOptions)
-}
-
-fun NavGraphBuilder.photoLibraryGraph(
- navController: NavController,
-) {
- composable(route = photoLibraryRoute) {
- PhotoLibraryRoute(
- navController = navController,
- )
- }
-}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index d130eb7..621bb1e 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -29,4 +29,4 @@ include(":core:network")
include(":ui-test-hilt-manifest")
include(":feature:home")
-include(":feature:photolibrary")
+include(":feature:photo")