Add preferences for frequently used items in favorites

This commit is contained in:
MM20 2022-09-20 20:23:02 +02:00
parent d96019e063
commit 93f1f41d65
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
6 changed files with 175 additions and 40 deletions

View File

@ -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<DataMigration<Settings>> { internal fun getMigrations(context: Context): List<DataMigration<Settings>> {
return listOf( return listOf(
@ -35,5 +35,6 @@ internal fun getMigrations(context: Context): List<DataMigration<Settings>> {
Migration_6_7(), Migration_6_7(),
Migration_7_8(), Migration_7_8(),
Migration_8_9(), Migration_8_9(),
Migration_9_10(),
) )
} }

View File

@ -57,6 +57,8 @@ fun createFactorySettings(context: Context): Settings {
Settings.FavoritesSettings Settings.FavoritesSettings
.newBuilder() .newBuilder()
.setEnabled(true) .setEnabled(true)
.setFrequentlyUsed(true)
.setFrequentlyUsedRows(1)
) )
.setFileSearch( .setFileSearch(
Settings.FilesSearchSettings Settings.FilesSearchSettings

View File

@ -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)
)
}
}

View File

@ -126,6 +126,8 @@ message Settings {
message FavoritesSettings { message FavoritesSettings {
bool enabled = 1; bool enabled = 1;
bool frequently_used = 2;
int32 frequently_used_rows = 3;
} }
FavoritesSettings favorites = 8; FavoritesSettings favorites = 8;

View File

@ -7,6 +7,7 @@ import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.IntentSenderRequest import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells 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.Icons
import androidx.compose.material.icons.rounded.Add import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.Delete import androidx.compose.material.icons.rounded.Delete
import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
@ -184,7 +186,10 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM) {
onDismissRequest = { contextMenuItemKey = null }) { onDismissRequest = { contextMenuItemKey = null }) {
DropdownMenuItem( DropdownMenuItem(
leadingIcon = { leadingIcon = {
Icon(imageVector = Icons.Rounded.Delete, contentDescription = null) Icon(
imageVector = Icons.Rounded.Delete,
contentDescription = null
)
}, },
text = { text = {
Text(stringResource(R.string.menu_remove)) Text(stringResource(R.string.menu_remove))
@ -203,43 +208,122 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM) {
FavoritesSheetSection.AutomaticallySorted -> R.string.edit_favorites_dialog_pinned_unsorted FavoritesSheetSection.AutomaticallySorted -> R.string.edit_favorites_dialog_pinned_unsorted
FavoritesSheetSection.FrequentlyUsed -> R.string.edit_favorites_dialog_unpinned FavoritesSheetSection.FrequentlyUsed -> R.string.edit_favorites_dialog_unpinned
} }
Row( var showSettings by remember { mutableStateOf(false) }
modifier = Modifier.padding(vertical = 8.dp), Column(modifier = Modifier.fillMaxWidth()) {
verticalAlignment = Alignment.CenterVertically Row(
) { modifier = Modifier.padding(vertical = 8.dp),
Text( verticalAlignment = Alignment.CenterVertically
modifier = Modifier ) {
.weight(1f) Text(
.padding(end = 16.dp), modifier = Modifier
maxLines = 1, .weight(1f)
overflow = TextOverflow.Ellipsis, .padding(end = 16.dp),
text = stringResource(id = title), maxLines = 1,
style = MaterialTheme.typography.titleSmall, overflow = TextOverflow.Ellipsis,
color = MaterialTheme.colorScheme.secondary 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) { val frequentlyUsedRows by viewModel.frequentlyUsedRows.observeAsState(1)
/*FilledTonalIconToggleButton( AnimatedVisibility(showSettings) {
modifier = Modifier.offset(x = 4.dp), Surface(
checked = false, modifier = Modifier
onCheckedChange = {}) { .fillMaxWidth()
Icon( .padding(bottom = 16.dp),
imageVector = Icons.Rounded.Settings, color = MaterialTheme.colorScheme.surfaceVariant,
contentDescription = null shape = MaterialTheme.shapes.small
) ) {
}*/ Column(
} else { modifier = Modifier.fillMaxWidth()
FilledTonalIconButton( ) {
modifier = Modifier.offset(x = 4.dp), Row(
onClick = { modifier = Modifier
viewModel.pickShortcut(it.section) .fillMaxWidth()
}) { .padding(vertical = 4.dp)
Icon( .padding(horizontal = 16.dp),
imageVector = Icons.Rounded.Add, verticalAlignment = Alignment.CenterVertically
contentDescription = null ) {
) 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 -> { is FavoritesSheetGridItem.EmptySection -> {
val shape = MaterialTheme.shapes.medium val shape = MaterialTheme.shapes.medium

View File

@ -2,12 +2,12 @@ package de.mm20.launcher2.ui.launcher.modals
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.Intent.ShortcutIconResource
import android.content.pm.LauncherApps
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.lazy.grid.LazyGridItemInfo import androidx.compose.foundation.lazy.grid.LazyGridItemInfo
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.appshortcuts.AppShortcutRepository import de.mm20.launcher2.appshortcuts.AppShortcutRepository
import de.mm20.launcher2.badges.Badge import de.mm20.launcher2.badges.Badge
import de.mm20.launcher2.badges.BadgeRepository 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.icons.LauncherIcon
import de.mm20.launcher2.permissions.PermissionGroup import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager 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.AppShortcut
import de.mm20.launcher2.search.data.LauncherShortcut
import de.mm20.launcher2.search.data.LegacyShortcut
import de.mm20.launcher2.search.data.Searchable import de.mm20.launcher2.search.data.Searchable
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow 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.KoinComponent
import org.koin.core.component.inject import org.koin.core.component.inject
@ -33,6 +34,7 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent {
private val iconRepository: IconRepository by inject() private val iconRepository: IconRepository by inject()
private val badgeRepository: BadgeRepository by inject() private val badgeRepository: BadgeRepository by inject()
private val permissionsManager: PermissionsManager by inject() private val permissionsManager: PermissionsManager by inject()
private val dataStore: LauncherDataStore by inject()
val gridItems = MutableLiveData<List<FavoritesSheetGridItem>>(emptyList()) val gridItems = MutableLiveData<List<FavoritesSheetGridItem>>(emptyList())
@ -204,7 +206,8 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent {
fun remove(key: String) { fun remove(key: String) {
val gridItems = gridItems.value?.toMutableList() ?: return 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) { if (item != null) {
repository.removeFromFavorites(item.item) repository.removeFromFavorites(item.item)
gridItems.remove(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()
}
}
}
} }