From bce57efd53474ad1b4583d5c6cc6a067cb1e68b0 Mon Sep 17 00:00:00 2001 From: joeloewi7178 Date: Fri, 12 Jan 2024 00:57:47 +0900 Subject: [PATCH 1/4] mod: replace object to data object if possible mod: enableEdgeToEdge calling position mod: setStartDestination instead of navigateTo in emptyScreen --- .../com/joeloewi/croissant/MainActivity.kt | 102 ++++++++++-------- .../ResinStatusWidgetConfigurationActivity.kt | 13 +-- .../attendances/AttendancesDestination.kt | 56 +++++++--- .../main/global/GlobalDestination.kt | 8 +- .../RedemptionCodesDestination.kt | 8 +- .../main/settings/SettingsDestination.kt | 12 +-- ...esinStatusWidgetConfigurationNavigation.kt | 2 +- ...sinStatusWidgetConfigurationDestination.kt | 27 +++-- .../croissant/util/NotificationGenerator.kt | 4 +- 9 files changed, 134 insertions(+), 98 deletions(-) diff --git a/app/src/main/kotlin/com/joeloewi/croissant/MainActivity.kt b/app/src/main/kotlin/com/joeloewi/croissant/MainActivity.kt index 27477bd6..c64fc08d 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/MainActivity.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/MainActivity.kt @@ -108,9 +108,10 @@ class MainActivity : AppCompatActivity() { @SuppressLint("HardwareIds") override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() - enableEdgeToEdge() super.onCreate(savedInstanceState) + enableEdgeToEdge() + DynamicColors.applyToActivityIfAvailable(this) lifecycleScope.launch { @@ -125,12 +126,14 @@ class MainActivity : AppCompatActivity() { } } - Firebase.analytics.setUserId( - Settings.Secure.getString( - contentResolver, - Settings.Secure.ANDROID_ID + lifecycleScope.launch(Dispatchers.IO + CoroutineExceptionHandler { _, _ -> }) { + Firebase.analytics.setUserId( + Settings.Secure.getString( + contentResolver, + Settings.Secure.ANDROID_ID + ) ) - ) + } setContent { CroissantTheme { @@ -155,7 +158,6 @@ class MainActivity : AppCompatActivity() { } } -@SuppressLint("RestrictedApi") @OptIn(ExperimentalMaterial3WindowSizeClassApi::class) @Composable fun CroissantApp( @@ -179,7 +181,6 @@ fun CroissantApp( GlobalDestination.EmptyScreen.route ).toImmutableList() } - val currentBackStack by navController.currentBackStack.collectAsStateWithLifecycle() val windowSizeClass = calculateWindowSizeClass(activity = activity) val croissantNavigations = remember { listOf( @@ -206,9 +207,9 @@ fun CroissantApp( Scaffold( contentWindowInsets = WindowInsets.systemBars.only(WindowInsetsSides.Horizontal), bottomBar = { - val currentBackStackEntry by navController.currentBackStackEntryFlow.collectAsStateWithLifecycle( - initialValue = null, - ) + val currentBackStackEntry by remember(navController) { + navController.currentBackStackEntryFlow + }.collectAsStateWithLifecycle(initialValue = null) val isBottomNavigationBarVisible by remember { derivedStateOf { !fullScreenDestinations.any { route -> @@ -226,26 +227,7 @@ fun CroissantApp( currentBackStackEntry = { currentBackStackEntry }, onClickNavigationButton = { route -> navController.navigate(route) { - val startDestination = - navController.graph.findStartDestination() - - val popUpToDestination = - if (currentBackStack.any { - it.destination == startDestination - }) { - - startDestination.route - ?: activity::class.java.simpleName - } else if (currentBackStack.any { - it.destination.route == AttendancesDestination.AttendancesScreen.route - }) { - - AttendancesDestination.AttendancesScreen.route - } else { - activity::class.java.simpleName - } - - popUpTo(popUpToDestination) { + popUpTo(navController.graph.findStartDestination().id) { saveState = true } launchSingleTop = true @@ -422,9 +404,7 @@ fun CroissantNavHost( composable( route = AttendancesDestination.AttendanceDetailScreen().route, arguments = AttendancesDestination.AttendanceDetailScreen().arguments.map { argument -> - navArgument(argument.first) { - type = argument.second - } + navArgument(argument.first, argument.second) }, deepLinks = listOf( navDeepLink { @@ -432,14 +412,40 @@ fun CroissantNavHost( "$deepLinkUri/${AttendancesDestination.AttendanceDetailScreen().route}" } ) - ) { + ) { navBackStackEntry -> + val fromDeeplink = remember(navBackStackEntry.arguments) { + navBackStackEntry.arguments?.getBoolean(AttendancesDestination.AttendanceDetailScreen.FROM_DEEPLINK) + ?: false + } val newCookie by remember { - it.savedStateHandle.getStateFlow(COOKIE, "") + navBackStackEntry.savedStateHandle.getStateFlow(COOKIE, "") }.collectAsStateWithLifecycle() + LaunchedEffect(fromDeeplink) { + if (fromDeeplink) { + with(navController.value.graph) { + findNode(CroissantNavigation.Attendances.route)?.id?.let { + setStartDestination( + it + ) + } + } + } + } + AttendanceDetailScreen( newCookie = { newCookie }, - onNavigateUp = { navController.value.navigateUp() }, + onNavigateUp = { + if (fromDeeplink) { + with(navController.value.graph) { + findNode(CroissantNavigation.Attendances.route)?.id?.let { + navController.value.popBackStack(it, inclusive = true) + } + } + } else { + navController.value.navigateUp() + } + }, onClickRefreshSession = { navController.value.navigate(AttendancesDestination.LoginHoYoLabScreen.route) }, @@ -457,9 +463,7 @@ fun CroissantNavHost( composable( route = AttendancesDestination.AttendanceLogsCalendarScreen().route, arguments = AttendancesDestination.AttendanceLogsCalendarScreen().arguments.map { argument -> - navArgument(argument.first) { - type = argument.second - } + navArgument(argument.first, argument.second) } ) { AttendanceLogsCalendarScreen( @@ -479,9 +483,7 @@ fun CroissantNavHost( composable( route = AttendancesDestination.AttendanceLogsDayScreen().route, arguments = AttendancesDestination.AttendanceLogsDayScreen().arguments.map { argument -> - navArgument(argument.first) { - type = argument.second - } + navArgument(argument.first, argument.second) } ) { AttendanceLogsDayScreen( @@ -534,6 +536,13 @@ fun CroissantNavHost( } }, onShowDefaultScreen = { + with(navController.value.graph) { + findNode(CroissantNavigation.Attendances.route)?.id?.let { + setStartDestination( + it + ) + } + } navController.value.navigate(AttendancesDestination.AttendancesScreen.route) { popUpTo(activity::class.java.simpleName) { inclusive = true @@ -546,6 +555,13 @@ fun CroissantNavHost( composable(route = GlobalDestination.FirstLaunchScreen.route) { FirstLaunchScreen( onNavigateToAttendances = { + with(navController.value.graph) { + findNode(CroissantNavigation.Attendances.route)?.id?.let { + setStartDestination( + it + ) + } + } navController.value.navigate(AttendancesDestination.AttendancesScreen.route) { popUpTo(activity::class.java.simpleName) { inclusive = true diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ResinStatusWidgetConfigurationActivity.kt b/app/src/main/kotlin/com/joeloewi/croissant/ResinStatusWidgetConfigurationActivity.kt index 733e957e..18ca2966 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ResinStatusWidgetConfigurationActivity.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ResinStatusWidgetConfigurationActivity.kt @@ -143,10 +143,7 @@ fun ResinStatusWidgetConfigurationApp() { composable( route = ResinStatusWidgetConfigurationDestination.LoadingScreen().route, arguments = ResinStatusWidgetConfigurationDestination.LoadingScreen().arguments.map { argument -> - navArgument(argument.first) { - type = argument.second - defaultValue = AppWidgetManager.INVALID_APPWIDGET_ID - } + navArgument(argument.first, argument.second) } ) { val loadingViewModel: LoadingViewModel = hiltViewModel() @@ -160,9 +157,7 @@ fun ResinStatusWidgetConfigurationApp() { composable( route = ResinStatusWidgetConfigurationDestination.CreateResinStatusWidgetScreen().route, arguments = ResinStatusWidgetConfigurationDestination.CreateResinStatusWidgetScreen().arguments.map { argument -> - navArgument(argument.first) { - type = argument.second - } + navArgument(argument.first, argument.second) }, ) { val newCookie by remember { @@ -196,9 +191,7 @@ fun ResinStatusWidgetConfigurationApp() { composable( route = ResinStatusWidgetConfigurationDestination.ResinStatusWidgetDetailScreen().route, arguments = ResinStatusWidgetConfigurationDestination.ResinStatusWidgetDetailScreen().arguments.map { argument -> - navArgument(argument.first) { - type = argument.second - } + navArgument(argument.first, argument.second) } ) { ResinStatusWidgetDetailScreen() diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/AttendancesDestination.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/AttendancesDestination.kt index 35370b2b..031dd35c 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/AttendancesDestination.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/AttendancesDestination.kt @@ -1,10 +1,11 @@ package com.joeloewi.croissant.ui.navigation.main.attendances +import androidx.navigation.NavArgumentBuilder import androidx.navigation.NavType import com.joeloewi.croissant.domain.common.LoggableWorker sealed class AttendancesDestination { - abstract val arguments: List>> + abstract val arguments: List Unit>> protected abstract val plainRoute: String val route: String get() = "${plainRoute}${ @@ -18,33 +19,44 @@ sealed class AttendancesDestination { ) { "{$it}" } }" - object AttendancesScreen : AttendancesDestination() { - override val arguments: List>> = listOf() + data object AttendancesScreen : AttendancesDestination() { + override val arguments: List Unit>> = listOf() override val plainRoute = "attendancesScreen" } - object CreateAttendanceScreen : AttendancesDestination() { - override val arguments: List>> = listOf() + data object CreateAttendanceScreen : AttendancesDestination() { + override val arguments: List Unit>> = listOf() override val plainRoute = "createAttendanceScreen" } - object LoginHoYoLabScreen : AttendancesDestination() { - override val arguments: List>> = listOf() + data object LoginHoYoLabScreen : AttendancesDestination() { + override val arguments: List Unit>> = listOf() override val plainRoute = "loginHoYoLabScreen" } class AttendanceDetailScreen : AttendancesDestination() { companion object { const val ATTENDANCE_ID = "attendanceId" + const val FROM_DEEPLINK = "fromDeeplink" } - override val arguments: List>> = listOf( - ATTENDANCE_ID to NavType.LongType + override val arguments: List Unit)>> = listOf( + ATTENDANCE_ID to { + type = NavType.LongType + + }, + FROM_DEEPLINK to { + type = NavType.BoolType + defaultValue = false + } ) override val plainRoute: String = "attendanceDetailScreen" - fun generateRoute(attendanceId: Long) = "${plainRoute}/${attendanceId}" + fun generateRoute( + attendanceId: Long, + fromDeeplink: Boolean = false + ) = "${plainRoute}/${attendanceId}/${fromDeeplink}" } class AttendanceLogsCalendarScreen : AttendancesDestination() { @@ -53,9 +65,13 @@ sealed class AttendancesDestination { const val LOGGABLE_WORKER = "loggableWorker" } - override val arguments: List>> = listOf( - ATTENDANCE_ID to NavType.LongType, - LOGGABLE_WORKER to NavType.EnumType(LoggableWorker::class.java) + override val arguments: List Unit>> = listOf( + ATTENDANCE_ID to { + type = NavType.LongType + }, + LOGGABLE_WORKER to { + type = NavType.EnumType(LoggableWorker::class.java) + } ) override val plainRoute: String = "attendanceLogsCalendarScreen" @@ -71,10 +87,16 @@ sealed class AttendancesDestination { const val LOCAL_DATE = "localDate" } - override val arguments: List>> = listOf( - ATTENDANCE_ID to NavType.LongType, - LOGGABLE_WORKER to NavType.EnumType(LoggableWorker::class.java), - LOCAL_DATE to NavType.StringType + override val arguments: List Unit>> = listOf( + ATTENDANCE_ID to { + type = NavType.LongType + }, + LOGGABLE_WORKER to { + type = NavType.EnumType(LoggableWorker::class.java) + }, + LOCAL_DATE to { + type = NavType.StringType + } ) override val plainRoute: String = "attendanceLogsDayScreen" diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/global/GlobalDestination.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/global/GlobalDestination.kt index 3bdab030..f3511230 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/global/GlobalDestination.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/global/GlobalDestination.kt @@ -1,9 +1,9 @@ package com.joeloewi.croissant.ui.navigation.main.global -import androidx.navigation.NavType +import androidx.navigation.NavArgumentBuilder sealed class GlobalDestination { - abstract val arguments: List>> + abstract val arguments: List Unit>> abstract val plainRoute: String open val route: String get() = "${plainRoute}${ @@ -18,12 +18,12 @@ sealed class GlobalDestination { }" data object EmptyScreen : GlobalDestination() { - override val arguments: List>> = emptyList() + override val arguments: List Unit>> = emptyList() override val plainRoute: String = "EmptyScreen" } data object FirstLaunchScreen : GlobalDestination() { - override val arguments: List>> = listOf() + override val arguments: List Unit>> = listOf() override val plainRoute = "firstLaunchScreen" } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/redemptioncodes/RedemptionCodesDestination.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/redemptioncodes/RedemptionCodesDestination.kt index 771689fc..421ee85b 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/redemptioncodes/RedemptionCodesDestination.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/redemptioncodes/RedemptionCodesDestination.kt @@ -1,9 +1,9 @@ package com.joeloewi.croissant.ui.navigation.main.redemptioncodes -import androidx.navigation.NavType +import androidx.navigation.NavArgumentBuilder sealed class RedemptionCodesDestination { - abstract val arguments: List>> + abstract val arguments: List Unit>> protected abstract val plainRoute: String val route: String by lazy { "${plainRoute}${ @@ -18,8 +18,8 @@ sealed class RedemptionCodesDestination { }" } - object RedemptionCodesScreen : RedemptionCodesDestination() { - override val arguments: List>> = listOf() + data object RedemptionCodesScreen : RedemptionCodesDestination() { + override val arguments: List Unit>> = listOf() override val plainRoute: String = "redemptionCodesScreen" } } diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/settings/SettingsDestination.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/settings/SettingsDestination.kt index 8d105aab..a96a76a6 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/settings/SettingsDestination.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/settings/SettingsDestination.kt @@ -1,9 +1,9 @@ package com.joeloewi.croissant.ui.navigation.main.settings -import androidx.navigation.NavType +import androidx.navigation.NavArgumentBuilder sealed class SettingsDestination { - abstract val arguments: List>> + abstract val arguments: List Unit>> protected abstract val plainRoute: String val route: String by lazy { "${plainRoute}${ @@ -18,13 +18,13 @@ sealed class SettingsDestination { }" } - object SettingsScreen : SettingsDestination() { - override val arguments: List>> = listOf() + data object SettingsScreen : SettingsDestination() { + override val arguments: List Unit>> = listOf() override val plainRoute: String = "settingsScreen" } - object DeveloperInfoScreen : SettingsDestination() { - override val arguments: List>> = listOf() + data object DeveloperInfoScreen : SettingsDestination() { + override val arguments: List Unit>> = listOf() override val plainRoute: String = "developerInfoScreen" } } diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/ResinStatusWidgetConfigurationNavigation.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/ResinStatusWidgetConfigurationNavigation.kt index f0258c98..32b91d78 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/ResinStatusWidgetConfigurationNavigation.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/ResinStatusWidgetConfigurationNavigation.kt @@ -3,7 +3,7 @@ package com.joeloewi.croissant.ui.navigation.widgetconfiguration.resinstatus sealed class ResinStatusWidgetConfigurationNavigation( val route: String = "" ) { - object Configuration : ResinStatusWidgetConfigurationNavigation( + data object Configuration : ResinStatusWidgetConfigurationNavigation( route = "configuration" ) } diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/resinstatuswidgetconfiguration/ResinStatusWidgetConfigurationDestination.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/resinstatuswidgetconfiguration/ResinStatusWidgetConfigurationDestination.kt index 2f2d2e7a..f2a1ab68 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/resinstatuswidgetconfiguration/ResinStatusWidgetConfigurationDestination.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/resinstatuswidgetconfiguration/ResinStatusWidgetConfigurationDestination.kt @@ -1,9 +1,11 @@ package com.joeloewi.croissant.ui.navigation.widgetconfiguration.resinstatus.resinstatuswidgetconfiguration +import android.appwidget.AppWidgetManager +import androidx.navigation.NavArgumentBuilder import androidx.navigation.NavType sealed class ResinStatusWidgetConfigurationDestination { - abstract val arguments: List>> + abstract val arguments: List Unit>> protected abstract val plainRoute: String val route: String by lazy { "${plainRoute}${ @@ -18,14 +20,17 @@ sealed class ResinStatusWidgetConfigurationDestination { }" } - object EmptyScreen : ResinStatusWidgetConfigurationDestination() { - override val arguments: List>> = listOf() + data object EmptyScreen : ResinStatusWidgetConfigurationDestination() { + override val arguments: List Unit>> = listOf() override val plainRoute: String = "emptyScreen" } class LoadingScreen( - override val arguments: List>> = listOf( - APP_WIDGET_ID to NavType.IntType + override val arguments: List Unit>> = listOf( + APP_WIDGET_ID to { + type = NavType.IntType + defaultValue = AppWidgetManager.INVALID_APPWIDGET_ID + } ), override val plainRoute: String = "loadingScreen" ) : ResinStatusWidgetConfigurationDestination() { @@ -37,8 +42,8 @@ sealed class ResinStatusWidgetConfigurationDestination { } class CreateResinStatusWidgetScreen( - override val arguments: List>> = listOf( - APP_WIDGET_ID to NavType.IntType + override val arguments: List Unit>> = listOf( + APP_WIDGET_ID to { type = NavType.IntType } ), override val plainRoute: String = "createResinStatusWidgetScreen" ) : ResinStatusWidgetConfigurationDestination() { @@ -50,8 +55,8 @@ sealed class ResinStatusWidgetConfigurationDestination { } class ResinStatusWidgetDetailScreen( - override val arguments: List>> = listOf( - APP_WIDGET_ID to NavType.IntType + override val arguments: List Unit>> = listOf( + APP_WIDGET_ID to { type = NavType.IntType } ), override val plainRoute: String = "resinStatusWidgetDetailScreen" ) : ResinStatusWidgetConfigurationDestination() { @@ -62,8 +67,8 @@ sealed class ResinStatusWidgetConfigurationDestination { fun generateRoute(appWidgetId: Int) = "${plainRoute}/${appWidgetId}" } - object LoginHoYoLABScreen : ResinStatusWidgetConfigurationDestination() { - override val arguments: List>> = listOf() + data object LoginHoYoLABScreen : ResinStatusWidgetConfigurationDestination() { + override val arguments: List Unit>> = listOf() override val plainRoute: String = "loginHoYoLABScreen" } } diff --git a/app/src/main/kotlin/com/joeloewi/croissant/util/NotificationGenerator.kt b/app/src/main/kotlin/com/joeloewi/croissant/util/NotificationGenerator.kt index 60b54cc3..54a35179 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/util/NotificationGenerator.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/util/NotificationGenerator.kt @@ -184,7 +184,7 @@ class NotificationGenerator( .authority(context.packageName) .appendEncodedPath( AttendancesDestination.AttendanceDetailScreen() - .generateRoute(attendanceId) + .generateRoute(attendanceId, true) ) .build() ) @@ -243,7 +243,7 @@ class NotificationGenerator( .authority(context.packageName) .appendEncodedPath( AttendancesDestination.AttendanceDetailScreen() - .generateRoute(attendanceId) + .generateRoute(attendanceId, true) ) .build() ) From e1811392bac93ef31b995893c812ec85934eb021 Mon Sep 17 00:00:00 2001 From: joeloewi7178 Date: Fri, 12 Jan 2024 16:05:02 +0900 Subject: [PATCH 2/4] mod: run code in processLifecycleScope when received broadcast mod: call apply dynamic color in application class, not in initializer mod: use fastForEach when draw bottom navigation bar mod: annotate immutable to navigation, destination class mod: set back route when started with deeplink mod: declare notificationGenerator as singleton --- app/src/main/AndroidManifest.xml | 3 -- .../croissant/CroissantApplication.kt | 8 ++- .../com/joeloewi/croissant/MainActivity.kt | 34 ++++++------- .../ResinStatusWidgetConfigurationActivity.kt | 2 - .../com/joeloewi/croissant/di/EntryPoints.kt | 3 -- .../com/joeloewi/croissant/di/UtilModule.kt | 1 + .../initializer/DynamicColorInitializer.kt | 19 ------- .../croissant/receiver/AlarmReceiver.kt | 19 +++---- .../croissant/receiver/MigrationHelper.kt | 12 ++--- .../receiver/ResinStatusWidgetProvider.kt | 14 +++--- .../receiver/TimeZoneChangedReceiver.kt | 12 ++--- .../ui/navigation/main/CroissantNavigation.kt | 2 + .../attendances/AttendancesDestination.kt | 50 ++++++++++++------- .../screen/AttendanceDetailScreen.kt | 5 ++ .../main/global/GlobalDestination.kt | 4 +- .../RedemptionCodesDestination.kt | 2 + .../main/settings/SettingsDestination.kt | 2 + ...sinStatusWidgetConfigurationDestination.kt | 2 + .../croissant/util/NotificationGenerator.kt | 22 +++----- 19 files changed, 103 insertions(+), 113 deletions(-) delete mode 100644 app/src/main/kotlin/com/joeloewi/croissant/initializer/DynamicColorInitializer.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 785e5a98..b7aa9b91 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -72,9 +72,6 @@ - diff --git a/app/src/main/kotlin/com/joeloewi/croissant/CroissantApplication.kt b/app/src/main/kotlin/com/joeloewi/croissant/CroissantApplication.kt index 99cce0e1..0285181e 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/CroissantApplication.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/CroissantApplication.kt @@ -1,7 +1,13 @@ package com.joeloewi.croissant import android.app.Application +import com.google.android.material.color.DynamicColors import dagger.hilt.android.HiltAndroidApp @HiltAndroidApp -class CroissantApplication : Application() \ No newline at end of file +class CroissantApplication : Application() { + override fun onCreate() { + super.onCreate() + DynamicColors.applyToActivitiesIfAvailable(this) + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/joeloewi/croissant/MainActivity.kt b/app/src/main/kotlin/com/joeloewi/croissant/MainActivity.kt index c64fc08d..5cf3b29d 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/MainActivity.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/MainActivity.kt @@ -45,6 +45,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.util.fastForEach import androidx.compose.ui.window.DialogProperties import androidx.core.os.bundleOf import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen @@ -62,7 +63,6 @@ import androidx.navigation.compose.navigation import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument import androidx.navigation.navDeepLink -import com.google.android.material.color.DynamicColors import com.google.firebase.Firebase import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.analytics @@ -112,8 +112,6 @@ class MainActivity : AppCompatActivity() { enableEdgeToEdge() - DynamicColors.applyToActivityIfAvailable(this) - lifecycleScope.launch { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { _mainActivityViewModel.darkThemeEnabled.onEach { darkThemeEnabled -> @@ -354,7 +352,7 @@ fun CroissantNavHost( }, onClickAttendance = { navController.value.navigate( - AttendancesDestination.AttendanceDetailScreen().generateRoute(it.id) + AttendancesDestination.AttendanceDetailScreen.generateRoute(it.id) ) } ) @@ -372,7 +370,7 @@ fun CroissantNavHost( }, onNavigateToAttendanceDetailScreen = { navController.value.navigate( - AttendancesDestination.AttendanceDetailScreen().generateRoute(it) + AttendancesDestination.AttendanceDetailScreen.generateRoute(it) ) { popUpTo(AttendancesDestination.CreateAttendanceScreen.route) { inclusive = true @@ -402,14 +400,14 @@ fun CroissantNavHost( } composable( - route = AttendancesDestination.AttendanceDetailScreen().route, - arguments = AttendancesDestination.AttendanceDetailScreen().arguments.map { argument -> + route = AttendancesDestination.AttendanceDetailScreen.route, + arguments = AttendancesDestination.AttendanceDetailScreen.arguments.map { argument -> navArgument(argument.first, argument.second) }, deepLinks = listOf( navDeepLink { uriPattern = - "$deepLinkUri/${AttendancesDestination.AttendanceDetailScreen().route}" + "$deepLinkUri/${AttendancesDestination.AttendanceDetailScreen.route}" } ) ) { navBackStackEntry -> @@ -437,10 +435,8 @@ fun CroissantNavHost( newCookie = { newCookie }, onNavigateUp = { if (fromDeeplink) { - with(navController.value.graph) { - findNode(CroissantNavigation.Attendances.route)?.id?.let { - navController.value.popBackStack(it, inclusive = true) - } + with(navController.value) { + popBackStack(graph.findStartDestination().id, inclusive = true) } } else { navController.value.navigateUp() @@ -451,7 +447,7 @@ fun CroissantNavHost( }, onClickLogSummary = { attendanceId, loggableWorker -> navController.value.navigate( - AttendancesDestination.AttendanceLogsCalendarScreen().generateRoute( + AttendancesDestination.AttendanceLogsCalendarScreen.generateRoute( attendanceId, loggableWorker ) @@ -461,8 +457,8 @@ fun CroissantNavHost( } composable( - route = AttendancesDestination.AttendanceLogsCalendarScreen().route, - arguments = AttendancesDestination.AttendanceLogsCalendarScreen().arguments.map { argument -> + route = AttendancesDestination.AttendanceLogsCalendarScreen.route, + arguments = AttendancesDestination.AttendanceLogsCalendarScreen.arguments.map { argument -> navArgument(argument.first, argument.second) } ) { @@ -470,7 +466,7 @@ fun CroissantNavHost( onNavigateUp = { navController.value.navigateUp() }, onClickDay = { attendanceId, loggableWorker, localDate -> navController.value.navigate( - AttendancesDestination.AttendanceLogsDayScreen().generateRoute( + AttendancesDestination.AttendanceLogsDayScreen.generateRoute( attendanceId = attendanceId, loggableWorker = loggableWorker, localDate = localDate, @@ -481,8 +477,8 @@ fun CroissantNavHost( } composable( - route = AttendancesDestination.AttendanceLogsDayScreen().route, - arguments = AttendancesDestination.AttendanceLogsDayScreen().arguments.map { argument -> + route = AttendancesDestination.AttendanceLogsDayScreen.route, + arguments = AttendancesDestination.AttendanceLogsDayScreen.arguments.map { argument -> navArgument(argument.first, argument.second) } ) { @@ -631,7 +627,7 @@ private fun CroissantBottomNavigationBar( NavigationBar( modifier = modifier ) { - croissantNavigations.forEach { croissantNavigation -> + croissantNavigations.fastForEach { croissantNavigation -> key(croissantNavigation.route) { val isSelected by remember(croissantNavigation.route) { derivedStateOf { currentBackStackEntry()?.destination?.hierarchy?.any { it.route == croissantNavigation.route } == true } diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ResinStatusWidgetConfigurationActivity.kt b/app/src/main/kotlin/com/joeloewi/croissant/ResinStatusWidgetConfigurationActivity.kt index 18ca2966..1a9011e0 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ResinStatusWidgetConfigurationActivity.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ResinStatusWidgetConfigurationActivity.kt @@ -31,7 +31,6 @@ import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.navigation import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument -import com.google.android.material.color.DynamicColors import com.google.firebase.Firebase import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.analytics @@ -61,7 +60,6 @@ class ResinStatusWidgetConfigurationActivity : AppCompatActivity() { super.onCreate(savedInstanceState) enableEdgeToEdge() - DynamicColors.applyToActivityIfAvailable(this) lifecycleScope.launch { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { diff --git a/app/src/main/kotlin/com/joeloewi/croissant/di/EntryPoints.kt b/app/src/main/kotlin/com/joeloewi/croissant/di/EntryPoints.kt index 4fc6b087..3e6919c1 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/di/EntryPoints.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/di/EntryPoints.kt @@ -16,7 +16,6 @@ package com.joeloewi.croissant.di -import android.app.Application import android.content.Context import androidx.hilt.work.HiltWorkerFactory import androidx.work.RunnableScheduler @@ -35,8 +34,6 @@ import kotlin.reflect.KClass interface InitializerEntryPoint { fun imageLoader(): ImageLoader fun hiltWorkerFactory(): HiltWorkerFactory - fun application(): Application - @DefaultDispatcherExecutor fun executor(): Executor fun runnableScheduler(): RunnableScheduler diff --git a/app/src/main/kotlin/com/joeloewi/croissant/di/UtilModule.kt b/app/src/main/kotlin/com/joeloewi/croissant/di/UtilModule.kt index 9e4fabef..7b57d574 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/di/UtilModule.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/di/UtilModule.kt @@ -51,6 +51,7 @@ object UtilModule { @ApplicationContext context: Context ): TextToSpeechFactory = TextToSpeechFactory(context) + @Singleton @Provides fun provideNotificationGenerator( @ApplicationContext context: Context diff --git a/app/src/main/kotlin/com/joeloewi/croissant/initializer/DynamicColorInitializer.kt b/app/src/main/kotlin/com/joeloewi/croissant/initializer/DynamicColorInitializer.kt deleted file mode 100644 index 63eb8e84..00000000 --- a/app/src/main/kotlin/com/joeloewi/croissant/initializer/DynamicColorInitializer.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.joeloewi.croissant.initializer - -import android.content.Context -import androidx.startup.Initializer -import com.google.android.material.color.DynamicColors -import com.joeloewi.croissant.di.InitializerEntryPoint -import com.joeloewi.croissant.di.entryPoints - -class DynamicColorInitializer : Initializer { - - override fun create(context: Context) { - val initializerEntryPoint: InitializerEntryPoint by context.entryPoints() - val application = initializerEntryPoint.application() - - DynamicColors.applyToActivitiesIfAvailable(application) - } - - override fun dependencies(): MutableList>> = mutableListOf() -} \ No newline at end of file diff --git a/app/src/main/kotlin/com/joeloewi/croissant/receiver/AlarmReceiver.kt b/app/src/main/kotlin/com/joeloewi/croissant/receiver/AlarmReceiver.kt index f8e27d71..490bdfa6 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/receiver/AlarmReceiver.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/receiver/AlarmReceiver.kt @@ -31,13 +31,13 @@ import javax.inject.Inject @AndroidEntryPoint class AlarmReceiver : BroadcastReceiver() { + private val _processLifecycleScope = ProcessLifecycleOwner.get().lifecycleScope private val _coroutineContext = Dispatchers.IO + CoroutineExceptionHandler { _, throwable -> Firebase.crashlytics.apply { log(this@AlarmReceiver.javaClass.simpleName) recordException(throwable) } } - private val _processLifecycleScope by lazy { ProcessLifecycleOwner.get().lifecycleScope } @Inject lateinit var application: Application @@ -58,9 +58,9 @@ class AlarmReceiver : BroadcastReceiver() { lateinit var alarmScheduler: AlarmScheduler override fun onReceive(p0: Context, p1: Intent) { - when (p1.action) { - Intent.ACTION_BOOT_COMPLETED, Intent.ACTION_MY_PACKAGE_REPLACED, AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED -> { - _processLifecycleScope.launch(_coroutineContext) { + _processLifecycleScope.launch(_coroutineContext) { + when (p1.action) { + Intent.ACTION_BOOT_COMPLETED, Intent.ACTION_MY_PACKAGE_REPLACED, AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED -> { getAllOneShotAttendanceUseCase().map { attendance -> async(SupervisorJob() + Dispatchers.IO + CoroutineExceptionHandler { _, _ -> }) { attendance.runCatching { @@ -72,12 +72,9 @@ class AlarmReceiver : BroadcastReceiver() { } }.awaitAll() } - } - - RECEIVE_ATTEND_CHECK_IN_ALARM -> { - val attendanceId = p1.getLongExtra(ATTENDANCE_ID, Long.MIN_VALUE) - _processLifecycleScope.launch(_coroutineContext) { + RECEIVE_ATTEND_CHECK_IN_ALARM -> { + val attendanceId = p1.getLongExtra(ATTENDANCE_ID, Long.MIN_VALUE) val attendanceWithGames = getOneAttendanceUseCase(attendanceId) val attendance = attendanceWithGames.attendance val oneTimeWork = OneTimeWorkRequestBuilder() @@ -101,10 +98,10 @@ class AlarmReceiver : BroadcastReceiver() { scheduleForTomorrow = true ) } - } - else -> { + else -> { + } } } } diff --git a/app/src/main/kotlin/com/joeloewi/croissant/receiver/MigrationHelper.kt b/app/src/main/kotlin/com/joeloewi/croissant/receiver/MigrationHelper.kt index a1377c32..c3b1605a 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/receiver/MigrationHelper.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/receiver/MigrationHelper.kt @@ -22,13 +22,13 @@ import javax.inject.Inject @AndroidEntryPoint class MigrationHelper : BroadcastReceiver() { + private val _processLifecycleScope = ProcessLifecycleOwner.get().lifecycleScope private val _coroutineContext = Dispatchers.IO + CoroutineExceptionHandler { _, throwable -> Firebase.crashlytics.apply { log(this@MigrationHelper.javaClass.simpleName) recordException(throwable) } } - private val _processLifecycleScope by lazy { ProcessLifecycleOwner.get().lifecycleScope } @Inject lateinit var application: Application @@ -46,9 +46,9 @@ class MigrationHelper : BroadcastReceiver() { lateinit var workManager: WorkManager override fun onReceive(p0: Context, p1: Intent) { - when (p1.action) { - Intent.ACTION_MY_PACKAGE_REPLACED -> { - _processLifecycleScope.launch(_coroutineContext) { + _processLifecycleScope.launch(_coroutineContext) { + when (p1.action) { + Intent.ACTION_MY_PACKAGE_REPLACED -> { //because work manager's job can be deferred, cancel check in event worker //instead of work manager, use alarm manager getAllOneShotAttendanceUseCase().map { attendance -> @@ -57,10 +57,8 @@ class MigrationHelper : BroadcastReceiver() { } }.awaitAll() } - } - - else -> { + else -> {} } } } diff --git a/app/src/main/kotlin/com/joeloewi/croissant/receiver/ResinStatusWidgetProvider.kt b/app/src/main/kotlin/com/joeloewi/croissant/receiver/ResinStatusWidgetProvider.kt index 825fe9eb..d55b519f 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/receiver/ResinStatusWidgetProvider.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/receiver/ResinStatusWidgetProvider.kt @@ -30,7 +30,7 @@ import javax.inject.Inject @AndroidEntryPoint class ResinStatusWidgetProvider : AppWidgetProvider() { - private val _processLifecycleOwner by lazy { ProcessLifecycleOwner.get() } + private val _processLifecycleScope = ProcessLifecycleOwner.get().lifecycleScope private val _coroutineContext = Dispatchers.IO + CoroutineExceptionHandler { _, throwable -> Firebase.crashlytics.apply { log(this@ResinStatusWidgetProvider.javaClass.simpleName) @@ -55,10 +55,8 @@ class ResinStatusWidgetProvider : AppWidgetProvider() { appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { - super.onUpdate(context, appWidgetManager, appWidgetIds) //this method also called when user put widget on home screen - - _processLifecycleOwner.lifecycleScope.launch(_coroutineContext) { + _processLifecycleScope.launch(_coroutineContext) { appWidgetIds.map { appWidgetId -> async(SupervisorJob() + Dispatchers.IO + CoroutineExceptionHandler { _, _ -> }) { if (powerManager.isPowerSaveMode && !powerManager.isIgnoringBatteryOptimizationsCompat( @@ -99,12 +97,12 @@ class ResinStatusWidgetProvider : AppWidgetProvider() { } }.awaitAll() } + + super.onUpdate(context, appWidgetManager, appWidgetIds) } override fun onDeleted(context: Context, appWidgetIds: IntArray) { - super.onDeleted(context, appWidgetIds) - - _processLifecycleOwner.lifecycleScope.launch(_coroutineContext) { + _processLifecycleScope.launch(_coroutineContext) { appWidgetIds.run { map { appWidgetId -> async(SupervisorJob() + Dispatchers.IO + CoroutineExceptionHandler { _, _ -> }) { @@ -119,5 +117,7 @@ class ResinStatusWidgetProvider : AppWidgetProvider() { deleteByAppWidgetIdResinStatusWidgetUseCase(*this) } } + + super.onDeleted(context, appWidgetIds) } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/joeloewi/croissant/receiver/TimeZoneChangedReceiver.kt b/app/src/main/kotlin/com/joeloewi/croissant/receiver/TimeZoneChangedReceiver.kt index 0775a157..9a008ba6 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/receiver/TimeZoneChangedReceiver.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/receiver/TimeZoneChangedReceiver.kt @@ -18,21 +18,21 @@ import javax.inject.Inject @AndroidEntryPoint class TimeZoneChangedReceiver @Inject constructor( ) : BroadcastReceiver() { + private val _processLifecycleScope = ProcessLifecycleOwner.get().lifecycleScope private val _coroutineContext = Dispatchers.IO + CoroutineExceptionHandler { _, throwable -> Firebase.crashlytics.apply { log(this@TimeZoneChangedReceiver.javaClass.simpleName) recordException(throwable) } } - private val _processLifecycleScope by lazy { ProcessLifecycleOwner.get().lifecycleScope } @Inject lateinit var notificationGenerator: NotificationGenerator override fun onReceive(context: Context, intent: Intent) { - when (intent.action) { - Intent.ACTION_TIMEZONE_CHANGED -> { - _processLifecycleScope.launch(_coroutineContext) { + _processLifecycleScope.launch(_coroutineContext) { + when (intent.action) { + Intent.ACTION_TIMEZONE_CHANGED -> { with(notificationGenerator) { safeNotify( UUID.randomUUID().toString(), @@ -41,10 +41,10 @@ class TimeZoneChangedReceiver @Inject constructor( ) } } - } - else -> { + else -> { + } } } } diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/CroissantNavigation.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/CroissantNavigation.kt index d05f57f5..7478f8d9 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/CroissantNavigation.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/CroissantNavigation.kt @@ -8,9 +8,11 @@ import androidx.compose.material.icons.filled.TaskAlt import androidx.compose.material.icons.outlined.Redeem import androidx.compose.material.icons.outlined.Settings import androidx.compose.material.icons.outlined.TaskAlt +import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.vector.ImageVector import com.joeloewi.croissant.R +@Immutable sealed class CroissantNavigation( val route: String, val filledIcon: ImageVector, diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/AttendancesDestination.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/AttendancesDestination.kt index 031dd35c..8c490ee5 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/AttendancesDestination.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/AttendancesDestination.kt @@ -1,13 +1,18 @@ package com.joeloewi.croissant.ui.navigation.main.attendances +import android.content.Context +import android.net.Uri +import androidx.compose.runtime.Immutable import androidx.navigation.NavArgumentBuilder import androidx.navigation.NavType +import com.joeloewi.croissant.R import com.joeloewi.croissant.domain.common.LoggableWorker +@Immutable sealed class AttendancesDestination { abstract val arguments: List Unit>> protected abstract val plainRoute: String - val route: String + open val route: String get() = "${plainRoute}${ arguments.map { it.first }.joinToString( separator = "/", @@ -34,11 +39,9 @@ sealed class AttendancesDestination { override val plainRoute = "loginHoYoLabScreen" } - class AttendanceDetailScreen : AttendancesDestination() { - companion object { - const val ATTENDANCE_ID = "attendanceId" - const val FROM_DEEPLINK = "fromDeeplink" - } + data object AttendanceDetailScreen : AttendancesDestination() { + const val ATTENDANCE_ID = "attendanceId" + const val FROM_DEEPLINK = "fromDeeplink" override val arguments: List Unit)>> = listOf( ATTENDANCE_ID to { @@ -53,17 +56,30 @@ sealed class AttendancesDestination { override val plainRoute: String = "attendanceDetailScreen" + override val route: String + get() = "${plainRoute}/{${ATTENDANCE_ID}}?${FROM_DEEPLINK}={${FROM_DEEPLINK}}" + fun generateRoute( attendanceId: Long, fromDeeplink: Boolean = false - ) = "${plainRoute}/${attendanceId}/${fromDeeplink}" + ) = "${plainRoute}/$attendanceId?${FROM_DEEPLINK}={$fromDeeplink}" + + fun generateDeepLinkUri( + context: Context, + attendanceId: Long, + fromDeeplink: Boolean = true + ): Uri = Uri.Builder() + .scheme(context.getString(R.string.deep_link_scheme)) + .authority(context.packageName) + .appendEncodedPath(plainRoute) + .appendPath("$attendanceId") + .appendQueryParameter(FROM_DEEPLINK, "$fromDeeplink") + .build() } - class AttendanceLogsCalendarScreen : AttendancesDestination() { - companion object { - const val ATTENDANCE_ID = "attendanceId" - const val LOGGABLE_WORKER = "loggableWorker" - } + data object AttendanceLogsCalendarScreen : AttendancesDestination() { + const val ATTENDANCE_ID = "attendanceId" + const val LOGGABLE_WORKER = "loggableWorker" override val arguments: List Unit>> = listOf( ATTENDANCE_ID to { @@ -80,12 +96,10 @@ sealed class AttendancesDestination { "${plainRoute}/${attendanceId}/${loggableWorker}" } - class AttendanceLogsDayScreen : AttendancesDestination() { - companion object { - const val ATTENDANCE_ID = "attendanceId" - const val LOGGABLE_WORKER = "loggableWorker" - const val LOCAL_DATE = "localDate" - } + data object AttendanceLogsDayScreen : AttendancesDestination() { + const val ATTENDANCE_ID = "attendanceId" + const val LOGGABLE_WORKER = "loggableWorker" + const val LOCAL_DATE = "localDate" override val arguments: List Unit>> = listOf( ATTENDANCE_ID to { diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/screen/AttendanceDetailScreen.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/screen/AttendanceDetailScreen.kt index 81d97a9e..ff417eb0 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/screen/AttendanceDetailScreen.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/attendances/screen/AttendanceDetailScreen.kt @@ -1,5 +1,6 @@ package com.joeloewi.croissant.ui.navigation.main.attendances.screen +import androidx.activity.compose.BackHandler import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -170,6 +171,10 @@ private fun AttendanceDetailContent( ) var showConfirmDeleteDialog by remember { mutableStateOf(false) } + BackHandler { + onNavigateUp() + } + LaunchedEffect(snackbarHostState) { withContext(Dispatchers.IO) { snapshotFlow(newCookie).catch { }.collect { diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/global/GlobalDestination.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/global/GlobalDestination.kt index f3511230..25d1658e 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/global/GlobalDestination.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/global/GlobalDestination.kt @@ -1,7 +1,9 @@ package com.joeloewi.croissant.ui.navigation.main.global +import androidx.compose.runtime.Immutable import androidx.navigation.NavArgumentBuilder +@Immutable sealed class GlobalDestination { abstract val arguments: List Unit>> abstract val plainRoute: String @@ -18,7 +20,7 @@ sealed class GlobalDestination { }" data object EmptyScreen : GlobalDestination() { - override val arguments: List Unit>> = emptyList() + override val arguments: List Unit>> = listOf() override val plainRoute: String = "EmptyScreen" } diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/redemptioncodes/RedemptionCodesDestination.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/redemptioncodes/RedemptionCodesDestination.kt index 421ee85b..5432f8b1 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/redemptioncodes/RedemptionCodesDestination.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/redemptioncodes/RedemptionCodesDestination.kt @@ -1,7 +1,9 @@ package com.joeloewi.croissant.ui.navigation.main.redemptioncodes +import androidx.compose.runtime.Immutable import androidx.navigation.NavArgumentBuilder +@Immutable sealed class RedemptionCodesDestination { abstract val arguments: List Unit>> protected abstract val plainRoute: String diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/settings/SettingsDestination.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/settings/SettingsDestination.kt index a96a76a6..fc8b2228 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/settings/SettingsDestination.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/main/settings/SettingsDestination.kt @@ -1,7 +1,9 @@ package com.joeloewi.croissant.ui.navigation.main.settings +import androidx.compose.runtime.Immutable import androidx.navigation.NavArgumentBuilder +@Immutable sealed class SettingsDestination { abstract val arguments: List Unit>> protected abstract val plainRoute: String diff --git a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/resinstatuswidgetconfiguration/ResinStatusWidgetConfigurationDestination.kt b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/resinstatuswidgetconfiguration/ResinStatusWidgetConfigurationDestination.kt index f2a1ab68..663aaae0 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/resinstatuswidgetconfiguration/ResinStatusWidgetConfigurationDestination.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/ui/navigation/widgetconfiguration/resinstatus/resinstatuswidgetconfiguration/ResinStatusWidgetConfigurationDestination.kt @@ -1,9 +1,11 @@ package com.joeloewi.croissant.ui.navigation.widgetconfiguration.resinstatus.resinstatuswidgetconfiguration import android.appwidget.AppWidgetManager +import androidx.compose.runtime.Immutable import androidx.navigation.NavArgumentBuilder import androidx.navigation.NavType +@Immutable sealed class ResinStatusWidgetConfigurationDestination { abstract val arguments: List Unit>> protected abstract val plainRoute: String diff --git a/app/src/main/kotlin/com/joeloewi/croissant/util/NotificationGenerator.kt b/app/src/main/kotlin/com/joeloewi/croissant/util/NotificationGenerator.kt index 54a35179..6ed573c7 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/util/NotificationGenerator.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/util/NotificationGenerator.kt @@ -179,14 +179,9 @@ class NotificationGenerator( addNextIntentWithParentStack( Intent( Intent.ACTION_VIEW, - Uri.Builder() - .scheme(context.getString(R.string.deep_link_scheme)) - .authority(context.packageName) - .appendEncodedPath( - AttendancesDestination.AttendanceDetailScreen() - .generateRoute(attendanceId, true) - ) - .build() + AttendancesDestination.AttendanceDetailScreen.generateDeepLinkUri( + context, attendanceId + ) ) ) getPendingIntent(0, pendingIntentFlagUpdateCurrent) @@ -238,14 +233,9 @@ class NotificationGenerator( addNextIntentWithParentStack( Intent( Intent.ACTION_VIEW, - Uri.Builder() - .scheme(context.getString(R.string.deep_link_scheme)) - .authority(context.packageName) - .appendEncodedPath( - AttendancesDestination.AttendanceDetailScreen() - .generateRoute(attendanceId, true) - ) - .build() + AttendancesDestination.AttendanceDetailScreen.generateDeepLinkUri( + context, attendanceId + ) ) ) getPendingIntent(0, pendingIntentFlagUpdateCurrent) From d8385e0f0d536b6c9a43edc8fa1c321af49d7391 Mon Sep 17 00:00:00 2001 From: joeloewi7178 Date: Fri, 12 Jan 2024 16:06:46 +0900 Subject: [PATCH 3/4] mod: reformat code --- app/src/main/kotlin/com/joeloewi/croissant/di/EntryPoints.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/kotlin/com/joeloewi/croissant/di/EntryPoints.kt b/app/src/main/kotlin/com/joeloewi/croissant/di/EntryPoints.kt index 3e6919c1..46b525f0 100644 --- a/app/src/main/kotlin/com/joeloewi/croissant/di/EntryPoints.kt +++ b/app/src/main/kotlin/com/joeloewi/croissant/di/EntryPoints.kt @@ -34,6 +34,7 @@ import kotlin.reflect.KClass interface InitializerEntryPoint { fun imageLoader(): ImageLoader fun hiltWorkerFactory(): HiltWorkerFactory + @DefaultDispatcherExecutor fun executor(): Executor fun runnableScheduler(): RunnableScheduler From 2c6e02bc7e878509aa7810303a25fa7cfa4de308 Mon Sep 17 00:00:00 2001 From: joeloewi7178 Date: Fri, 12 Jan 2024 16:08:08 +0900 Subject: [PATCH 4/4] versionCode 50 versionName 1.2.2 --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index cf36b13d..fde94c62 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,7 +20,7 @@ android { defaultConfig { applicationId = "com.joeloewi.croissant" - versionCode = 49 + versionCode = 50 versionName = "1.2.2" targetSdk = 34