From edd59f2d069a223d0e48459daebf43dcb036119a Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Wed, 2 Mar 2022 13:21:32 +0100 Subject: [PATCH] Add clock widget parts preferences --- i18n/src/main/res/values/strings.xml | 10 ++++ .../mm20/launcher2/preferences/DataStore.kt | 9 ++- .../de/mm20/launcher2/preferences/Defaults.kt | 4 ++ .../preferences/migrations/Migration_2_3.kt | 15 +++++ preferences/src/main/proto/settings.proto | 4 ++ .../launcher/widgets/clock/ClockWidgetVM.kt | 18 ++++-- .../clockwidget/ClockWidgetSettingsScreen.kt | 57 +++++++++++++++++-- .../ClockWidgetSettingsScreenVM.kt | 52 +++++++++++++++++ 8 files changed, 156 insertions(+), 13 deletions(-) create mode 100644 preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_2_3.kt diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index 41ab65d9..e611c34e 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -478,6 +478,16 @@ Horizontal Style Select a clock + + Date + Show the current date + Music + Show media controls when there is an active media session + Battery + Show the current battery level when the battery is low or charging + Alarms + Show alarms that will ring within the next 15 minutes + Crash reporter Error and crash reports Export log file diff --git a/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt b/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt index 0c04ed43..2b1f36d5 100644 --- a/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt +++ b/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt @@ -8,6 +8,7 @@ import androidx.datastore.dataStore import de.mm20.launcher2.crashreporter.CrashReporter import de.mm20.launcher2.preferences.migrations.FactorySettingsMigration import de.mm20.launcher2.preferences.migrations.Migration_1_2 +import de.mm20.launcher2.preferences.migrations.Migration_2_3 typealias LauncherDataStore = DataStore @@ -15,7 +16,11 @@ internal val Context.dataStore: LauncherDataStore by dataStore( fileName = "settings.pb", serializer = SettingsSerializer, produceMigrations = { - listOf(FactorySettingsMigration(it), Migration_1_2()) + listOf( + FactorySettingsMigration(it), + Migration_1_2(), + Migration_2_3() + ) }, corruptionHandler = ReplaceFileCorruptionHandler { CrashReporter.logException(it) @@ -24,4 +29,4 @@ internal val Context.dataStore: LauncherDataStore by dataStore( } ) -internal const val SchemaVersion = 2 \ No newline at end of file +internal const val SchemaVersion = 3 \ No newline at end of file diff --git a/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt b/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt index bd0aed80..abec5b9a 100644 --- a/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt +++ b/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt @@ -35,6 +35,10 @@ fun createFactorySettings(context: Context): Settings { .newBuilder() .setLayout(Settings.ClockWidgetSettings.ClockWidgetLayout.Vertical) .setClockStyle(Settings.ClockWidgetSettings.ClockStyle.DigitalClock1) + .setAlarmPart(true) + .setBatteryPart(true) + .setDatePart(true) + .setMusicPart(true) .build() ) .setFavorites( diff --git a/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_2_3.kt b/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_2_3.kt new file mode 100644 index 00000000..2467e76c --- /dev/null +++ b/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_2_3.kt @@ -0,0 +1,15 @@ +package de.mm20.launcher2.preferences.migrations + +import de.mm20.launcher2.preferences.Settings + +class Migration_2_3: VersionedMigration(2, 3) { + override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder { + return builder.setClockWidget( + builder.clockWidget.toBuilder() + .setAlarmPart(true) + .setBatteryPart(true) + .setDatePart(true) + .setMusicPart(true) + ) + } +} \ No newline at end of file diff --git a/preferences/src/main/proto/settings.proto b/preferences/src/main/proto/settings.proto index 0ea22f24..fb7a3021 100644 --- a/preferences/src/main/proto/settings.proto +++ b/preferences/src/main/proto/settings.proto @@ -52,6 +52,10 @@ message Settings { EmptyClock = 4; } ClockStyle clock_style = 2; + bool date_part = 3; + bool music_part = 4; + bool battery_part = 5; + bool alarm_part = 6; } ClockWidgetSettings clock_widget = 7; 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 620fc994..da4cc1be 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 @@ -8,12 +8,14 @@ import android.provider.AlarmClock import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.asLiveData +import androidx.lifecycle.viewModelScope import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.preferences.LauncherDataStore import de.mm20.launcher2.ui.launcher.widgets.clock.parts.* import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.trySendBlocking import kotlinx.coroutines.flow.* +import kotlinx.coroutines.launch import org.koin.core.component.KoinComponent import org.koin.core.component.inject @@ -23,12 +25,16 @@ class ClockWidgetVM : ViewModel(), KoinComponent { private val partProviders = MutableStateFlow>(emptyList()) init { - partProviders.value = listOf( - DatePartProvider(), - MusicPartProvider(), - AlarmPartProvider(), - BatteryPartProvider(), - ) + viewModelScope.launch { + dataStore.data.map { it.clockWidget }.distinctUntilChanged().collectLatest { + val providers = mutableListOf() + if (it.datePart) providers += DatePartProvider() + if (it.musicPart) providers += MusicPartProvider() + if (it.batteryPart) providers += BatteryPartProvider() + if (it.alarmPart) providers += AlarmPartProvider() + partProviders.value = providers + } + } } val time = MutableStateFlow(System.currentTimeMillis()) 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 a755d97c..145e6ddf 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 @@ -2,6 +2,8 @@ package de.mm20.launcher2.ui.settings.clockwidget import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.height +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.* import androidx.compose.material3.AlertDialog import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text @@ -21,10 +23,7 @@ import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout import de.mm20.launcher2.ui.Clock import de.mm20.launcher2.ui.R -import de.mm20.launcher2.ui.component.preferences.ListPreference -import de.mm20.launcher2.ui.component.preferences.Preference -import de.mm20.launcher2.ui.component.preferences.PreferenceCategory -import de.mm20.launcher2.ui.component.preferences.PreferenceScreen +import de.mm20.launcher2.ui.component.preferences.* @Composable fun ClockWidgetSettingsScreen() { @@ -56,6 +55,50 @@ fun ClockWidgetSettingsScreen() { ) } } + item { + PreferenceCategory { + val datePart by viewModel.datePart.observeAsState() + SwitchPreference( + title = stringResource(R.string.preference_clockwidget_date_part), + summary = stringResource(R.string.preference_clockwidget_date_part_summary), + icon = Icons.Rounded.CalendarToday, + value = datePart == true, + onValueChanged = { + viewModel.setDatePart(it) + } + ) + val musicPart by viewModel.musicPart.observeAsState() + SwitchPreference( + title = stringResource(R.string.preference_clockwidget_music_part), + summary = stringResource(R.string.preference_clockwidget_music_part_summary), + icon = Icons.Rounded.MusicNote, + value = musicPart == true, + onValueChanged = { + viewModel.setMusicPart(it) + } + ) + val alarmPart by viewModel.alarmPart.observeAsState() + SwitchPreference( + title = stringResource(R.string.preference_clockwidget_alarm_part), + summary = stringResource(R.string.preference_clockwidget_alarm_part_summary), + icon = Icons.Rounded.Alarm, + value = alarmPart == true, + onValueChanged = { + viewModel.setAlarmPart(it) + } + ) + val batteryPart by viewModel.batteryPart.observeAsState() + SwitchPreference( + title = stringResource(R.string.preference_clockwidget_battery_part), + summary = stringResource(R.string.preference_clockwidget_battery_part_summary), + icon = Icons.Rounded.BatteryFull, + value = batteryPart == true, + onValueChanged = { + viewModel.setBatteryPart(it) + } + ) + } + } } } @@ -111,7 +154,11 @@ fun ClockStylePreference( state = pagerState, modifier = Modifier.height(300.dp) ) { - Clock(style = styles[it], layout = layout, time = System.currentTimeMillis()) + Clock( + style = styles[it], + layout = layout, + time = System.currentTimeMillis() + ) } HorizontalPagerIndicator(pagerState = pagerState) } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt index 304d143a..771c052b 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt @@ -37,4 +37,56 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent { } } } + + val datePart = dataStore.data.map { it.clockWidget.datePart }.asLiveData() + fun setDatePart(datePart: Boolean) { + viewModelScope.launch { + dataStore.updateData { + it.toBuilder() + .setClockWidget( + it.clockWidget.toBuilder() + .setDatePart(datePart) + ).build() + } + } + } + + val batteryPart = dataStore.data.map { it.clockWidget.batteryPart }.asLiveData() + fun setBatteryPart(batteryPart: Boolean) { + viewModelScope.launch { + dataStore.updateData { + it.toBuilder() + .setClockWidget( + it.clockWidget.toBuilder() + .setBatteryPart(batteryPart) + ).build() + } + } + } + + val musicPart = dataStore.data.map { it.clockWidget.musicPart }.asLiveData() + fun setMusicPart(musicPart: Boolean) { + viewModelScope.launch { + dataStore.updateData { + it.toBuilder() + .setClockWidget( + it.clockWidget.toBuilder() + .setMusicPart(musicPart) + ).build() + } + } + } + + val alarmPart = dataStore.data.map { it.clockWidget.alarmPart }.asLiveData() + fun setAlarmPart(alarmPart: Boolean) { + viewModelScope.launch { + dataStore.updateData { + it.toBuilder() + .setClockWidget( + it.clockWidget.toBuilder() + .setAlarmPart(alarmPart) + ).build() + } + } + } } \ No newline at end of file