From 08e736f5d13793f95e3efe03f383ba3503acff65 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Wed, 15 Jun 2022 17:46:53 +0200 Subject: [PATCH] Provide current time as composition local --- .../launcher2/ui/base/ProvideCurrentTime.kt | 40 ++++++ .../launcher2/ui/launcher/LauncherActivity.kt | 135 +++++++++--------- .../ui/launcher/widgets/clock/ClockWidget.kt | 19 +-- .../launcher/widgets/clock/ClockWidgetVM.kt | 25 +--- .../clock/parts/BatteryPartProvider.kt | 7 - .../widgets/clock/parts/DatePartProvider.kt | 9 +- .../clockwidget/ClockWidgetSettingsScreen.kt | 3 +- 7 files changed, 120 insertions(+), 118 deletions(-) create mode 100644 ui/src/main/java/de/mm20/launcher2/ui/base/ProvideCurrentTime.kt diff --git a/ui/src/main/java/de/mm20/launcher2/ui/base/ProvideCurrentTime.kt b/ui/src/main/java/de/mm20/launcher2/ui/base/ProvideCurrentTime.kt new file mode 100644 index 00000000..c0408d49 --- /dev/null +++ b/ui/src/main/java/de/mm20/launcher2/ui/base/ProvideCurrentTime.kt @@ -0,0 +1,40 @@ +package de.mm20.launcher2.ui.base + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.util.Log +import androidx.compose.runtime.* +import androidx.compose.ui.platform.LocalContext + +@Composable +fun ProvideCurrentTime(content: @Composable () -> Unit) { + + val context = LocalContext.current + + var time by remember { mutableStateOf(System.currentTimeMillis()) } + + DisposableEffect(null) { + val receiver = object : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + time = System.currentTimeMillis() + Log.d("MM20", "Time Changed: $time") + } + } + context.registerReceiver(receiver, IntentFilter().apply { + addAction(Intent.ACTION_TIME_TICK) + addAction(Intent.ACTION_TIME_CHANGED) + }) + onDispose { + context.unregisterReceiver(receiver) + } + } + + CompositionLocalProvider( + LocalTime provides time, + content = content + ) +} + +val LocalTime = compositionLocalOf { System.currentTimeMillis() } \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivity.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivity.kt index df107e5b..1c7e28f9 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivity.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherActivity.kt @@ -35,6 +35,7 @@ import de.mm20.launcher2.icons.DynamicIconController import de.mm20.launcher2.preferences.Settings import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.base.BaseActivity +import de.mm20.launcher2.ui.base.ProvideCurrentTime import de.mm20.launcher2.ui.base.ProvideSettings import de.mm20.launcher2.ui.component.NavBarEffects import de.mm20.launcher2.ui.ktx.animateTo @@ -72,77 +73,79 @@ class LauncherActivity : BaseActivity() { LocalSnackbarHostState provides snackbarHostState ) { LauncherTheme { - ProvideSettings { - val lightStatus by viewModel.lightStatusBar.observeAsState(false) - val lightNav by viewModel.lightNavBar.observeAsState(false) - val hideStatus by viewModel.hideStatusBar.observeAsState(false) - val hideNav by viewModel.hideNavBar.observeAsState(false) - val dimBackground by viewModel.dimBackground.observeAsState(false) - val layout by viewModel.layout.observeAsState(null) + ProvideCurrentTime { + ProvideSettings { + val lightStatus by viewModel.lightStatusBar.observeAsState(false) + val lightNav by viewModel.lightNavBar.observeAsState(false) + val hideStatus by viewModel.hideStatusBar.observeAsState(false) + val hideNav by viewModel.hideNavBar.observeAsState(false) + val dimBackground by viewModel.dimBackground.observeAsState(false) + val layout by viewModel.layout.observeAsState(null) - val systemUiController = rememberSystemUiController() + val systemUiController = rememberSystemUiController() - val enterTransition = remember { mutableStateOf(1f) } + val enterTransition = remember { mutableStateOf(1f) } - LaunchedEffect(null) { - homeTransitionManager - .currentTransition - .flowWithLifecycle(lifecycle, Lifecycle.State.RESUMED) - .collect { - enterTransition.value = 0f - enterTransition.animateTo(1f) - } - } - - LaunchedEffect(hideStatus) { - systemUiController.isStatusBarVisible = !hideStatus - } - LaunchedEffect(hideNav) { - systemUiController.isNavigationBarVisible = !hideNav - } - - Box( - modifier = Modifier - .fillMaxSize() - .background(if (dimBackground) Color.Black.copy(alpha = 0.30f) else Color.Transparent), - contentAlignment = Alignment.BottomCenter - ) { - NavBarEffects(modifier = Modifier.fillMaxSize()) - when (layout) { - Settings.AppearanceSettings.Layout.PullDown -> { - PullDownScaffold( - modifier = Modifier - .fillMaxSize() - .graphicsLayer { - scaleX = 0.5f + enterTransition.value * 0.5f - scaleY = 0.5f + enterTransition.value * 0.5f - alpha = enterTransition.value - }, - darkStatusBarIcons = lightStatus, - darkNavBarIcons = lightNav, - ) - } - Settings.AppearanceSettings.Layout.Pager -> { - PagerScaffold( - modifier = Modifier - .fillMaxSize() - .graphicsLayer { - scaleX = enterTransition.value - scaleY = enterTransition.value - alpha = enterTransition.value - }, - darkStatusBarIcons = lightStatus, - darkNavBarIcons = lightNav, - ) - } - else -> {} + LaunchedEffect(null) { + homeTransitionManager + .currentTransition + .flowWithLifecycle(lifecycle, Lifecycle.State.RESUMED) + .collect { + enterTransition.value = 0f + enterTransition.animateTo(1f) + } } - SnackbarHost( - snackbarHostState, + + LaunchedEffect(hideStatus) { + systemUiController.isStatusBarVisible = !hideStatus + } + LaunchedEffect(hideNav) { + systemUiController.isNavigationBarVisible = !hideNav + } + + Box( modifier = Modifier - .navigationBarsPadding() - .imePadding() - ) + .fillMaxSize() + .background(if (dimBackground) Color.Black.copy(alpha = 0.30f) else Color.Transparent), + contentAlignment = Alignment.BottomCenter + ) { + NavBarEffects(modifier = Modifier.fillMaxSize()) + when (layout) { + Settings.AppearanceSettings.Layout.PullDown -> { + PullDownScaffold( + modifier = Modifier + .fillMaxSize() + .graphicsLayer { + scaleX = 0.5f + enterTransition.value * 0.5f + scaleY = 0.5f + enterTransition.value * 0.5f + alpha = enterTransition.value + }, + darkStatusBarIcons = lightStatus, + darkNavBarIcons = lightNav, + ) + } + Settings.AppearanceSettings.Layout.Pager -> { + PagerScaffold( + modifier = Modifier + .fillMaxSize() + .graphicsLayer { + scaleX = enterTransition.value + scaleY = enterTransition.value + alpha = enterTransition.value + }, + darkStatusBarIcons = lightStatus, + darkNavBarIcons = lightNav, + ) + } + else -> {} + } + SnackbarHost( + snackbarHostState, + modifier = Modifier + .navigationBarsPadding() + .imePadding() + ) + } } } } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt index 5546613f..f297c421 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt @@ -14,13 +14,11 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.unit.dp -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout +import de.mm20.launcher2.ui.base.LocalTime import de.mm20.launcher2.ui.launcher.widgets.clock.ClockWidgetVM import de.mm20.launcher2.ui.launcher.widgets.clock.clocks.* import de.mm20.launcher2.ui.launcher.widgets.clock.parts.PartProvider @@ -31,15 +29,12 @@ fun ClockWidget( ) { val viewModel: ClockWidgetVM = viewModel() val context = LocalContext.current - val lifecycleOwner = LocalLifecycleOwner.current - val time by viewModel.time.collectAsState(System.currentTimeMillis()) val layout by viewModel.layout.observeAsState() val clockStyle by viewModel.clockStyle.observeAsState() + val time = LocalTime.current - LaunchedEffect(null) { - lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) { - viewModel.onActive(context) - } + LaunchedEffect(time) { + viewModel.updateTime(time) } val partProvider by viewModel.getActivePart(LocalContext.current).collectAsState(null) @@ -66,7 +61,7 @@ fun ClockWidget( viewModel.launchClockApp(context) } ) { - Clock(clockStyle, ClockWidgetLayout.Vertical, time) + Clock(clockStyle, ClockWidgetLayout.Vertical) } DynamicZone( @@ -114,7 +109,7 @@ fun ClockWidget( viewModel.launchClockApp(context) } ) { - Clock(clockStyle, ClockWidgetLayout.Horizontal, time) + Clock(clockStyle, ClockWidgetLayout.Horizontal) } } } @@ -128,8 +123,8 @@ fun ClockWidget( fun Clock( style: ClockStyle?, layout: ClockWidgetLayout, - time: Long ) { + val time = LocalTime.current when (style) { ClockStyle.DigitalClock1 -> DigitalClock1(time, layout) ClockStyle.DigitalClock2 -> DigitalClock2(time, layout) diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt index 2bc6d29e..803358b3 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt @@ -67,23 +67,7 @@ class ClockWidgetVM : ViewModel(), KoinComponent { val layout = dataStore.data.map { it.clockWidget.layout }.asLiveData() val clockStyle = dataStore.data.map { it.clockWidget.clockStyle }.asLiveData() - private fun getTime(context: Context): Flow = callbackFlow { - trySendBlocking(System.currentTimeMillis()) - val receiver = object : BroadcastReceiver() { - override fun onReceive(context: Context?, intent: Intent?) { - trySendBlocking(System.currentTimeMillis()) - } - } - context.registerReceiver(receiver, IntentFilter().apply { - addAction(Intent.ACTION_TIME_TICK) - addAction(Intent.ACTION_TIME_CHANGED) - }) - awaitClose { - context.unregisterReceiver(receiver) - } - } - - private fun updatePartsTime(time: Long) { + fun updateTime(time: Long) { partProviders.value.forEach { it.setTime(time) } } @@ -92,11 +76,4 @@ class ClockWidgetVM : ViewModel(), KoinComponent { flags = Intent.FLAG_ACTIVITY_NEW_TASK }) } - - suspend fun onActive(context: Context) { - getTime(context).collectLatest { - time.value = it - updatePartsTime(it) - } - } } \ No newline at end of file diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/BatteryPartProvider.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/BatteryPartProvider.kt index 0c4347a5..8254a71d 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/BatteryPartProvider.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/BatteryPartProvider.kt @@ -53,13 +53,6 @@ class BatteryPartProvider : PartProvider { } } - private val time = MutableStateFlow(System.currentTimeMillis()) - - override fun setTime(time: Long) { - super.setTime(time) - this.time.value = time - } - @OptIn(ExperimentalComposeUiApi::class) @Composable override fun Component(layout: Settings.ClockWidgetSettings.ClockWidgetLayout) { diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/DatePartProvider.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/DatePartProvider.kt index e8fc5609..e5a31e33 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/DatePartProvider.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/DatePartProvider.kt @@ -16,6 +16,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.em import androidx.lifecycle.viewmodel.compose.viewModel import de.mm20.launcher2.preferences.Settings +import de.mm20.launcher2.ui.base.LocalTime import de.mm20.launcher2.ui.launcher.widgets.clock.ClockWidgetVM import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow @@ -29,15 +30,9 @@ class DatePartProvider: PartProvider { emit(1) } - private val time = MutableStateFlow(System.currentTimeMillis()) - - override fun setTime(time: Long) { - this.time.value = time - } - @Composable override fun Component(layout: Settings.ClockWidgetSettings.ClockWidgetLayout) { - val time by this.time.collectAsState(System.currentTimeMillis()) + val time = LocalTime.current val verticalLayout = layout == Settings.ClockWidgetSettings.ClockWidgetLayout.Vertical val context = LocalContext.current TextButton( diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt index ee92a28b..41e2a2ca 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt @@ -167,8 +167,7 @@ fun ClockStylePreference( ) { Clock( style = styles[it], - layout = layout, - time = System.currentTimeMillis() + layout = layout ) } HorizontalPagerIndicator(pagerState = pagerState)