Add the ability to explicitely remove items from frequently used items

Close #113
This commit is contained in:
MM20 2022-09-19 22:57:57 +02:00
parent 91e68cd8d3
commit db7db74d2d
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
5 changed files with 90 additions and 18 deletions

View File

@ -160,4 +160,7 @@ interface SearchDao {
@Query("UPDATE Searchable SET `pinned` = 0")
fun unpinAll()
@Query("UPDATE Searchable Set `pinned` = 0, `launchCount` = 0 WHERE `key` = :key")
suspend fun resetPinStatusAndLaunchCounter(key: String)
}

View File

@ -54,14 +54,23 @@ interface FavoritesRepository {
fun unhideItem(searchable: Searchable)
fun incrementLaunchCounter(searchable: Searchable)
fun updateFavorites(
manuallySorted: List<Searchable>,
automaticallySorted: List<Searchable>,
manuallySorted: List<Searchable>,
automaticallySorted: List<Searchable>,
)
fun getHiddenItems(): Flow<List<Searchable>>
fun getHiddenItemKeys(): Flow<List<String>>
/**
* Remove this item from the Searchable database
*/
fun remove(searchable: Searchable)
/**
* Remove this item from favorites and reset launch counter
*/
fun removeFromFavorites(searchable: Searchable)
/**
* Ensure that this searchable exists in the Favorites table.
* If it doesn't exist, insert it with 0 launch count, not pinned and not hidden
@ -287,6 +296,12 @@ internal class FavoritesRepositoryImpl(
}
}
override fun removeFromFavorites(searchable: Searchable) {
scope.launch {
database.searchDao().resetPinStatusAndLaunchCounter(searchable.key)
}
}
override fun save(searchable: Searchable) {
scope.launch {
withContext(Dispatchers.IO) {
@ -322,17 +337,18 @@ internal class FavoritesRepositoryImpl(
entity.pinPosition = manuallySorted.size - index + 1
entity
}
val updatedAutomaticallySorted = automaticallySorted.mapIndexedNotNull { index, searchable ->
val entity = entities.find { searchable.key == it.key } ?: FavoritesItem(
key = searchable.key,
searchable = searchable,
launchCount = 0,
pinPosition = 0,
hidden = false,
).toDatabaseEntity() ?: return@mapIndexedNotNull null
entity.pinPosition = 1
entity
}
val updatedAutomaticallySorted =
automaticallySorted.mapIndexedNotNull { index, searchable ->
val entity = entities.find { searchable.key == it.key } ?: FavoritesItem(
key = searchable.key,
searchable = searchable,
launchCount = 0,
pinPosition = 0,
hidden = false,
).toDatabaseEntity() ?: return@mapIndexedNotNull null
entity.pinPosition = 1
entity
}
database.runInTransaction {
dao.unpinAll()
dao.insertAllReplaceExisting(updatedManuallySorted)
@ -439,7 +455,10 @@ internal class FavoritesRepositoryImpl(
if (item.searchable == null || item.searchable.key != item.key) {
removeInvalidItem(item.key)
removed++
Log.i("MM20", "SearchableDatabase cleanup: removed invalid item ${item.key}")
Log.i(
"MM20",
"SearchableDatabase cleanup: removed invalid item ${item.key}"
)
}
}
page++

View File

@ -31,6 +31,7 @@ import kotlin.coroutines.coroutineContext
fun rememberLazyDragAndDropGridState(
gridState: LazyGridState = rememberLazyGridState(),
onDragStart: (item: LazyGridItemInfo) -> Boolean = { true },
onDrag: (item: LazyGridItemInfo, offset: Offset) -> Unit = {_, _ ->},
onDragEnd: (item: LazyGridItemInfo) -> Unit = {},
onDragCancel: (item: LazyGridItemInfo) -> Unit = {},
onItemMove: (from: LazyGridItemInfo, to: LazyGridItemInfo) -> Unit
@ -39,6 +40,7 @@ fun rememberLazyDragAndDropGridState(
LazyDragAndDropGridState(
gridState,
onDragStart,
onDrag,
onDragEnd,
onDragCancel,
onItemMove
@ -49,6 +51,7 @@ fun rememberLazyDragAndDropGridState(
data class LazyDragAndDropGridState(
val gridState: LazyGridState,
val onDragStart: (item: LazyGridItemInfo) -> Boolean = { true },
val onDrag: (item: LazyGridItemInfo, offset: Offset) -> Unit = {_, _ ->},
val onDragEnd: (item: LazyGridItemInfo) -> Unit = {},
val onDragCancel: (item: LazyGridItemInfo) -> Unit = {},
val onItemMove: (from: LazyGridItemInfo, to: LazyGridItemInfo) -> Unit
@ -259,7 +262,7 @@ fun Modifier.dragAndDrop(
).contains(draggedCenter)
}
if (dragOver != null && dragOver.key != state.draggedItem?.key) {
if (dragOver != null && dragOver.key != draggedItem.key) {
scope.launch {
state.attemptMove(dragOver)
}
@ -280,6 +283,8 @@ fun Modifier.dragAndDrop(
} else {
state.endScrolling()
}
state.draggedItemOffset?.let { state.onDrag(draggedItem, it) }
}
},
onDragCancel = {

View File

@ -14,6 +14,7 @@ import androidx.compose.foundation.lazy.grid.GridItemSpan
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.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
@ -112,9 +113,23 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM) {
val items by viewModel.gridItems.observeAsState(emptyList())
val columns = LocalGridColumns.current
var contextMenuItemKey by remember { mutableStateOf<String?>(null) }
val contextMenuCloseDistance = 8.dp.toPixels()
val state = rememberLazyDragAndDropGridState(
onDragStart = {
items.getOrNull(it.index) is FavoritesSheetGridItem.Favorite
val item = items.getOrNull(it.index)
if (item !is FavoritesSheetGridItem.Favorite) return@rememberLazyDragAndDropGridState false
contextMenuItemKey = item.item.key
true
},
onDrag = { _, offset ->
if (offset.getDistanceSquared() > contextMenuCloseDistance) {
contextMenuItemKey = null
}
}
) { from, to ->
viewModel.moveItem(from, to)
@ -163,6 +178,23 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM) {
icon = icon,
badge = badge
)
if (contextMenuItemKey == it.item.key) {
DropdownMenu(
expanded = true,
onDismissRequest = { contextMenuItemKey = null }) {
DropdownMenuItem(
leadingIcon = {
Icon(imageVector = Icons.Rounded.Delete, contentDescription = null)
},
text = {
Text("Remove")
}, onClick = {
contextMenuItemKey?.let { viewModel.remove(it) }
contextMenuItemKey = null
}
)
}
}
}
}
is FavoritesSheetGridItem.Divider -> {
@ -331,8 +363,11 @@ fun ShortcutPicker(viewModel: EditFavoritesSheetVM) {
.fillMaxWidth()
.padding(vertical = 4.dp),
onClick = {
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
val sender = launcherApps.getShortcutConfigActivityIntent(it.launcherActivityInfo) ?: return@OutlinedCard
val launcherApps =
context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
val sender =
launcherApps.getShortcutConfigActivityIntent(it.launcherActivityInfo)
?: return@OutlinedCard
activityLauncher.launch(IntentSenderRequest.Builder(sender).build(), null)
}) {
Row(

View File

@ -202,5 +202,15 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent {
createShortcutTarget.value = null
}
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?
if (item != null) {
repository.removeFromFavorites(item.item)
gridItems.remove(item)
this.gridItems.value = gridItems
}
}
}