diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/AlarmPartProvider.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/AlarmPartProvider.kt index f22eb47e8..e5fa30262 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/AlarmPartProvider.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/AlarmPartProvider.kt @@ -5,13 +5,13 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.content.IntentFilter +import android.icu.text.DateFormat +import android.icu.util.ULocale import android.provider.AlarmClock -import android.text.format.DateUtils import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.* import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier @@ -21,6 +21,9 @@ import androidx.compose.ui.unit.dp import androidx.core.content.getSystemService import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ui.R +import de.mm20.launcher2.ui.locals.LocalTimeFormat +import de.mm20.launcher2.ui.utils.isTwentyFourHours +import java.util.Date import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.trySendBlocking import kotlinx.coroutines.flow.* @@ -51,7 +54,8 @@ class AlarmPartProvider : PartProvider { if (alarm > it + AlarmWindow) { send(0) } else { - send(60) + // Highest ranking, so the alarm always sits directly below the clock. + send(100) } } } @@ -77,11 +81,15 @@ class AlarmPartProvider : PartProvider { @Composable override fun Component(compactLayout: Boolean) { val context = LocalContext.current + val timeFormat = LocalTimeFormat.current val alarmTime by nextAlarmTime - val time by this.time.collectAsState(System.currentTimeMillis()) - alarmTime?.let { + alarmTime?.let { alarm -> + + val skeleton = if (timeFormat.isTwentyFourHours(context)) "HH:mm" else "hh:mm a" + val alarmText = DateFormat.getInstanceForSkeleton(skeleton, ULocale.getDefault()) + .format(Date(alarm)) if (!compactLayout) { @@ -99,12 +107,7 @@ class AlarmPartProvider : PartProvider { ) Text( modifier = Modifier.padding(start = 12.dp), - text = DateUtils.getRelativeTimeSpanString( - it, - time, - DateUtils.MINUTE_IN_MILLIS - ) - .toString(), + text = alarmText, ) } } else { @@ -123,12 +126,7 @@ class AlarmPartProvider : PartProvider { ) Text( modifier = Modifier.padding(start = 12.dp), - text = DateUtils.getRelativeTimeSpanString( - it, - time, - DateUtils.MINUTE_IN_MILLIS - ) - .toString(), + text = alarmText, style = MaterialTheme.typography.titleMedium ) } diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/CalendarPartProvider.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/CalendarPartProvider.kt index 138cfcbe8..2958d009c 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/CalendarPartProvider.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/CalendarPartProvider.kt @@ -54,6 +54,7 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -69,17 +70,14 @@ import java.util.Date */ private const val MaxRows = 4 -/** An event that starts within this time frame (or is running) raises the ranking. */ -private const val SoonThreshold = 30 * 60 * 1000L - /** Re-query interval, so the agenda survives calendar changes that don't notify. */ private const val RefreshInterval = 15 * 60 * 1000L -private const val RankingToday = 30 -private const val RankingSoon = 70 +/** Static ranking: the agenda is shown whenever there are events left today. */ +private const val Ranking = 30 /** Width of the dot column. Kept fixed so the rows line up with each other. */ -private val DotColumn = 12.dp +private val DotColumn = 20.dp /** Width of the time column. Wide enough for "11:59 PM" and "all-day". */ private val TimeColumn = 64.dp @@ -100,17 +98,12 @@ class CalendarPartProvider : PartProvider, KoinComponent { private val searchSettings: CalendarSearchSettings by inject() private val agenda = MutableStateFlow>(emptyList()) - private val time = MutableStateFlow(System.currentTimeMillis()) - - override fun setTime(time: Long) { - this.time.value = time - } override fun getRanking(context: Context): Flow = channelFlow { // Load the agenda in the background; the ranking itself only depends on the - // already known agenda and the current time, so it can be emitted right away. + // already known agenda, so it can be emitted right away. launch { observeAgenda(context) } - combine(agenda, time) { events, now -> ranking(events, now) } + agenda.map { ranking(it) } .distinctUntilChanged() .collect { send(it) } } @@ -167,13 +160,8 @@ class CalendarPartProvider : PartProvider, KoinComponent { } } - private fun ranking(events: List, now: Long): Int { - if (events.isEmpty()) return 0 - val soon = events.any { event -> - val start = event.startTime - !event.allDay && start != null && start <= now + SoonThreshold && event.endTime > now - } - return if (soon) RankingSoon else RankingToday + private fun ranking(events: List): Int { + return if (events.isEmpty()) 0 else Ranking } private fun endOfDay(now: Long): Long { diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/DatePartProvider.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/DatePartProvider.kt index d7d4613f3..c343a34d0 100644 --- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/DatePartProvider.kt +++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/DatePartProvider.kt @@ -24,7 +24,8 @@ import java.util.* class DatePartProvider : PartProvider { override fun getRanking(context: Context): Flow = flow { - emit(1) + // Second highest, so the date follows the alarm below the clock. + emit(90) } @Composable