Add additional row in vertical and horizontal pager in horizontal clock mode showing favorites (#246)

* Add setting for clock widget to show two DynamicZones, one of them always being favorites

* implementing horizontal pager

* undoing changes

* checking if withFavoriteBar is set in horizontal layout

* Clock widget: use compose pager, not accompanist pager

* Pull favorites part provider from view model

* Clock widget settings: remove divider

* Remove date_part from settings.proto

* Remove datePart settings references

---------

Co-authored-by: MM20 <15646950+MM2-0@users.noreply.github.com>
This commit is contained in:
Christoph 2023-02-08 16:14:38 +01:00 committed by GitHub
parent 9fb514dc68
commit 0a63a104bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 57 additions and 62 deletions

View File

@ -4,6 +4,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.ExpandLess import androidx.compose.material.icons.rounded.ExpandLess
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@ -16,12 +17,12 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetColors import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetColors
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout
import de.mm20.launcher2.ui.base.LocalTime import de.mm20.launcher2.ui.base.LocalTime
import de.mm20.launcher2.ui.launcher.widgets.clock.clocks.* 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.launcher.widgets.clock.parts.PartProvider
import de.mm20.launcher2.ui.locals.LocalPreferDarkContentOverWallpaper import de.mm20.launcher2.ui.locals.LocalPreferDarkContentOverWallpaper
@ -40,7 +41,8 @@ fun ClockWidget(
viewModel.updateTime(time) viewModel.updateTime(time)
} }
val partProvider by viewModel.getActivePart(LocalContext.current).collectAsState(null) val partProvider by remember { viewModel.getActivePart(context) }.collectAsState(null)
val withFavoriteBar by viewModel.withFavorites.observeAsState()
Box( Box(
modifier = Modifier modifier = Modifier
@ -48,11 +50,12 @@ fun ClockWidget(
contentAlignment = Alignment.BottomCenter contentAlignment = Alignment.BottomCenter
) { ) {
val contentColor = if (color == ClockWidgetColors.Auto && LocalPreferDarkContentOverWallpaper.current || color == ClockWidgetColors.Dark) { val contentColor =
Color(0,0,0, 180) if (color == ClockWidgetColors.Auto && LocalPreferDarkContentOverWallpaper.current || color == ClockWidgetColors.Dark) {
} else { Color(0, 0, 0, 180)
Color.White } else {
} Color.White
}
CompositionLocalProvider( CompositionLocalProvider(
LocalContentColor provides contentColor LocalContentColor provides contentColor
@ -74,10 +77,22 @@ fun ClockWidget(
} }
DynamicZone( DynamicZone(
modifier = Modifier.padding(bottom = 16.dp), modifier = if (true == withFavoriteBar) {
ClockWidgetLayout.Vertical, Modifier.padding(bottom = 8.dp, top = 8.dp)
} else {
Modifier.padding(bottom = 16.dp)
},
layout = ClockWidgetLayout.Vertical,
provider = partProvider, provider = partProvider,
) )
if (true == withFavoriteBar) {
DynamicZone(
modifier = Modifier.padding(bottom = 16.dp),
layout = ClockWidgetLayout.Vertical,
provider = viewModel.favoritesPartProvider,
)
}
} }
} }
if (layout == ClockWidgetLayout.Horizontal) { if (layout == ClockWidgetLayout.Horizontal) {
@ -95,11 +110,28 @@ fun ClockWidget(
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween horizontalArrangement = Arrangement.SpaceBetween
) { ) {
DynamicZone( if (true == withFavoriteBar) {
modifier = Modifier.weight(1f), HorizontalPager(
ClockWidgetLayout.Horizontal, pageCount = 2,
provider = partProvider, beyondBoundsPageCount = 1,
) modifier = Modifier.weight(1f)
) {
DynamicZone(
modifier = Modifier.fillMaxWidth(),
layout = ClockWidgetLayout.Horizontal,
provider = when (it) {
0 -> viewModel.favoritesPartProvider
else -> partProvider
}
)
}
} else {
DynamicZone(
modifier = Modifier.weight(1f),
layout = ClockWidgetLayout.Horizontal,
provider = partProvider
)
}
Box( Box(
modifier = Modifier modifier = Modifier
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
@ -124,7 +156,6 @@ fun ClockWidget(
} }
} }
} }
} }
} }

View File

