Reorganize Searchable data types

This commit is contained in:
MM20
2022-10-12 20:36:39 +02:00
parent a01b0aa03d
commit bcda89c211
98 changed files with 817 additions and 738 deletions
@@ -1,15 +1,16 @@
package de.mm20.launcher2.favorites
import de.mm20.launcher2.database.entities.FavoritesItemEntity
import de.mm20.launcher2.search.PinnableSearchable
import de.mm20.launcher2.search.SearchableSerializer
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.search.Searchable
data class FavoritesItem(
val key: String,
/**
* null if searchable could not be deserialized (i.e. the app has been uninstalled)
*/
val searchable: Searchable?,
val searchable: PinnableSearchable?,
var launchCount: Int,
var pinPosition: Int,
var hidden: Boolean
@@ -5,11 +5,10 @@ import android.util.Log
import de.mm20.launcher2.crashreporter.CrashReporter
import de.mm20.launcher2.database.AppDatabase
import de.mm20.launcher2.database.entities.FavoritesItemEntity
import de.mm20.launcher2.ktx.ceilToInt
import de.mm20.launcher2.ktx.jsonObjectOf
import de.mm20.launcher2.search.PinnableSearchable
import de.mm20.launcher2.search.SearchableDeserializer
import de.mm20.launcher2.search.data.CalendarEvent
import de.mm20.launcher2.search.data.Searchable
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import org.json.JSONArray
@@ -34,47 +33,47 @@ interface FavoritesRepository {
automaticallySorted: Boolean = false,
frequentlyUsed: Boolean = false,
limit: Int = 100
): Flow<List<Searchable>>
): Flow<List<PinnableSearchable>>
fun getPinnedCalendarEvents(): Flow<List<Searchable>>
fun getPinnedCalendarEvents(): Flow<List<PinnableSearchable>>
fun getHiddenCalendarEventKeys(): Flow<List<String>>
fun isPinned(searchable: Searchable): Flow<Boolean>
fun pinItem(searchable: Searchable)
fun unpinItem(searchable: Searchable)
fun isHidden(searchable: Searchable): Flow<Boolean>
fun hideItem(searchable: Searchable)
fun unhideItem(searchable: Searchable)
fun incrementLaunchCounter(searchable: Searchable)
fun isPinned(searchable: PinnableSearchable): Flow<Boolean>
fun pinItem(searchable: PinnableSearchable)
fun unpinItem(searchable: PinnableSearchable)
fun isHidden(searchable: PinnableSearchable): Flow<Boolean>
fun hideItem(searchable: PinnableSearchable)
fun unhideItem(searchable: PinnableSearchable)
fun incrementLaunchCounter(searchable: PinnableSearchable)
fun updateFavorites(
manuallySorted: List<Searchable>,
automaticallySorted: List<Searchable>,
manuallySorted: List<PinnableSearchable>,
automaticallySorted: List<PinnableSearchable>,
)
fun getHiddenItems(): Flow<List<Searchable>>
fun getHiddenItems(): Flow<List<PinnableSearchable>>
fun getHiddenItemKeys(): Flow<List<String>>
/**
* Remove this item from the Searchable database
*/
fun remove(searchable: Searchable)
fun remove(searchable: PinnableSearchable)
/**
* Remove this item from favorites and reset launch counter
*/
fun removeFromFavorites(searchable: Searchable)
fun removeFromFavorites(searchable: PinnableSearchable)
/**
* 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
*/
fun save(searchable: Searchable)
fun save(searchable: PinnableSearchable)
/**
* Get items with the given keys from the favorites database.
* Items that don't exist in the database will not be returned.
*/
suspend fun getFromKeys(keys: List<String>): List<Searchable>
suspend fun getFromKeys(keys: List<String>): List<PinnableSearchable>
suspend fun export(toDir: File)
suspend fun import(fromDir: File)
@@ -101,7 +100,7 @@ internal class FavoritesRepositoryImpl(
automaticallySorted: Boolean,
frequentlyUsed: Boolean,
limit: Int
): Flow<List<Searchable>> {
): Flow<List<PinnableSearchable>> {
val dao = database.searchDao()
val entities = when {
includeTypes == null && excludeTypes == null -> dao.getFavorites(
@@ -150,11 +149,11 @@ internal class FavoritesRepositoryImpl(
return database.searchDao().getHiddenCalendarEventKeys()
}
override fun isPinned(searchable: Searchable): Flow<Boolean> {
override fun isPinned(searchable: PinnableSearchable): Flow<Boolean> {
return AppDatabase.getInstance(context).searchDao().isPinned(searchable.key)
}
override fun pinItem(searchable: Searchable) {
override fun pinItem(searchable: PinnableSearchable) {
scope.launch {
withContext(Dispatchers.IO) {
val dao = AppDatabase.getInstance(context).searchDao()
@@ -171,7 +170,7 @@ internal class FavoritesRepositoryImpl(
}
}
override fun unpinItem(searchable: Searchable) {
override fun unpinItem(searchable: PinnableSearchable) {
scope.launch {
withContext(Dispatchers.IO) {
AppDatabase.getInstance(context).searchDao().unpinFavorite(searchable.key)
@@ -179,11 +178,11 @@ internal class FavoritesRepositoryImpl(
}
}
override fun isHidden(searchable: Searchable): Flow<Boolean> {
override fun isHidden(searchable: PinnableSearchable): Flow<Boolean> {
return AppDatabase.getInstance(context).searchDao().isHidden(searchable.key)
}
override fun hideItem(searchable: Searchable) {
override fun hideItem(searchable: PinnableSearchable) {
scope.launch {
withContext(Dispatchers.IO) {
val dao = AppDatabase.getInstance(context).searchDao()
@@ -200,7 +199,7 @@ internal class FavoritesRepositoryImpl(
}
}
override fun unhideItem(searchable: Searchable) {
override fun unhideItem(searchable: PinnableSearchable) {
scope.launch {
withContext(Dispatchers.IO) {
AppDatabase.getInstance(context).searchDao().unhideItem(searchable.key)
@@ -208,7 +207,7 @@ internal class FavoritesRepositoryImpl(
}
}
override fun incrementLaunchCounter(searchable: Searchable) {
override fun incrementLaunchCounter(searchable: PinnableSearchable) {
scope.launch {
withContext(Dispatchers.IO) {
val item = FavoritesItem(searchable.key, searchable, 0, 0, false)
@@ -220,7 +219,7 @@ internal class FavoritesRepositoryImpl(
}
}
override fun getHiddenItems(): Flow<List<Searchable>> {
override fun getHiddenItems(): Flow<List<PinnableSearchable>> {
return database.searchDao().getHiddenItems().map {
it.mapNotNull { fromDatabaseEntity(it).searchable }
}
@@ -230,7 +229,7 @@ internal class FavoritesRepositoryImpl(
return database.searchDao().getHiddenItemKeys()
}
override fun remove(searchable: Searchable) {
override fun remove(searchable: PinnableSearchable) {
scope.launch {
withContext(Dispatchers.IO) {
database.searchDao().deleteByKey(searchable.key)
@@ -238,13 +237,13 @@ internal class FavoritesRepositoryImpl(
}
}
override fun removeFromFavorites(searchable: Searchable) {
override fun removeFromFavorites(searchable: PinnableSearchable) {
scope.launch {
database.searchDao().resetPinStatusAndLaunchCounter(searchable.key)
}
}
override fun save(searchable: Searchable) {
override fun save(searchable: PinnableSearchable) {
scope.launch {
withContext(Dispatchers.IO) {
val entity = FavoritesItem(
@@ -260,8 +259,8 @@ internal class FavoritesRepositoryImpl(
}
override fun updateFavorites(
manuallySorted: List<Searchable>,
automaticallySorted: List<Searchable>
manuallySorted: List<PinnableSearchable>,
automaticallySorted: List<PinnableSearchable>
) {
val dao = database.searchDao()
scope.launch {
@@ -321,7 +320,7 @@ internal class FavoritesRepositoryImpl(
}
}
override suspend fun getFromKeys(keys: List<String>): List<Searchable> {
override suspend fun getFromKeys(keys: List<String>): List<PinnableSearchable> {
val dao = database.searchDao()
return dao.getFromKeys(keys)
.mapNotNull { fromDatabaseEntity(it).searchable }
@@ -12,6 +12,7 @@ import de.mm20.launcher2.contacts.ContactSerializer
import de.mm20.launcher2.files.*
import de.mm20.launcher2.search.NullDeserializer
import de.mm20.launcher2.search.NullSerializer
import de.mm20.launcher2.search.Searchable
import de.mm20.launcher2.search.SearchableDeserializer
import de.mm20.launcher2.search.SearchableSerializer
import de.mm20.launcher2.search.data.*
@@ -1,14 +1,14 @@
package de.mm20.launcher2.favorites
import android.content.Context
import de.mm20.launcher2.search.PinnableSearchable
import de.mm20.launcher2.search.SearchableDeserializer
import de.mm20.launcher2.search.SearchableSerializer
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.search.Searchable
import de.mm20.launcher2.search.data.Tag
import org.json.JSONObject
class TagSerializer: SearchableSerializer {
override fun serialize(searchable: Searchable): String {
override fun serialize(searchable: PinnableSearchable): String {
searchable as Tag
val json = JSONObject()
json.put("tag", searchable.tag)
@@ -20,7 +20,7 @@ class TagSerializer: SearchableSerializer {
}
class TagDeserializer: SearchableDeserializer {
override fun deserialize(serialized: String): Searchable {
override fun deserialize(serialized: String): PinnableSearchable {
val json = JSONObject(serialized)
return Tag(json.getString("tag"))
@@ -1,20 +1,40 @@
package de.mm20.launcher2.search.data
import android.content.Context
import android.os.Bundle
import de.mm20.launcher2.icons.ColorLayer
import de.mm20.launcher2.icons.StaticLauncherIcon
import de.mm20.launcher2.icons.TextLayer
import de.mm20.launcher2.search.PinnableSearchable
import de.mm20.launcher2.search.Searchable
class Tag(
data class Tag(
val tag: String,
): Searchable() {
override val key: String = "tag://$tag"
override val labelOverride: String? = null
): PinnableSearchable {
override val domain: String = Domain
override val key: String = "$domain://$tag"
override val label: String = tag
override val preferDetailsOverLaunch: Boolean = true
override fun launch(context: Context, options: Bundle?): Boolean {
return false
}
override fun overrideLabel(label: String): PinnableSearchable {
return this.copy(labelOverride = label)
}
override fun getPlaceholderIcon(context: Context): StaticLauncherIcon {
return StaticLauncherIcon(
foregroundLayer = TextLayer("#"),
backgroundLayer = ColorLayer()
)
}
companion object {
const val Domain = "tag"
}
}