Merge remote-tracking branch 'upstream/main' into feat/materialYouCompat
Signed-off-by: Guillermo Villafuerte <gvillafu@comunidad.unam.mx> # Conflicts: # app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt # app/ui/src/main/java/de/mm20/launcher2/ui/theme/colorscheme/Custom.kt # core/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt # core/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt
This commit is contained in:
@@ -4,6 +4,7 @@ plugins {
|
||||
alias(libs.plugins.android.library)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.protobuf)
|
||||
alias(libs.plugins.kotlin.plugin.serialization)
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -57,6 +58,7 @@ protobuf {
|
||||
|
||||
dependencies {
|
||||
implementation(libs.kotlin.stdlib)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
implementation(libs.androidx.core)
|
||||
implementation(libs.androidx.appcompat)
|
||||
api(libs.androidx.datastore)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
-keepclassmembers class de.mm20.launcher2.preferences.Settings {
|
||||
-keepclassmembers class de.mm20.launcher2.preferences.LegacySettings {
|
||||
<fields>;
|
||||
}
|
||||
|
||||
-keepclassmembers class de.mm20.launcher2.preferences.Settings$* {
|
||||
-keepclassmembers class de.mm20.launcher2.preferences.LegacySettings$* {
|
||||
<fields>;
|
||||
}
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package de.mm20.launcher2.preferences
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataMigration
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
|
||||
import androidx.datastore.dataStore
|
||||
import de.mm20.launcher2.crashreporter.CrashReporter
|
||||
import de.mm20.launcher2.preferences.migrations.*
|
||||
|
||||
typealias LauncherDataStore = DataStore<Settings>
|
||||
|
||||
internal val Context.dataStore: LauncherDataStore by dataStore(
|
||||
fileName = "settings.pb",
|
||||
serializer = SettingsSerializer,
|
||||
produceMigrations = {
|
||||
getMigrations(it)
|
||||
},
|
||||
corruptionHandler = ReplaceFileCorruptionHandler {
|
||||
CrashReporter.logException(it)
|
||||
Settings.getDefaultInstance()
|
||||
}
|
||||
)
|
||||
|
||||
internal const val SchemaVersion = 19
|
||||
|
||||
internal fun getMigrations(context: Context): List<DataMigration<Settings>> {
|
||||
return listOf(
|
||||
FactorySettingsMigration(context),
|
||||
Migration_1_2(),
|
||||
Migration_2_3(),
|
||||
Migration_3_4(),
|
||||
Migration_4_5(),
|
||||
Migration_5_6(),
|
||||
Migration_6_7(),
|
||||
Migration_7_8(),
|
||||
Migration_8_9(),
|
||||
Migration_9_10(),
|
||||
Migration_10_11(),
|
||||
Migration_11_12(),
|
||||
Migration_12_13(),
|
||||
Migration_13_14(),
|
||||
Migration_14_15(),
|
||||
Migration_15_16(),
|
||||
Migration_16_17(),
|
||||
Migration_17_18(),
|
||||
Migration_18_19(),
|
||||
)
|
||||
}
|
||||
@@ -2,59 +2,58 @@ package de.mm20.launcher2.preferences
|
||||
|
||||
import android.content.Context
|
||||
import de.mm20.launcher2.ktx.isAtLeastApiLevel
|
||||
import de.mm20.launcher2.preferences.Settings.SearchBarSettings.SearchBarColors
|
||||
import de.mm20.launcher2.preferences.LegacySettings.SearchBarSettings.SearchBarColors
|
||||
import de.mm20.launcher2.preferences.ktx.toSettingsColorsScheme
|
||||
import scheme.Scheme
|
||||
import java.util.UUID
|
||||
|
||||
fun createFactorySettings(context: Context): Settings {
|
||||
return Settings.newBuilder()
|
||||
fun createFactorySettings(context: Context): LegacySettings {
|
||||
return LegacySettings.newBuilder()
|
||||
.setAppearance(
|
||||
Settings.AppearanceSettings
|
||||
LegacySettings.AppearanceSettings
|
||||
.newBuilder()
|
||||
.setTheme(Settings.AppearanceSettings.Theme.System)
|
||||
.setTheme(LegacySettings.AppearanceSettings.Theme.System)
|
||||
.setDimWallpaper(false)
|
||||
.setBlurWallpaper(true)
|
||||
.setBlurWallpaperRadius(32)
|
||||
.setThemeId(UUID(0L, 0L).toString())
|
||||
.setFont(Settings.AppearanceSettings.Font.Outfit)
|
||||
.setForceCompatModeSystemColors(false)
|
||||
.setFont(LegacySettings.AppearanceSettings.Font.Outfit)
|
||||
.build()
|
||||
)
|
||||
.setWeather(
|
||||
Settings.WeatherSettings
|
||||
LegacySettings.WeatherSettings
|
||||
.newBuilder()
|
||||
.setProvider(Settings.WeatherSettings.WeatherProvider.MetNo)
|
||||
.setProvider(LegacySettings.WeatherSettings.WeatherProvider.MetNo)
|
||||
.setImperialUnits(context.resources.getBoolean(R.bool.default_imperialUnits))
|
||||
.build()
|
||||
)
|
||||
.setMusicWidget(
|
||||
Settings.MusicWidgetSettings
|
||||
LegacySettings.MusicWidgetSettings
|
||||
.newBuilder()
|
||||
.build()
|
||||
)
|
||||
.setCalendarWidget(
|
||||
Settings.CalendarWidgetSettings
|
||||
LegacySettings.CalendarWidgetSettings
|
||||
.newBuilder()
|
||||
.setHideAlldayEvents(false)
|
||||
)
|
||||
.setClockWidget(
|
||||
Settings.ClockWidgetSettings
|
||||
LegacySettings.ClockWidgetSettings
|
||||
.newBuilder()
|
||||
.setLayout(Settings.ClockWidgetSettings.ClockWidgetLayout.Vertical)
|
||||
.setClockStyle(Settings.ClockWidgetSettings.ClockStyle.DigitalClock1)
|
||||
.setColor(Settings.ClockWidgetSettings.ClockWidgetColors.Auto)
|
||||
.setLayout(LegacySettings.ClockWidgetSettings.ClockWidgetLayout.Vertical)
|
||||
.setClockStyle(LegacySettings.ClockWidgetSettings.ClockStyle.DigitalClock1)
|
||||
.setColor(LegacySettings.ClockWidgetSettings.ClockWidgetColors.Auto)
|
||||
.setAlarmPart(true)
|
||||
.setBatteryPart(true)
|
||||
.setMusicPart(true)
|
||||
.setDatePart(true)
|
||||
.setFavoritesPart(false)
|
||||
.setFillHeight(true)
|
||||
.setAlignment(Settings.ClockWidgetSettings.ClockWidgetAlignment.Bottom)
|
||||
.setAlignment(LegacySettings.ClockWidgetSettings.ClockWidgetAlignment.Bottom)
|
||||
.build()
|
||||
)
|
||||
.setFavorites(
|
||||
Settings.FavoritesSettings
|
||||
LegacySettings.FavoritesSettings
|
||||
.newBuilder()
|
||||
.setEnabled(true)
|
||||
.setFrequentlyUsed(true)
|
||||
@@ -62,7 +61,7 @@ fun createFactorySettings(context: Context): Settings {
|
||||
.setEditButton(true)
|
||||
)
|
||||
.setFileSearch(
|
||||
Settings.FilesSearchSettings
|
||||
LegacySettings.FilesSearchSettings
|
||||
.newBuilder()
|
||||
.setLocalFiles(true)
|
||||
.setNextcloud(false)
|
||||
@@ -71,50 +70,50 @@ fun createFactorySettings(context: Context): Settings {
|
||||
.setNextcloud(false)
|
||||
)
|
||||
.setContactsSearch(
|
||||
Settings.ContactsSearchSettings
|
||||
LegacySettings.ContactsSearchSettings
|
||||
.newBuilder()
|
||||
.setEnabled(true)
|
||||
)
|
||||
.setCalendarSearch(
|
||||
Settings.CalendarSearchSettings
|
||||
LegacySettings.CalendarSearchSettings
|
||||
.newBuilder()
|
||||
.setEnabled(true)
|
||||
)
|
||||
.setAppShortcutSearch(
|
||||
Settings.AppShortcutSearchSettings
|
||||
LegacySettings.AppShortcutSearchSettings
|
||||
.newBuilder()
|
||||
.setEnabled(true)
|
||||
)
|
||||
.setCalculatorSearch(
|
||||
Settings.CalculatorSearchSettings
|
||||
LegacySettings.CalculatorSearchSettings
|
||||
.newBuilder()
|
||||
.setEnabled(true)
|
||||
)
|
||||
.setUnitConverterSearch(
|
||||
Settings.UnitConverterSearchSettings
|
||||
LegacySettings.UnitConverterSearchSettings
|
||||
.newBuilder()
|
||||
.setEnabled(true)
|
||||
.setCurrencies(true)
|
||||
)
|
||||
.setWikipediaSearch(
|
||||
Settings.WikipediaSearchSettings
|
||||
LegacySettings.WikipediaSearchSettings
|
||||
.newBuilder()
|
||||
.setEnabled(false)
|
||||
.setImages(false)
|
||||
.setCustomUrl("")
|
||||
)
|
||||
.setWebsiteSearch(
|
||||
Settings.WebsiteSearchSettings
|
||||
LegacySettings.WebsiteSearchSettings
|
||||
.newBuilder()
|
||||
.setEnabled(false)
|
||||
)
|
||||
.setWebSearch(
|
||||
Settings.WebSearchSettings
|
||||
LegacySettings.WebSearchSettings
|
||||
.newBuilder()
|
||||
.setEnabled(true)
|
||||
)
|
||||
.setBadges(
|
||||
Settings.BadgeSettings
|
||||
LegacySettings.BadgeSettings
|
||||
.newBuilder()
|
||||
.setNotifications(true)
|
||||
.setCloudFiles(true)
|
||||
@@ -122,15 +121,15 @@ fun createFactorySettings(context: Context): Settings {
|
||||
.setSuspendedApps(true)
|
||||
)
|
||||
.setGrid(
|
||||
Settings.GridSettings.newBuilder()
|
||||
LegacySettings.GridSettings.newBuilder()
|
||||
.setColumnCount(context.resources.getInteger(R.integer.config_columnCount))
|
||||
.setIconSize(48)
|
||||
.setShowLabels(true)
|
||||
.build()
|
||||
)
|
||||
.setSearchBar(
|
||||
Settings.SearchBarSettings.newBuilder()
|
||||
.setSearchBarStyle(Settings.SearchBarSettings.SearchBarStyle.Transparent)
|
||||
LegacySettings.SearchBarSettings.newBuilder()
|
||||
.setSearchBarStyle(LegacySettings.SearchBarSettings.SearchBarStyle.Transparent)
|
||||
.setAutoFocus(true)
|
||||
.setLaunchOnEnter(true)
|
||||
.setColor(SearchBarColors.Auto)
|
||||
@@ -138,67 +137,67 @@ fun createFactorySettings(context: Context): Settings {
|
||||
.build()
|
||||
)
|
||||
.setIcons(
|
||||
Settings.IconSettings.newBuilder()
|
||||
LegacySettings.IconSettings.newBuilder()
|
||||
.setAdaptify(true)
|
||||
.setShape(Settings.IconSettings.IconShape.PlatformDefault)
|
||||
.setShape(LegacySettings.IconSettings.IconShape.PlatformDefault)
|
||||
.setThemedIcons(false)
|
||||
.setIconPack("")
|
||||
.setIconPackThemed(true)
|
||||
)
|
||||
.setEasterEgg(false)
|
||||
.setSystemBars(
|
||||
Settings.SystemBarsSettings.newBuilder()
|
||||
.setNavBarColor(Settings.SystemBarsSettings.SystemBarColors.Auto)
|
||||
.setStatusBarColor(Settings.SystemBarsSettings.SystemBarColors.Auto)
|
||||
LegacySettings.SystemBarsSettings.newBuilder()
|
||||
.setNavBarColor(LegacySettings.SystemBarsSettings.SystemBarColors.Auto)
|
||||
.setStatusBarColor(LegacySettings.SystemBarsSettings.SystemBarColors.Auto)
|
||||
.setHideStatusBar(false)
|
||||
.setHideNavBar(false)
|
||||
)
|
||||
.setCards(
|
||||
Settings.CardSettings.newBuilder()
|
||||
LegacySettings.CardSettings.newBuilder()
|
||||
.setBorderWidth(0)
|
||||
.setRadius(12)
|
||||
.setOpacity(1f)
|
||||
)
|
||||
.setWidgets(
|
||||
Settings.WidgetSettings.newBuilder()
|
||||
LegacySettings.WidgetSettings.newBuilder()
|
||||
.setEditButton(true)
|
||||
)
|
||||
.setLayout(
|
||||
Settings.LayoutSettings.newBuilder()
|
||||
.setBaseLayout(Settings.LayoutSettings.Layout.PullDown)
|
||||
LegacySettings.LayoutSettings.newBuilder()
|
||||
.setBaseLayout(LegacySettings.LayoutSettings.Layout.PullDown)
|
||||
.setBottomSearchBar(false)
|
||||
.setReverseSearchResults(false)
|
||||
.setFixedRotation(false)
|
||||
)
|
||||
.setGestures(
|
||||
Settings.GestureSettings.newBuilder()
|
||||
LegacySettings.GestureSettings.newBuilder()
|
||||
.setDoubleTap(
|
||||
if (isAtLeastApiLevel(28)) {
|
||||
Settings.GestureSettings.GestureAction.LockScreen
|
||||
LegacySettings.GestureSettings.GestureAction.LockScreen
|
||||
} else {
|
||||
Settings.GestureSettings.GestureAction.None
|
||||
LegacySettings.GestureSettings.GestureAction.None
|
||||
})
|
||||
.setLongPress(Settings.GestureSettings.GestureAction.None)
|
||||
.setSwipeDown(Settings.GestureSettings.GestureAction.OpenNotificationDrawer)
|
||||
.setSwipeLeft(Settings.GestureSettings.GestureAction.None)
|
||||
.setSwipeRight(Settings.GestureSettings.GestureAction.None)
|
||||
.setLongPress(LegacySettings.GestureSettings.GestureAction.None)
|
||||
.setSwipeDown(LegacySettings.GestureSettings.GestureAction.OpenNotificationDrawer)
|
||||
.setSwipeLeft(LegacySettings.GestureSettings.GestureAction.None)
|
||||
.setSwipeRight(LegacySettings.GestureSettings.GestureAction.None)
|
||||
)
|
||||
.setResultOrdering(
|
||||
Settings.SearchResultOrderingSettings.newBuilder()
|
||||
.setOrdering(Settings.SearchResultOrderingSettings.Ordering.Weighted)
|
||||
.setWeightFactor(Settings.SearchResultOrderingSettings.WeightFactor.Default)
|
||||
LegacySettings.SearchResultOrderingSettings.newBuilder()
|
||||
.setOrdering(LegacySettings.SearchResultOrderingSettings.Ordering.Weighted)
|
||||
.setWeightFactor(LegacySettings.SearchResultOrderingSettings.WeightFactor.Default)
|
||||
)
|
||||
.setAnimations(
|
||||
Settings.AnimationSettings.newBuilder()
|
||||
LegacySettings.AnimationSettings.newBuilder()
|
||||
.setCharging(true)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
internal val DefaultCustomColorsBase: Settings.AppearanceSettings.CustomColors.BaseColors
|
||||
internal val DefaultCustomColorsBase: LegacySettings.AppearanceSettings.CustomColors.BaseColors
|
||||
get() {
|
||||
val scheme = Scheme.light(0xFFACE330.toInt())
|
||||
return Settings.AppearanceSettings.CustomColors.BaseColors.newBuilder()
|
||||
return LegacySettings.AppearanceSettings.CustomColors.BaseColors.newBuilder()
|
||||
.setAccent1(scheme.primary)
|
||||
.setAccent2(scheme.secondary)
|
||||
.setAccent3(scheme.tertiary)
|
||||
@@ -208,13 +207,13 @@ internal val DefaultCustomColorsBase: Settings.AppearanceSettings.CustomColors.B
|
||||
.build()
|
||||
}
|
||||
|
||||
internal val DefaultLightCustomColorScheme: Settings.AppearanceSettings.CustomColors.Scheme
|
||||
internal val DefaultLightCustomColorScheme: LegacySettings.AppearanceSettings.CustomColors.Scheme
|
||||
get() {
|
||||
val scheme = Scheme.light(0xFFACE330.toInt())
|
||||
return scheme.toSettingsColorsScheme()
|
||||
}
|
||||
|
||||
internal val DefaultDarkCustomColorScheme: Settings.AppearanceSettings.CustomColors.Scheme
|
||||
internal val DefaultDarkCustomColorScheme: LegacySettings.AppearanceSettings.CustomColors.Scheme
|
||||
get() {
|
||||
val scheme = Scheme.dark(0xFFACE330.toInt())
|
||||
return scheme.toSettingsColorsScheme()
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
package de.mm20.launcher2.preferences
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStoreFactory
|
||||
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
|
||||
import de.mm20.launcher2.backup.Backupable
|
||||
import de.mm20.launcher2.crashreporter.CrashReporter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import java.io.File
|
||||
|
||||
internal class LauncherStoreBackupComponent(
|
||||
private val context: Context,
|
||||
private val dataStore: LauncherDataStore
|
||||
): Backupable {
|
||||
override suspend fun backup(toDir: File) {
|
||||
dataStore.export(toDir)
|
||||
}
|
||||
|
||||
override suspend fun restore(fromDir: File) {
|
||||
dataStore.import(context, fromDir)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun LauncherDataStore.export(toDir: File) {
|
||||
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
val backupDataStore = DataStoreFactory.create(
|
||||
serializer = SettingsSerializer,
|
||||
produceFile = {
|
||||
File(toDir, "settings")
|
||||
},
|
||||
scope = scope
|
||||
)
|
||||
val settings = this.data.firstOrNull() ?: return
|
||||
backupDataStore.updateData {
|
||||
settings
|
||||
}
|
||||
scope.cancel()
|
||||
}
|
||||
|
||||
|
||||
suspend fun LauncherDataStore.import(context: Context, fromDir: File) {
|
||||
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
val backupDataStore = DataStoreFactory.create(
|
||||
serializer = SettingsSerializer,
|
||||
migrations = getMigrations(context),
|
||||
corruptionHandler = ReplaceFileCorruptionHandler {
|
||||
CrashReporter.logException(it)
|
||||
Settings.getDefaultInstance()
|
||||
},
|
||||
produceFile = {
|
||||
File(fromDir, "settings")
|
||||
},
|
||||
scope = scope
|
||||
)
|
||||
val settings = backupDataStore.data.firstOrNull() ?: return
|
||||
|
||||
this.updateData {
|
||||
settings
|
||||
}
|
||||
scope.cancel()
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package de.mm20.launcher2.preferences
|
||||
|
||||
import android.content.Context
|
||||
import de.mm20.launcher2.preferences.migrations.Migration1
|
||||
import de.mm20.launcher2.settings.BaseSettings
|
||||
|
||||
internal class LauncherDataStore(
|
||||
private val context: Context,
|
||||
legacyDataStore: LegacyDataStore,
|
||||
): BaseSettings<LauncherSettingsData>(
|
||||
context,
|
||||
fileName = "settings.json",
|
||||
serializer = LauncherSettingsDataSerializer,
|
||||
migrations = listOf(Migration1(legacyDataStore)),
|
||||
) {
|
||||
|
||||
val data
|
||||
get() = context.dataStore.data
|
||||
|
||||
fun update(block: (LauncherSettingsData) -> LauncherSettingsData) {
|
||||
updateData(block)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
package de.mm20.launcher2.preferences
|
||||
|
||||
import android.content.Context
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.util.UUID
|
||||
|
||||
@Serializable
|
||||
data class LauncherSettingsData(
|
||||
val schemaVersion: Int = 1,
|
||||
|
||||
val uiColorScheme: ColorScheme = ColorScheme.System,
|
||||
val uiTheme: ThemeDescriptor = ThemeDescriptor.Default,
|
||||
val uiCompatModeColors: Boolean = false,
|
||||
val uiFont: Font = Font.Outfit,
|
||||
val uiBaseLayout: BaseLayout = BaseLayout.PullDown,
|
||||
val uiOrientation: ScreenOrientation = ScreenOrientation.Auto,
|
||||
|
||||
val wallpaperDim: Boolean = false,
|
||||
val wallpaperBlur: Boolean = true,
|
||||
val wallpaperBlurRadius: Int = 32,
|
||||
|
||||
val mediaAllowList: Set<String> = emptySet(),
|
||||
val mediaDenyList: Set<String> = emptySet(),
|
||||
|
||||
val clockWidgetCompact: Boolean = false,
|
||||
val clockWidgetStyle: ClockWidgetStyle = ClockWidgetStyle.Digital1(),
|
||||
val clockWidgetColors: ClockWidgetColors = ClockWidgetColors.Auto,
|
||||
val clockWidgetAlarmPart: Boolean = true,
|
||||
val clockWidgetBatteryPart: Boolean = true,
|
||||
val clockWidgetMusicPart: Boolean = true,
|
||||
val clockWidgetDatePart: Boolean = true,
|
||||
val clockWidgetFillHeight: Boolean = true,
|
||||
val clockWidgetAlignment: ClockWidgetAlignment = ClockWidgetAlignment.Bottom,
|
||||
|
||||
val homeScreenDock: Boolean = false,
|
||||
|
||||
val favoritesEnabled: Boolean = true,
|
||||
val favoritesFrequentlyUsed: Boolean = true,
|
||||
val favoritesFrequentlyUsedRows: Int = 1,
|
||||
val favoritesEditButton: Boolean = true,
|
||||
|
||||
val fileSearchProviders: Set<String> = setOf("local"),
|
||||
|
||||
val contactSearchEnabled: Boolean = true,
|
||||
|
||||
val calendarSearchEnabled: Boolean = true,
|
||||
|
||||
val shortcutSearchEnabled: Boolean = true,
|
||||
|
||||
val calculatorEnabled: Boolean = true,
|
||||
|
||||
val unitConverterEnabled: Boolean = true,
|
||||
val unitConverterCurrencies: Boolean = true,
|
||||
|
||||
val wikipediaSearchEnabled: Boolean = false,
|
||||
val wikipediaSearchImages: Boolean = false,
|
||||
val wikipediaCustomUrl: String? = null,
|
||||
|
||||
val websiteSearchEnabled: Boolean = false,
|
||||
|
||||
val badgesNotifications: Boolean = true,
|
||||
val badgesSuspendedApps: Boolean = true,
|
||||
val badgesCloudFiles: Boolean = true,
|
||||
val badgesShortcuts: Boolean = true,
|
||||
val badgesPlugins: Boolean = true,
|
||||
|
||||
val gridColumnCount: Int = 5,
|
||||
val gridIconSize: Int = 48,
|
||||
val gridLabels: Boolean = true,
|
||||
|
||||
val searchBarStyle: SearchBarStyle = SearchBarStyle.Transparent,
|
||||
val searchBarColors: SearchBarColors = SearchBarColors.Auto,
|
||||
val searchBarKeyboard: Boolean = true,
|
||||
val searchLaunchOnEnter: Boolean = true,
|
||||
val searchBarBottom: Boolean = false,
|
||||
val searchBarFixed: Boolean = false,
|
||||
|
||||
val searchResultsReversed: Boolean = false,
|
||||
val searchResultOrder: SearchResultOrder = SearchResultOrder.Weighted,
|
||||
|
||||
val rankingWeightFactor: WeightFactor = WeightFactor.Default,
|
||||
|
||||
val hiddenItemsShowButton: Boolean = true,
|
||||
|
||||
val iconsShape: IconShape = IconShape.PlatformDefault,
|
||||
val iconsAdaptify: Boolean = false,
|
||||
val iconsThemed: Boolean = false,
|
||||
val iconsForceThemed: Boolean = false,
|
||||
val iconsPack: String? = null,
|
||||
val iconsPackThemed: Boolean = false,
|
||||
|
||||
val easterEgg: Boolean = false,
|
||||
|
||||
val systemBarsHideStatus: Boolean = false,
|
||||
val systemBarsHideNav: Boolean = false,
|
||||
val systemBarsStatusColors: SystemBarColors = SystemBarColors.Auto,
|
||||
val systemBarsNavColors: SystemBarColors = SystemBarColors.Auto,
|
||||
|
||||
val surfacesOpacity: Float = 1f,
|
||||
val surfacesRadius: Int = 24,
|
||||
val surfacesBorderWidth: Int = 0,
|
||||
val surfacesShape: SurfaceShape = SurfaceShape.Rounded,
|
||||
|
||||
val widgetsEditButton: Boolean = true,
|
||||
|
||||
val gesturesSwipeDown: GestureAction = GestureAction.Notifications,
|
||||
val gesturesSwipeLeft: GestureAction = GestureAction.NoAction,
|
||||
val gesturesSwipeRight: GestureAction = GestureAction.NoAction,
|
||||
val gesturesDoubleTap: GestureAction = GestureAction.ScreenLock,
|
||||
val gesturesLongPress: GestureAction = GestureAction.NoAction,
|
||||
val gesturesHomeButton: GestureAction = GestureAction.NoAction,
|
||||
|
||||
val animationsCharging: Boolean = true,
|
||||
|
||||
val stateTagsMultiline: Boolean = false,
|
||||
|
||||
val weatherProvider: String = "metno",
|
||||
val weatherAutoLocation: Boolean = true,
|
||||
val weatherLocation: LatLon? = null,
|
||||
val weatherLocationName: String? = null,
|
||||
val weatherLastLocation: LatLon? = null,
|
||||
val weatherLastUpdate: Long = 0L,
|
||||
val weatherProviderSettings: Map<String, ProviderSettings> = emptyMap(),
|
||||
val weatherImperialUnits: Boolean = false,
|
||||
|
||||
) {
|
||||
constructor(
|
||||
context: Context,
|
||||
) : this(
|
||||
weatherImperialUnits = context.resources.getBoolean(R.bool.default_imperialUnits),
|
||||
gridColumnCount = context.resources.getInteger(R.integer.config_columnCount),
|
||||
)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class ColorScheme {
|
||||
Light,
|
||||
Dark,
|
||||
System,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class Font {
|
||||
Outfit,
|
||||
System,
|
||||
}
|
||||
|
||||
|
||||
@Serializable
|
||||
sealed interface ThemeDescriptor {
|
||||
@Serializable
|
||||
@SerialName("default")
|
||||
data object Default : ThemeDescriptor
|
||||
|
||||
@Serializable
|
||||
@SerialName("bw")
|
||||
data object BlackAndWhite : ThemeDescriptor
|
||||
|
||||
@Serializable
|
||||
@SerialName("custom")
|
||||
data class Custom(
|
||||
val id: String,
|
||||
) : ThemeDescriptor
|
||||
}
|
||||
|
||||
@Serializable
|
||||
sealed interface ClockWidgetStyle {
|
||||
@Serializable
|
||||
@SerialName("digital1")
|
||||
data class Digital1(
|
||||
val outlined: Boolean = false,
|
||||
val variant: Variant = Variant.Default,
|
||||
) : ClockWidgetStyle {
|
||||
@Serializable
|
||||
enum class Variant {
|
||||
Default,
|
||||
MDY,
|
||||
OnePlus,
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@SerialName("digital2")
|
||||
data object Digital2 : ClockWidgetStyle
|
||||
|
||||
@Serializable
|
||||
@SerialName("orbit")
|
||||
data object Orbit : ClockWidgetStyle
|
||||
|
||||
@Serializable
|
||||
@SerialName("analog")
|
||||
data object Analog : ClockWidgetStyle
|
||||
|
||||
@Serializable
|
||||
@SerialName("binary")
|
||||
data object Binary : ClockWidgetStyle
|
||||
|
||||
@Serializable
|
||||
@SerialName("empty")
|
||||
data object Empty : ClockWidgetStyle
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class ClockWidgetColors {
|
||||
Auto,
|
||||
Light,
|
||||
Dark,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class ClockWidgetAlignment {
|
||||
Top,
|
||||
Center,
|
||||
Bottom,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class SearchBarStyle {
|
||||
Transparent,
|
||||
Solid,
|
||||
Hidden,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class SearchBarColors {
|
||||
Auto,
|
||||
Light,
|
||||
Dark,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class IconShape {
|
||||
PlatformDefault,
|
||||
Circle,
|
||||
Square,
|
||||
RoundedSquare,
|
||||
Triangle,
|
||||
Squircle,
|
||||
Hexagon,
|
||||
Pentagon,
|
||||
Teardrop,
|
||||
Pebble,
|
||||
EasterEgg,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class SystemBarColors {
|
||||
Auto,
|
||||
Light,
|
||||
Dark,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class SurfaceShape {
|
||||
Rounded,
|
||||
Cut,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class BaseLayout {
|
||||
PullDown,
|
||||
Pager,
|
||||
PagerReversed,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class ScreenOrientation {
|
||||
Auto,
|
||||
Portrait,
|
||||
Landscape,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
sealed interface GestureAction {
|
||||
@Serializable
|
||||
@SerialName("no_action")
|
||||
data object NoAction : GestureAction
|
||||
|
||||
@Serializable
|
||||
@SerialName("notifications")
|
||||
data object Notifications : GestureAction
|
||||
|
||||
@Serializable
|
||||
@SerialName("quick_settings")
|
||||
data object QuickSettings : GestureAction
|
||||
|
||||
@Serializable
|
||||
@SerialName("screen_lock")
|
||||
data object ScreenLock : GestureAction
|
||||
|
||||
@Serializable
|
||||
@SerialName("search")
|
||||
data object Search : GestureAction
|
||||
|
||||
@Serializable
|
||||
@SerialName("power_menu")
|
||||
data object PowerMenu : GestureAction
|
||||
|
||||
@Serializable
|
||||
@SerialName("recents")
|
||||
data object Recents : GestureAction
|
||||
|
||||
@Serializable
|
||||
@SerialName("launch_searchable")
|
||||
data class Launch(val key: String?) : GestureAction
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class SearchResultOrder {
|
||||
Weighted,
|
||||
Alphabetical,
|
||||
LaunchCount,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
enum class WeightFactor {
|
||||
Default,
|
||||
Low,
|
||||
High,
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class LatLon(
|
||||
val lat: Double,
|
||||
val lon: Double,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ProviderSettings(
|
||||
val locationId: String? = null,
|
||||
val locationName: String? = null,
|
||||
)
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package de.mm20.launcher2.preferences
|
||||
|
||||
import androidx.datastore.core.CorruptionException
|
||||
import androidx.datastore.core.Serializer
|
||||
import kotlinx.serialization.SerializationException
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
import kotlinx.serialization.json.encodeToStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
internal object LauncherSettingsDataSerializer : Serializer<LauncherSettingsData> {
|
||||
|
||||
internal val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
encodeDefaults = true
|
||||
}
|
||||
|
||||
override val defaultValue: LauncherSettingsData
|
||||
get() = LauncherSettingsData(schemaVersion = 0)
|
||||
|
||||
override suspend fun readFrom(input: InputStream): LauncherSettingsData {
|
||||
try {
|
||||
return json.decodeFromStream(input)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
throw (CorruptionException("Cannot read json.", e))
|
||||
} catch (e: SerializationException) {
|
||||
throw (CorruptionException("Cannot read json.", e))
|
||||
} catch (e: IOException) {
|
||||
throw (CorruptionException("Cannot read json.", e))
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeTo(t: LauncherSettingsData, output: OutputStream) {
|
||||
json.encodeToStream(t, output)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package de.mm20.launcher2.preferences
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.CorruptionException
|
||||
import androidx.datastore.core.DataMigration
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.core.Serializer
|
||||
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
|
||||
import androidx.datastore.dataStore
|
||||
import com.google.protobuf.InvalidProtocolBufferException
|
||||
import de.mm20.launcher2.crashreporter.CrashReporter
|
||||
import de.mm20.launcher2.preferences.migrations.*
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
internal typealias LegacyDataStore = DataStore<LegacySettings>
|
||||
|
||||
internal val Context.legacyDataStore: LegacyDataStore by dataStore(
|
||||
fileName = "settings.pb",
|
||||
serializer = LegacySettingsSerializer,
|
||||
produceMigrations = {
|
||||
getMigrations(it)
|
||||
},
|
||||
corruptionHandler = ReplaceFileCorruptionHandler {
|
||||
CrashReporter.logException(it)
|
||||
LegacySettings.getDefaultInstance()
|
||||
}
|
||||
)
|
||||
|
||||
internal const val SchemaVersion = 18
|
||||
|
||||
internal fun getMigrations(context: Context): List<DataMigration<LegacySettings>> {
|
||||
return listOf()
|
||||
}
|
||||
|
||||
|
||||
|
||||
object LegacySettingsSerializer : Serializer<LegacySettings> {
|
||||
override val defaultValue: LegacySettings = LegacySettings.getDefaultInstance()
|
||||
|
||||
override suspend fun readFrom(input: InputStream): LegacySettings {
|
||||
try {
|
||||
return LegacySettings.parseFrom(input)
|
||||
} catch (e: InvalidProtocolBufferException) {
|
||||
throw CorruptionException("Cannot read proto.", e)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeTo(t: LegacySettings, output: OutputStream) {
|
||||
t.writeTo(output)
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,50 @@
|
||||
package de.mm20.launcher2.preferences
|
||||
|
||||
import de.mm20.launcher2.backup.Backupable
|
||||
import de.mm20.launcher2.preferences.search.ContactSearchSettings
|
||||
import de.mm20.launcher2.preferences.media.MediaSettings
|
||||
import de.mm20.launcher2.preferences.search.CalculatorSearchSettings
|
||||
import de.mm20.launcher2.preferences.search.CalendarSearchSettings
|
||||
import de.mm20.launcher2.preferences.search.FavoritesSettings
|
||||
import de.mm20.launcher2.preferences.search.FileSearchSettings
|
||||
import de.mm20.launcher2.preferences.search.RankingSettings
|
||||
import de.mm20.launcher2.preferences.search.ShortcutSearchSettings
|
||||
import de.mm20.launcher2.preferences.search.UnitConverterSettings
|
||||
import de.mm20.launcher2.preferences.search.WebsiteSearchSettings
|
||||
import de.mm20.launcher2.preferences.search.WikipediaSearchSettings
|
||||
import de.mm20.launcher2.preferences.ui.BadgeSettings
|
||||
import de.mm20.launcher2.preferences.ui.ClockWidgetSettings
|
||||
import de.mm20.launcher2.preferences.ui.GestureSettings
|
||||
import de.mm20.launcher2.preferences.ui.IconSettings
|
||||
import de.mm20.launcher2.preferences.ui.SearchUiSettings
|
||||
import de.mm20.launcher2.preferences.ui.UiSettings
|
||||
import de.mm20.launcher2.preferences.ui.UiState
|
||||
import de.mm20.launcher2.preferences.weather.WeatherSettings
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.dsl.module
|
||||
|
||||
val preferencesModule = module {
|
||||
single { androidContext().dataStore }
|
||||
factory<Backupable>(named<LauncherDataStore>()) { LauncherStoreBackupComponent(androidContext(), get()) }
|
||||
single { androidContext().legacyDataStore }
|
||||
single { LauncherDataStore(androidContext(), get()) }
|
||||
factory<Backupable>(named<LauncherDataStore>()) { get<LauncherDataStore>() }
|
||||
factory { MediaSettings(get()) }
|
||||
factory { ContactSearchSettings(get()) }
|
||||
factory { FileSearchSettings(get()) }
|
||||
factory { UnitConverterSettings(get()) }
|
||||
factory { BadgeSettings(get()) }
|
||||
factory { UiSettings(get()) }
|
||||
factory { ShortcutSearchSettings(get()) }
|
||||
factory { FavoritesSettings(get()) }
|
||||
factory { WikipediaSearchSettings(get()) }
|
||||
factory { IconSettings(get()) }
|
||||
factory { RankingSettings(get()) }
|
||||
factory { CalendarSearchSettings(get()) }
|
||||
factory { WebsiteSearchSettings(get()) }
|
||||
factory { UiState(get()) }
|
||||
factory { SearchUiSettings(get()) }
|
||||
factory { WeatherSettings(get()) }
|
||||
factory { GestureSettings(get()) }
|
||||
factory { CalculatorSearchSettings(get()) }
|
||||
factory { ClockWidgetSettings(get()) }
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package de.mm20.launcher2.preferences
|
||||
|
||||
import androidx.datastore.core.CorruptionException
|
||||
import androidx.datastore.core.Serializer
|
||||
import com.google.protobuf.InvalidProtocolBufferException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
|
||||
object SettingsSerializer : Serializer<Settings> {
|
||||
override val defaultValue: Settings = Settings.getDefaultInstance()
|
||||
|
||||
override suspend fun readFrom(input: InputStream): Settings {
|
||||
try {
|
||||
return Settings.parseFrom(input)
|
||||
} catch (e: InvalidProtocolBufferException) {
|
||||
throw CorruptionException("Cannot read proto.", e)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeTo(t: Settings, output: OutputStream) {
|
||||
t.writeTo(output)
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package de.mm20.launcher2.preferences.ktx
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
import scheme.Scheme
|
||||
|
||||
fun Scheme.toSettingsColorsScheme(): Settings.AppearanceSettings.CustomColors.Scheme {
|
||||
fun Scheme.toSettingsColorsScheme(): LegacySettings.AppearanceSettings.CustomColors.Scheme {
|
||||
val scheme = this
|
||||
return Settings.AppearanceSettings.CustomColors.Scheme.newBuilder()
|
||||
return LegacySettings.AppearanceSettings.CustomColors.Scheme.newBuilder()
|
||||
.setPrimary(scheme.primary)
|
||||
.setSurfaceTint(scheme.primary)
|
||||
.setOnPrimary(scheme.onPrimary)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package de.mm20.launcher2.preferences.media
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
data class MediaSettingsData(
|
||||
val allowList: Set<String>,
|
||||
val denyList: Set<String>,
|
||||
)
|
||||
|
||||
class MediaSettings internal constructor(
|
||||
private val launcherDataStore: LauncherDataStore
|
||||
) : Flow<MediaSettingsData> by (launcherDataStore.data.map {
|
||||
MediaSettingsData(
|
||||
it.mediaAllowList,
|
||||
it.mediaDenyList
|
||||
)
|
||||
}) {
|
||||
val allowList
|
||||
get() = launcherDataStore.data.map { it.mediaAllowList }
|
||||
|
||||
fun setLists(allowList: Set<String>, denyList: Set<String>) {
|
||||
launcherDataStore.update {
|
||||
it.copy(mediaAllowList = allowList)
|
||||
}
|
||||
}
|
||||
|
||||
val denyList
|
||||
get() = launcherDataStore.data.map { it.mediaDenyList }
|
||||
}
|
||||
+4
-4
@@ -4,22 +4,22 @@ import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.datastore.core.DataMigration
|
||||
import de.mm20.launcher2.preferences.SchemaVersion
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
import de.mm20.launcher2.preferences.createFactorySettings
|
||||
|
||||
class FactorySettingsMigration(private val context: Context): DataMigration<Settings> {
|
||||
class FactorySettingsMigration(private val context: Context): DataMigration<LegacySettings> {
|
||||
override suspend fun cleanUp() {
|
||||
|
||||
}
|
||||
|
||||
override suspend fun migrate(currentData: Settings): Settings {
|
||||
override suspend fun migrate(currentData: LegacySettings): LegacySettings {
|
||||
Log.d("MM20", "Initializing user settings…")
|
||||
Log.d("MM20", "Done")
|
||||
val defaults = createFactorySettings(context)
|
||||
return defaults.toBuilder().setVersion(SchemaVersion).build()
|
||||
}
|
||||
|
||||
override suspend fun shouldMigrate(currentData: Settings): Boolean {
|
||||
override suspend fun shouldMigrate(currentData: LegacySettings): Boolean {
|
||||
return currentData.version == 0
|
||||
}
|
||||
}
|
||||
+254
@@ -0,0 +1,254 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import androidx.datastore.core.DataMigration
|
||||
import de.mm20.launcher2.preferences.BaseLayout
|
||||
import de.mm20.launcher2.preferences.ClockWidgetAlignment
|
||||
import de.mm20.launcher2.preferences.ClockWidgetColors
|
||||
import de.mm20.launcher2.preferences.ClockWidgetStyle
|
||||
import de.mm20.launcher2.preferences.ColorScheme
|
||||
import de.mm20.launcher2.preferences.Font
|
||||
import de.mm20.launcher2.preferences.GestureAction
|
||||
import de.mm20.launcher2.preferences.IconShape
|
||||
import de.mm20.launcher2.preferences.LauncherSettingsData
|
||||
import de.mm20.launcher2.preferences.LegacyDataStore
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
import de.mm20.launcher2.preferences.ScreenOrientation
|
||||
import de.mm20.launcher2.preferences.SearchBarColors
|
||||
import de.mm20.launcher2.preferences.SearchBarStyle
|
||||
import de.mm20.launcher2.preferences.SearchResultOrder
|
||||
import de.mm20.launcher2.preferences.SurfaceShape
|
||||
import de.mm20.launcher2.preferences.SystemBarColors
|
||||
import de.mm20.launcher2.preferences.ThemeDescriptor
|
||||
import de.mm20.launcher2.preferences.WeightFactor
|
||||
import kotlinx.coroutines.flow.first
|
||||
import java.util.UUID
|
||||
|
||||
class Migration1(
|
||||
private val legacyDataStore: LegacyDataStore,
|
||||
) : DataMigration<LauncherSettingsData> {
|
||||
override suspend fun cleanUp() {
|
||||
|
||||
}
|
||||
|
||||
override suspend fun shouldMigrate(currentData: LauncherSettingsData): Boolean {
|
||||
return legacyDataStore.data.first().version > 0 && currentData.schemaVersion < 1
|
||||
}
|
||||
|
||||
override suspend fun migrate(currentData: LauncherSettingsData): LauncherSettingsData {
|
||||
val legacyData = legacyDataStore.data.first()
|
||||
return currentData.copy(
|
||||
schemaVersion = 1,
|
||||
uiBaseLayout = when (legacyData.layout.baseLayout) {
|
||||
LegacySettings.LayoutSettings.Layout.Pager -> BaseLayout.PullDown
|
||||
LegacySettings.LayoutSettings.Layout.PagerReversed -> BaseLayout.PagerReversed
|
||||
else -> BaseLayout.PullDown
|
||||
},
|
||||
gridColumnCount = legacyData.grid.columnCount,
|
||||
animationsCharging = legacyData.animations.charging,
|
||||
badgesCloudFiles = legacyData.badges.cloudFiles,
|
||||
badgesNotifications = legacyData.badges.notifications,
|
||||
badgesShortcuts = legacyData.badges.shortcuts,
|
||||
badgesSuspendedApps = legacyData.badges.suspendedApps,
|
||||
calculatorEnabled = legacyData.calculatorSearch.enabled,
|
||||
calendarSearchEnabled = legacyData.calendarSearch.enabled,
|
||||
clockWidgetAlarmPart = legacyData.clockWidget.alarmPart,
|
||||
clockWidgetBatteryPart = legacyData.clockWidget.batteryPart,
|
||||
clockWidgetDatePart = legacyData.clockWidget.datePart,
|
||||
clockWidgetColors = when (legacyData.clockWidget.color) {
|
||||
LegacySettings.ClockWidgetSettings.ClockWidgetColors.Light -> ClockWidgetColors.Light
|
||||
LegacySettings.ClockWidgetSettings.ClockWidgetColors.Dark -> ClockWidgetColors.Dark
|
||||
else -> ClockWidgetColors.Auto
|
||||
},
|
||||
clockWidgetAlignment = when (legacyData.clockWidget.alignment) {
|
||||
LegacySettings.ClockWidgetSettings.ClockWidgetAlignment.Top -> ClockWidgetAlignment.Top
|
||||
LegacySettings.ClockWidgetSettings.ClockWidgetAlignment.Center -> ClockWidgetAlignment.Center
|
||||
else -> ClockWidgetAlignment.Bottom
|
||||
},
|
||||
homeScreenDock = legacyData.clockWidget.favoritesPart,
|
||||
clockWidgetFillHeight = legacyData.clockWidget.fillHeight,
|
||||
clockWidgetCompact = legacyData.clockWidget.layout == LegacySettings.ClockWidgetSettings.ClockWidgetLayout.Horizontal,
|
||||
clockWidgetMusicPart = legacyData.clockWidget.musicPart,
|
||||
clockWidgetStyle = when (legacyData.clockWidget.clockStyle) {
|
||||
LegacySettings.ClockWidgetSettings.ClockStyle.DigitalClock1 -> ClockWidgetStyle.Digital1()
|
||||
LegacySettings.ClockWidgetSettings.ClockStyle.DigitalClock2 -> ClockWidgetStyle.Digital2
|
||||
LegacySettings.ClockWidgetSettings.ClockStyle.OrbitClock -> ClockWidgetStyle.Orbit
|
||||
LegacySettings.ClockWidgetSettings.ClockStyle.BinaryClock -> ClockWidgetStyle.Binary
|
||||
LegacySettings.ClockWidgetSettings.ClockStyle.AnalogClock -> ClockWidgetStyle.Analog
|
||||
LegacySettings.ClockWidgetSettings.ClockStyle.EmptyClock -> ClockWidgetStyle.Empty
|
||||
LegacySettings.ClockWidgetSettings.ClockStyle.DigitalClock1_MDY -> ClockWidgetStyle.Digital1(
|
||||
variant = ClockWidgetStyle.Digital1.Variant.MDY
|
||||
)
|
||||
|
||||
LegacySettings.ClockWidgetSettings.ClockStyle.DigitalClock1_Outlined -> ClockWidgetStyle.Digital1(
|
||||
outlined = true
|
||||
)
|
||||
|
||||
LegacySettings.ClockWidgetSettings.ClockStyle.DigitalClock1_OnePlus -> ClockWidgetStyle.Digital1(
|
||||
variant = ClockWidgetStyle.Digital1.Variant.OnePlus
|
||||
)
|
||||
|
||||
else -> ClockWidgetStyle.Digital1()
|
||||
},
|
||||
contactSearchEnabled = legacyData.contactsSearch.enabled,
|
||||
easterEgg = legacyData.easterEgg,
|
||||
favoritesEditButton = legacyData.favorites.editButton,
|
||||
favoritesEnabled = legacyData.favorites.enabled,
|
||||
favoritesFrequentlyUsed = legacyData.favorites.frequentlyUsed,
|
||||
favoritesFrequentlyUsedRows = legacyData.favorites.frequentlyUsedRows,
|
||||
rankingWeightFactor = when (legacyData.resultOrdering.weightFactor) {
|
||||
LegacySettings.SearchResultOrderingSettings.WeightFactor.Low -> WeightFactor.Low
|
||||
LegacySettings.SearchResultOrderingSettings.WeightFactor.High -> WeightFactor.High
|
||||
else -> WeightFactor.Default
|
||||
},
|
||||
fileSearchProviders = buildSet {
|
||||
if (legacyData.fileSearch.localFiles) add("local")
|
||||
if (legacyData.fileSearch.nextcloud) add("nextcloud")
|
||||
if (legacyData.fileSearch.gdrive) add("gdrive")
|
||||
if (legacyData.fileSearch.onedrive) add("onedrive")
|
||||
},
|
||||
gesturesDoubleTap = makeGestureSettings(
|
||||
legacyData.gestures.doubleTap,
|
||||
legacyData.gestures.doubleTapApp
|
||||
),
|
||||
gesturesSwipeDown = makeGestureSettings(
|
||||
legacyData.gestures.swipeDown,
|
||||
legacyData.gestures.swipeDownApp
|
||||
),
|
||||
gesturesSwipeLeft = makeGestureSettings(
|
||||
legacyData.gestures.swipeLeft,
|
||||
legacyData.gestures.swipeLeftApp
|
||||
),
|
||||
gesturesSwipeRight = makeGestureSettings(
|
||||
legacyData.gestures.swipeRight,
|
||||
legacyData.gestures.swipeRightApp
|
||||
),
|
||||
gesturesLongPress = makeGestureSettings(
|
||||
legacyData.gestures.longPress,
|
||||
legacyData.gestures.longPressApp
|
||||
),
|
||||
gesturesHomeButton = makeGestureSettings(
|
||||
legacyData.gestures.homeButton,
|
||||
legacyData.gestures.homeButtonApp
|
||||
),
|
||||
gridIconSize = legacyData.grid.iconSize,
|
||||
gridLabels = legacyData.grid.showLabels,
|
||||
mediaAllowList = legacyData.musicWidget.allowListList.toSet(),
|
||||
mediaDenyList = legacyData.musicWidget.denyListList.toSet(),
|
||||
hiddenItemsShowButton = legacyData.searchBar.hiddenItemsButton,
|
||||
iconsAdaptify = legacyData.icons.adaptify,
|
||||
iconsForceThemed = legacyData.icons.forceThemed,
|
||||
iconsPack = legacyData.icons.iconPack.takeIf { it.isNotBlank() },
|
||||
iconsPackThemed = legacyData.icons.iconPackThemed,
|
||||
iconsShape = when (legacyData.icons.shape) {
|
||||
LegacySettings.IconSettings.IconShape.Circle -> IconShape.Circle
|
||||
LegacySettings.IconSettings.IconShape.Square -> IconShape.Square
|
||||
LegacySettings.IconSettings.IconShape.Squircle -> IconShape.Squircle
|
||||
LegacySettings.IconSettings.IconShape.RoundedSquare -> IconShape.RoundedSquare
|
||||
LegacySettings.IconSettings.IconShape.EasterEgg -> IconShape.EasterEgg
|
||||
LegacySettings.IconSettings.IconShape.Hexagon -> IconShape.Hexagon
|
||||
LegacySettings.IconSettings.IconShape.Triangle -> IconShape.Triangle
|
||||
LegacySettings.IconSettings.IconShape.Pentagon -> IconShape.Pentagon
|
||||
LegacySettings.IconSettings.IconShape.Teardrop -> IconShape.Teardrop
|
||||
LegacySettings.IconSettings.IconShape.Pebble -> IconShape.Pebble
|
||||
else -> IconShape.PlatformDefault
|
||||
},
|
||||
iconsThemed = legacyData.icons.themedIcons,
|
||||
searchBarBottom = legacyData.layout.bottomSearchBar,
|
||||
searchBarColors = when (legacyData.systemBars.statusBarColor) {
|
||||
LegacySettings.SystemBarsSettings.SystemBarColors.Light -> SearchBarColors.Light
|
||||
LegacySettings.SystemBarsSettings.SystemBarColors.Dark -> SearchBarColors.Dark
|
||||
else -> SearchBarColors.Auto
|
||||
},
|
||||
searchBarFixed = legacyData.layout.bottomSearchBar,
|
||||
searchBarKeyboard = legacyData.searchBar.autoFocus,
|
||||
searchBarStyle = when (legacyData.searchBar.searchBarStyle) {
|
||||
LegacySettings.SearchBarSettings.SearchBarStyle.Hidden -> SearchBarStyle.Hidden
|
||||
LegacySettings.SearchBarSettings.SearchBarStyle.Solid -> SearchBarStyle.Solid
|
||||
else -> SearchBarStyle.Transparent
|
||||
},
|
||||
searchLaunchOnEnter = legacyData.searchBar.launchOnEnter,
|
||||
searchResultOrder = when (legacyData.resultOrdering.ordering) {
|
||||
LegacySettings.SearchResultOrderingSettings.Ordering.Alphabetic -> SearchResultOrder.Alphabetical
|
||||
LegacySettings.SearchResultOrderingSettings.Ordering.LaunchCount -> SearchResultOrder.LaunchCount
|
||||
else -> SearchResultOrder.Weighted
|
||||
},
|
||||
searchResultsReversed = legacyData.layout.reverseSearchResults,
|
||||
shortcutSearchEnabled = legacyData.appShortcutSearch.enabled,
|
||||
stateTagsMultiline = legacyData.ui.searchTagsMultiline,
|
||||
surfacesBorderWidth = legacyData.cards.borderWidth,
|
||||
surfacesOpacity = legacyData.cards.opacity,
|
||||
surfacesRadius = legacyData.cards.radius,
|
||||
surfacesShape = when (legacyData.cards.shape) {
|
||||
LegacySettings.CardSettings.Shape.Cut -> SurfaceShape.Cut
|
||||
else -> SurfaceShape.Rounded
|
||||
},
|
||||
systemBarsHideNav = legacyData.systemBars.hideNavBar,
|
||||
systemBarsHideStatus = legacyData.systemBars.hideStatusBar,
|
||||
systemBarsNavColors = when (legacyData.systemBars.navBarColor) {
|
||||
LegacySettings.SystemBarsSettings.SystemBarColors.Light -> SystemBarColors.Light
|
||||
LegacySettings.SystemBarsSettings.SystemBarColors.Dark -> SystemBarColors.Dark
|
||||
else -> SystemBarColors.Auto
|
||||
},
|
||||
systemBarsStatusColors = when (legacyData.systemBars.statusBarColor) {
|
||||
LegacySettings.SystemBarsSettings.SystemBarColors.Light -> SystemBarColors.Light
|
||||
LegacySettings.SystemBarsSettings.SystemBarColors.Dark -> SystemBarColors.Dark
|
||||
else -> SystemBarColors.Auto
|
||||
},
|
||||
uiColorScheme = when (legacyData.appearance.theme) {
|
||||
LegacySettings.AppearanceSettings.Theme.Light -> ColorScheme.Light
|
||||
LegacySettings.AppearanceSettings.Theme.Dark -> ColorScheme.Dark
|
||||
else -> ColorScheme.System
|
||||
},
|
||||
uiFont = when (legacyData.appearance.font) {
|
||||
LegacySettings.AppearanceSettings.Font.SystemDefault -> Font.System
|
||||
else -> Font.Outfit
|
||||
},
|
||||
uiOrientation = when (legacyData.layout.fixedRotation) {
|
||||
true -> ScreenOrientation.Portrait
|
||||
else -> ScreenOrientation.Auto
|
||||
},
|
||||
uiTheme = when (legacyData.appearance.themeId) {
|
||||
UUID(0L, 0L).toString() -> ThemeDescriptor.Default
|
||||
UUID(0L, 1L).toString() -> ThemeDescriptor.BlackAndWhite
|
||||
else -> ThemeDescriptor.Custom(legacyData.appearance.themeId)
|
||||
},
|
||||
unitConverterCurrencies = legacyData.unitConverterSearch.currencies,
|
||||
unitConverterEnabled = legacyData.unitConverterSearch.enabled,
|
||||
wallpaperBlur = legacyData.appearance.blurWallpaper,
|
||||
weatherImperialUnits = legacyData.weather.imperialUnits,
|
||||
wallpaperBlurRadius = legacyData.appearance.blurWallpaperRadius,
|
||||
wallpaperDim = legacyData.appearance.dimWallpaper,
|
||||
weatherProvider = when (legacyData.weather.provider) {
|
||||
LegacySettings.WeatherSettings.WeatherProvider.MetNo -> "metno"
|
||||
LegacySettings.WeatherSettings.WeatherProvider.OpenWeatherMap -> "owm"
|
||||
LegacySettings.WeatherSettings.WeatherProvider.Here -> "here"
|
||||
LegacySettings.WeatherSettings.WeatherProvider.BrightSky -> "dwd"
|
||||
else -> "metno"
|
||||
},
|
||||
websiteSearchEnabled = legacyData.websiteSearch.enabled,
|
||||
widgetsEditButton = legacyData.widgets.editButton,
|
||||
wikipediaCustomUrl = legacyData.wikipediaSearch.customUrl.takeIf { it.isNotBlank() },
|
||||
wikipediaSearchEnabled = legacyData.wikipediaSearch.enabled,
|
||||
wikipediaSearchImages = legacyData.wikipediaSearch.images,
|
||||
)
|
||||
}
|
||||
|
||||
private fun makeGestureSettings(
|
||||
gesture: LegacySettings.GestureSettings.GestureAction,
|
||||
key: String
|
||||
): GestureAction {
|
||||
return when (gesture) {
|
||||
LegacySettings.GestureSettings.GestureAction.OpenSearch -> GestureAction.Search
|
||||
LegacySettings.GestureSettings.GestureAction.OpenNotificationDrawer -> GestureAction.Notifications
|
||||
LegacySettings.GestureSettings.GestureAction.LockScreen -> GestureAction.ScreenLock
|
||||
LegacySettings.GestureSettings.GestureAction.OpenQuickSettings -> GestureAction.QuickSettings
|
||||
LegacySettings.GestureSettings.GestureAction.OpenRecents -> GestureAction.Recents
|
||||
LegacySettings.GestureSettings.GestureAction.OpenPowerDialog -> GestureAction.PowerMenu
|
||||
LegacySettings.GestureSettings.GestureAction.LaunchApp -> GestureAction.Launch(
|
||||
key
|
||||
)
|
||||
|
||||
else -> GestureAction.NoAction
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_10_11: VersionedMigration(10, 11) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setAppearance(
|
||||
builder.appearance.toBuilder()
|
||||
.setCustomColors(
|
||||
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.ktx.isAtLeastApiLevel
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.Settings.GestureSettings
|
||||
import de.mm20.launcher2.preferences.Settings.LayoutSettings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
import de.mm20.launcher2.preferences.LegacySettings.GestureSettings
|
||||
import de.mm20.launcher2.preferences.LegacySettings.LayoutSettings
|
||||
|
||||
class Migration_11_12: VersionedMigration(11, 12) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
val oldLayout = builder.appearance.layout
|
||||
when(oldLayout) {
|
||||
LayoutSettings.Layout.Pager -> {
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.Settings.SearchResultOrderingSettings.WeightFactor
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
import de.mm20.launcher2.preferences.LegacySettings.SearchResultOrderingSettings.WeightFactor
|
||||
|
||||
class Migration_12_13: VersionedMigration(12, 13) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder
|
||||
.setClockWidget(
|
||||
builder.clockWidget.toBuilder()
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_13_14 : VersionedMigration(13, 14) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder
|
||||
.setIcons(
|
||||
builder.icons.toBuilder()
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_14_15: VersionedMigration(14, 15) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setSearchBar(
|
||||
builder.searchBar.toBuilder()
|
||||
.setHiddenItemsButton(true)
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.CustomColors.Scheme
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
import de.mm20.launcher2.preferences.LegacySettings.AppearanceSettings.CustomColors.Scheme
|
||||
import palettes.TonalPalette
|
||||
|
||||
class Migration_15_16 : VersionedMigration(15, 16) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setAppearance(
|
||||
builder.appearance.toBuilder()
|
||||
.setCustomColors(
|
||||
|
||||
+4
-4
@@ -1,16 +1,16 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
import java.util.UUID
|
||||
|
||||
class Migration_16_17: VersionedMigration(16, 17) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setAppearance(
|
||||
builder.appearance.toBuilder()
|
||||
.setThemeId(
|
||||
when(builder.appearance.colorScheme) {
|
||||
Settings.AppearanceSettings.ColorScheme.BlackAndWhite -> UUID(0L, 1L)
|
||||
Settings.AppearanceSettings.ColorScheme.Custom -> UUID(1L, 1L)
|
||||
LegacySettings.AppearanceSettings.ColorScheme.BlackAndWhite -> UUID(0L, 1L)
|
||||
LegacySettings.AppearanceSettings.ColorScheme.Custom -> UUID(1L, 1L)
|
||||
else -> UUID(0L, 0L)
|
||||
}.toString()
|
||||
)
|
||||
|
||||
+3
-3
@@ -1,15 +1,15 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_17_18 : VersionedMigration(17, 18) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder
|
||||
.setAppearance(builder.appearance.toBuilder()
|
||||
.setBlurWallpaperRadius(32)
|
||||
)
|
||||
.setClockWidget(builder.clockWidget.toBuilder()
|
||||
.setAlignment(Settings.ClockWidgetSettings.ClockWidgetAlignment.Bottom)
|
||||
.setAlignment(LegacySettings.ClockWidgetSettings.ClockWidgetAlignment.Bottom)
|
||||
)
|
||||
}
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
|
||||
class Migration_18_19 : VersionedMigration(18, 19) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
return builder
|
||||
.setAppearance(builder.appearance.toBuilder()
|
||||
.setForceCompatModeSystemColors(false)
|
||||
)
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_1_2: VersionedMigration(1, 2) {
|
||||
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setSystemBars(
|
||||
builder.systemBars.toBuilder()
|
||||
.setHideNavBar(false)
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_2_3: VersionedMigration(2, 3) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setClockWidget(
|
||||
builder.clockWidget.toBuilder()
|
||||
.setAlarmPart(true)
|
||||
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_3_4: VersionedMigration(3, 4) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setAppShortcutSearch(
|
||||
Settings.AppShortcutSearchSettings.newBuilder()
|
||||
LegacySettings.AppShortcutSearchSettings.newBuilder()
|
||||
.setEnabled(true)
|
||||
)
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_4_5: VersionedMigration(4, 5) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setGrid(
|
||||
builder.grid.toBuilder()
|
||||
.setIconSize(48)
|
||||
|
||||
+4
-3
@@ -3,13 +3,14 @@ package de.mm20.launcher2.preferences.migrations
|
||||
import de.mm20.launcher2.preferences.DefaultCustomColorsBase
|
||||
import de.mm20.launcher2.preferences.DefaultDarkCustomColorScheme
|
||||
import de.mm20.launcher2.preferences.DefaultLightCustomColorScheme
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_5_6: VersionedMigration(5, 6) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setAppearance(
|
||||
builder.appearance.toBuilder()
|
||||
.setCustomColors(Settings.AppearanceSettings.CustomColors.newBuilder()
|
||||
.setCustomColors(
|
||||
LegacySettings.AppearanceSettings.CustomColors.newBuilder()
|
||||
.setAdvancedMode(false)
|
||||
.setBaseColors(DefaultCustomColorsBase)
|
||||
.setLightScheme(DefaultLightCustomColorScheme)
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_6_7 : VersionedMigration(6, 7) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setIcons(
|
||||
builder.icons.toBuilder()
|
||||
.setAdaptify(true)
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_7_8: VersionedMigration(7, 8) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder.setAppearance(
|
||||
builder.appearance.toBuilder()
|
||||
.setBlurWallpaper(true)
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_8_9: VersionedMigration(8, 9) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder
|
||||
.setClockWidget(
|
||||
builder.clockWidget.toBuilder()
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
class Migration_9_10 : VersionedMigration(9, 10) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
override suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder {
|
||||
return builder
|
||||
.setFavorites(
|
||||
builder.favorites.toBuilder()
|
||||
@@ -12,7 +12,7 @@ class Migration_9_10 : VersionedMigration(9, 10) {
|
||||
.setEditButton(true)
|
||||
)
|
||||
.setWidgets(
|
||||
Settings.WidgetSettings.newBuilder()
|
||||
LegacySettings.WidgetSettings.newBuilder()
|
||||
.setEditButton(true)
|
||||
)
|
||||
}
|
||||
|
||||
+5
-5
@@ -2,15 +2,15 @@ package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import androidx.datastore.core.DataMigration
|
||||
import de.mm20.launcher2.preferences.SchemaVersion
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.LegacySettings
|
||||
|
||||
abstract class VersionedMigration(
|
||||
private val fromVersion: Int,
|
||||
private val toVersion: Int
|
||||
) : DataMigration<Settings> {
|
||||
abstract suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder
|
||||
) : DataMigration<LegacySettings> {
|
||||
abstract suspend fun applyMigrations(builder: LegacySettings.Builder): LegacySettings.Builder
|
||||
|
||||
final override suspend fun migrate(currentData: Settings): Settings {
|
||||
final override suspend fun migrate(currentData: LegacySettings): LegacySettings {
|
||||
val builder = currentData.toBuilder()
|
||||
applyMigrations(builder)
|
||||
builder.version = toVersion
|
||||
@@ -19,7 +19,7 @@ abstract class VersionedMigration(
|
||||
|
||||
override suspend fun cleanUp() {}
|
||||
|
||||
override suspend fun shouldMigrate(currentData: Settings): Boolean {
|
||||
override suspend fun shouldMigrate(currentData: LegacySettings): Boolean {
|
||||
return currentData.version <= fromVersion && SchemaVersion >= toVersion
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package de.mm20.launcher2.preferences.search
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class CalculatorSearchSettings internal constructor(
|
||||
private val dataStore: LauncherDataStore,
|
||||
){
|
||||
val enabled
|
||||
get() = dataStore.data.map { it.calculatorEnabled }.distinctUntilChanged()
|
||||
|
||||
fun setEnabled(enabled: Boolean) {
|
||||
dataStore.update {
|
||||
it.copy(calculatorEnabled = enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package de.mm20.launcher2.preferences.search
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class CalendarSearchSettings internal constructor(
|
||||
private val dataStore: LauncherDataStore,
|
||||
){
|
||||
val enabled
|
||||
get() = dataStore.data.map { it.calendarSearchEnabled }
|
||||
|
||||
fun setEnabled(enabled: Boolean) {
|
||||
dataStore.update {
|
||||
it.copy(calendarSearchEnabled = enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package de.mm20.launcher2.preferences.search
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class ContactSearchSettings internal constructor(private val dataStore: LauncherDataStore) {
|
||||
val enabled: Flow<Boolean>
|
||||
get() = dataStore.data.map { it.contactSearchEnabled }.distinctUntilChanged()
|
||||
|
||||
fun setEnabled(enabled: Boolean) {
|
||||
dataStore.update { it.copy(contactSearchEnabled = enabled) }
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package de.mm20.launcher2.preferences.search
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
data class FavoritesSettingsData(
|
||||
val columns: Int,
|
||||
val frequentlyUsed: Boolean,
|
||||
val frequentlyUsedRows: Int,
|
||||
)
|
||||
|
||||
class FavoritesSettings internal constructor(
|
||||
private val dataStore: LauncherDataStore,
|
||||
) : Flow<FavoritesSettingsData> by (dataStore.data.map {
|
||||
FavoritesSettingsData(
|
||||
columns = it.favoritesFrequentlyUsedRows,
|
||||
frequentlyUsed = it.favoritesFrequentlyUsed,
|
||||
frequentlyUsedRows = it.favoritesFrequentlyUsedRows,
|
||||
)
|
||||
}.distinctUntilChanged()) {
|
||||
|
||||
val showEditButton
|
||||
get() = dataStore.data.map { it.favoritesEditButton }.distinctUntilChanged()
|
||||
|
||||
fun setShowEditButton(showEditButton: Boolean) {
|
||||
dataStore.update { it.copy(favoritesEditButton = showEditButton) }
|
||||
}
|
||||
|
||||
val frequentlyUsed: Flow<Boolean>
|
||||
get() = dataStore.data.map { it.favoritesFrequentlyUsed }.distinctUntilChanged()
|
||||
|
||||
fun setFrequentlyUsed(frequentlyUsed: Boolean) {
|
||||
dataStore.update { it.copy(favoritesFrequentlyUsed = frequentlyUsed) }
|
||||
}
|
||||
|
||||
val frequentlyUsedRows: Flow<Int>
|
||||
get() = dataStore.data.map { it.favoritesFrequentlyUsedRows }.distinctUntilChanged()
|
||||
|
||||
fun setFrequentlyUsedRows(frequentlyUsedRows: Int) {
|
||||
dataStore.update { it.copy(favoritesFrequentlyUsedRows = frequentlyUsedRows) }
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
package de.mm20.launcher2.preferences.search
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class FileSearchSettings internal constructor(
|
||||
private val launcherDataStore: LauncherDataStore,
|
||||
) {
|
||||
val enabledProviders: Flow<Set<String>>
|
||||
get() = launcherDataStore.data.map { it.fileSearchProviders }
|
||||
|
||||
val localFiles
|
||||
get() = launcherDataStore.data.map { it.fileSearchProviders.contains("local") }
|
||||
|
||||
fun setLocalFiles(localFiles: Boolean) {
|
||||
launcherDataStore.update {
|
||||
if (localFiles) {
|
||||
it.copy(fileSearchProviders = it.fileSearchProviders + "local")
|
||||
} else {
|
||||
it.copy(fileSearchProviders = it.fileSearchProviders - "local")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val gdriveFiles
|
||||
get() = launcherDataStore.data.map { it.fileSearchProviders.contains("gdrive") }
|
||||
|
||||
fun setGdriveFiles(gdriveFiles: Boolean) {
|
||||
launcherDataStore.update {
|
||||
if (gdriveFiles) {
|
||||
it.copy(fileSearchProviders = it.fileSearchProviders + "gdrive")
|
||||
} else {
|
||||
it.copy(fileSearchProviders = it.fileSearchProviders - "gdrive")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val nextcloudFiles
|
||||
get() = launcherDataStore.data.map { it.fileSearchProviders.contains("nextcloud") }
|
||||
|
||||
fun setNextcloudFiles(nextcloudFiles: Boolean) {
|
||||
launcherDataStore.update {
|
||||
if (nextcloudFiles) {
|
||||
it.copy(fileSearchProviders = it.fileSearchProviders + "nextcloud")
|
||||
} else {
|
||||
it.copy(fileSearchProviders = it.fileSearchProviders - "nextcloud")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val owncloudFiles
|
||||
get() = launcherDataStore.data.map { it.fileSearchProviders.contains("owncloud") }
|
||||
|
||||
fun setOwncloudFiles(owncloudFiles: Boolean) {
|
||||
launcherDataStore.update {
|
||||
if (owncloudFiles) {
|
||||
it.copy(fileSearchProviders = it.fileSearchProviders + "owncloud")
|
||||
} else {
|
||||
it.copy(fileSearchProviders = it.fileSearchProviders - "owncloud")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val enabledPlugins: Flow<Set<String>>
|
||||
get() = launcherDataStore.data.map { it.fileSearchProviders - "local" - "gdrive" - "nextcloud" - "owncloud" }
|
||||
|
||||
fun setPluginEnabled(authority: String, enabled: Boolean) {
|
||||
launcherDataStore.update {
|
||||
if (enabled) {
|
||||
it.copy(fileSearchProviders = it.fileSearchProviders + authority)
|
||||
} else {
|
||||
it.copy(fileSearchProviders = it.fileSearchProviders - authority)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package de.mm20.launcher2.preferences.search
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.WeightFactor
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class RankingSettings internal constructor(
|
||||
private val launcherDataStore: LauncherDataStore,
|
||||
){
|
||||
val weightFactor
|
||||
get() = launcherDataStore.data.map { it.rankingWeightFactor }.distinctUntilChanged()
|
||||
|
||||
fun setWeightFactor(weightFactor: WeightFactor) {
|
||||
launcherDataStore.update {
|
||||
it.copy(rankingWeightFactor = weightFactor)
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package de.mm20.launcher2.preferences.search
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class ShortcutSearchSettings internal constructor(
|
||||
private val dataStore: LauncherDataStore
|
||||
) {
|
||||
val enabled
|
||||
get() = dataStore.data.map { it.shortcutSearchEnabled }.distinctUntilChanged()
|
||||
|
||||
fun setEnabled(enabled: Boolean) {
|
||||
dataStore.update {
|
||||
it.copy(shortcutSearchEnabled = enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package de.mm20.launcher2.preferences.search
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
data class UnitConverterSettingsData(
|
||||
val enabled: Boolean,
|
||||
val currencies: Boolean,
|
||||
)
|
||||
|
||||
class UnitConverterSettings internal constructor(
|
||||
private val dataStore: LauncherDataStore,
|
||||
) : Flow<UnitConverterSettingsData> by (dataStore.data.map {
|
||||
UnitConverterSettingsData(
|
||||
enabled = it.unitConverterEnabled,
|
||||
currencies = it.unitConverterCurrencies,
|
||||
)
|
||||
}.distinctUntilChanged()) {
|
||||
val enabled: Flow<Boolean>
|
||||
get() = dataStore.data.map { it.unitConverterEnabled }.distinctUntilChanged()
|
||||
|
||||
fun setEnabled(enabled: Boolean) {
|
||||
dataStore.update { it.copy(unitConverterEnabled = enabled) }
|
||||
}
|
||||
|
||||
val currencies: Flow<Boolean>
|
||||
get() = dataStore.data.map { it.unitConverterCurrencies }.distinctUntilChanged()
|
||||
|
||||
fun setCurrencies(currencies: Boolean) {
|
||||
dataStore.update { it.copy(unitConverterCurrencies = currencies) }
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package de.mm20.launcher2.preferences.search
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class WebsiteSearchSettings internal constructor(
|
||||
private val dataStore: LauncherDataStore,
|
||||
){
|
||||
val enabled
|
||||
get() = dataStore.data.map { it.websiteSearchEnabled }
|
||||
|
||||
fun setEnabled(enabled: Boolean) {
|
||||
dataStore.update {
|
||||
it.copy(websiteSearchEnabled = enabled)
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package de.mm20.launcher2.preferences.search
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class WikipediaSearchSettings internal constructor(
|
||||
private val dataStore: LauncherDataStore
|
||||
) {
|
||||
val enabled
|
||||
get() = dataStore.data.map { it.wikipediaSearchEnabled }.distinctUntilChanged()
|
||||
|
||||
fun setEnabled(enabled: Boolean) {
|
||||
dataStore.update {
|
||||
it.copy(wikipediaSearchEnabled = enabled)
|
||||
}
|
||||
}
|
||||
|
||||
val customUrl
|
||||
get() = dataStore.data.map { it.wikipediaCustomUrl }.distinctUntilChanged()
|
||||
|
||||
fun setCustomUrl(customUrl: String?) {
|
||||
dataStore.update {
|
||||
it.copy(wikipediaCustomUrl = customUrl?.takeIf { it.isNotBlank() })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package de.mm20.launcher2.preferences.ui
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
data class BadgeSettingsData(
|
||||
val notifications: Boolean = true,
|
||||
val suspendedApps: Boolean = true,
|
||||
val cloudFiles: Boolean = true,
|
||||
val shortcuts: Boolean = true,
|
||||
val plugins: Boolean = true,
|
||||
)
|
||||
|
||||
class BadgeSettings internal constructor(
|
||||
private val launcherDataStore: LauncherDataStore,
|
||||
) : Flow<BadgeSettingsData> by (launcherDataStore.data.map {
|
||||
BadgeSettingsData(
|
||||
notifications = it.badgesNotifications,
|
||||
suspendedApps = it.badgesSuspendedApps,
|
||||
cloudFiles = it.badgesCloudFiles,
|
||||
shortcuts = it.badgesShortcuts,
|
||||
plugins = it.badgesPlugins,
|
||||
)
|
||||
}) {
|
||||
|
||||
val notifications
|
||||
get() = launcherDataStore.data.map { it.badgesNotifications }
|
||||
|
||||
fun setNotifications(notifications: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(badgesNotifications = notifications)
|
||||
}
|
||||
}
|
||||
|
||||
val suspendedApps
|
||||
get() = launcherDataStore.data.map { it.badgesSuspendedApps }
|
||||
|
||||
fun setSuspendedApps(suspendedApps: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(badgesSuspendedApps = suspendedApps)
|
||||
}
|
||||
}
|
||||
|
||||
val cloudFiles
|
||||
get() = launcherDataStore.data.map { it.badgesCloudFiles }
|
||||
|
||||
fun setCloudFiles(cloudFiles: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(badgesCloudFiles = cloudFiles)
|
||||
}
|
||||
}
|
||||
|
||||
val shortcuts
|
||||
get() = launcherDataStore.data.map { it.badgesShortcuts }
|
||||
|
||||
fun setShortcuts(shortcuts: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(badgesShortcuts = shortcuts)
|
||||
}
|
||||
}
|
||||
|
||||
val plugins
|
||||
get() = launcherDataStore.data.map { it.badgesPlugins }
|
||||
|
||||
fun setPlugins(plugins: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(badgesPlugins = plugins)
|
||||
}
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
package de.mm20.launcher2.preferences.ui
|
||||
|
||||
import de.mm20.launcher2.preferences.ClockWidgetAlignment
|
||||
import de.mm20.launcher2.preferences.ClockWidgetColors
|
||||
import de.mm20.launcher2.preferences.ClockWidgetStyle
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
data class ClockWidgetParts(
|
||||
val date: Boolean,
|
||||
val music: Boolean = false,
|
||||
val battery: Boolean = false,
|
||||
val alarm: Boolean = false,
|
||||
)
|
||||
|
||||
class ClockWidgetSettings internal constructor(
|
||||
private val launcherDataStore: LauncherDataStore,
|
||||
) {
|
||||
val compact
|
||||
get() = launcherDataStore.data.map { it.clockWidgetCompact }
|
||||
|
||||
fun setCompact(compact: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(clockWidgetCompact = compact)
|
||||
}
|
||||
}
|
||||
|
||||
val parts
|
||||
get() = launcherDataStore.data.map {
|
||||
ClockWidgetParts(
|
||||
date = it.clockWidgetDatePart,
|
||||
music = it.clockWidgetMusicPart,
|
||||
battery = it.clockWidgetBatteryPart,
|
||||
alarm = it.clockWidgetAlarmPart,
|
||||
)
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setDatePart(datePart: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(clockWidgetDatePart = datePart)
|
||||
}
|
||||
}
|
||||
|
||||
fun setMusicPart(musicPart: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(clockWidgetMusicPart = musicPart)
|
||||
}
|
||||
}
|
||||
|
||||
fun setBatteryPart(batteryPart: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(clockWidgetBatteryPart = batteryPart)
|
||||
}
|
||||
}
|
||||
|
||||
fun setAlarmPart(alarmPart: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(clockWidgetAlarmPart = alarmPart)
|
||||
}
|
||||
}
|
||||
|
||||
val fillHeight
|
||||
get() = launcherDataStore.data.map { it.clockWidgetFillHeight }
|
||||
|
||||
fun setFillHeight(fillHeight: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(clockWidgetFillHeight = fillHeight)
|
||||
}
|
||||
}
|
||||
|
||||
val dock
|
||||
get() = launcherDataStore.data.map { it.homeScreenDock }
|
||||
|
||||
fun setDock(dock: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(homeScreenDock = dock)
|
||||
}
|
||||
}
|
||||
|
||||
val alignment
|
||||
get() = launcherDataStore.data.map { it.clockWidgetAlignment }
|
||||
|
||||
fun setAlignment(alignment: ClockWidgetAlignment) {
|
||||
launcherDataStore.update {
|
||||
it.copy(clockWidgetAlignment = alignment)
|
||||
}
|
||||
}
|
||||
|
||||
val clockStyle
|
||||
get() = launcherDataStore.data.map { it.clockWidgetStyle }
|
||||
|
||||
fun setClockStyle(clockStyle: ClockWidgetStyle) {
|
||||
launcherDataStore.update {
|
||||
it.copy(clockWidgetStyle = clockStyle)
|
||||
}
|
||||
}
|
||||
|
||||
fun setColor(color: ClockWidgetColors) {
|
||||
launcherDataStore.update {
|
||||
it.copy(clockWidgetColors = color)
|
||||
}
|
||||
}
|
||||
|
||||
val color
|
||||
get() = launcherDataStore.data.map { it.clockWidgetColors }
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package de.mm20.launcher2.preferences.ui
|
||||
|
||||
import de.mm20.launcher2.preferences.GestureAction
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
data class GestureSettingsData(
|
||||
val swipeDown: GestureAction,
|
||||
val swipeLeft: GestureAction,
|
||||
val swipeRight: GestureAction,
|
||||
val doubleTap: GestureAction,
|
||||
val longPress: GestureAction,
|
||||
val homeButton: GestureAction,
|
||||
)
|
||||
|
||||
class GestureSettings internal constructor(
|
||||
private val dataStore: LauncherDataStore,
|
||||
): Flow<GestureSettingsData> by (
|
||||
dataStore.data.map {
|
||||
GestureSettingsData(
|
||||
swipeDown = it.gesturesSwipeDown,
|
||||
swipeLeft = it.gesturesSwipeLeft,
|
||||
swipeRight = it.gesturesSwipeRight,
|
||||
doubleTap = it.gesturesDoubleTap,
|
||||
longPress = it.gesturesLongPress,
|
||||
homeButton = it.gesturesHomeButton,
|
||||
)
|
||||
}.distinctUntilChanged()
|
||||
) {
|
||||
val swipeDown: Flow<GestureAction> = dataStore.data.map { it.gesturesSwipeDown }
|
||||
.distinctUntilChanged()
|
||||
|
||||
val swipeLeft: Flow<GestureAction> = dataStore.data.map { it.gesturesSwipeLeft }
|
||||
.distinctUntilChanged()
|
||||
|
||||
val swipeRight: Flow<GestureAction> = dataStore.data.map { it.gesturesSwipeRight }
|
||||
.distinctUntilChanged()
|
||||
|
||||
val doubleTap: Flow<GestureAction> = dataStore.data.map { it.gesturesDoubleTap }
|
||||
.distinctUntilChanged()
|
||||
|
||||
val longPress: Flow<GestureAction> = dataStore.data.map { it.gesturesLongPress }
|
||||
.distinctUntilChanged()
|
||||
|
||||
val homeButton: Flow<GestureAction> = dataStore.data.map { it.gesturesHomeButton }
|
||||
.distinctUntilChanged()
|
||||
|
||||
fun setSwipeDown(action: GestureAction) {
|
||||
dataStore.update {
|
||||
it.copy(gesturesSwipeDown = action)
|
||||
}
|
||||
}
|
||||
|
||||
fun setSwipeLeft(action: GestureAction) {
|
||||
dataStore.update {
|
||||
it.copy(gesturesSwipeLeft = action)
|
||||
}
|
||||
}
|
||||
|
||||
fun setSwipeRight(action: GestureAction) {
|
||||
dataStore.update {
|
||||
it.copy(gesturesSwipeRight = action)
|
||||
}
|
||||
}
|
||||
|
||||
fun setDoubleTap(action: GestureAction) {
|
||||
dataStore.update {
|
||||
it.copy(gesturesDoubleTap = action)
|
||||
}
|
||||
}
|
||||
|
||||
fun setLongPress(action: GestureAction) {
|
||||
dataStore.update {
|
||||
it.copy(gesturesLongPress = action)
|
||||
}
|
||||
}
|
||||
|
||||
fun setHomeButton(action: GestureAction) {
|
||||
dataStore.update {
|
||||
it.copy(gesturesHomeButton = action)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package de.mm20.launcher2.preferences.ui
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
data class IconSettingsData(
|
||||
val themedIcons: Boolean,
|
||||
val forceThemed: Boolean,
|
||||
val adaptify: Boolean,
|
||||
val iconPack: String?,
|
||||
val iconPackThemed: Boolean,
|
||||
)
|
||||
|
||||
class IconSettings internal constructor(
|
||||
private val launcherDataStore: LauncherDataStore,
|
||||
) : Flow<IconSettingsData> by (
|
||||
launcherDataStore.data.map {
|
||||
IconSettingsData(
|
||||
themedIcons = it.iconsThemed,
|
||||
forceThemed = it.iconsForceThemed,
|
||||
adaptify = it.iconsAdaptify,
|
||||
iconPack = it.iconsPack,
|
||||
iconPackThemed = it.iconsPackThemed,
|
||||
)
|
||||
}
|
||||
) {
|
||||
|
||||
fun setAdaptifyLegacyIcons(adaptify: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(iconsAdaptify = adaptify)
|
||||
}
|
||||
}
|
||||
|
||||
fun setThemedIcons(themedIcons: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(iconsThemed = themedIcons)
|
||||
}
|
||||
}
|
||||
|
||||
fun setForceThemedIcons(forceThemed: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(iconsForceThemed = forceThemed)
|
||||
}
|
||||
}
|
||||
|
||||
fun setIconPack(iconPack: String?) {
|
||||
launcherDataStore.update {
|
||||
it.copy(iconsPack = iconPack)
|
||||
}
|
||||
}
|
||||
|
||||
fun setIconPackThemed(iconPackThemed: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(iconsPackThemed = iconPackThemed)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package de.mm20.launcher2.preferences.ui
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.SearchResultOrder
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class SearchUiSettings internal constructor(
|
||||
private val launcherDataStore: LauncherDataStore,
|
||||
){
|
||||
val launchOnEnter
|
||||
get() = launcherDataStore.data.map { it.searchLaunchOnEnter }.distinctUntilChanged()
|
||||
|
||||
fun setLaunchOnEnter(launchOnEnter: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(searchLaunchOnEnter = launchOnEnter)
|
||||
}
|
||||
}
|
||||
|
||||
val hiddenItemsButton
|
||||
get() = launcherDataStore.data.map { it.hiddenItemsShowButton }.distinctUntilChanged()
|
||||
|
||||
fun setHiddenItemsButton(hiddenItemsButton: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(hiddenItemsShowButton = hiddenItemsButton)
|
||||
}
|
||||
}
|
||||
|
||||
val favorites
|
||||
get() = launcherDataStore.data.map { it.favoritesEnabled }.distinctUntilChanged()
|
||||
|
||||
fun setFavorites(favorites: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(favoritesEnabled = favorites)
|
||||
}
|
||||
}
|
||||
|
||||
val resultOrder
|
||||
get() = launcherDataStore.data.map { it.searchResultOrder }.distinctUntilChanged()
|
||||
|
||||
fun setResultOrder(resultOrder: SearchResultOrder) {
|
||||
launcherDataStore.update {
|
||||
it.copy(searchResultOrder = resultOrder)
|
||||
}
|
||||
}
|
||||
|
||||
val openKeyboard
|
||||
get() = launcherDataStore.data.map { it.searchBarKeyboard }.distinctUntilChanged()
|
||||
|
||||
fun setOpenKeyboard(openKeyboard: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(searchBarKeyboard = openKeyboard)
|
||||
}
|
||||
}
|
||||
|
||||
val reversedResults
|
||||
get() = launcherDataStore.data.map { it.searchResultsReversed }.distinctUntilChanged()
|
||||
|
||||
fun setReversedResults(reversedResults: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(searchResultsReversed = reversedResults)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
package de.mm20.launcher2.preferences.ui
|
||||
|
||||
import de.mm20.launcher2.preferences.BaseLayout
|
||||
import de.mm20.launcher2.preferences.ColorScheme
|
||||
import de.mm20.launcher2.preferences.Font
|
||||
import de.mm20.launcher2.preferences.IconShape
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.ScreenOrientation
|
||||
import de.mm20.launcher2.preferences.SearchBarColors
|
||||
import de.mm20.launcher2.preferences.SearchBarStyle
|
||||
import de.mm20.launcher2.preferences.SurfaceShape
|
||||
import de.mm20.launcher2.preferences.SystemBarColors
|
||||
import de.mm20.launcher2.preferences.ThemeDescriptor
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
data class CardStyle(
|
||||
val opacity: Float = 1f,
|
||||
val cornerRadius: Int = 0,
|
||||
val shape: SurfaceShape = SurfaceShape.Rounded,
|
||||
val borderWidth: Int = 0,
|
||||
)
|
||||
|
||||
data class GridSettings(
|
||||
val columnCount: Int = 5,
|
||||
val iconSize: Int = 48,
|
||||
val showLabels: Boolean = true,
|
||||
)
|
||||
|
||||
class UiSettings internal constructor(
|
||||
private val launcherDataStore: LauncherDataStore,
|
||||
) {
|
||||
val favoritesEnabled
|
||||
get() = launcherDataStore.data.map { it.favoritesEnabled || it.homeScreenDock }
|
||||
|
||||
val iconShape
|
||||
get() = launcherDataStore.data.map {
|
||||
it.iconsShape
|
||||
}
|
||||
|
||||
fun setIconShape(iconShape: IconShape) {
|
||||
launcherDataStore.update {
|
||||
it.copy(iconsShape = iconShape)
|
||||
}
|
||||
}
|
||||
|
||||
val gridSettings
|
||||
get() = launcherDataStore.data.map {
|
||||
GridSettings(
|
||||
showLabels = it.gridLabels,
|
||||
iconSize = it.gridIconSize,
|
||||
columnCount = it.gridColumnCount,
|
||||
)
|
||||
}
|
||||
|
||||
fun setGridColumnCount(columnCount: Int) {
|
||||
launcherDataStore.update {
|
||||
it.copy(gridColumnCount = columnCount)
|
||||
}
|
||||
}
|
||||
|
||||
fun setGridIconSize(iconSize: Int) {
|
||||
launcherDataStore.update {
|
||||
it.copy(gridIconSize = iconSize)
|
||||
}
|
||||
}
|
||||
|
||||
fun setGridShowLabels(showLabels: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(gridLabels = showLabels)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val cardStyle
|
||||
get() = launcherDataStore.data.map {
|
||||
CardStyle(
|
||||
opacity = it.surfacesOpacity,
|
||||
cornerRadius = it.surfacesRadius,
|
||||
shape = it.surfacesShape,
|
||||
borderWidth = it.surfacesBorderWidth,
|
||||
)
|
||||
}
|
||||
|
||||
fun setCardOpacity(opacity: Float) {
|
||||
launcherDataStore.update {
|
||||
it.copy(surfacesOpacity = opacity)
|
||||
}
|
||||
}
|
||||
|
||||
fun setCardRadius(radius: Int) {
|
||||
launcherDataStore.update {
|
||||
it.copy(surfacesRadius = radius)
|
||||
}
|
||||
}
|
||||
|
||||
fun setCardBorderWidth(borderWidth: Int) {
|
||||
launcherDataStore.update {
|
||||
it.copy(surfacesBorderWidth = borderWidth)
|
||||
}
|
||||
}
|
||||
|
||||
fun setCardShape(shape: SurfaceShape) {
|
||||
launcherDataStore.update {
|
||||
it.copy(surfacesShape = shape)
|
||||
}
|
||||
}
|
||||
|
||||
val dimWallpaper
|
||||
get() = launcherDataStore.data.map {
|
||||
it.wallpaperDim
|
||||
}
|
||||
|
||||
fun setDimWallpaper(dimWallpaper: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(wallpaperDim = dimWallpaper)
|
||||
}
|
||||
}
|
||||
|
||||
val blurWallpaper
|
||||
get() = launcherDataStore.data.map {
|
||||
it.wallpaperBlur
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setBlurWallpaper(blurWallpaper: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(wallpaperBlur = blurWallpaper)
|
||||
}
|
||||
}
|
||||
|
||||
val wallpaperBlurRadius
|
||||
get() = launcherDataStore.data.map {
|
||||
it.wallpaperBlurRadius
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setWallpaperBlurRadius(wallpaperBlurRadius: Int) {
|
||||
launcherDataStore.update {
|
||||
it.copy(wallpaperBlurRadius = wallpaperBlurRadius)
|
||||
}
|
||||
}
|
||||
|
||||
val colorScheme
|
||||
get() = launcherDataStore.data.map {
|
||||
it.uiColorScheme
|
||||
}.distinctUntilChanged()
|
||||
|
||||
val compatModeColors
|
||||
get() = launcherDataStore.data.map {
|
||||
it.uiCompatModeColors
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setCompatModeColors(enabled: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(uiCompatModeColors = enabled)
|
||||
}
|
||||
}
|
||||
|
||||
val statusBarColor
|
||||
get() = launcherDataStore.data.map {
|
||||
it.systemBarsStatusColors
|
||||
}.distinctUntilChanged()
|
||||
|
||||
val hideStatusBar
|
||||
get() = launcherDataStore.data.map {
|
||||
it.systemBarsHideStatus
|
||||
}.distinctUntilChanged()
|
||||
|
||||
val hideNavigationBar
|
||||
get() = launcherDataStore.data.map {
|
||||
it.systemBarsHideNav
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setHideStatusBar(hideStatusBar: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(systemBarsHideStatus = hideStatusBar)
|
||||
}
|
||||
}
|
||||
|
||||
fun setHideNavigationBar(hideNavigationBar: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(systemBarsHideNav = hideNavigationBar)
|
||||
}
|
||||
}
|
||||
|
||||
val navigationBarColor
|
||||
get() = launcherDataStore.data.map {
|
||||
it.systemBarsNavColors
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setStatusBarColor(statusBarColor: SystemBarColors) {
|
||||
launcherDataStore.update {
|
||||
it.copy(systemBarsStatusColors = statusBarColor)
|
||||
}
|
||||
}
|
||||
|
||||
fun setNavigationBarColor(navigationBarColor: SystemBarColors) {
|
||||
launcherDataStore.update {
|
||||
it.copy(systemBarsNavColors = navigationBarColor)
|
||||
}
|
||||
}
|
||||
|
||||
val chargingAnimation
|
||||
get() = launcherDataStore.data.map {
|
||||
it.animationsCharging
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setChargingAnimation(chargingAnimation: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(animationsCharging = chargingAnimation)
|
||||
}
|
||||
}
|
||||
|
||||
val baseLayout
|
||||
get() = launcherDataStore.data.map {
|
||||
it.uiBaseLayout
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setBaseLayout(baseLayout: BaseLayout) {
|
||||
launcherDataStore.update {
|
||||
it.copy(uiBaseLayout = baseLayout)
|
||||
}
|
||||
}
|
||||
|
||||
val clockFillScreen
|
||||
get() = launcherDataStore.data.map {
|
||||
it.clockWidgetFillHeight
|
||||
}.distinctUntilChanged()
|
||||
|
||||
val searchBarStyle
|
||||
get() = launcherDataStore.data.map {
|
||||
it.searchBarStyle
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setSearchBarStyle(searchBarStyle: SearchBarStyle) {
|
||||
launcherDataStore.update {
|
||||
it.copy(searchBarStyle = searchBarStyle)
|
||||
}
|
||||
}
|
||||
|
||||
val searchBarColor
|
||||
get() = launcherDataStore.data.map {
|
||||
it.searchBarColors
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setSearchBarColor(color: SearchBarColors) {
|
||||
launcherDataStore.update {
|
||||
it.copy(searchBarColors = color)
|
||||
}
|
||||
}
|
||||
|
||||
val bottomSearchBar
|
||||
get() = launcherDataStore.data.map {
|
||||
it.searchBarBottom
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setBottomSearchBar(bottomSearchBar: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(searchBarBottom = bottomSearchBar)
|
||||
}
|
||||
}
|
||||
|
||||
val reverseSearchResults
|
||||
get() = launcherDataStore.data.map {
|
||||
it.searchResultsReversed
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setReverseSearchResults(reverseSearchResults: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(searchResultsReversed = reverseSearchResults)
|
||||
}
|
||||
}
|
||||
|
||||
val fixedSearchBar
|
||||
get() = launcherDataStore.data.map {
|
||||
it.searchBarFixed
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setFixedSearchBar(fixedSearchBar: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(searchBarFixed = fixedSearchBar)
|
||||
}
|
||||
}
|
||||
|
||||
val openKeyboardOnSearch
|
||||
get() = launcherDataStore.data.map {
|
||||
it.searchBarKeyboard
|
||||
}.distinctUntilChanged()
|
||||
|
||||
|
||||
val orientation
|
||||
get() = launcherDataStore.data.map {
|
||||
it.uiOrientation
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setOrientation(orientation: ScreenOrientation) {
|
||||
launcherDataStore.update {
|
||||
it.copy(uiOrientation = orientation)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val theme
|
||||
get() = launcherDataStore.data.map {
|
||||
it.uiTheme
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setTheme(theme: ThemeDescriptor) {
|
||||
launcherDataStore.update {
|
||||
it.copy(uiTheme = theme)
|
||||
}
|
||||
}
|
||||
|
||||
val font
|
||||
get() = launcherDataStore.data.map {
|
||||
it.uiFont
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setFont(font: Font) {
|
||||
launcherDataStore.update {
|
||||
it.copy(uiFont = font)
|
||||
}
|
||||
}
|
||||
|
||||
fun setColorScheme(colorScheme: ColorScheme) {
|
||||
launcherDataStore.update {
|
||||
it.copy(uiColorScheme = colorScheme)
|
||||
}
|
||||
}
|
||||
|
||||
val dock
|
||||
get() = launcherDataStore.data.map {
|
||||
it.homeScreenDock
|
||||
}.distinctUntilChanged()
|
||||
|
||||
val widgetEditButton
|
||||
get() = launcherDataStore.data.map {
|
||||
it.widgetsEditButton
|
||||
}.distinctUntilChanged()
|
||||
|
||||
fun setWidgetEditButton(editButton: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(widgetsEditButton = editButton)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package de.mm20.launcher2.preferences.ui
|
||||
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class UiState internal constructor(
|
||||
private val launcherDataStore: LauncherDataStore,
|
||||
){
|
||||
val favoritesTagsExpanded
|
||||
get() = launcherDataStore.data.map { it.stateTagsMultiline }.distinctUntilChanged()
|
||||
|
||||
fun setFavoritesTagsExpanded(favoritesTagsExpanded: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(stateTagsMultiline = favoritesTagsExpanded)
|
||||
}
|
||||
}
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
package de.mm20.launcher2.preferences.weather
|
||||
|
||||
import de.mm20.launcher2.preferences.LatLon
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.ProviderSettings
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
sealed interface WeatherLocation {
|
||||
val name: String
|
||||
|
||||
data class LatLon(
|
||||
override val name: String,
|
||||
val lat: Double,
|
||||
val lon: Double,
|
||||
) : WeatherLocation
|
||||
|
||||
data class Id(
|
||||
override val name: String,
|
||||
val locationId: String,
|
||||
) : WeatherLocation
|
||||
}
|
||||
|
||||
data class WeatherSettingsData(
|
||||
val provider: String = "metno",
|
||||
val autoLocation: Boolean = true,
|
||||
val location: LatLon? = null,
|
||||
val locationName: String? = null,
|
||||
val lastLocation: LatLon? = null,
|
||||
val lastUpdate: Long = 0L,
|
||||
val providerSettings: Map<String, ProviderSettings> = emptyMap(),
|
||||
)
|
||||
|
||||
class WeatherSettings internal constructor(
|
||||
private val launcherDataStore: LauncherDataStore,
|
||||
) :
|
||||
Flow<WeatherSettingsData> by (
|
||||
launcherDataStore.data.map {
|
||||
WeatherSettingsData(
|
||||
provider = it.weatherProvider,
|
||||
autoLocation = it.weatherAutoLocation,
|
||||
location = it.weatherLocation,
|
||||
locationName = it.weatherLocationName,
|
||||
lastLocation = it.weatherLastLocation,
|
||||
lastUpdate = it.weatherLastUpdate,
|
||||
providerSettings = it.weatherProviderSettings,
|
||||
)
|
||||
}.distinctUntilChanged()
|
||||
) {
|
||||
|
||||
val location = launcherDataStore.data.map {
|
||||
val providerSettings = it.weatherProviderSettings[it.weatherProvider]
|
||||
val id = providerSettings?.locationId
|
||||
val name = providerSettings?.locationName
|
||||
|
||||
if (id != null && name != null) {
|
||||
WeatherLocation.Id(name, id)
|
||||
} else if (it.weatherLocation != null && it.weatherLocationName != null) {
|
||||
WeatherLocation.LatLon(
|
||||
it.weatherLocationName,
|
||||
it.weatherLocation.lat,
|
||||
it.weatherLocation.lon
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}.distinctUntilChanged()
|
||||
|
||||
val autoLocation = launcherDataStore.data.map { it.weatherAutoLocation }
|
||||
.distinctUntilChanged()
|
||||
|
||||
fun setLocation(location: WeatherLocation) {
|
||||
launcherDataStore.update {
|
||||
val providerSettings =
|
||||
it.weatherProviderSettings.getOrDefault(it.weatherProvider, ProviderSettings())
|
||||
when (location) {
|
||||
is WeatherLocation.LatLon -> {
|
||||
it.copy(
|
||||
weatherLocation = LatLon(lat = location.lat, lon = location.lon),
|
||||
weatherLocationName = location.name,
|
||||
weatherLastUpdate = 0L,
|
||||
weatherAutoLocation = false,
|
||||
weatherProviderSettings = it.weatherProviderSettings.toMutableMap().apply {
|
||||
put(
|
||||
it.weatherProvider,
|
||||
providerSettings.copy(
|
||||
locationId = null,
|
||||
locationName = null,
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
is WeatherLocation.Id -> {
|
||||
it.copy(
|
||||
weatherLocation = null,
|
||||
weatherLocationName = null,
|
||||
weatherAutoLocation = false,
|
||||
weatherLastUpdate = 0L,
|
||||
weatherProviderSettings = it.weatherProviderSettings.toMutableMap().apply {
|
||||
put(
|
||||
it.weatherProvider,
|
||||
providerSettings.copy(
|
||||
locationId = location.locationId,
|
||||
locationName = location.name
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setLastLocation(location: LatLon) {
|
||||
launcherDataStore.update {
|
||||
it.copy(
|
||||
weatherLastLocation = location,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val lastUpdate = launcherDataStore.data.map { it.weatherLastUpdate }
|
||||
.distinctUntilChanged()
|
||||
|
||||
fun setLastUpdate(lastUpdate: Long) {
|
||||
launcherDataStore.update {
|
||||
it.copy(weatherLastUpdate = lastUpdate)
|
||||
}
|
||||
}
|
||||
|
||||
val providerId = launcherDataStore.data.map { it.weatherProvider }
|
||||
.distinctUntilChanged()
|
||||
|
||||
fun setProvider(provider: String) {
|
||||
launcherDataStore.update {
|
||||
it.copy(
|
||||
weatherProvider = provider,
|
||||
weatherLastUpdate = 0L,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setAutoLocation(autoLocation: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(
|
||||
weatherAutoLocation = autoLocation,
|
||||
weatherLastUpdate = 0L,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val imperialUnits = launcherDataStore.data.map { it.weatherImperialUnits }
|
||||
.distinctUntilChanged()
|
||||
|
||||
fun setImperialUnits(imperialUnits: Boolean) {
|
||||
launcherDataStore.update {
|
||||
it.copy(
|
||||
weatherImperialUnits = imperialUnits,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ syntax = "proto3";
|
||||
option java_package = "de.mm20.launcher2.preferences";
|
||||
option java_multiple_files = true;
|
||||
|
||||
message Settings {
|
||||
message LegacySettings {
|
||||
uint32 version = 1;
|
||||
message AppearanceSettings {
|
||||
enum Theme {
|
||||
@@ -90,8 +90,6 @@ message Settings {
|
||||
// UUID of the selected theme
|
||||
string theme_id = 12;
|
||||
uint32 blur_wallpaper_radius = 13;
|
||||
|
||||
bool force_compat_mode_system_colors = 14;
|
||||
}
|
||||
AppearanceSettings appearance = 2;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user