diff --git a/app/src/main/kotlin/com/livetl/android/ui/MainActivity.kt b/app/src/main/kotlin/com/livetl/android/ui/MainActivity.kt index 02e6a32..9b8226d 100644 --- a/app/src/main/kotlin/com/livetl/android/ui/MainActivity.kt +++ b/app/src/main/kotlin/com/livetl/android/ui/MainActivity.kt @@ -13,8 +13,8 @@ import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsControllerCompat import androidx.navigation.NavHostController -import com.livetl.android.ui.navigation.mainNavHost import com.livetl.android.ui.navigation.Route +import com.livetl.android.ui.navigation.mainNavHost import com.livetl.android.ui.navigation.navigateToPlayer import com.livetl.android.ui.theme.LiveTLTheme import com.livetl.android.util.AppPreferences diff --git a/app/src/main/kotlin/com/livetl/android/ui/navigation/MainNavHost.kt b/app/src/main/kotlin/com/livetl/android/ui/navigation/MainNavHost.kt index 70099b2..518a06b 100644 --- a/app/src/main/kotlin/com/livetl/android/ui/navigation/MainNavHost.kt +++ b/app/src/main/kotlin/com/livetl/android/ui/navigation/MainNavHost.kt @@ -2,6 +2,9 @@ package com.livetl.android.ui.navigation import androidx.compose.foundation.background import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.navigation.ModalBottomSheetLayout +import androidx.compose.material.navigation.bottomSheet +import androidx.compose.material.navigation.rememberBottomSheetNavigator import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -12,26 +15,20 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument import androidx.navigation.plusAssign -import com.google.accompanist.navigation.material.ModalBottomSheetLayout -import com.google.accompanist.navigation.material.bottomSheet -import com.google.accompanist.navigation.material.rememberBottomSheetNavigator +import androidx.navigation.toRoute import com.livetl.android.ui.screen.about.AboutScreen import com.livetl.android.ui.screen.about.LicensesScreen import com.livetl.android.ui.screen.home.HomeScreen -import com.livetl.android.ui.screen.home.HomeViewModel import com.livetl.android.ui.screen.home.composable.StreamInfo -import com.livetl.android.ui.screen.home.composable.StreamInfoViewModel import com.livetl.android.ui.screen.home.settings.SettingsScreen -import com.livetl.android.ui.screen.home.settings.SettingsViewModel import com.livetl.android.ui.screen.player.PlayerScreen import com.livetl.android.ui.screen.player.PlayerViewModel import com.livetl.android.ui.screen.welcome.WelcomeScreen -import com.livetl.android.ui.screen.welcome.WelcomeViewModel fun NavHostController.navigateToPlayer(urlOrId: String) { - navigate("${Route.Player.id}?urlOrId=$urlOrId") { + navigate(Route.Player(urlOrId)) { launchSingleTop = true - popUpTo(Route.Home.id) {} + popUpTo(Route.Home) {} } } @@ -56,72 +53,58 @@ fun mainNavHost( .fillMaxSize() .background(MaterialTheme.colorScheme.background), ) { - NavHost(navController, startDestination = startRoute.id) { - composable(Route.Home.id) { - val homeViewModel = hiltViewModel() - + NavHost(navController, startDestination = startRoute) { + composable { HomeScreen( - navigateToStreamInfo = { navController.navigate("${Route.StreamInfo.id}?urlOrId=$it") }, + navigateToStreamInfo = { navController.navigate("${Route.StreamInfo}?urlOrId=$it") }, navigateToPlayer = { navController.navigateToPlayer(it) }, - navigateToSettings = { navController.navigate(Route.Settings.id) }, - navigateToAbout = { navController.navigate(Route.About.id) }, - viewModel = homeViewModel, + navigateToSettings = { navController.navigate(Route.Settings) }, + navigateToAbout = { navController.navigate(Route.About) }, ) } + // TODO: use typesafe data class when possible bottomSheet( - "${Route.StreamInfo.id}?urlOrId={urlOrId}", + "${Route.StreamInfo}?urlOrId={urlOrId}", arguments = listOf(navArgument("urlOrId") { defaultValue = "" }), ) { backStackEntry -> - val streamInfoViewModel = hiltViewModel() - val urlOrId = backStackEntry.arguments?.getString("urlOrId")!! StreamInfo( urlOrId = urlOrId, - viewModel = streamInfoViewModel, ) } - composable(Route.Welcome.id) { - val welcomeViewModel = hiltViewModel() - + composable { WelcomeScreen( - navigateToHome = { navController.navigate(Route.Home.id) }, - viewModel = welcomeViewModel, + navigateToHome = { navController.navigate(Route.Home) }, ) } - composable( - "${Route.Player.id}?urlOrId={urlOrId}", - arguments = listOf(navArgument("urlOrId") { defaultValue = "" }), - ) { backStackEntry -> + composable { backStackEntry -> val playerViewModel = hiltViewModel() - val urlOrId = backStackEntry.arguments?.getString("urlOrId")!! + val urlOrId = backStackEntry.toRoute().urlOrId val videoId = playerViewModel.getVideoId(urlOrId) PlayerScreen(videoId, setKeepScreenOn, setFullscreen, playerViewModel) } - composable(Route.Settings.id) { - val settingsViewModel = hiltViewModel() - + composable { SettingsScreen( onBackPressed = { navigateBack() }, - viewModel = settingsViewModel, ) } - composable(Route.About.id) { + composable { AboutScreen( onBackPressed = { navigateBack() }, - navigateToLicenses = { navController.navigate(Route.Licenses.id) }, - navigateToWelcome = { navController.navigate(Route.Welcome.id) }, + navigateToLicenses = { navController.navigate(Route.Licenses) }, + navigateToWelcome = { navController.navigate(Route.Welcome) }, ) } - composable(Route.Licenses.id) { + composable { LicensesScreen( onBackPressed = { navigateBack() }, ) diff --git a/app/src/main/kotlin/com/livetl/android/ui/navigation/Routes.kt b/app/src/main/kotlin/com/livetl/android/ui/navigation/Routes.kt index e82241f..ed0ac31 100644 --- a/app/src/main/kotlin/com/livetl/android/ui/navigation/Routes.kt +++ b/app/src/main/kotlin/com/livetl/android/ui/navigation/Routes.kt @@ -1,17 +1,26 @@ package com.livetl.android.ui.navigation -sealed class Route(val id: String) { - data object Home : Route("home") +import kotlinx.serialization.Serializable - data object StreamInfo : Route("stream") +sealed interface Route { + @Serializable + data object Home : Route - data object Welcome : Route("welcome") + @Serializable + data class StreamInfo(val urlOrId: String) : Route - data object Player : Route("player") + @Serializable + data object Welcome : Route - data object Settings : Route("settings") + @Serializable + data class Player(val urlOrId: String) : Route - data object About : Route("about") + @Serializable + data object Settings : Route - data object Licenses : Route("licenses") + @Serializable + data object Licenses : Route + + @Serializable + data object About : Route } diff --git a/app/src/main/kotlin/com/livetl/android/ui/screen/home/HomeScreen.kt b/app/src/main/kotlin/com/livetl/android/ui/screen/home/HomeScreen.kt index 75eb7d6..fe71dd5 100644 --- a/app/src/main/kotlin/com/livetl/android/ui/screen/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/livetl/android/ui/screen/home/HomeScreen.kt @@ -29,6 +29,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import com.livetl.android.R import com.livetl.android.data.feed.Stream import com.livetl.android.ui.common.TabIndicator @@ -41,7 +42,7 @@ fun HomeScreen( navigateToPlayer: (String) -> Unit, navigateToSettings: () -> Unit, navigateToAbout: () -> Unit, - viewModel: HomeViewModel, + viewModel: HomeViewModel = hiltViewModel(), ) { val coroutineScope = rememberCoroutineScope() val pagerState = rememberPagerState { viewModel.tabs.size } diff --git a/app/src/main/kotlin/com/livetl/android/ui/screen/home/composable/StreamInfo.kt b/app/src/main/kotlin/com/livetl/android/ui/screen/home/composable/StreamInfo.kt index 131ca1b..13942c3 100644 --- a/app/src/main/kotlin/com/livetl/android/ui/screen/home/composable/StreamInfo.kt +++ b/app/src/main/kotlin/com/livetl/android/ui/screen/home/composable/StreamInfo.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import coil.compose.AsyncImage import com.livetl.android.R import com.livetl.android.data.feed.Stream @@ -39,7 +40,7 @@ import kotlinx.coroutines.launch @Composable fun StreamInfo( urlOrId: String, - viewModel: StreamInfoViewModel, + viewModel: StreamInfoViewModel = hiltViewModel(), ) { val coroutineScope = rememberCoroutineScope() var loading by remember { mutableStateOf(true) } diff --git a/app/src/main/kotlin/com/livetl/android/ui/screen/home/settings/SettingsScreen.kt b/app/src/main/kotlin/com/livetl/android/ui/screen/home/settings/SettingsScreen.kt index 458a122..7eb12b0 100644 --- a/app/src/main/kotlin/com/livetl/android/ui/screen/home/settings/SettingsScreen.kt +++ b/app/src/main/kotlin/com/livetl/android/ui/screen/home/settings/SettingsScreen.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import com.livetl.android.R import com.livetl.android.data.feed.ORGANIZATIONS import com.livetl.android.util.collectAsState @@ -33,7 +34,7 @@ import com.livetl.android.util.collectAsState @Composable fun SettingsScreen( onBackPressed: () -> Unit, - viewModel: SettingsViewModel, + viewModel: SettingsViewModel = hiltViewModel(), ) { val selectedOrganization by viewModel.prefs.feedOrganization().collectAsState() @@ -59,9 +60,9 @@ fun SettingsScreen( ) { contentPadding -> LazyColumn( modifier = - Modifier - .fillMaxWidth() - .padding(contentPadding), + Modifier + .fillMaxWidth() + .padding(contentPadding), ) { items( items = ORGANIZATIONS, diff --git a/app/src/main/kotlin/com/livetl/android/ui/screen/player/PlayerScreen.kt b/app/src/main/kotlin/com/livetl/android/ui/screen/player/PlayerScreen.kt index e942fe6..8dfff13 100644 --- a/app/src/main/kotlin/com/livetl/android/ui/screen/player/PlayerScreen.kt +++ b/app/src/main/kotlin/com/livetl/android/ui/screen/player/PlayerScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.viewinterop.AndroidView +import androidx.hilt.navigation.compose.hiltViewModel import com.livetl.android.data.stream.StreamInfo import com.livetl.android.ui.common.LoadingIndicator import com.livetl.android.util.collectAsState @@ -33,7 +34,7 @@ fun PlayerScreen( videoId: String, setKeepScreenOn: (Boolean) -> Unit, toggleFullscreen: (Boolean) -> Unit, - viewModel: PlayerViewModel, + viewModel: PlayerViewModel = hiltViewModel(), ) { val coroutineScope = rememberCoroutineScope() val context = LocalContext.current diff --git a/app/src/main/kotlin/com/livetl/android/ui/screen/welcome/WelcomeScreen.kt b/app/src/main/kotlin/com/livetl/android/ui/screen/welcome/WelcomeScreen.kt index cce0719..6d6dea5 100644 --- a/app/src/main/kotlin/com/livetl/android/ui/screen/welcome/WelcomeScreen.kt +++ b/app/src/main/kotlin/com/livetl/android/ui/screen/welcome/WelcomeScreen.kt @@ -23,12 +23,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import com.livetl.android.R @Composable fun WelcomeScreen( navigateToHome: () -> Unit, - viewModel: WelcomeViewModel, + viewModel: WelcomeViewModel = hiltViewModel(), ) { Scaffold( topBar = { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6981c18..9251dd0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -37,7 +37,7 @@ compose-activity = { module = "androidx.activity:activity-compose", version = "1 compose-lintchecks = { module = "com.slack.lint.compose:compose-lint-checks", version = "1.3.1" } navigation-compose = "androidx.navigation:navigation-compose:2.8.0-beta01" -navigation-accompanist = "com.google.accompanist:accompanist-navigation-material:0.35.1-alpha" +compose-material-navigation = { module = "androidx.compose.material:material-navigation", version = "1.7.0-beta01" } coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines_version" } coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines_version" } @@ -65,5 +65,5 @@ compose = ["compose-activity", "compose-material", "compose-material-icons-exten compose-debug = ["compose-ui-tooling-debug"] coroutines = ["coroutines-core", "coroutines-android"] ktor = ["ktor-core", "ktor-logging"] -navigation = ["navigation-compose", "navigation-accompanist", "hilt-navigation"] +navigation = ["navigation-compose", "compose-material-navigation", "hilt-navigation"] preferences = ["preferences-androidx", "preferences-flow"] \ No newline at end of file