From f04f9be4b67c9a065be197ba31bc9d09f637da69 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Thu, 15 Sep 2022 20:27:21 +0200 Subject: [PATCH] Refactor favorites DAO --- .../de/mm20/launcher2/database/SearchDao.kt | 47 +++++++++++++++---- .../favorites/FavoritesRepository.kt | 46 +++++++++++------- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/database/src/main/java/de/mm20/launcher2/database/SearchDao.kt b/database/src/main/java/de/mm20/launcher2/database/SearchDao.kt index 7194e5e7..c5443b8c 100644 --- a/database/src/main/java/de/mm20/launcher2/database/SearchDao.kt +++ b/database/src/main/java/de/mm20/launcher2/database/SearchDao.kt @@ -1,6 +1,5 @@ package de.mm20.launcher2.database -import androidx.lifecycle.LiveData import androidx.room.* import de.mm20.launcher2.database.entities.FavoritesItemEntity import de.mm20.launcher2.database.entities.WebsearchEntity @@ -18,11 +17,46 @@ interface SearchDao { @Insert(onConflict = OnConflictStrategy.IGNORE) fun insertSkipExisting(items: FavoritesItemEntity) - @Query("SELECT * FROM Searchable WHERE pinned > 0 AND (NOT :excludeCalendarEvents OR NOT `key` LIKE 'calendar://%') ORDER BY pinned DESC, launchCount DESC LIMIT :limit") - fun getFavorites(excludeCalendarEvents: Boolean = false, limit: Int): Flow> - @Query("SELECT * FROM Searchable WHERE pinned > 0 AND `key` LIKE 'calendar://%' ORDER BY pinned DESC, launchCount DESC") - fun getPinnedCalendarEvents(): Flow> + @Query("SELECT * FROM Searchable " + + "WHERE ((:manuallySorted AND pinned > 1) OR " + + "(:automaticallySorted AND pinned = 1) OR" + + "(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" + + ") ORDER BY pinned DESC, launchCount DESC LIMIT :limit") + fun getFavorites( + manuallySorted: Boolean = false, + automaticallySorted: Boolean = false, + frequentlyUsed: Boolean = false, + limit: Int, + ): Flow> + + @Query("SELECT * FROM Searchable " + + "WHERE SUBSTR(`key`, 0, INSTR(`key`, '://')) IN (:includeTypes) AND (" + + "(:manuallySorted AND pinned > 1) OR " + + "(:automaticallySorted AND pinned = 1) OR" + + "(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" + + ") ORDER BY pinned DESC, launchCount DESC LIMIT :limit") + fun getFavoritesWithTypes( + includeTypes: List, + manuallySorted: Boolean = false, + automaticallySorted: Boolean = false, + frequentlyUsed: Boolean = false, + limit: Int, + ): Flow> + + @Query("SELECT * FROM Searchable " + + "WHERE SUBSTR(`key`, 0, INSTR(`key`, '://')) NOT IN (:excludeTypes) AND (" + + "(:manuallySorted AND pinned > 1) OR " + + "(:automaticallySorted AND pinned = 1) OR" + + "(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" + + ") ORDER BY pinned DESC, launchCount DESC LIMIT :limit") + fun getFavoritesWithoutTypes( + excludeTypes: List, + manuallySorted: Boolean = false, + automaticallySorted: Boolean = false, + frequentlyUsed: Boolean = false, + limit: Int, + ): Flow> @Query("SELECT `key` FROM Searchable WHERE hidden = 1 AND `key` LIKE 'calendar://%'") fun getHiddenCalendarEventKeys(): Flow> @@ -112,9 +146,6 @@ interface SearchDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertReplaceExisting(toDatabaseEntity: FavoritesItemEntity) - @Query("SELECT * FROM Searchable WHERE (pinned > 0 OR launchCount > 0) AND hidden = 0 ORDER BY pinned DESC, launchCount DESC") - fun getAllFavoriteItems(): List - @Transaction fun saveFavorites(favorites: List) { deleteAllFavorites() diff --git a/favorites/src/main/java/de/mm20/launcher2/favorites/FavoritesRepository.kt b/favorites/src/main/java/de/mm20/launcher2/favorites/FavoritesRepository.kt index 4708e6a2..3ed79100 100644 --- a/favorites/src/main/java/de/mm20/launcher2/favorites/FavoritesRepository.kt +++ b/favorites/src/main/java/de/mm20/launcher2/favorites/FavoritesRepository.kt @@ -10,10 +10,7 @@ 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.Flow -import kotlinx.coroutines.flow.channelFlow -import kotlinx.coroutines.flow.collectLatest -import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.* import org.json.JSONArray import org.json.JSONException import org.koin.core.component.KoinComponent @@ -35,7 +32,6 @@ interface FavoritesRepository { fun hideItem(searchable: Searchable) fun unhideItem(searchable: Searchable) fun incrementLaunchCounter(searchable: Searchable) - suspend fun getAllFavoriteItems(): List fun saveFavorites(favorites: List) fun getHiddenItems(): Flow> fun getHiddenItemKeys(): Flow> @@ -73,7 +69,21 @@ internal class FavoritesRepositoryImpl( withContext(Dispatchers.IO) { val dao = database.searchDao() val pinnedFavorites = - dao.getFavorites(excludeCalendarEvents, columns * (maxRows ?: 20)).map { + if (excludeCalendarEvents) { + dao.getFavoritesWithoutTypes( + excludeTypes = listOf("calendar"), + manuallySorted = true, + automaticallySorted = true, + frequentlyUsed = false, + limit = columns * (maxRows ?: 20) + ) + } else { + dao.getFavorites( + manuallySorted = true, + automaticallySorted = true, + frequentlyUsed = false, + limit = columns * (maxRows ?: 20)) + }.map { it.mapNotNull { val item = fromDatabaseEntity(it).searchable if (item == null) { @@ -86,9 +96,12 @@ internal class FavoritesRepositoryImpl( pinnedFavorites.collectLatest { pinned -> var favCount = (pinned.size.toDouble() / columns).ceilToInt() * columns if (pinned.size < columns) favCount += columns - val autoFavs = dao.getAutoFavorites( - favCount.coerceAtMost((maxRows ?: 20) * columns) - pinned.size - ).mapNotNull { + val autoFavs = dao.getFavorites( + manuallySorted = false, + automaticallySorted = false, + frequentlyUsed = true, + limit = favCount.coerceAtMost((maxRows ?: 20) * columns) - pinned.size + ).first().mapNotNull { val item = fromDatabaseEntity(it).searchable if (item == null) { dao.deleteByKey(it.key) @@ -101,7 +114,12 @@ internal class FavoritesRepositoryImpl( } override fun getPinnedCalendarEvents(): Flow> { - return database.searchDao().getPinnedCalendarEvents().map { + return database.searchDao().getFavoritesWithTypes( + includeTypes = listOf("calendar"), + automaticallySorted = true, + manuallySorted = true, + limit = 50 + ).map { it.mapNotNull { fromDatabaseEntity(it).searchable as? CalendarEvent } } } @@ -180,14 +198,6 @@ internal class FavoritesRepositoryImpl( } } - override suspend fun getAllFavoriteItems(): List { - return withContext(Dispatchers.IO) { - AppDatabase.getInstance(context).searchDao().getAllFavoriteItems().mapNotNull { - fromDatabaseEntity(it).takeIf { it.searchable != null } - } - } - } - override fun saveFavorites(favorites: List) { scope.launch { withContext(Dispatchers.IO) {