Bring back the option to disable the clock widget's date part
This commit is contained in:
parent
e82fd23619
commit
d54b904c0a
@ -16,13 +16,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle
|
||||
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetColors
|
||||
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout
|
||||
import de.mm20.launcher2.ui.base.LocalTime
|
||||
import de.mm20.launcher2.ui.launcher.widgets.clock.clocks.*
|
||||
import de.mm20.launcher2.ui.launcher.widgets.clock.parts.FavoritesPartProvider
|
||||
import de.mm20.launcher2.ui.launcher.widgets.clock.parts.PartProvider
|
||||
import de.mm20.launcher2.ui.locals.LocalPreferDarkContentOverWallpaper
|
||||
|
||||
@ -41,8 +41,7 @@ fun ClockWidget(
|
||||
viewModel.updateTime(time)
|
||||
}
|
||||
|
||||
val partProvider by remember { viewModel.getActivePart(context) }.collectAsState(null)
|
||||
val withFavoriteBar by viewModel.withFavorites.observeAsState()
|
||||
val partProviders by remember { viewModel.getActiveParts(context) }.collectAsStateWithLifecycle(emptyList())
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
@ -76,21 +75,11 @@ fun ClockWidget(
|
||||
Clock(clockStyle, ClockWidgetLayout.Vertical)
|
||||
}
|
||||
|
||||
DynamicZone(
|
||||
modifier = if (true == withFavoriteBar) {
|
||||
Modifier.padding(bottom = 8.dp, top = 8.dp)
|
||||
} else {
|
||||
Modifier.padding(bottom = 16.dp)
|
||||
},
|
||||
layout = ClockWidgetLayout.Vertical,
|
||||
provider = partProvider,
|
||||
)
|
||||
|
||||
if (true == withFavoriteBar) {
|
||||
for (part in partProviders) {
|
||||
DynamicZone(
|
||||
modifier = Modifier.padding(bottom = 16.dp),
|
||||
modifier = Modifier.padding(bottom = 8.dp),
|
||||
layout = ClockWidgetLayout.Vertical,
|
||||
provider = viewModel.favoritesPartProvider,
|
||||
provider = part,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -110,7 +99,7 @@ fun ClockWidget(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
if (true == withFavoriteBar) {
|
||||
if (partProviders.size > 1) {
|
||||
HorizontalPager(
|
||||
pageCount = 2,
|
||||
beyondBoundsPageCount = 1,
|
||||
@ -119,17 +108,14 @@ fun ClockWidget(
|
||||
DynamicZone(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
layout = ClockWidgetLayout.Horizontal,
|
||||
provider = when (it) {
|
||||
0 -> viewModel.favoritesPartProvider
|
||||
else -> partProvider
|
||||
}
|
||||
provider = partProviders[it],
|
||||
)
|
||||
}
|
||||
} else {
|
||||
} else if (partProviders.isNotEmpty()) {
|
||||
DynamicZone(
|
||||
modifier = Modifier.weight(1f),
|
||||
layout = ClockWidgetLayout.Horizontal,
|
||||
provider = partProvider
|
||||
provider = partProviders[0],
|
||||
)
|
||||
}
|
||||
Box(
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
package de.mm20.launcher2.ui.launcher.widgets.clock
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.provider.AlarmClock
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
@ -11,55 +9,47 @@ 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 de.mm20.launcher2.ui.launcher.widgets.clock.parts.AlarmPartProvider
|
||||
import de.mm20.launcher2.ui.launcher.widgets.clock.parts.BatteryPartProvider
|
||||
import de.mm20.launcher2.ui.launcher.widgets.clock.parts.DatePartProvider
|
||||
import de.mm20.launcher2.ui.launcher.widgets.clock.parts.FavoritesPartProvider
|
||||
import de.mm20.launcher2.ui.launcher.widgets.clock.parts.MusicPartProvider
|
||||
import de.mm20.launcher2.ui.launcher.widgets.clock.parts.PartProvider
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class ClockWidgetVM : ViewModel(), KoinComponent {
|
||||
private val dataStore: LauncherDataStore by inject()
|
||||
|
||||
private val partProviders = MutableStateFlow<List<PartProvider>>(emptyList())
|
||||
private val partProviders = dataStore.data.map { it.clockWidget }.distinctUntilChanged().map {
|
||||
val providers = mutableListOf<PartProvider>()
|
||||
if (it.datePart) providers += DatePartProvider()
|
||||
if (it.favoritesPart) providers += FavoritesPartProvider()
|
||||
if (it.musicPart) providers += MusicPartProvider()
|
||||
if (it.batteryPart) providers += BatteryPartProvider()
|
||||
if (it.alarmPart) providers += AlarmPartProvider()
|
||||
providers
|
||||
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
dataStore.data.map { it.clockWidget }.distinctUntilChanged().collectLatest {
|
||||
val providers = mutableListOf<PartProvider>(
|
||||
DatePartProvider()
|
||||
)
|
||||
if (it.musicPart) providers += MusicPartProvider()
|
||||
if (it.batteryPart) providers += BatteryPartProvider()
|
||||
if (it.alarmPart) providers += AlarmPartProvider()
|
||||
partProviders.value = providers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val withFavorites = dataStore.data.map { it.clockWidget.favoritesPart }.asLiveData()
|
||||
val favoritesPartProvider = FavoritesPartProvider()
|
||||
|
||||
val time = MutableStateFlow(System.currentTimeMillis())
|
||||
|
||||
fun getActivePart(context: Context): Flow<PartProvider?> = channelFlow {
|
||||
fun getActiveParts(context: Context): Flow<List<PartProvider>> = channelFlow {
|
||||
partProviders.collectLatest { providers ->
|
||||
if (providers.isEmpty()) {
|
||||
send(null)
|
||||
send(emptyList())
|
||||
return@collectLatest
|
||||
}
|
||||
val rankings = providers.map { it.getRanking(context) }
|
||||
val rankings = providers.map { it.getRanking(context).map { r -> r to it } }
|
||||
combine(rankings) { r ->
|
||||
var prov = providers[0]
|
||||
var ranking = r[0]
|
||||
for (i in 1 until providers.size) {
|
||||
if (ranking < r[i]) {
|
||||
prov = providers[i]
|
||||
ranking = r[i]
|
||||
}
|
||||
}
|
||||
return@combine prov
|
||||
val sorted = r.sortedBy { it.first }
|
||||
sorted.takeLast(if (sorted.last().second is FavoritesPartProvider) 2 else 1)
|
||||
.map { it.second }
|
||||
}.collectLatest {
|
||||
send(it)
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ class FavoritesPartProvider : PartProvider, KoinComponent {
|
||||
private val dataStore: LauncherDataStore by inject()
|
||||
|
||||
override fun getRanking(context: Context): Flow<Int> = flow {
|
||||
emit(2)
|
||||
emit(Int.MAX_VALUE)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@ -75,6 +75,20 @@ fun ClockWidgetSettingsScreen() {
|
||||
value = fillHeight == true,
|
||||
onValueChanged = { viewModel.setFillHeight(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
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.Today,
|
||||
value = datePart == true,
|
||||
onValueChanged = {
|
||||
viewModel.setDatePart(it)
|
||||
},
|
||||
)
|
||||
val favoritesPart by viewModel.favoritesPart.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_clockwidget_favorites_part),
|
||||
|
||||
@ -66,6 +66,19 @@ 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 favoritesPart = dataStore.data.map { it.clockWidget.favoritesPart }.asLiveData()
|
||||
fun setFavoritesPart(favoritesPart: Boolean) {
|
||||
viewModelScope.launch {
|
||||
|
||||
@ -22,7 +22,7 @@ internal val Context.dataStore: LauncherDataStore by dataStore(
|
||||
}
|
||||
)
|
||||
|
||||
internal const val SchemaVersion = 12
|
||||
internal const val SchemaVersion = 13
|
||||
|
||||
internal fun getMigrations(context: Context): List<DataMigration<Settings>> {
|
||||
return listOf(
|
||||
@ -38,5 +38,6 @@ internal fun getMigrations(context: Context): List<DataMigration<Settings>> {
|
||||
Migration_9_10(),
|
||||
Migration_10_11(),
|
||||
Migration_11_12(),
|
||||
Migration_12_13(),
|
||||
)
|
||||
}
|
||||
@ -51,6 +51,7 @@ fun createFactorySettings(context: Context): Settings {
|
||||
.setAlarmPart(true)
|
||||
.setBatteryPart(true)
|
||||
.setMusicPart(true)
|
||||
.setDatePart(true)
|
||||
.setFavoritesPart(false)
|
||||
.setFillHeight(true)
|
||||
.build()
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
|
||||
class Migration_12_13: VersionedMigration(12, 13) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
return builder
|
||||
.setClockWidget(
|
||||
builder.clockWidget.toBuilder()
|
||||
.setDatePart(true)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -116,7 +116,7 @@ message Settings {
|
||||
EmptyClock = 4;
|
||||
}
|
||||
ClockStyle clock_style = 2;
|
||||
reserved 3;
|
||||
bool date_part = 3;
|
||||
bool music_part = 4;
|
||||
bool battery_part = 5;
|
||||
bool alarm_part = 6;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user