@ -27,17 +27,20 @@ class ClockWidgetVM : ViewModel(), KoinComponent {
init { init {
viewModelScope.launch { viewModelScope.launch {
dataStore.data.map { it.clockWidget }.distinctUntilChanged().collectLatest { dataStore.data.map { it.clockWidget }.distinctUntilChanged().collectLatest {
val providers = mutableListOf<PartProvider>() val providers = mutableListOf<PartProvider>(
if (it.datePart) providers += DatePartProvider() DatePartProvider()
)
if (it.musicPart) providers += MusicPartProvider() if (it.musicPart) providers += MusicPartProvider()
if (it.batteryPart) providers += BatteryPartProvider() if (it.batteryPart) providers += BatteryPartProvider()
if (it.alarmPart) providers += AlarmPartProvider() if (it.alarmPart) providers += AlarmPartProvider()
if (it.favoritesPart) providers += FavoritesPartProvider()
partProviders.value = providers partProviders.value = providers
} }
} }
} }
val withFavorites = dataStore.data.map { it.clockWidget.favoritesPart }.asLiveData()
val favoritesPartProvider = FavoritesPartProvider()
val time = MutableStateFlow(System.currentTimeMillis()) val time = MutableStateFlow(System.currentTimeMillis())
fun getActivePart(context: Context): Flow<PartProvider?> = channelFlow { fun getActivePart(context: Context): Flow<PartProvider?> = channelFlow {

View File

@ -65,7 +65,6 @@ class FavoritesPartProvider : PartProvider, KoinComponent {
SearchResultGrid( SearchResultGrid(
items = favorites, showLabels = false, columns = columns, items = favorites, showLabels = false, columns = columns,
) )
} }
} }
} }

View File

@ -41,7 +41,7 @@ fun ClockWidgetSettingsScreen() {
value = layout, value = layout,
items = listOf( items = listOf(
stringResource(R.string.preference_clockwidget_layout_vertical) to ClockWidgetLayout.Vertical, stringResource(R.string.preference_clockwidget_layout_vertical) to ClockWidgetLayout.Vertical,
stringResource(R.string.preference_clockwidget_layout_horizontal) to ClockWidgetLayout.Horizontal stringResource(R.string.preference_clockwidget_layout_horizontal) to ClockWidgetLayout.Horizontal,
), ),
onValueChanged = { onValueChanged = {
if (it != null) viewModel.setLayout(it) if (it != null) viewModel.setLayout(it)
@ -75,20 +75,6 @@ fun ClockWidgetSettingsScreen() {
value = fillHeight == true, value = fillHeight == true,
onValueChanged = { viewModel.setFillHeight(it) } 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.CalendarToday,
value = datePart == true,
onValueChanged = {
viewModel.setDatePart(it)
}
)
val favoritesPart by viewModel.favoritesPart.observeAsState() val favoritesPart by viewModel.favoritesPart.observeAsState()
SwitchPreference( SwitchPreference(
title = stringResource(R.string.preference_clockwidget_favorites_part), title = stringResource(R.string.preference_clockwidget_favorites_part),
@ -97,7 +83,7 @@ fun ClockWidgetSettingsScreen() {
value = favoritesPart == true, value = favoritesPart == true,
onValueChanged = { onValueChanged = {
viewModel.setFavoritesPart(it) viewModel.setFavoritesPart(it)
} },
) )
} }
} }

View File

@ -6,6 +6,7 @@ import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetColors import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetColors
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent import org.koin.core.component.KoinComponent
@ -65,24 +66,6 @@ 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)
.also {
if (datePart) {
it.setFavoritesPart(false)
}
}
).build()
}
}
}
val favoritesPart = dataStore.data.map { it.clockWidget.favoritesPart }.asLiveData() val favoritesPart = dataStore.data.map { it.clockWidget.favoritesPart }.asLiveData()
fun setFavoritesPart(favoritesPart: Boolean) { fun setFavoritesPart(favoritesPart: Boolean) {
viewModelScope.launch { viewModelScope.launch {
@ -91,11 +74,6 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent {
.setClockWidget( .setClockWidget(
it.clockWidget.toBuilder() it.clockWidget.toBuilder()
.setFavoritesPart(favoritesPart) .setFavoritesPart(favoritesPart)
.also {
if (favoritesPart) {
it.setDatePart(false)
}
}
).build() ).build()
} }
} }

View File

@ -50,9 +50,8 @@ fun createFactorySettings(context: Context): Settings {
.setColor(Settings.ClockWidgetSettings.ClockWidgetColors.Auto) .setColor(Settings.ClockWidgetSettings.ClockWidgetColors.Auto)
.setAlarmPart(true) .setAlarmPart(true)
.setBatteryPart(true) .setBatteryPart(true)
.setDatePart(true)
.setMusicPart(true) .setMusicPart(true)
.setFavoritesPart(false) .setFavoritesPart(true)
.setFillHeight(true) .setFillHeight(true)
.build() .build()
) )

View File

@ -8,7 +8,6 @@ class Migration_2_3: VersionedMigration(2, 3) {
builder.clockWidget.toBuilder() builder.clockWidget.toBuilder()
.setAlarmPart(true) .setAlarmPart(true)
.setBatteryPart(true) .setBatteryPart(true)
.setDatePart(true)
.setMusicPart(true) .setMusicPart(true)
) )
} }

View File

@ -115,7 +115,7 @@ message Settings {
EmptyClock = 4; EmptyClock = 4;
} }
ClockStyle clock_style = 2; ClockStyle clock_style = 2;
bool date_part = 3; reserved 3;
bool music_part = 4; bool music_part = 4;
bool battery_part = 5; bool battery_part = 5;
bool alarm_part = 6; bool alarm_part = 6;