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