@@ -8,6 +8,10 @@ import androidx.activity.enableEdgeToEdge
88import androidx.annotation.DrawableRes
99import androidx.annotation.StringRes
1010import androidx.appcompat.app.AppCompatActivity
11+ import androidx.compose.animation.AnimatedVisibility
12+ import androidx.compose.animation.core.tween
13+ import androidx.compose.animation.fadeIn
14+ import androidx.compose.animation.fadeOut
1115import androidx.compose.foundation.background
1216import androidx.compose.foundation.layout.Box
1317import androidx.compose.foundation.layout.padding
@@ -19,7 +23,6 @@ import androidx.compose.runtime.Composable
1923import androidx.compose.runtime.mutableStateOf
2024import androidx.compose.runtime.remember
2125import androidx.compose.ui.Modifier
22- import androidx.compose.ui.graphics.Color
2326import androidx.compose.ui.text.TextRange
2427import androidx.compose.ui.text.input.TextFieldValue
2528import androidx.navigation.compose.NavHost
@@ -34,6 +37,7 @@ import com.inspiredandroid.linuxcommandbibliotheca.ui.screens.basiccategories.Ba
3437import com.inspiredandroid.linuxcommandbibliotheca.ui.screens.basicgroups.BasicGroupsScreen
3538import com.inspiredandroid.linuxcommandbibliotheca.ui.screens.commanddetail.CommandDetailScreen
3639import com.inspiredandroid.linuxcommandbibliotheca.ui.screens.commandlist.CommandListScreen
40+ import com.inspiredandroid.linuxcommandbibliotheca.ui.screens.search.SearchScreen
3741import com.inspiredandroid.linuxcommandbibliotheca.ui.screens.tips.TipsScreen
3842import com.inspiredandroid.linuxcommandbibliotheca.ui.theme.LinuxTheme
3943import com.inspiredandroid.linuxcommandbibliotheca.ui.theme.LocalCustomColors
@@ -64,9 +68,9 @@ class MainActivity : AppCompatActivity() {
6468 enableEdgeToEdge(statusBarStyle = SystemBarStyle .dark(android.graphics.Color .TRANSPARENT ))
6569 super .onCreate(savedInstanceState)
6670
67- if (! hasDatabase(this ) || ! preferenceManager.isDatabaseUpToDate(this )) {
71+ if (! hasDatabase(this ) || ! preferenceManager.isDatabaseUpToDate()) {
6872 startActivity(Intent (this , InitializeDatabaseActivity ::class .java))
69- preferenceManager.updateDatabaseVersion(this )
73+ preferenceManager.updateDatabaseVersion()
7074 finish()
7175 return
7276 }
@@ -104,6 +108,7 @@ fun LinuxApp() {
104108 TextFieldValue (text = " " , selection = TextRange (0 )),
105109 )
106110 }
111+ val showSearch = remember { mutableStateOf(false ) }
107112 val onNavigate: (String ) -> Unit = {
108113 navController.navigate(it)
109114 }
@@ -116,93 +121,123 @@ fun LinuxApp() {
116121 onNavigateBack = {
117122 navController.popBackStack()
118123 },
124+ showSearch = showSearch,
119125 )
120126 },
121127 bottomBar = {
122- BottomBar (navController)
128+ BottomBar (
129+ navController = navController,
130+ resetSearch = {
131+ searchTextValue.value = TextFieldValue (text = " " , selection = TextRange (0 ))
132+ showSearch.value = false
133+ },
134+ )
123135 },
124136 ) { innerPadding ->
125-
126- NavHost (
127- navController = navController,
128- startDestination = Screen .Basics .route,
137+ Box (
129138 modifier = Modifier .padding(innerPadding),
130139 ) {
131- composable(
132- Screen .Basics .route,
133- deepLinks = listOf (
134- navDeepLink { uriPattern = " $DEEPLINK_URI /basics" },
135- navDeepLink { uriPattern = " $DEEPLINK_URI /basics.html" },
136- ),
137- ) {
138- BasicCategoriesScreen (onNavigate)
139- }
140- composable(
141- Screen .Commands .route,
142- deepLinks = listOf (
143- navDeepLink { uriPattern = " $DEEPLINK_URI /" },
144- navDeepLink { uriPattern = " $DEEPLINK_URI /index.html" },
145- ),
140+ NavHost (
141+ navController = navController,
142+ startDestination = Screen .Basics .route,
146143 ) {
147- CommandListScreen (
148- searchText = searchTextValue.value.text,
149- onNavigate = onNavigate,
150- )
151- }
152- composable(
153- Screen .Tips .route,
154- deepLinks = listOf (
155- navDeepLink { uriPattern = " $DEEPLINK_URI /tips" },
156- navDeepLink { uriPattern = " $DEEPLINK_URI /tips.html" },
157- ),
158- ) {
159- TipsScreen (onNavigate)
160- }
161- composable(
162- " basicgroups?categoryId={categoryId}&categoryName={categoryName}" ,
163- arguments = listOf (
164- navArgument(" categoryId" ) { defaultValue = " " },
165- navArgument(" categoryName" ) {},
166- ),
167- deepLinks = listOf (
168- navDeepLink {
169- uriPattern = " $DEEPLINK_URI /basic/{categoryName}.html"
170- },
171- navDeepLink { uriPattern = " $DEEPLINK_URI /basic/{categoryName}" },
172- ),
173- ) { backStackEntry ->
174- val categoryId = backStackEntry.getCategoryId()
175- if (categoryId != null ) {
176- BasicGroupsScreen (
177- categoryId = categoryId,
144+ composable(
145+ Screen .Basics .route,
146+ deepLinks = listOf (
147+ navDeepLink { uriPattern = " $DEEPLINK_URI /basics" },
148+ navDeepLink { uriPattern = " $DEEPLINK_URI /basics.html" },
149+ ),
150+ ) {
151+ BasicCategoriesScreen (
178152 onNavigate = onNavigate,
179153 )
180- } else {
181- // open tips screen on invalid deeplink parameters
182- TipsScreen (onNavigate)
183154 }
184- }
185- composable(
186- " command?commandId={commandId}&commandName={commandName}" ,
187- arguments = listOf (
188- navArgument(" commandId" ) { defaultValue = " " },
189- navArgument(" commandName" ) {},
190- ),
191- deepLinks = listOf (
192- navDeepLink { uriPattern = " $DEEPLINK_URI /man/{commandName}.html" },
193- navDeepLink { uriPattern = " $DEEPLINK_URI /man/{commandName}" },
194- ),
195- ) { backStackEntry ->
196- val commandId = backStackEntry.getCommandId()
197- if (commandId != null ) {
198- CommandDetailScreen (
199- commandId = commandId,
155+ composable(
156+ Screen .Commands .route,
157+ deepLinks = listOf (
158+ navDeepLink { uriPattern = " $DEEPLINK_URI /" },
159+ navDeepLink { uriPattern = " $DEEPLINK_URI /index.html" },
160+ ),
161+ ) {
162+ CommandListScreen (
200163 onNavigate = onNavigate,
201164 )
202- } else {
203- // open tips screen on invalid deeplink parameters
165+ }
166+ composable(
167+ Screen .Tips .route,
168+ deepLinks = listOf (
169+ navDeepLink { uriPattern = " $DEEPLINK_URI /tips" },
170+ navDeepLink { uriPattern = " $DEEPLINK_URI /tips.html" },
171+ ),
172+ ) {
204173 TipsScreen (onNavigate)
205174 }
175+ composable(
176+ " basicgroups?categoryId={categoryId}&categoryName={categoryName}" ,
177+ arguments = listOf (
178+ navArgument(" categoryId" ) { defaultValue = " " },
179+ navArgument(" categoryName" ) {},
180+ ),
181+ deepLinks = listOf (
182+ navDeepLink {
183+ uriPattern = " $DEEPLINK_URI /basic/{categoryName}.html"
184+ },
185+ navDeepLink { uriPattern = " $DEEPLINK_URI /basic/{categoryName}" },
186+ ),
187+ ) { backStackEntry ->
188+ val categoryId = backStackEntry.getCategoryId()
189+ if (categoryId != null ) {
190+ BasicGroupsScreen (
191+ categoryId = categoryId,
192+ onNavigate = onNavigate,
193+ )
194+ } else {
195+ // open tips screen on invalid deeplink parameters
196+ TipsScreen (onNavigate)
197+ }
198+ }
199+ composable(
200+ " command?commandId={commandId}&commandName={commandName}" ,
201+ arguments = listOf (
202+ navArgument(" commandId" ) { defaultValue = " " },
203+ navArgument(" commandName" ) {},
204+ ),
205+ deepLinks = listOf (
206+ navDeepLink { uriPattern = " $DEEPLINK_URI /man/{commandName}.html" },
207+ navDeepLink { uriPattern = " $DEEPLINK_URI /man/{commandName}" },
208+ ),
209+ ) { backStackEntry ->
210+ val commandId = backStackEntry.getCommandId()
211+ if (commandId != null ) {
212+ CommandDetailScreen (
213+ commandId = commandId,
214+ onNavigate = onNavigate,
215+ )
216+ } else {
217+ // open tips screen on invalid deeplink parameters
218+ TipsScreen (onNavigate)
219+ }
220+ }
221+ }
222+
223+ val isSearchVisible = remember(
224+ searchTextValue.value.text,
225+ navBackStackEntry.value?.destination?.route,
226+ ) {
227+ searchTextValue.value.text.isNotEmpty() &&
228+ navBackStackEntry.value?.destination?.route?.startsWith(" command?" ) == false
229+ }
230+ AnimatedVisibility (
231+ visible = isSearchVisible,
232+ enter = fadeIn(animationSpec = tween(300 )),
233+ exit = fadeOut(animationSpec = tween(durationMillis = 300 , delayMillis = 300 )), // work around for navigation overlaps
234+ ) {
235+ SearchScreen (
236+ searchText = searchTextValue.value.text,
237+ onNavigate = {
238+ navController.navigate(it)
239+ },
240+ )
206241 }
207242 }
208243 }
0 commit comments