Migrate grid column count preference
This commit is contained in:
parent
8799c15682
commit
b01f9d3f4d
@ -4,6 +4,7 @@ import android.content.Context
|
|||||||
import de.mm20.launcher2.database.AppDatabase
|
import de.mm20.launcher2.database.AppDatabase
|
||||||
import de.mm20.launcher2.database.entities.FavoritesItemEntity
|
import de.mm20.launcher2.database.entities.FavoritesItemEntity
|
||||||
import de.mm20.launcher2.ktx.ceilToInt
|
import de.mm20.launcher2.ktx.ceilToInt
|
||||||
|
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||||
import de.mm20.launcher2.preferences.LauncherPreferences
|
import de.mm20.launcher2.preferences.LauncherPreferences
|
||||||
import de.mm20.launcher2.search.SearchableDeserializer
|
import de.mm20.launcher2.search.SearchableDeserializer
|
||||||
import de.mm20.launcher2.search.data.CalendarEvent
|
import de.mm20.launcher2.search.data.CalendarEvent
|
||||||
@ -33,7 +34,8 @@ interface FavoritesRepository {
|
|||||||
|
|
||||||
internal class FavoritesRepositoryImpl(
|
internal class FavoritesRepositoryImpl(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val database: AppDatabase
|
private val database: AppDatabase,
|
||||||
|
private val dataStore: LauncherDataStore
|
||||||
) : FavoritesRepository, KoinComponent {
|
) : FavoritesRepository, KoinComponent {
|
||||||
|
|
||||||
private val scope = CoroutineScope(Job() + Dispatchers.Default)
|
private val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||||
@ -42,16 +44,7 @@ internal class FavoritesRepositoryImpl(
|
|||||||
|
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
|
|
||||||
val gridColumns = callbackFlow {
|
val gridColumns = dataStore.data.map { it.grid.columnCount }.distinctUntilChanged()
|
||||||
send(LauncherPreferences.instance.gridColumnCount)
|
|
||||||
val unregister =
|
|
||||||
LauncherPreferences.instance.doOnPreferenceChange("grid_column_count") {
|
|
||||||
trySendBlocking(LauncherPreferences.instance.gridColumnCount)
|
|
||||||
}
|
|
||||||
awaitClose {
|
|
||||||
unregister()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val dao = database.searchDao()
|
val dao = database.searchDao()
|
||||||
|
|
||||||
val pinnedFavorites = dao.getFavorites().map {
|
val pinnedFavorites = dao.getFavorites().map {
|
||||||
|
|||||||
@ -91,5 +91,5 @@ val favoritesModule = module {
|
|||||||
return@factory NullDeserializer()
|
return@factory NullDeserializer()
|
||||||
}
|
}
|
||||||
|
|
||||||
single<FavoritesRepository> { FavoritesRepositoryImpl(androidContext(), get()) }
|
single<FavoritesRepository> { FavoritesRepositoryImpl(androidContext(), get(), get()) }
|
||||||
}
|
}
|
||||||
@ -4,81 +4,101 @@ import android.content.Context
|
|||||||
|
|
||||||
fun createFactorySettings(context: Context): Settings {
|
fun createFactorySettings(context: Context): Settings {
|
||||||
return Settings.newBuilder()
|
return Settings.newBuilder()
|
||||||
.setAppearance(Settings.AppearanceSettings
|
.setAppearance(
|
||||||
.newBuilder()
|
Settings.AppearanceSettings
|
||||||
.setTheme(Settings.AppearanceSettings.Theme.System)
|
.newBuilder()
|
||||||
.setColorScheme(Settings.AppearanceSettings.ColorScheme.Default)
|
.setTheme(Settings.AppearanceSettings.Theme.System)
|
||||||
.build()
|
.setColorScheme(Settings.AppearanceSettings.ColorScheme.Default)
|
||||||
|
.build()
|
||||||
)
|
)
|
||||||
.setWeather(Settings.WeatherSettings
|
.setWeather(
|
||||||
.newBuilder()
|
Settings.WeatherSettings
|
||||||
.setProvider(Settings.WeatherSettings.WeatherProvider.MetNo)
|
.newBuilder()
|
||||||
.setImperialUnits(context.resources.getBoolean(R.bool.default_imperialUnits))
|
.setProvider(Settings.WeatherSettings.WeatherProvider.MetNo)
|
||||||
.build()
|
.setImperialUnits(context.resources.getBoolean(R.bool.default_imperialUnits))
|
||||||
|
.build()
|
||||||
)
|
)
|
||||||
.setMusicWidget(Settings.MusicWidgetSettings
|
.setMusicWidget(
|
||||||
.newBuilder()
|
Settings.MusicWidgetSettings
|
||||||
.setFilterSources(true)
|
.newBuilder()
|
||||||
.build()
|
.setFilterSources(true)
|
||||||
|
.build()
|
||||||
)
|
)
|
||||||
.setCalendarWidget(Settings.CalendarWidgetSettings
|
.setCalendarWidget(
|
||||||
.newBuilder()
|
Settings.CalendarWidgetSettings
|
||||||
.setHideAlldayEvents(false)
|
.newBuilder()
|
||||||
|
.setHideAlldayEvents(false)
|
||||||
)
|
)
|
||||||
.setClockWidget(Settings.ClockWidgetSettings
|
.setClockWidget(
|
||||||
.newBuilder()
|
Settings.ClockWidgetSettings
|
||||||
.setLayout(Settings.ClockWidgetSettings.ClockWidgetLayout.Vertical)
|
.newBuilder()
|
||||||
.setClockStyle(Settings.ClockWidgetSettings.ClockStyle.DigitalClock1)
|
.setLayout(Settings.ClockWidgetSettings.ClockWidgetLayout.Vertical)
|
||||||
.build()
|
.setClockStyle(Settings.ClockWidgetSettings.ClockStyle.DigitalClock1)
|
||||||
|
.build()
|
||||||
)
|
)
|
||||||
.setFavorites(Settings.FavoritesSettings
|
.setFavorites(
|
||||||
.newBuilder()
|
Settings.FavoritesSettings
|
||||||
.setEnabled(true)
|
.newBuilder()
|
||||||
|
.setEnabled(true)
|
||||||
)
|
)
|
||||||
.setFileSearch(Settings.FilesSearchSettings
|
.setFileSearch(
|
||||||
.newBuilder()
|
Settings.FilesSearchSettings
|
||||||
.setLocalFiles(true)
|
.newBuilder()
|
||||||
.setNextcloud(false)
|
.setLocalFiles(true)
|
||||||
.setGdrive(false)
|
.setNextcloud(false)
|
||||||
.setOnedrive(false)
|
.setGdrive(false)
|
||||||
.setNextcloud(false)
|
.setOnedrive(false)
|
||||||
|
.setNextcloud(false)
|
||||||
)
|
)
|
||||||
.setContactsSearch(Settings.ContactsSearchSettings
|
.setContactsSearch(
|
||||||
.newBuilder()
|
Settings.ContactsSearchSettings
|
||||||
.setEnabled(true)
|
.newBuilder()
|
||||||
|
.setEnabled(true)
|
||||||
)
|
)
|
||||||
.setCalendarSearch(Settings.CalendarSearchSettings
|
.setCalendarSearch(
|
||||||
.newBuilder()
|
Settings.CalendarSearchSettings
|
||||||
.setEnabled(true)
|
.newBuilder()
|
||||||
|
.setEnabled(true)
|
||||||
)
|
)
|
||||||
.setCalculatorSearch(Settings.CalculatorSearchSettings
|
.setCalculatorSearch(
|
||||||
.newBuilder()
|
Settings.CalculatorSearchSettings
|
||||||
.setEnabled(true)
|
.newBuilder()
|
||||||
|
.setEnabled(true)
|
||||||
)
|
)
|
||||||
.setUnitConverterSearch(Settings.UnitConverterSearchSettings
|
.setUnitConverterSearch(
|
||||||
.newBuilder()
|
Settings.UnitConverterSearchSettings
|
||||||
.setEnabled(true)
|
.newBuilder()
|
||||||
|
.setEnabled(true)
|
||||||
)
|
)
|
||||||
.setWikipediaSearch(Settings.WikipediaSearchSettings
|
.setWikipediaSearch(
|
||||||
.newBuilder()
|
Settings.WikipediaSearchSettings
|
||||||
.setEnabled(false)
|
.newBuilder()
|
||||||
.setImages(false)
|
.setEnabled(false)
|
||||||
.setCustomUrl("")
|
.setImages(false)
|
||||||
|
.setCustomUrl("")
|
||||||
)
|
)
|
||||||
.setWebsiteSearch(Settings.WebsiteSearchSettings
|
.setWebsiteSearch(
|
||||||
.newBuilder()
|
Settings.WebsiteSearchSettings
|
||||||
.setEnabled(false)
|
.newBuilder()
|
||||||
|
.setEnabled(false)
|
||||||
)
|
)
|
||||||
.setWebSearch(Settings.WebSearchSettings
|
.setWebSearch(
|
||||||
.newBuilder()
|
Settings.WebSearchSettings
|
||||||
.setEnabled(true)
|
.newBuilder()
|
||||||
|
.setEnabled(true)
|
||||||
)
|
)
|
||||||
.setBadges(Settings.BadgeSettings
|
.setBadges(
|
||||||
.newBuilder()
|
Settings.BadgeSettings
|
||||||
.setNotifications(true)
|
.newBuilder()
|
||||||
.setCloudFiles(true)
|
.setNotifications(true)
|
||||||
.setShortcuts(true)
|
.setCloudFiles(true)
|
||||||
.setSuspendedApps(true)
|
.setShortcuts(true)
|
||||||
|
.setSuspendedApps(true)
|
||||||
|
)
|
||||||
|
.setGrid(
|
||||||
|
Settings.GridSettings.newBuilder()
|
||||||
|
.setColumnCount(context.resources.getInteger(R.integer.config_columnCount))
|
||||||
|
.build()
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
@ -74,19 +74,6 @@ class LauncherPreferences(val context: Application, version: Int = 3) {
|
|||||||
|
|
||||||
var easterEggEnabled by BooleanPreference("easter_egg", default = false)
|
var easterEggEnabled by BooleanPreference("easter_egg", default = false)
|
||||||
|
|
||||||
var gridColumnCount by IntPreference("grid_column_count", default = context.resources.getInteger(R.integer.config_columnCount))
|
|
||||||
|
|
||||||
|
|
||||||
fun doOnPreferenceChange(vararg keys: String, action: (String) -> Unit): () -> Unit {
|
|
||||||
val listener = { _: SharedPreferences, key: String ->
|
|
||||||
if (keys.contains(key)) action(key)
|
|
||||||
}
|
|
||||||
preferences.registerOnSharedPreferenceChangeListener(listener)
|
|
||||||
return {
|
|
||||||
preferences.unregisterOnSharedPreferenceChangeListener(listener)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
lateinit var instance: LauncherPreferences
|
lateinit var instance: LauncherPreferences
|
||||||
fun initialize(app: Application) {
|
fun initialize(app: Application) {
|
||||||
|
|||||||
@ -117,4 +117,9 @@ message Settings {
|
|||||||
}
|
}
|
||||||
BadgeSettings badges = 18;
|
BadgeSettings badges = 18;
|
||||||
|
|
||||||
|
message GridSettings {
|
||||||
|
uint32 column_count = 1;
|
||||||
|
}
|
||||||
|
GridSettings grid = 19;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -6,36 +6,61 @@ import android.util.AttributeSet
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.children
|
import androidx.core.view.children
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.ListUpdateCallback
|
import androidx.recyclerview.widget.ListUpdateCallback
|
||||||
import de.mm20.launcher2.ktx.ceilToInt
|
import de.mm20.launcher2.ktx.ceilToInt
|
||||||
|
import de.mm20.launcher2.ktx.lifecycleOwner
|
||||||
import de.mm20.launcher2.ktx.lifecycleScope
|
import de.mm20.launcher2.ktx.lifecycleScope
|
||||||
import de.mm20.launcher2.legacy.helper.ActivityStarter
|
import de.mm20.launcher2.legacy.helper.ActivityStarter
|
||||||
import de.mm20.launcher2.legacy.helper.ActivityStarterCallback
|
import de.mm20.launcher2.legacy.helper.ActivityStarterCallback
|
||||||
|
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||||
import de.mm20.launcher2.preferences.LauncherPreferences
|
import de.mm20.launcher2.preferences.LauncherPreferences
|
||||||
import de.mm20.launcher2.search.data.Searchable
|
import de.mm20.launcher2.search.data.Searchable
|
||||||
import de.mm20.launcher2.ui.R
|
import de.mm20.launcher2.ui.R
|
||||||
import de.mm20.launcher2.ui.legacy.searchable.SearchableView
|
import de.mm20.launcher2.ui.legacy.searchable.SearchableView
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.channels.actor
|
import kotlinx.coroutines.channels.actor
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import org.koin.core.component.KoinComponent
|
||||||
|
import org.koin.core.component.inject
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class SearchGridView : ViewGroup, ActivityStarterCallback {
|
class SearchGridView : ViewGroup, ActivityStarterCallback, KoinComponent {
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
while (postponedDiffs.isNotEmpty()) {
|
while (postponedDiffs.isNotEmpty()) {
|
||||||
postponedDiffs.poll()?.let { applyDiff(it, true) }
|
postponedDiffs.poll()?.let { applyDiff(it, true) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val dataStore: LauncherDataStore by inject()
|
||||||
|
|
||||||
|
var job: Job? = null
|
||||||
|
override fun onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow()
|
||||||
|
job?.cancel()
|
||||||
|
lifecycleScope.launch {
|
||||||
|
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
dataStore.data.map { it.grid.columnCount }.distinctUntilChanged().collectLatest {
|
||||||
|
columnCount = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var columnCount: Int = 1
|
var columnCount: Int = 1
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value > 0) field = value
|
if (value > 0) {
|
||||||
|
field = value
|
||||||
|
requestLayout()
|
||||||
|
}
|
||||||
else throw IllegalArgumentException("columnCount must be positive (is $value)")
|
else throw IllegalArgumentException("columnCount must be positive (is $value)")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,8 +125,9 @@ class SearchGridView : ViewGroup, ActivityStarterCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
columnCount = LauncherPreferences.instance.gridColumnCount.takeIf { it > 1 }
|
columnCount = runBlocking {
|
||||||
?: context.resources.getInteger(R.integer.config_columnCount)
|
dataStore.data.map { it.grid.columnCount }.first().takeIf { it > 0 } ?: 5
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
|
|||||||
@ -45,6 +45,19 @@ fun AppearanceSettingsScreen() {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
PreferenceCategory(title = stringResource(R.string.preference_category_grid)) {
|
||||||
|
val columnCount by viewModel.columnCount.observeAsState()
|
||||||
|
ListPreference(
|
||||||
|
title = stringResource(R.string.preference_grid_column_count),
|
||||||
|
items = (3..8).map {
|
||||||
|
it.toString() to it
|
||||||
|
},
|
||||||
|
value = columnCount,
|
||||||
|
onValueChanged = {
|
||||||
|
if (it != null) viewModel.setColumnCount(it)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,4 +35,15 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val columnCount = dataStore.data.map { it.grid.columnCount }.asLiveData()
|
||||||
|
fun setColumnCount(columnCount: Int) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
dataStore.updateData {
|
||||||
|
it.toBuilder()
|
||||||
|
.setGrid(it.grid.toBuilder().setColumnCount(columnCount))
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user