Clock widget: always display favorites part on bottom of screen if enabled
This commit is contained in:
parent
557aa9fc88
commit
15ac8912b1
@ -64,7 +64,6 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
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.ClockWidgetAlignment
|
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetAlignment
|
||||||
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetColors
|
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetColors
|
||||||
@ -107,9 +106,7 @@ fun ClockWidget(
|
|||||||
viewModel.updateTime(time)
|
viewModel.updateTime(time)
|
||||||
}
|
}
|
||||||
|
|
||||||
val partProviders by remember { viewModel.getActiveParts(context) }.collectAsStateWithLifecycle(
|
val partProvider by remember { viewModel.getActivePart(context) }.collectAsStateWithLifecycle(null)
|
||||||
emptyList()
|
|
||||||
)
|
|
||||||
|
|
||||||
AnimatedContent(editMode, label = "ClockWidget") {
|
AnimatedContent(editMode, label = "ClockWidget") {
|
||||||
if (it) {
|
if (it) {
|
||||||
@ -154,93 +151,92 @@ fun ClockWidget(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Box(
|
Column(modifier = modifier) {
|
||||||
modifier = modifier,
|
Box(
|
||||||
contentAlignment = when (alignment) {
|
modifier = Modifier
|
||||||
ClockWidgetAlignment.Center -> Alignment.Center
|
.weight(1f)
|
||||||
ClockWidgetAlignment.Top -> Alignment.TopCenter
|
.fillMaxWidth(),
|
||||||
else -> Alignment.BottomCenter
|
contentAlignment = when (alignment) {
|
||||||
}
|
ClockWidgetAlignment.Center -> Alignment.Center
|
||||||
) {
|
ClockWidgetAlignment.Top -> Alignment.TopCenter
|
||||||
|
else -> Alignment.BottomCenter
|
||||||
CompositionLocalProvider(
|
}
|
||||||
LocalContentColor provides contentColor
|
|
||||||
) {
|
) {
|
||||||
if (layout == ClockWidgetLayout.Vertical) {
|
CompositionLocalProvider(
|
||||||
Column(
|
LocalContentColor provides contentColor
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
) {
|
||||||
) {
|
if (layout == ClockWidgetLayout.Vertical) {
|
||||||
Box(
|
Column(
|
||||||
modifier = Modifier.clickable(
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
enabled = clockStyle != ClockStyle.EmptyClock,
|
|
||||||
indication = null,
|
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
|
||||||
) {
|
|
||||||
viewModel.launchClockApp(context)
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
Clock(clockStyle, ClockWidgetLayout.Vertical)
|
Box(
|
||||||
}
|
modifier = Modifier.clickable(
|
||||||
|
enabled = clockStyle != ClockStyle.EmptyClock,
|
||||||
|
indication = null,
|
||||||
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
) {
|
||||||
|
viewModel.launchClockApp(context)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Clock(clockStyle, ClockWidgetLayout.Vertical)
|
||||||
|
}
|
||||||
|
|
||||||
for (part in partProviders) {
|
if (partProvider != null) {
|
||||||
DynamicZone(
|
DynamicZone(
|
||||||
modifier = Modifier.padding(bottom = 8.dp),
|
modifier = Modifier.padding(bottom = 8.dp),
|
||||||
layout = ClockWidgetLayout.Vertical,
|
layout = ClockWidgetLayout.Vertical,
|
||||||
provider = part,
|
provider = partProvider,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (layout == ClockWidgetLayout.Horizontal) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(end = 8.dp, bottom = 16.dp),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
if (partProvider != null) {
|
||||||
|
DynamicZone(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
layout = ClockWidgetLayout.Horizontal,
|
||||||
|
provider = partProvider,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.height(56.dp)
|
||||||
|
.width(2.dp)
|
||||||
|
.background(
|
||||||
|
LocalContentColor.current
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.clickable(
|
||||||
|
enabled = clockStyle != ClockStyle.EmptyClock,
|
||||||
|
indication = null,
|
||||||
|
interactionSource = remember { MutableInteractionSource() }
|
||||||
|
) {
|
||||||
|
viewModel.launchClockApp(context)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Clock(clockStyle, ClockWidgetLayout.Horizontal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (layout == ClockWidgetLayout.Horizontal) {
|
}
|
||||||
Row(
|
val dockProvider by viewModel.dockProvider.collectAsState()
|
||||||
modifier = Modifier
|
if (dockProvider != null) {
|
||||||
.fillMaxWidth()
|
Box(
|
||||||
.padding(end = 8.dp, bottom = 16.dp),
|
modifier = Modifier
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
.fillMaxWidth()
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
.padding(bottom = 16.dp)
|
||||||
) {
|
) {
|
||||||
if (partProviders.size > 1) {
|
dockProvider?.Component(ClockWidgetLayout.Vertical)
|
||||||
HorizontalPager(
|
|
||||||
state = rememberPagerState { 2 },
|
|
||||||
beyondBoundsPageCount = 1,
|
|
||||||
modifier = Modifier.weight(1f)
|
|
||||||
) {
|
|
||||||
partProviders.getOrNull(it)?.let {
|
|
||||||
DynamicZone(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
layout = ClockWidgetLayout.Horizontal,
|
|
||||||
provider = it,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (partProviders.isNotEmpty()) {
|
|
||||||
DynamicZone(
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
layout = ClockWidgetLayout.Horizontal,
|
|
||||||
provider = partProviders[0],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
.height(56.dp)
|
|
||||||
.width(2.dp)
|
|
||||||
.background(
|
|
||||||
LocalContentColor.current
|
|
||||||
),
|
|
||||||
)
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.clickable(
|
|
||||||
enabled = clockStyle != ClockStyle.EmptyClock,
|
|
||||||
indication = null,
|
|
||||||
interactionSource = remember { MutableInteractionSource() }
|
|
||||||
) {
|
|
||||||
viewModel.launchClockApp(context)
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Clock(clockStyle, ClockWidgetLayout.Horizontal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,24 +30,21 @@ class ClockWidgetVM : ViewModel(), KoinComponent {
|
|||||||
private val partProviders = dataStore.data.map { it.clockWidget }.distinctUntilChanged().map {
|
private val partProviders = dataStore.data.map { it.clockWidget }.distinctUntilChanged().map {
|
||||||
val providers = mutableListOf<PartProvider>()
|
val providers = mutableListOf<PartProvider>()
|
||||||
if (it.datePart) providers += DatePartProvider()
|
if (it.datePart) providers += DatePartProvider()
|
||||||
if (it.favoritesPart) providers += FavoritesPartProvider()
|
|
||||||
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()
|
||||||
providers
|
providers
|
||||||
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
|
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
|
||||||
|
|
||||||
fun getActiveParts(context: Context): Flow<List<PartProvider>> = channelFlow {
|
fun getActivePart(context: Context): Flow<PartProvider?> = channelFlow {
|
||||||
partProviders.collectLatest { providers ->
|
partProviders.collectLatest { providers ->
|
||||||
if (providers.isEmpty()) {
|
if (providers.isEmpty()) {
|
||||||
send(emptyList())
|
send(null)
|
||||||
return@collectLatest
|
return@collectLatest
|
||||||
}
|
}
|
||||||
val rankings = providers.map { it.getRanking(context).map { r -> r to it } }
|
val rankings = providers.map { it.getRanking(context).map { r -> r to it } }
|
||||||
combine(rankings) { r ->
|
combine(rankings) { r ->
|
||||||
val sorted = r.sortedBy { it.first }
|
r.filter { it.first > 0 }.maxByOrNull { it.first }?.second
|
||||||
sorted.takeLast(if (sorted.last().second is FavoritesPartProvider) 2 else 1)
|
|
||||||
.map { it.second }
|
|
||||||
}.collectLatest {
|
}.collectLatest {
|
||||||
send(it)
|
send(it)
|
||||||
}
|
}
|
||||||
@ -65,6 +62,10 @@ class ClockWidgetVM : ViewModel(), KoinComponent {
|
|||||||
val alignment = dataStore.data.map { it.clockWidget.alignment }
|
val alignment = dataStore.data.map { it.clockWidget.alignment }
|
||||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
|
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
|
||||||
|
|
||||||
|
val dockProvider = dataStore.data
|
||||||
|
.map { if (it.clockWidget.favoritesPart) FavoritesPartProvider() else null }
|
||||||
|
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
|
||||||
|
|
||||||
fun updateTime(time: Long) {
|
fun updateTime(time: Long) {
|
||||||
partProviders.value.forEach { it.setTime(time) }
|
partProviders.value.forEach { it.setTime(time) }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,11 +59,10 @@ class FavoritesPartProvider : PartProvider, KoinComponent {
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = 8.dp)
|
|
||||||
.wrapContentHeight()
|
.wrapContentHeight()
|
||||||
) {
|
) {
|
||||||
SearchResultGrid(
|
SearchResultGrid(
|
||||||
items = favorites, showLabels = false, columns = columns,
|
items = favorites, showLabels = false, columns = columns.coerceAtMost(favorites.size),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user