From a4d2e5c87bb4cb07f56c020edef4b2c389d768c0 Mon Sep 17 00:00:00 2001 From: validcube Date: Sun, 23 Jun 2024 14:03:20 +0700 Subject: [PATCH] Add custom date and time format for Smartspace Adds the ability for users to customize the date and time format displayed in Smartspace. --- lawnchair/res/values/strings.xml | 7 +++ .../preferences2/PreferenceManager2.kt | 15 ++++++ .../lawnchair/smartspace/IcuDateTextView.kt | 23 ++++++++ .../smartspace/model/SmartspaceCalendar.kt | 6 ++- .../smartspace/model/SmartspaceTimeFormat.kt | 7 +++ .../components/layout/PreferenceGroup.kt | 3 +- .../destinations/SmartspacePreferences.kt | 54 ++++++++++++++++++- 7 files changed, 111 insertions(+), 4 deletions(-) diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml index 7149ccd335e..957cc8e9f2e 100644 --- a/lawnchair/res/values/strings.xml +++ b/lawnchair/res/values/strings.xml @@ -309,12 +309,16 @@ Gregorian Persian + Custom %1$s, %2$s EEEMMMd HH:mm hh:mm aa dd MMMM + EEEMMMd + HH:mm + dd MMMM l، j F H:i g:i a @@ -332,12 +336,15 @@ Calendar Date & time + Custom Date Date Time Time format Follow system 12-hour format 24-hour format + Custom Time format + Custom Date format Weather diff --git a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt index 68fe978562f..6e41a558fa7 100644 --- a/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt +++ b/lawnchair/src/app/lawnchair/preferences2/PreferenceManager2.kt @@ -531,6 +531,21 @@ class PreferenceManager2 private constructor(private val context: Context) : Pre save = { it.toString() }, ) + val smartspaceCustomTimeFormat = preference( + key = stringPreferencesKey(name = "smartspace_custom_time_format"), + defaultValue = context.getString(R.string.smartspace_icu_date_pattern_custom_time), + ) + + val smartspaceCustomDate = preference( + key = stringPreferencesKey(name = "smartspace_custom_date"), + defaultValue = context.getString(R.string.smartspace_icu_date_pattern_custom_date), + ) + + val smartspaceCustomDateWithoutYear = preference( + key = stringPreferencesKey(name = "smartspace_custom_date_wmd"), + defaultValue = context.getString(R.string.smartspace_icu_date_pattern_custom_wday_month_day_no_year), + ) + val wallpaperDepthEffect = preference( key = booleanPreferencesKey(name = "enable_wallpaper_depth_effect"), defaultValue = true, diff --git a/lawnchair/src/app/lawnchair/smartspace/IcuDateTextView.kt b/lawnchair/src/app/lawnchair/smartspace/IcuDateTextView.kt index 4f0449230d7..53d2e702940 100644 --- a/lawnchair/src/app/lawnchair/smartspace/IcuDateTextView.kt +++ b/lawnchair/src/app/lawnchair/smartspace/IcuDateTextView.kt @@ -8,10 +8,12 @@ import android.icu.text.DisplayContext import android.os.SystemClock import android.text.format.DateFormat.is24HourFormat import android.util.AttributeSet +import android.util.Log import app.lawnchair.preferences2.PreferenceManager2 import app.lawnchair.smartspace.model.SmartspaceCalendar import app.lawnchair.smartspace.model.SmartspaceTimeFormat import app.lawnchair.util.broadcastReceiverFlow +import app.lawnchair.util.firstBlocking import app.lawnchair.util.repeatOnAttached import app.lawnchair.util.subscribeBlocking import com.android.launcher3.R @@ -95,12 +97,33 @@ class IcuDateTextView @JvmOverloads constructor( } val formatter = when (calendar) { SmartspaceCalendar.Persian -> createPersianFormatter() + SmartspaceCalendar.Custom -> createCustomFormatter() else -> createGregorianFormatter() } formatterFunction = formatter return formatter } + private fun createCustomFormatter(): FormatterFunction { + val TAG = "createCustomFormatter" + + var format: String + if (dateTimeOptions.showTime) { + format = prefs.smartspaceCustomTimeFormat.get().firstBlocking() + if (dateTimeOptions.showDate) format = prefs.smartspaceCustomDate.get().firstBlocking() + format + } else { + format = prefs.smartspaceCustomDateWithoutYear.get().firstBlocking() + } + try { + val formatter = DateFormat.getInstanceForSkeleton(format, Locale.getDefault()) + formatter.setContext(DisplayContext.CAPITALIZATION_FOR_STANDALONE) + return { formatter.format(it) } + } catch(T: Throwable) { + Log.w(TAG, "Fallback to Gregorian formatter", T) + return createGregorianFormatter() + } + } + private fun createPersianFormatter(): FormatterFunction { var format: String if (dateTimeOptions.showTime) { diff --git a/lawnchair/src/app/lawnchair/smartspace/model/SmartspaceCalendar.kt b/lawnchair/src/app/lawnchair/smartspace/model/SmartspaceCalendar.kt index 77d20e62b06..38e3190ef8d 100644 --- a/lawnchair/src/app/lawnchair/smartspace/model/SmartspaceCalendar.kt +++ b/lawnchair/src/app/lawnchair/smartspace/model/SmartspaceCalendar.kt @@ -14,13 +14,14 @@ sealed class SmartspaceCalendar(@StringRes val nameResourceId: Int, val formatCu fun fromString(value: String): SmartspaceCalendar = when (value) { "persian" -> Persian + "custom" -> Custom else -> Gregorian } /** * @return The list of all calendars. */ - fun values() = listOf(Gregorian, Persian) + fun values() = listOf(Gregorian, Persian, Custom) } object Gregorian : SmartspaceCalendar(nameResourceId = R.string.smartspace_calendar_gregorian) { @@ -29,4 +30,7 @@ sealed class SmartspaceCalendar(@StringRes val nameResourceId: Int, val formatCu object Persian : SmartspaceCalendar(nameResourceId = R.string.smartspace_calendar_persian) { override fun toString() = "persian" } + object Custom : SmartspaceCalendar(nameResourceId = R.string.smartspace_calendar_custom) { + override fun toString() = "custom" + } } diff --git a/lawnchair/src/app/lawnchair/smartspace/model/SmartspaceTimeFormat.kt b/lawnchair/src/app/lawnchair/smartspace/model/SmartspaceTimeFormat.kt index 839e15d15e9..6a5684dac48 100644 --- a/lawnchair/src/app/lawnchair/smartspace/model/SmartspaceTimeFormat.kt +++ b/lawnchair/src/app/lawnchair/smartspace/model/SmartspaceTimeFormat.kt @@ -10,6 +10,7 @@ sealed class SmartspaceTimeFormat(@StringRes val nameResourceId: Int) { fun fromString(value: String): SmartspaceTimeFormat = when (value) { "12_hour_format" -> TwelveHourFormat "24_hour_format" -> TwentyFourHourFormat + "custom" -> CustomHourFormat else -> FollowSystem } @@ -36,4 +37,10 @@ sealed class SmartspaceTimeFormat(@StringRes val nameResourceId: Int) { ) { override fun toString() = "24_hour_format" } + + object CustomHourFormat : SmartspaceTimeFormat( + nameResourceId = R.string.smartspace_time_custom_format + ) { + override fun toString() = "custom" + } } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/layout/PreferenceGroup.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/layout/PreferenceGroup.kt index 4448c931d39..3bd4ec0bf53 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/layout/PreferenceGroup.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/layout/PreferenceGroup.kt @@ -42,6 +42,7 @@ fun PreferenceGroup( dividerStartIndent: Dp = 0.dp, dividerEndIndent: Dp = 0.dp, dividersToSkip: Int = 0, + elevation: Dp = 1.dp, content: @Composable () -> Unit, ) { Column( @@ -51,7 +52,7 @@ fun PreferenceGroup( Surface( modifier = Modifier.padding(horizontal = 16.dp), shape = MaterialTheme.shapes.large, - tonalElevation = 1.dp, + tonalElevation = elevation, ) { if (showDividers) { DividerColumn( diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/SmartspacePreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/SmartspacePreferences.kt index 5e3454e39a2..671a2871ea5 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/SmartspacePreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/SmartspacePreferences.kt @@ -1,6 +1,9 @@ package app.lawnchair.ui.preferences.destinations import android.app.Activity +import android.icu.text.DateFormat +import android.icu.text.DisplayContext +import android.util.Log import android.view.ContextThemeWrapper import android.view.ViewGroup import android.view.ViewGroup.LayoutParams.MATCH_PARENT @@ -40,6 +43,7 @@ import app.lawnchair.ui.preferences.components.controls.ListPreference import app.lawnchair.ui.preferences.components.controls.ListPreferenceEntry import app.lawnchair.ui.preferences.components.controls.MainSwitchPreference import app.lawnchair.ui.preferences.components.controls.SwitchPreference +import app.lawnchair.ui.preferences.components.controls.TextPreference import app.lawnchair.ui.preferences.components.layout.DividerColumn import app.lawnchair.ui.preferences.components.layout.ExpandAndShrink import app.lawnchair.ui.preferences.components.layout.PreferenceGroup @@ -225,6 +229,13 @@ fun SmartspaceDateAndTimePreferences( ExpandAndShrink(visible = calendarSelectionEnabled.state.value && showDateAdapter.state.value) { SmartspaceCalendarPreference() } + val smartspaceCalendar = preferenceManager2().smartspaceCalendar.getAdapter() + ExpandAndShrink(visible = smartspaceCalendar.state.value is SmartspaceCalendar.Custom) { + SmartspaceCustomDateTimePreference() + // TODO: wtf is this layout!! + val TAG = "SmartspacePrefCustom" + Log.w(TAG, "Not supposed to be here?") + } SwitchPreference( adapter = showTimeAdapter, label = stringResource(id = R.string.smartspace_time), @@ -238,6 +249,45 @@ fun SmartspaceDateAndTimePreferences( } } +@Composable +fun SmartspaceCustomDateTimePreference( + modifier: Modifier = Modifier +) { + PreferenceGroup( + heading = stringResource(id = R.string.smartspace_custom_date_header), + modifier = Modifier, + elevation = 2.dp, + ) { + val preferenceManager2 = preferenceManager2() + val TAG = "SmartspaceCustomDateTimePref" + + //val date = preferenceManager2.smartspaceCustomDate.getAdapter().state.value + //val formatter = DateTimeFormatter.ofPattern(date) + var result: String = "blah" // formatter.format(LocalDate.now()) + + // TODO + Log.w(TAG, "Live result is not implemented") + + TextPreference( + adapter = preferenceManager2.smartspaceCustomTimeFormat.getAdapter(), + label = stringResource(id = R.string.smartspace_time_custom_format), + modifier = modifier, + ) + result = "Not implemented" + TextPreference( + adapter = preferenceManager2.smartspaceCustomDate.getAdapter(), + label = stringResource(id = R.string.smartspace_date_custom_format), + modifier = modifier, + description = { "Format: $result" }, + ) + TextPreference( + adapter = preferenceManager2.smartspaceCustomDateWithoutYear.getAdapter(), + label = stringResource(id = R.string.smartspace_time_custom_format), + modifier = modifier, + ) + } +} + @Composable fun SmartspaceTimeFormatPreference( modifier: Modifier = Modifier, @@ -268,10 +318,10 @@ fun SmartspaceCalendarPreference( }.toPersistentList() } - val adapter = preferenceManager2().smartspaceCalendar.getAdapter() + val smartspaceCalendar = preferenceManager2().smartspaceCalendar.getAdapter() ListPreference( - adapter = adapter, + adapter = smartspaceCalendar, entries = entries, label = stringResource(id = R.string.smartspace_calendar), modifier = modifier,