Add clock widget parts preferences

This commit is contained in:
MM20 2022-03-02 13:21:32 +01:00
parent bdbcba6d67
commit edd59f2d06
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
8 changed files with 156 additions and 13 deletions

View File

@ -478,6 +478,16 @@
<string name="preference_clockwidget_layout_horizontal">Horizontal</string>
<string name="preference_clock_widget_style">Style</string>
<string name="preference_clock_widget_style_summary">Select a clock</string>
<string name="preference_clockwidget_date_part">Date</string>
<string name="preference_clockwidget_date_part_summary">Show the current date</string>
<string name="preference_clockwidget_music_part">Music</string>
<string name="preference_clockwidget_music_part_summary">Show media controls when there is an active media session</string>
<string name="preference_clockwidget_battery_part">Battery</string>
<string name="preference_clockwidget_battery_part_summary">Show the current battery level when the battery is low or charging</string>
<string name="preference_clockwidget_alarm_part">Alarms</string>
<string name="preference_clockwidget_alarm_part_summary">Show alarms that will ring within the next 15 minutes</string>
<string name="preference_crash_reporter">Crash reporter</string>
<string name="preference_crash_reporter_summary">Error and crash reports</string>
<string name="preference_export_log">Export log file</string>

View File

@ -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<Settings>
@ -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
internal const val SchemaVersion = 3

View File

@ -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(

View File

@ -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)
)
}
}

View File

@ -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;

View File

@ -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<List<PartProvider>>(emptyList())
init {
partProviders.value = listOf(
DatePartProvider(),
MusicPartProvider(),
AlarmPartProvider(),
BatteryPartProvider(),
)
viewModelScope.launch {
dataStore.data.map { it.clockWidget }.distinctUntilChanged().collectLatest {
val providers = mutableListOf<PartProvider>()
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())

View File

@ -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)
}

View File

@ -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()
}
}
}
}