From ad5a01b8d0847ba9dacc48dd00aa44dd3cc54035 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Sun, 6 Feb 2022 15:48:22 +0530 Subject: [PATCH] android: refactor and extract things from LobstersApp --- .../msfjarvis/claw/android/ui/ColorUtils.kt | 29 ----- .../msfjarvis/claw/android/ui/LobstersApp.kt | 34 ++---- .../claw/android/ui/PostActions.ext.kt | 36 ------- .../dev/msfjarvis/claw/android/ui/ext.kt | 100 ++++++++++++++++++ 4 files changed, 106 insertions(+), 93 deletions(-) delete mode 100644 android/src/main/kotlin/dev/msfjarvis/claw/android/ui/ColorUtils.kt delete mode 100644 android/src/main/kotlin/dev/msfjarvis/claw/android/ui/PostActions.ext.kt create mode 100644 android/src/main/kotlin/dev/msfjarvis/claw/android/ui/ext.kt diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/ColorUtils.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/ColorUtils.kt deleted file mode 100644 index e1c266ce..00000000 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/ColorUtils.kt +++ /dev/null @@ -1,29 +0,0 @@ -package dev.msfjarvis.claw.android.ui - -import android.content.Context -import android.os.Build -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material3.ColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme -import androidx.compose.runtime.Composable -import dev.msfjarvis.claw.common.theme.DarkThemeColors -import dev.msfjarvis.claw.common.theme.LightThemeColors - -@Composable -fun decideColorScheme(context: Context): ColorScheme { - val isDarkTheme = isSystemInDarkTheme() - return if (Build.VERSION.SDK_INT >= 31) { - if (isDarkTheme) { - dynamicDarkColorScheme(context) - } else { - dynamicLightColorScheme(context) - } - } else { - if (isDarkTheme) { - DarkThemeColors - } else { - LightThemeColors - } - } -} diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt index 1e4244d8..3fabf6fd 100644 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/LobstersApp.kt @@ -12,10 +12,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.nestedscroll.NestedScrollConnection -import androidx.compose.ui.input.nestedscroll.NestedScrollSource import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalUriHandler @@ -35,8 +32,6 @@ import dev.msfjarvis.claw.common.comments.LocalHTMLConverter import dev.msfjarvis.claw.common.theme.LobstersTheme import dev.msfjarvis.claw.common.urllauncher.UrlLauncher -private const val ScrollDelta = 50 - @OptIn(ExperimentalMaterial3Api::class) @Composable fun LobstersApp( @@ -45,34 +40,19 @@ fun LobstersApp( htmlConverter: HTMLConverter, setWebUri: (String) -> Unit, ) { + var isFabVisible by remember { mutableStateOf(false) } + val systemUiController = rememberSystemUiController() val networkListState = rememberLazyListState() val savedListState = rememberLazyListState() val navController = rememberNavController() val postActions = rememberPostActions(urlLauncher, navController, viewModel) - // The destination needs to be tracked here rather than used directly since - // `NavController#currentDestination` is not a Composable state. - var currentDestination by remember { mutableStateOf(null) } - var isFabVisible by remember { mutableStateOf(false) } - val nestedScrollConnection = remember { - object : NestedScrollConnection { - override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { - val delta = available.y + val currentDestination by currentNavigationDestination(navController) + val nestedScrollConnection = rememberNestedScrollConnection { isFabVisible = it } - if (delta > ScrollDelta) { - isFabVisible = true - } else if (delta < -ScrollDelta) { - isFabVisible = false - } + val networkPosts = viewModel.pagerFlow.collectAsLazyPagingItems() + val savedPosts by viewModel.savedPosts.collectAsState(emptyList()) - // We didn't consume any offset here so return Offset.Zero - return Offset.Zero - } - } - } - navController.addOnDestinationChangedListener { _, destination, _ -> - currentDestination = destination.route ?: Destinations.Hottest.getRoute() - } LobstersTheme( LocalUriHandler provides urlLauncher, LocalHTMLConverter provides htmlConverter, @@ -85,8 +65,6 @@ fun LobstersApp( systemUiController.setStatusBarColor(color = statusBarColor) systemUiController.setNavigationBarColor(color = Color.Transparent) } - val networkPosts = viewModel.pagerFlow.collectAsLazyPagingItems() - val savedPosts by viewModel.savedPosts.collectAsState(emptyList()) Scaffold( topBar = { ClawAppBar(modifier = Modifier.statusBarsPadding()) }, diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/PostActions.ext.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/PostActions.ext.kt deleted file mode 100644 index 43e92450..00000000 --- a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/PostActions.ext.kt +++ /dev/null @@ -1,36 +0,0 @@ -package dev.msfjarvis.claw.android.ui - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.navigation.NavController -import dev.msfjarvis.claw.android.viewmodel.ClawViewModel -import dev.msfjarvis.claw.common.posts.PostActions -import dev.msfjarvis.claw.common.urllauncher.UrlLauncher -import dev.msfjarvis.claw.database.local.SavedPost - -@Composable -fun rememberPostActions( - urlLauncher: UrlLauncher, - navController: NavController, - viewModel: ClawViewModel, -): PostActions { - return remember { - object : PostActions { - override fun viewPost(postUrl: String, commentsUrl: String) { - urlLauncher.openUri(postUrl.ifEmpty { commentsUrl }) - } - - override fun viewComments(postId: String) { - navController.navigate(Destinations.Comments.getRoute(postId)) - } - - override fun viewCommentsPage(commentsUrl: String) { - urlLauncher.openUri(commentsUrl) - } - - override fun toggleSave(post: SavedPost) { - viewModel.toggleSave(post) - } - } - } -} diff --git a/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/ext.kt b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/ext.kt new file mode 100644 index 00000000..b4f63804 --- /dev/null +++ b/android/src/main/kotlin/dev/msfjarvis/claw/android/ui/ext.kt @@ -0,0 +1,100 @@ +package dev.msfjarvis.claw.android.ui + +import android.content.Context +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.input.nestedscroll.NestedScrollConnection +import androidx.compose.ui.input.nestedscroll.NestedScrollSource +import androidx.navigation.NavController +import dev.msfjarvis.claw.android.viewmodel.ClawViewModel +import dev.msfjarvis.claw.common.posts.PostActions +import dev.msfjarvis.claw.common.theme.DarkThemeColors +import dev.msfjarvis.claw.common.theme.LightThemeColors +import dev.msfjarvis.claw.common.urllauncher.UrlLauncher +import dev.msfjarvis.claw.database.local.SavedPost + +// The destination needs to be tracked like this rather than used directly since +// `NavController#currentDestination` is not a Composable state. +@Composable +fun currentNavigationDestination(navController: NavController): State { + val currentDestination = remember { mutableStateOf(null) } + navController.addOnDestinationChangedListener { _, destination, _ -> + currentDestination.value = destination.route + } + return currentDestination +} + +@Composable +fun decideColorScheme(context: Context): ColorScheme { + val isDarkTheme = isSystemInDarkTheme() + return if (Build.VERSION.SDK_INT >= 31) { + if (isDarkTheme) { + dynamicDarkColorScheme(context) + } else { + dynamicLightColorScheme(context) + } + } else { + if (isDarkTheme) { + DarkThemeColors + } else { + LightThemeColors + } + } +} + +@Composable +fun rememberPostActions( + urlLauncher: UrlLauncher, + navController: NavController, + viewModel: ClawViewModel, +): PostActions { + return remember { + object : PostActions { + override fun viewPost(postUrl: String, commentsUrl: String) { + urlLauncher.openUri(postUrl.ifEmpty { commentsUrl }) + } + + override fun viewComments(postId: String) { + navController.navigate(Destinations.Comments.getRoute(postId)) + } + + override fun viewCommentsPage(commentsUrl: String) { + urlLauncher.openUri(commentsUrl) + } + + override fun toggleSave(post: SavedPost) { + viewModel.toggleSave(post) + } + } + } +} + +private const val ScrollDelta = 50 + +@Composable +fun rememberNestedScrollConnection(setVisibility: (Boolean) -> Unit): NestedScrollConnection { + return remember { + object : NestedScrollConnection { + override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { + val delta = available.y + + if (delta > ScrollDelta) { + setVisibility(true) + } else if (delta < -ScrollDelta) { + setVisibility(false) + } + + // We didn't consume any offset here so return Offset.Zero + return Offset.Zero + } + } + } +}