From 0aa663b229ef6a04b0d06bb92c4d46de09eb4e08 Mon Sep 17 00:00:00 2001 From: takahirom Date: Sat, 8 Jul 2023 19:27:11 +0900 Subject: [PATCH 1/6] Refactor navigation --- .../droidkaigi/confsched2023/KaigiApp.kt | 89 +++++++++++++------ .../contributors/ContributorsScreen.kt | 2 + .../confsched2023/main/MainScreen.kt | 67 ++++++++------ .../confsched2023/main/strings/MainStrings.kt | 6 +- .../sessions/TimetableItemDetailScreen.kt | 39 ++++++-- .../confsched2023/sessions/TimetableScreen.kt | 20 +++++ 6 files changed, 157 insertions(+), 66 deletions(-) diff --git a/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt b/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt index 503cd9cbf..e62eb018f 100644 --- a/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt +++ b/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt @@ -9,16 +9,25 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.google.accompanist.systemuicontroller.rememberSystemUiController import io.github.droidkaigi.confsched2023.contributors.ContributorsScreen import io.github.droidkaigi.confsched2023.contributors.ContributorsViewModel +import io.github.droidkaigi.confsched2023.contributors.contributorsScreenRoute import io.github.droidkaigi.confsched2023.designsystem.theme.KaigiTheme -import io.github.droidkaigi.confsched2023.main.MainScreen -import io.github.droidkaigi.confsched2023.sessions.TimetableItemDetailScreen -import io.github.droidkaigi.confsched2023.sessions.TimetableScreen +import io.github.droidkaigi.confsched2023.main.MainScreenTab.Contributor +import io.github.droidkaigi.confsched2023.main.MainScreenTab.Timetable +import io.github.droidkaigi.confsched2023.main.mainScreenRoute +import io.github.droidkaigi.confsched2023.main.mainScreens +import io.github.droidkaigi.confsched2023.sessions.nestedSessionScreens +import io.github.droidkaigi.confsched2023.sessions.navigateTimetableScreen +import io.github.droidkaigi.confsched2023.sessions.navigateToTimetableItemDetailScreen +import io.github.droidkaigi.confsched2023.sessions.sessionScreens +import io.github.droidkaigi.confsched2023.sessions.timetableScreenRoute @Composable fun KaigiApp(modifier: Modifier = Modifier) { @@ -35,33 +44,55 @@ fun KaigiApp(modifier: Modifier = Modifier) { modifier = modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background, ) { - val navController = rememberNavController() - NavHost(navController = navController, startDestination = "main") { - composable("main") { - MainScreen( - timetableScreen = { - TimetableScreen( - onTimetableItemClick = { - navController.navigate("timetable/${it.id.value}") - }, - onContributorsClick = { - navController.navigate("contributors") - }, - ) - }, - ) - } - composable("contributors") { - ContributorsScreen(hiltViewModel()) - } - composable("timetable/{timetableItemId}") { - TimetableItemDetailScreen( - onNavigationIconClick = { - navController.popBackStack() - }, + KaigiNavHost() + } + } +} + +@Composable +private fun KaigiNavHost(navController: NavHostController = rememberNavController()) { + + NavHost(navController = navController, startDestination = mainScreenRoute) { + mainScreen(navController) + sessionScreens( + onNavigationIconClick = { + navController.popBackStack() + } + ) + } +} + +private fun NavGraphBuilder.mainScreen(navController: NavHostController) { + mainScreens( + onTabSelected = { mainNestedNavController, tab -> + when (tab) { + Timetable -> mainNestedNavController.navigateTimetableScreen() + Contributor -> mainNestedNavController.navigate(contributorsScreenRoute) + } + }, + routeToTab = { + when (this) { + timetableScreenRoute -> Timetable + contributorsScreenRoute -> Contributor + else -> null + } + }, + mainNestedGraph = { mainNestedNavController, padding -> + nestedSessionScreens( + onTimetableItemClick = { timetableitem -> + navController.navigateToTimetableItemDetailScreen( + timetableitem.id ) - } + }, + onContributorsClick = { + // We don't abstract this logic because this screen is using Compose Multiplatform and + // Compose Navigation doesn't support Multiplatform yet + mainNestedNavController.navigate(contributorsScreenRoute) + }, + ) + composable(contributorsScreenRoute) { + ContributorsScreen(hiltViewModel()) } } - } + ) } diff --git a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched2023/contributors/ContributorsScreen.kt b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched2023/contributors/ContributorsScreen.kt index 0d8b8de92..ce1c73b25 100644 --- a/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched2023/contributors/ContributorsScreen.kt +++ b/feature/contributors/src/commonMain/kotlin/io/github/droidkaigi/confsched2023/contributors/ContributorsScreen.kt @@ -6,6 +6,8 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +const val contributorsScreenRoute = "contributors" + @Composable fun ContributorsScreen(viewModel: ContributorsViewModel) { val contributors = Contributors() diff --git a/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt b/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt index 025e95494..9fd727d04 100644 --- a/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt +++ b/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt @@ -1,24 +1,23 @@ package io.github.droidkaigi.confsched2023.main -import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.DateRange -import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material.icons.filled.List import androidx.compose.material3.Icon import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHostState -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState @@ -26,11 +25,28 @@ import androidx.navigation.compose.rememberNavController import io.github.droidkaigi.confsched2023.main.strings.MainStrings import io.github.droidkaigi.confsched2023.ui.SnackbarMessageEffect +const val mainScreenRoute = "main" +fun NavGraphBuilder.mainScreens( + onTabSelected: (mainNestedNavController: NavController, MainScreenTab) -> Unit, + routeToTab: String.() -> MainScreenTab?, + mainNestedGraph: NavGraphBuilder.(mainNestedNavController: NavController, PaddingValues) -> Unit +) { + composable(mainScreenRoute) { + MainScreen( + onTabSelected = onTabSelected, + routeToTab = routeToTab, + mainNestedNavGraph = mainNestedGraph, + ) + } +} + const val MainScreenTestTag = "MainScreen" @Composable fun MainScreen( - timetableScreen: @Composable () -> Unit, + onTabSelected: (NavController, MainScreenTab) -> Unit, + routeToTab: String.() -> MainScreenTab?, + mainNestedNavGraph: NavGraphBuilder.(NavController, PaddingValues) -> Unit, viewModel: MainScreenViewModel = hiltViewModel(), ) { val uiState by viewModel.uiState.collectAsState() @@ -43,24 +59,23 @@ fun MainScreen( MainScreen( uiState = uiState, snackbarHostState = snackbarHostState, - timetableScreen = timetableScreen, + routeToTab = routeToTab, + onTabSelected = onTabSelected, + mainNestedNavGraph = mainNestedNavGraph, ) } enum class MainScreenTab( val icon: ImageVector, val contentDescription: String, - val route: String, ) { Timetable( icon = Icons.Filled.DateRange, contentDescription = MainStrings.Timetable.asString(), - route = "timetable", ), - Play( - icon = Icons.Filled.PlayArrow, - contentDescription = MainStrings.Play.asString(), - route = "play", + Contributor( + icon = Icons.Filled.List, + contentDescription = MainStrings.Contributors.asString(), ), } @@ -70,20 +85,22 @@ class MainScreenUiState() private fun MainScreen( uiState: MainScreenUiState, snackbarHostState: SnackbarHostState, - timetableScreen: @Composable () -> Unit, + routeToTab: String.() -> MainScreenTab?, + onTabSelected: (NavController, MainScreenTab) -> Unit, + mainNestedNavGraph: NavGraphBuilder.(NavController, PaddingValues) -> Unit ) { - val bottomBarNavController = rememberNavController() - val navBackStackEntry by bottomBarNavController.currentBackStackEntryAsState() - val currentRoute = navBackStackEntry?.destination?.route + val mainNestedNavController = rememberNavController() + val navBackStackEntry by mainNestedNavController.currentBackStackEntryAsState() + val currentTab = navBackStackEntry?.destination?.route?.routeToTab() Scaffold( bottomBar = { NavigationBar { MainScreenTab.values().forEach { tab -> - val selected = currentRoute == tab.route + val selected = currentTab == tab NavigationBarItem( selected = selected, onClick = { - bottomBarNavController.navigate(tab.route) + onTabSelected(mainNestedNavController, tab) }, icon = { Icon( @@ -97,15 +114,9 @@ private fun MainScreen( }, contentWindowInsets = WindowInsets(0.dp), ) { padding -> - NavHost(navController = bottomBarNavController, startDestination = "timetable") { - composable(MainScreenTab.Timetable.route) { - Box(Modifier.padding(padding)) { - timetableScreen() - } - } - composable(MainScreenTab.Play.route) { - Text("play") - } + NavHost(navController = mainNestedNavController, startDestination = "timetable") { + mainNestedNavGraph(mainNestedNavController, padding) + } } } diff --git a/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/strings/MainStrings.kt b/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/strings/MainStrings.kt index a0aec79a8..f9e72c9e7 100644 --- a/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/strings/MainStrings.kt +++ b/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/strings/MainStrings.kt @@ -6,21 +6,21 @@ import io.github.droidkaigi.confsched2023.designsystem.strings.StringsBindings sealed class MainStrings : Strings(Bindings) { object Timetable : MainStrings() - object Play : MainStrings() + object Contributors : MainStrings() class Time(val hours: Int, val minutes: Int) : MainStrings() private object Bindings : StringsBindings( Lang.Japanese to { item, _ -> when (item) { Timetable -> "タイムテーブル" - Play -> "Play" + Contributors -> "Contributors" is Time -> "${item.hours}時${item.minutes}分" } }, Lang.English to { item, bindings -> when (item) { Timetable -> "Timetable" - Play -> "Play" + Contributors -> "Contributors" is Time -> "${item.hours}:${item.minutes}" } }, diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableItemDetailScreen.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableItemDetailScreen.kt index 17e40b43f..705bfe6c6 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableItemDetailScreen.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableItemDetailScreen.kt @@ -6,19 +6,38 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable import io.github.droidkaigi.confsched2023.model.TimetableItem +import io.github.droidkaigi.confsched2023.model.TimetableItemId import io.github.droidkaigi.confsched2023.sessions.component.TimetableItemDetailContent import io.github.droidkaigi.confsched2023.sessions.component.TimetableItemDetailFooter import io.github.droidkaigi.confsched2023.sessions.component.TimetableItemDetailHeader import io.github.droidkaigi.confsched2023.sessions.component.TimetableItemDetailSummary import io.github.droidkaigi.confsched2023.sessions.strings.TimetableItemDetailViewModel -sealed class TimetableItemDetailScreenUiState() { - object Loading : TimetableItemDetailScreenUiState() - data class Loaded( - val timetableItem: TimetableItem, - val isBookmarked: Boolean, - ) : TimetableItemDetailScreenUiState() +const val timetableItemDetailScreenRouteItemIdParameterName = "timetableItemId" +const val timetableItemDetailScreenRoute = + "timetableItemDetail/{$timetableItemDetailScreenRouteItemIdParameterName}" + +fun NavGraphBuilder.sessionScreens(onNavigationIconClick: () -> Unit) { + composable(timetableItemDetailScreenRoute) { + TimetableItemDetailScreen( + onNavigationIconClick = onNavigationIconClick, + ) + } +} + +fun NavController.navigateToTimetableItemDetailScreen( + timetableItemId: TimetableItemId, +) { + navigate( + timetableItemDetailScreenRoute.replace( + "{$timetableItemDetailScreenRouteItemIdParameterName}", + timetableItemId.value, + ) + ) } @Composable @@ -34,6 +53,14 @@ fun TimetableItemDetailScreen( ) } +sealed class TimetableItemDetailScreenUiState() { + object Loading : TimetableItemDetailScreenUiState() + data class Loaded( + val timetableItem: TimetableItem, + val isBookmarked: Boolean, + ) : TimetableItemDetailScreenUiState() +} + @Composable private fun TimetableItemDetailScreen( uiState: TimetableItemDetailScreenUiState, diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableScreen.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableScreen.kt index 741acd111..eac2a12f4 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableScreen.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableScreen.kt @@ -16,6 +16,9 @@ import androidx.compose.ui.layout.layout import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable import io.github.droidkaigi.confsched2023.model.TimetableItem import io.github.droidkaigi.confsched2023.sessions.component.TimetableTopArea import io.github.droidkaigi.confsched2023.sessions.component.rememberTimetableScreenScrollState @@ -24,6 +27,23 @@ import io.github.droidkaigi.confsched2023.sessions.section.TimetableSheetUiState import io.github.droidkaigi.confsched2023.ui.SnackbarMessageEffect import kotlin.math.roundToInt +const val timetableScreenRoute = "timetable" +fun NavGraphBuilder.nestedSessionScreens( + onContributorsClick: () -> Unit, + onTimetableItemClick: (TimetableItem) -> Unit, +) { + composable(timetableScreenRoute) { + TimetableScreen( + onContributorsClick = onContributorsClick, + onTimetableItemClick = onTimetableItemClick, + ) + } +} + +fun NavController.navigateTimetableScreen() { + navigate(timetableScreenRoute) +} + const val TimetableScreenTestTag = "TimetableScreen" @Composable From 692fcc4b887282c3338199ae502f6338f7f1b030 Mon Sep 17 00:00:00 2001 From: takahirom Date: Sat, 8 Jul 2023 19:44:19 +0900 Subject: [PATCH 2/6] Add KaigiAppMainScreenStateHolder --- .../droidkaigi/confsched2023/KaigiApp.kt | 48 ++++++++++++------- .../confsched2023/main/MainScreen.kt | 30 +++++++----- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt b/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt index e62eb018f..635d45a76 100644 --- a/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt +++ b/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt @@ -9,6 +9,7 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost @@ -19,10 +20,12 @@ import io.github.droidkaigi.confsched2023.contributors.ContributorsScreen import io.github.droidkaigi.confsched2023.contributors.ContributorsViewModel import io.github.droidkaigi.confsched2023.contributors.contributorsScreenRoute import io.github.droidkaigi.confsched2023.designsystem.theme.KaigiTheme +import io.github.droidkaigi.confsched2023.main.MainScreenStateHolder +import io.github.droidkaigi.confsched2023.main.MainScreenTab import io.github.droidkaigi.confsched2023.main.MainScreenTab.Contributor import io.github.droidkaigi.confsched2023.main.MainScreenTab.Timetable import io.github.droidkaigi.confsched2023.main.mainScreenRoute -import io.github.droidkaigi.confsched2023.main.mainScreens +import io.github.droidkaigi.confsched2023.main.mainScreen import io.github.droidkaigi.confsched2023.sessions.nestedSessionScreens import io.github.droidkaigi.confsched2023.sessions.navigateTimetableScreen import io.github.droidkaigi.confsched2023.sessions.navigateToTimetableItemDetailScreen @@ -50,8 +53,9 @@ fun KaigiApp(modifier: Modifier = Modifier) { } @Composable -private fun KaigiNavHost(navController: NavHostController = rememberNavController()) { - +private fun KaigiNavHost( + navController: NavHostController = rememberNavController() +) { NavHost(navController = navController, startDestination = mainScreenRoute) { mainScreen(navController) sessionScreens( @@ -63,20 +67,8 @@ private fun KaigiNavHost(navController: NavHostController = rememberNavControlle } private fun NavGraphBuilder.mainScreen(navController: NavHostController) { - mainScreens( - onTabSelected = { mainNestedNavController, tab -> - when (tab) { - Timetable -> mainNestedNavController.navigateTimetableScreen() - Contributor -> mainNestedNavController.navigate(contributorsScreenRoute) - } - }, - routeToTab = { - when (this) { - timetableScreenRoute -> Timetable - contributorsScreenRoute -> Contributor - else -> null - } - }, + mainScreen( + mainNestedGraphStateHolder = KaigiAppMainScreenStateHolder(), mainNestedGraph = { mainNestedNavController, padding -> nestedSessionScreens( onTimetableItemClick = { timetableitem -> @@ -96,3 +88,25 @@ private fun NavGraphBuilder.mainScreen(navController: NavHostController) { } ) } + +class KaigiAppMainScreenStateHolder : MainScreenStateHolder { + override val startDestination: String = timetableScreenRoute + + override fun routeToTab(route: String): MainScreenTab? { + return when (route) { + timetableScreenRoute -> Timetable + contributorsScreenRoute -> Contributor + else -> null + } + } + + override fun onTabSelected( + mainNestedNavController: NavController, + tab: MainScreenTab + ) { + when (tab) { + Timetable -> mainNestedNavController.navigateTimetableScreen() + Contributor -> mainNestedNavController.navigate(contributorsScreenRoute) + } + } +} diff --git a/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt b/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt index 9fd727d04..43f30379f 100644 --- a/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt +++ b/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt @@ -26,15 +26,14 @@ import io.github.droidkaigi.confsched2023.main.strings.MainStrings import io.github.droidkaigi.confsched2023.ui.SnackbarMessageEffect const val mainScreenRoute = "main" -fun NavGraphBuilder.mainScreens( - onTabSelected: (mainNestedNavController: NavController, MainScreenTab) -> Unit, - routeToTab: String.() -> MainScreenTab?, + +fun NavGraphBuilder.mainScreen( + mainNestedGraphStateHolder: MainScreenStateHolder, mainNestedGraph: NavGraphBuilder.(mainNestedNavController: NavController, PaddingValues) -> Unit ) { composable(mainScreenRoute) { MainScreen( - onTabSelected = onTabSelected, - routeToTab = routeToTab, + mainScreenStateHolder = mainNestedGraphStateHolder, mainNestedNavGraph = mainNestedGraph, ) } @@ -42,12 +41,17 @@ fun NavGraphBuilder.mainScreens( const val MainScreenTestTag = "MainScreen" +interface MainScreenStateHolder { + val startDestination: String + fun routeToTab(route: String): MainScreenTab? + fun onTabSelected(mainNestedNavController: NavController, tab: MainScreenTab) +} + @Composable fun MainScreen( - onTabSelected: (NavController, MainScreenTab) -> Unit, - routeToTab: String.() -> MainScreenTab?, - mainNestedNavGraph: NavGraphBuilder.(NavController, PaddingValues) -> Unit, + mainScreenStateHolder: MainScreenStateHolder, viewModel: MainScreenViewModel = hiltViewModel(), + mainNestedNavGraph: NavGraphBuilder.(NavController, PaddingValues) -> Unit, ) { val uiState by viewModel.uiState.collectAsState() val snackbarHostState = SnackbarHostState() @@ -59,8 +63,8 @@ fun MainScreen( MainScreen( uiState = uiState, snackbarHostState = snackbarHostState, - routeToTab = routeToTab, - onTabSelected = onTabSelected, + routeToTab = mainScreenStateHolder::routeToTab, + onTabSelected = mainScreenStateHolder::onTabSelected, mainNestedNavGraph = mainNestedNavGraph, ) } @@ -114,9 +118,11 @@ private fun MainScreen( }, contentWindowInsets = WindowInsets(0.dp), ) { padding -> - NavHost(navController = mainNestedNavController, startDestination = "timetable") { + NavHost( + navController = mainNestedNavController, + startDestination = "timetable" + ) { mainNestedNavGraph(mainNestedNavController, padding) - } } } From 4631a93a8a74a969d802455507fa71a7505cd3a7 Mon Sep 17 00:00:00 2001 From: takahirom Date: Sat, 8 Jul 2023 19:52:39 +0900 Subject: [PATCH 3/6] Fix contributor click --- .../java/io/github/droidkaigi/confsched2023/KaigiApp.kt | 5 ----- core/testing/build.gradle.kts | 1 + .../confsched2023/testing/robot/KaigiAppRobot.kt | 5 +++-- .../github/droidkaigi/confsched2023/main/MainScreen.kt | 4 ++-- .../droidkaigi/confsched2023/sessions/TimetableScreen.kt | 6 ------ .../confsched2023/sessions/section/TimetableList.kt | 9 --------- .../confsched2023/sessions/section/TimetableSheet.kt | 2 -- 7 files changed, 6 insertions(+), 26 deletions(-) diff --git a/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt b/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt index 635d45a76..273370134 100644 --- a/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt +++ b/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt @@ -76,11 +76,6 @@ private fun NavGraphBuilder.mainScreen(navController: NavHostController) { timetableitem.id ) }, - onContributorsClick = { - // We don't abstract this logic because this screen is using Compose Multiplatform and - // Compose Navigation doesn't support Multiplatform yet - mainNestedNavController.navigate(contributorsScreenRoute) - }, ) composable(contributorsScreenRoute) { ContributorsScreen(hiltViewModel()) diff --git a/core/testing/build.gradle.kts b/core/testing/build.gradle.kts index 54f900361..39da6646c 100644 --- a/core/testing/build.gradle.kts +++ b/core/testing/build.gradle.kts @@ -13,6 +13,7 @@ dependencies { implementation(project(":core:designsystem")) implementation(project(":core:data")) implementation(project(":app-android")) + implementation(project(":feature:main")) implementation(project(":feature:sessions")) implementation(libs.daggerHiltAndroidTesting) diff --git a/core/testing/src/main/java/io/github/droidkaigi/confsched2023/testing/robot/KaigiAppRobot.kt b/core/testing/src/main/java/io/github/droidkaigi/confsched2023/testing/robot/KaigiAppRobot.kt index 301fb0dbd..b0ea7c178 100644 --- a/core/testing/src/main/java/io/github/droidkaigi/confsched2023/testing/robot/KaigiAppRobot.kt +++ b/core/testing/src/main/java/io/github/droidkaigi/confsched2023/testing/robot/KaigiAppRobot.kt @@ -2,9 +2,10 @@ package io.github.droidkaigi.confsched2023.testing.robot import androidx.compose.ui.test.isRoot import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.performClick import com.github.takahirom.roborazzi.captureRoboImage +import io.github.droidkaigi.confsched2023.main.MainScreenTab import io.github.droidkaigi.confsched2023.testing.RobotTestRule import kotlinx.coroutines.test.TestDispatcher import javax.inject.Inject @@ -33,7 +34,7 @@ class KaigiAppRobot @Inject constructor( fun goToContributor() { composeTestRule - .onNodeWithText("Go to ContributorsScreen") + .onNodeWithContentDescription(MainScreenTab.Contributor.contentDescription) .performClick() waitUntilIdle() } diff --git a/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt b/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt index 43f30379f..de7b85353 100644 --- a/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt +++ b/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt @@ -26,6 +26,8 @@ import io.github.droidkaigi.confsched2023.main.strings.MainStrings import io.github.droidkaigi.confsched2023.ui.SnackbarMessageEffect const val mainScreenRoute = "main" +const val MainScreenTestTag = "MainScreen" + fun NavGraphBuilder.mainScreen( mainNestedGraphStateHolder: MainScreenStateHolder, @@ -39,8 +41,6 @@ fun NavGraphBuilder.mainScreen( } } -const val MainScreenTestTag = "MainScreen" - interface MainScreenStateHolder { val startDestination: String fun routeToTab(route: String): MainScreenTab? diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableScreen.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableScreen.kt index eac2a12f4..44304909a 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableScreen.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableScreen.kt @@ -29,12 +29,10 @@ import kotlin.math.roundToInt const val timetableScreenRoute = "timetable" fun NavGraphBuilder.nestedSessionScreens( - onContributorsClick: () -> Unit, onTimetableItemClick: (TimetableItem) -> Unit, ) { composable(timetableScreenRoute) { TimetableScreen( - onContributorsClick = onContributorsClick, onTimetableItemClick = onTimetableItemClick, ) } @@ -48,7 +46,6 @@ const val TimetableScreenTestTag = "TimetableScreen" @Composable fun TimetableScreen( - onContributorsClick: () -> Unit, onTimetableItemClick: (TimetableItem) -> Unit, viewModel: TimetableScreenViewModel = hiltViewModel(), ) { @@ -63,7 +60,6 @@ fun TimetableScreen( uiState = uiState, snackbarHostState = snackbarHostState, onTimetableItemClick = onTimetableItemClick, - onContributorsClick = onContributorsClick, onBookmarkClick = viewModel::onBookmarkClick, onTimetableUiChangeClick = viewModel::onUiTypeChange, ) @@ -78,7 +74,6 @@ private fun TimetableScreen( uiState: TimetableScreenUiState, snackbarHostState: SnackbarHostState, onTimetableItemClick: (TimetableItem) -> Unit, - onContributorsClick: () -> Unit, onBookmarkClick: (TimetableItem) -> Unit, onTimetableUiChangeClick: () -> Unit, ) { @@ -112,7 +107,6 @@ private fun TimetableScreen( } }, onTimetableItemClick = onTimetableItemClick, - onContributorsClick = onContributorsClick, uiState = uiState.contentUiState, timetableScreenScrollState = state, onFavoriteClick = onBookmarkClick, diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableList.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableList.kt index 9cd0dd227..fe8153412 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableList.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableList.kt @@ -20,20 +20,11 @@ fun TimetableList( uiState: TimetableListUiState, onBookmarkClick: (TimetableItem) -> Unit, onTimetableItemClick: (TimetableItem) -> Unit, - onContributorsClick: () -> Unit, modifier: Modifier = Modifier, ) { LazyColumn( modifier = modifier.testTag(TimetableListTestTag), ) { - item { - Text( - text = "Go to ContributorsScreen", - modifier = Modifier.clickable { - onContributorsClick() - }, - ) - } items(uiState.timetable.timetableItems) { session -> val isBookmarked = uiState.timetable.bookmarks.contains(session.id) TimetableListItem( diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableSheet.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableSheet.kt index fef3de347..61852aef8 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableSheet.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableSheet.kt @@ -45,7 +45,6 @@ fun TimetableSheet( uiState: TimetableSheetUiState, timetableScreenScrollState: TimetableScreenScrollState, onTimetableItemClick: (TimetableItem) -> Unit, - onContributorsClick: () -> Unit, onFavoriteClick: (TimetableItem) -> Unit, modifier: Modifier = Modifier, ) { @@ -92,7 +91,6 @@ fun TimetableSheet( TimetableList( uiState = uiState.timetableListUiState, onTimetableItemClick = onTimetableItemClick, - onContributorsClick = onContributorsClick, onBookmarkClick = onFavoriteClick, modifier = Modifier .fillMaxSize() From 31543e6f3242ab2e4d7eebc894bed7e72e3237c8 Mon Sep 17 00:00:00 2001 From: takahirom Date: Sat, 8 Jul 2023 22:34:00 +0900 Subject: [PATCH 4/6] Format --- .../droidkaigi/confsched2023/KaigiApp.kt | 20 +++++++++---------- .../confsched2023/main/MainScreen.kt | 19 +++++++++--------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt b/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt index 273370134..4c406a8e2 100644 --- a/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt +++ b/app-android/src/main/java/io/github/droidkaigi/confsched2023/KaigiApp.kt @@ -20,15 +20,15 @@ import io.github.droidkaigi.confsched2023.contributors.ContributorsScreen import io.github.droidkaigi.confsched2023.contributors.ContributorsViewModel import io.github.droidkaigi.confsched2023.contributors.contributorsScreenRoute import io.github.droidkaigi.confsched2023.designsystem.theme.KaigiTheme -import io.github.droidkaigi.confsched2023.main.MainScreenStateHolder +import io.github.droidkaigi.confsched2023.main.MainNestedGraphStateHolder import io.github.droidkaigi.confsched2023.main.MainScreenTab import io.github.droidkaigi.confsched2023.main.MainScreenTab.Contributor import io.github.droidkaigi.confsched2023.main.MainScreenTab.Timetable -import io.github.droidkaigi.confsched2023.main.mainScreenRoute import io.github.droidkaigi.confsched2023.main.mainScreen -import io.github.droidkaigi.confsched2023.sessions.nestedSessionScreens +import io.github.droidkaigi.confsched2023.main.mainScreenRoute import io.github.droidkaigi.confsched2023.sessions.navigateTimetableScreen import io.github.droidkaigi.confsched2023.sessions.navigateToTimetableItemDetailScreen +import io.github.droidkaigi.confsched2023.sessions.nestedSessionScreens import io.github.droidkaigi.confsched2023.sessions.sessionScreens import io.github.droidkaigi.confsched2023.sessions.timetableScreenRoute @@ -54,37 +54,37 @@ fun KaigiApp(modifier: Modifier = Modifier) { @Composable private fun KaigiNavHost( - navController: NavHostController = rememberNavController() + navController: NavHostController = rememberNavController(), ) { NavHost(navController = navController, startDestination = mainScreenRoute) { mainScreen(navController) sessionScreens( onNavigationIconClick = { navController.popBackStack() - } + }, ) } } private fun NavGraphBuilder.mainScreen(navController: NavHostController) { mainScreen( - mainNestedGraphStateHolder = KaigiAppMainScreenStateHolder(), + mainNestedGraphStateHolder = KaigiAppMainNestedGraphStateHolder(), mainNestedGraph = { mainNestedNavController, padding -> nestedSessionScreens( onTimetableItemClick = { timetableitem -> navController.navigateToTimetableItemDetailScreen( - timetableitem.id + timetableitem.id, ) }, ) composable(contributorsScreenRoute) { ContributorsScreen(hiltViewModel()) } - } + }, ) } -class KaigiAppMainScreenStateHolder : MainScreenStateHolder { +class KaigiAppMainNestedGraphStateHolder : MainNestedGraphStateHolder { override val startDestination: String = timetableScreenRoute override fun routeToTab(route: String): MainScreenTab? { @@ -97,7 +97,7 @@ class KaigiAppMainScreenStateHolder : MainScreenStateHolder { override fun onTabSelected( mainNestedNavController: NavController, - tab: MainScreenTab + tab: MainScreenTab, ) { when (tab) { Timetable -> mainNestedNavController.navigateTimetableScreen() diff --git a/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt b/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt index de7b85353..9392f4e47 100644 --- a/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt +++ b/feature/main/src/main/java/io/github/droidkaigi/confsched2023/main/MainScreen.kt @@ -28,20 +28,19 @@ import io.github.droidkaigi.confsched2023.ui.SnackbarMessageEffect const val mainScreenRoute = "main" const val MainScreenTestTag = "MainScreen" - fun NavGraphBuilder.mainScreen( - mainNestedGraphStateHolder: MainScreenStateHolder, - mainNestedGraph: NavGraphBuilder.(mainNestedNavController: NavController, PaddingValues) -> Unit + mainNestedGraphStateHolder: MainNestedGraphStateHolder, + mainNestedGraph: NavGraphBuilder.(mainNestedNavController: NavController, PaddingValues) -> Unit, ) { composable(mainScreenRoute) { MainScreen( - mainScreenStateHolder = mainNestedGraphStateHolder, + mainNestedGraphStateHolder = mainNestedGraphStateHolder, mainNestedNavGraph = mainNestedGraph, ) } } -interface MainScreenStateHolder { +interface MainNestedGraphStateHolder { val startDestination: String fun routeToTab(route: String): MainScreenTab? fun onTabSelected(mainNestedNavController: NavController, tab: MainScreenTab) @@ -49,7 +48,7 @@ interface MainScreenStateHolder { @Composable fun MainScreen( - mainScreenStateHolder: MainScreenStateHolder, + mainNestedGraphStateHolder: MainNestedGraphStateHolder, viewModel: MainScreenViewModel = hiltViewModel(), mainNestedNavGraph: NavGraphBuilder.(NavController, PaddingValues) -> Unit, ) { @@ -63,8 +62,8 @@ fun MainScreen( MainScreen( uiState = uiState, snackbarHostState = snackbarHostState, - routeToTab = mainScreenStateHolder::routeToTab, - onTabSelected = mainScreenStateHolder::onTabSelected, + routeToTab = mainNestedGraphStateHolder::routeToTab, + onTabSelected = mainNestedGraphStateHolder::onTabSelected, mainNestedNavGraph = mainNestedNavGraph, ) } @@ -91,7 +90,7 @@ private fun MainScreen( snackbarHostState: SnackbarHostState, routeToTab: String.() -> MainScreenTab?, onTabSelected: (NavController, MainScreenTab) -> Unit, - mainNestedNavGraph: NavGraphBuilder.(NavController, PaddingValues) -> Unit + mainNestedNavGraph: NavGraphBuilder.(NavController, PaddingValues) -> Unit, ) { val mainNestedNavController = rememberNavController() val navBackStackEntry by mainNestedNavController.currentBackStackEntryAsState() @@ -120,7 +119,7 @@ private fun MainScreen( ) { padding -> NavHost( navController = mainNestedNavController, - startDestination = "timetable" + startDestination = "timetable", ) { mainNestedNavGraph(mainNestedNavController, padding) } From 032cd29d1b776c434a47d793d809b4dc86c75033 Mon Sep 17 00:00:00 2001 From: takahirom Date: Sat, 8 Jul 2023 22:35:07 +0900 Subject: [PATCH 5/6] Format --- .../confsched2023/sessions/TimetableItemDetailScreen.kt | 2 +- .../droidkaigi/confsched2023/sessions/section/TimetableList.kt | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableItemDetailScreen.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableItemDetailScreen.kt index 705bfe6c6..99eefd92a 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableItemDetailScreen.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/TimetableItemDetailScreen.kt @@ -36,7 +36,7 @@ fun NavController.navigateToTimetableItemDetailScreen( timetableItemDetailScreenRoute.replace( "{$timetableItemDetailScreenRouteItemIdParameterName}", timetableItemId.value, - ) + ), ) } diff --git a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableList.kt b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableList.kt index fe8153412..fe4812a77 100644 --- a/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableList.kt +++ b/feature/sessions/src/main/java/io/github/droidkaigi/confsched2023/sessions/section/TimetableList.kt @@ -1,9 +1,7 @@ package io.github.droidkaigi.confsched2023.sessions.section -import androidx.compose.foundation.clickable import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.testTag From eb2cd670b4d7b9c762a75204f61a43cf6135ebc0 Mon Sep 17 00:00:00 2001 From: takahirom Date: Sat, 8 Jul 2023 23:15:21 +0900 Subject: [PATCH 6/6] Fix compile --- .../confsched2023/testing/robot/TimetableScreenRobot.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/core/testing/src/main/java/io/github/droidkaigi/confsched2023/testing/robot/TimetableScreenRobot.kt b/core/testing/src/main/java/io/github/droidkaigi/confsched2023/testing/robot/TimetableScreenRobot.kt index b1d824d28..8cf0b800a 100644 --- a/core/testing/src/main/java/io/github/droidkaigi/confsched2023/testing/robot/TimetableScreenRobot.kt +++ b/core/testing/src/main/java/io/github/droidkaigi/confsched2023/testing/robot/TimetableScreenRobot.kt @@ -36,7 +36,6 @@ class TimetableScreenRobot @Inject constructor( composeTestRule.setContent { KaigiTheme { TimetableScreen( - onContributorsClick = { }, onTimetableItemClick = { }, ) }