From 93f1f41d650e8802df78f35458a82de998556fc0 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Tue, 20 Sep 2022 20:23:02 +0200 Subject: [PATCH] Add preferences for frequently used items in favorites --- .../mm20/launcher2/preferences/DataStore.kt | 3 +- .../de/mm20/launcher2/preferences/Defaults.kt | 2 + .../preferences/migrations/Migration_9_10.kt | 13 ++ preferences/src/main/proto/settings.proto | 2 + .../ui/launcher/modals/EditFavoritesSheet.kt | 152 ++++++++++++++---- .../launcher/modals/EditFavoritesSheetVM.kt | 43 ++++- 6 files changed, 175 insertions(+), 40 deletions(-) create mode 100644 preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_9_10.kt diff --git a/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt b/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt index d4c4cb34..bd70628d 100644 --- a/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt +++ b/preferences/src/main/java/de/mm20/launcher2/preferences/DataStore.kt @@ -22,7 +22,7 @@ internal val Context.dataStore: LauncherDataStore by dataStore( } ) -internal const val SchemaVersion = 9 +internal const val SchemaVersion = 10 internal fun getMigrations(context: Context): List> { return listOf( @@ -35,5 +35,6 @@ internal fun getMigrations(context: Context): List> { Migration_6_7(), Migration_7_8(), Migration_8_9(), + Migration_9_10(), ) } \ No newline at end of file diff --git a/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt b/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt index c205e0ec..4623665a 100644 --- a/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt +++ b/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt @@ -57,6 +57,8 @@ fun createFactorySettings(context: Context): Settings { Settings.FavoritesSettings .newBuilder() .setEnabled(true) + .setFrequentlyUsed(true) + .setFrequentlyUsedRows(1) ) .setFileSearch( Settings.FilesSearchSettings diff --git a/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_9_10.kt b/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_9_10.kt new file mode 100644 index 00000000..949fffa2 --- /dev/null +++ b/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_9_10.kt @@ -0,0 +1,13 @@ +package de.mm20.launcher2.preferences.migrations + +import de.mm20.launcher2.preferences.Settings + +class Migration_9_10: VersionedMigration(9, 10) { + override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder { + return builder.setFavorites( + builder.favorites.toBuilder() + .setFrequentlyUsed(true) + .setFrequentlyUsedRows(1) + ) + } +} \ No newline at end of file diff --git a/preferences/src/main/proto/settings.proto b/preferences/src/main/proto/settings.proto index a2957d4d..21776fde 100644 --- a/preferences/src/main/proto/settings.proto +++ b/preferences/src/main/proto/settings.proto @@ -126,6 +126,8 @@ message Settings { message FavoritesSettings { bool enabled = 1; + bool frequently_used = 2; + int32 frequently_used_rows = 3; } FavoritesSettings favorites = 8; diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/EditFavoritesSheet.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/EditFavoritesSheet.kt index 61e60fef..7ecee11a 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/EditFavoritesSheet.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/EditFavoritesSheet.kt @@ -7,6 +7,7 @@ import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.IntentSenderRequest import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity +import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.grid.GridCells @@ -15,6 +16,7 @@ import androidx.compose.foundation.lazy.items import androidx.compose.material.icons.Icons import androidx.compose.material.icons.rounded.Add import androidx.compose.material.icons.rounded.Delete +import androidx.compose.material.icons.rounded.Settings import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState @@ -184,7 +186,10 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM) { onDismissRequest = { contextMenuItemKey = null }) { DropdownMenuItem( leadingIcon = { - Icon(imageVector = Icons.Rounded.Delete, contentDescription = null) + Icon( + imageVector = Icons.Rounded.Delete, + contentDescription = null + ) }, text = { Text(stringResource(R.string.menu_remove)) @@ -203,43 +208,122 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM) { FavoritesSheetSection.AutomaticallySorted -> R.string.edit_favorites_dialog_pinned_unsorted FavoritesSheetSection.FrequentlyUsed -> R.string.edit_favorites_dialog_unpinned } - Row( - modifier = Modifier.padding(vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Text( - modifier = Modifier - .weight(1f) - .padding(end = 16.dp), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - text = stringResource(id = title), - style = MaterialTheme.typography.titleSmall, - color = MaterialTheme.colorScheme.secondary + var showSettings by remember { mutableStateOf(false) } + Column(modifier = Modifier.fillMaxWidth()) { + Row( + modifier = Modifier.padding(vertical = 8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + modifier = Modifier + .weight(1f) + .padding(end = 16.dp), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + text = stringResource(id = title), + style = MaterialTheme.typography.titleSmall, + color = MaterialTheme.colorScheme.secondary + ) + if (it.section == FavoritesSheetSection.FrequentlyUsed) { + FilledTonalIconToggleButton( + modifier = Modifier.offset(x = 4.dp), + checked = showSettings, + onCheckedChange = { showSettings = it }) { + Icon( + imageVector = Icons.Rounded.Settings, + contentDescription = null + ) + } + } else { + FilledTonalIconButton( + modifier = Modifier.offset(x = 4.dp), + onClick = { + viewModel.pickShortcut(it.section) + }) { + Icon( + imageVector = Icons.Rounded.Add, + contentDescription = null + ) + } + } + } + val enableFrequentlyUsed by viewModel.enableFrequentlyUsed.observeAsState( + null ) - if (it.section == FavoritesSheetSection.FrequentlyUsed) { - /*FilledTonalIconToggleButton( - modifier = Modifier.offset(x = 4.dp), - checked = false, - onCheckedChange = {}) { - Icon( - imageVector = Icons.Rounded.Settings, - contentDescription = null - ) - }*/ - } else { - FilledTonalIconButton( - modifier = Modifier.offset(x = 4.dp), - onClick = { - viewModel.pickShortcut(it.section) - }) { - Icon( - imageVector = Icons.Rounded.Add, - contentDescription = null - ) + val frequentlyUsedRows by viewModel.frequentlyUsedRows.observeAsState(1) + AnimatedVisibility(showSettings) { + Surface( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp), + color = MaterialTheme.colorScheme.surfaceVariant, + shape = MaterialTheme.shapes.small + ) { + Column( + modifier = Modifier.fillMaxWidth() + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 4.dp) + .padding(horizontal = 16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + modifier = Modifier + .weight(1f) + .padding(end = 16.dp), + text = "Show in favorites", + style = MaterialTheme.typography.labelMedium + ) + Switch( + checked = enableFrequentlyUsed == true, + onCheckedChange = { + viewModel.setFrequentlyUsed(it) + } + ) + } + Column( + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp) + .padding(horizontal = 16.dp), + horizontalAlignment = Alignment.Start + ) { + Text( + modifier = Modifier.fillMaxWidth(), + text = "Number of rows", + style = MaterialTheme.typography.labelMedium + ) + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + Slider( + modifier = Modifier.weight(1f).padding(end = 16.dp), + value = frequentlyUsedRows.toFloat(), + colors = SliderDefaults.colors( + inactiveTrackColor = MaterialTheme.colorScheme.onSurfaceVariant + ), + onValueChange = { + viewModel.setFrequentlyUsedRows(it.roundToInt()) + }, + steps = 2, + valueRange = 1f..4f + ) + Text( + text = frequentlyUsedRows.toString(), + modifier = Modifier.width(52.dp).padding(4.dp), + style = MaterialTheme.typography.labelMedium, + textAlign = TextAlign.Center + ) + } + } + } } } } + } is FavoritesSheetGridItem.EmptySection -> { val shape = MaterialTheme.shapes.medium diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/EditFavoritesSheetVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/EditFavoritesSheetVM.kt index b74f8933..addad655 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/EditFavoritesSheetVM.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/modals/EditFavoritesSheetVM.kt @@ -2,12 +2,12 @@ package de.mm20.launcher2.ui.launcher.modals import android.content.Context import android.content.Intent -import android.content.Intent.ShortcutIconResource -import android.content.pm.LauncherApps import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.lazy.grid.LazyGridItemInfo import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import androidx.lifecycle.asLiveData +import androidx.lifecycle.viewModelScope import de.mm20.launcher2.appshortcuts.AppShortcutRepository import de.mm20.launcher2.badges.Badge import de.mm20.launcher2.badges.BadgeRepository @@ -16,13 +16,14 @@ import de.mm20.launcher2.icons.IconRepository import de.mm20.launcher2.icons.LauncherIcon import de.mm20.launcher2.permissions.PermissionGroup import de.mm20.launcher2.permissions.PermissionsManager +import de.mm20.launcher2.preferences.LauncherDataStore import de.mm20.launcher2.search.data.AppShortcut -import de.mm20.launcher2.search.data.LauncherShortcut -import de.mm20.launcher2.search.data.LegacyShortcut import de.mm20.launcher2.search.data.Searchable import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch import org.koin.core.component.KoinComponent import org.koin.core.component.inject @@ -33,6 +34,7 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent { private val iconRepository: IconRepository by inject() private val badgeRepository: BadgeRepository by inject() private val permissionsManager: PermissionsManager by inject() + private val dataStore: LauncherDataStore by inject() val gridItems = MutableLiveData>(emptyList()) @@ -204,7 +206,8 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent { fun remove(key: String) { val gridItems = gridItems.value?.toMutableList() ?: return - val item = gridItems.find { it is FavoritesSheetGridItem.Favorite && it.item.key == key } as FavoritesSheetGridItem.Favorite? + val item = + gridItems.find { it is FavoritesSheetGridItem.Favorite && it.item.key == key } as FavoritesSheetGridItem.Favorite? if (item != null) { repository.removeFromFavorites(item.item) gridItems.remove(item) @@ -212,5 +215,35 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent { } } + val enableFrequentlyUsed = dataStore.data.map { it.favorites.frequentlyUsed }.asLiveData() + fun setFrequentlyUsed(frequentlyUsed: Boolean) { + viewModelScope.launch { + dataStore.updateData { + it.toBuilder() + .setFavorites( + it.favorites + .toBuilder() + .setFrequentlyUsed(frequentlyUsed) + ) + .build() + } + } + } + + val frequentlyUsedRows = dataStore.data.map { it.favorites.frequentlyUsedRows }.asLiveData() + fun setFrequentlyUsedRows(frequentlyUsedRows: Int) { + viewModelScope.launch { + dataStore.updateData { + it.toBuilder() + .setFavorites( + it.favorites + .toBuilder() + .setFrequentlyUsedRows(frequentlyUsedRows) + ) + .build() + } + } + } + } \ No newline at end of file