Delete all search result data upon exiting search mode

MAILANDR-2511: search no results issue
This commit is contained in:
Rok Oblak
2025-03-05 17:23:46 +07:00
committed by MargeBot
parent 5d996a914f
commit ee15336dfc
11 changed files with 47 additions and 9 deletions
@@ -88,6 +88,7 @@ import ch.protonmail.android.mailmessage.domain.model.LabelSelectionList
import ch.protonmail.android.mailmessage.domain.model.MessageId
import ch.protonmail.android.mailmessage.domain.model.UnreadCounter
import ch.protonmail.android.mailmessage.domain.usecase.DeleteMessages
import ch.protonmail.android.mailmessage.domain.usecase.DeleteSearchResults
import ch.protonmail.android.mailmessage.domain.usecase.GetMessagesWithLabels
import ch.protonmail.android.mailmessage.domain.usecase.MarkMessagesAsRead
import ch.protonmail.android.mailmessage.domain.usecase.MarkMessagesAsUnread
@@ -184,6 +185,7 @@ class MailboxViewModel @Inject constructor(
private val unStarConversations: UnStarConversations,
private val mailboxReducer: MailboxReducer,
private val dispatchersProvider: DispatcherProvider,
private val deleteSearchResults: DeleteSearchResults,
private val observePrimaryUserAccountStorageStatus: ObservePrimaryUserAccountStorageStatus,
private val shouldUpgradeStorage: ShouldUpgradeStorage,
private val shouldShowRatingBooster: ShouldShowRatingBooster,
@@ -420,7 +422,9 @@ class MailboxViewModel @Inject constructor(
emitNewStateFrom(viewAction)
}
private fun handleExitSearchMode(viewAction: MailboxViewAction) {
private suspend fun handleExitSearchMode(viewAction: MailboxViewAction) {
val user = primaryUserId.filterNotNull().first()
deleteSearchResults(user)
emitNewStateFrom(viewAction)
}
@@ -105,6 +105,7 @@ import ch.protonmail.android.mailmessage.domain.model.MessageWithLabels
import ch.protonmail.android.mailmessage.domain.sample.MessageIdSample
import ch.protonmail.android.mailmessage.domain.sample.MessageSample
import ch.protonmail.android.mailmessage.domain.usecase.DeleteMessages
import ch.protonmail.android.mailmessage.domain.usecase.DeleteSearchResults
import ch.protonmail.android.mailmessage.domain.usecase.GetMessagesWithLabels
import ch.protonmail.android.mailmessage.domain.usecase.MarkMessagesAsRead
import ch.protonmail.android.mailmessage.domain.usecase.MarkMessagesAsUnread
@@ -272,6 +273,7 @@ class MailboxViewModelTest {
private val starConversations = mockk<StarConversations>()
private val unStarMessages = mockk<UnStarMessages>()
private val unStarConversations = mockk<UnStarConversations>()
private val deleteSearchResults = mockk<DeleteSearchResults>()
private val observePrimaryUserAccountStorageStatus = mockk<ObservePrimaryUserAccountStorageStatus> {
every { this@mockk() } returns flowOf()
}
@@ -332,6 +334,7 @@ class MailboxViewModelTest {
unStarConversations = unStarConversations,
mailboxReducer = mailboxReducer,
dispatchersProvider = TestDispatcherProvider(),
deleteSearchResults = deleteSearchResults,
observePrimaryUserAccountStorageStatus = observePrimaryUserAccountStorageStatus,
shouldUpgradeStorage = shouldUpgradeStorage,
shouldShowRatingBooster = shouldShowRatingBooster,
@@ -4746,6 +4749,7 @@ class MailboxViewModelTest {
MailboxViewAction.ExitSearchMode
)
} returns expectedState
coEvery { deleteSearchResults.invoke(any()) } just runs
// When
mailboxViewModel.submit(MailboxViewAction.ExitSearchMode)
@@ -4753,6 +4757,7 @@ class MailboxViewModelTest {
// Then
assertEquals(expectedState, awaitItem())
coVerify { deleteSearchResults.invoke(any()) }
}
}
@@ -4860,6 +4865,7 @@ class MailboxViewModelTest {
} returns mailboxSearchQueryState
every { observeAlmostAllMailSettings.invoke(any()) } returns flowOf(false)
coEvery { deleteSearchResults.invoke(any()) } just runs
mailboxViewModel.items.test {
// Then
@@ -4945,6 +4951,7 @@ class MailboxViewModelTest {
} returns mailboxSearchQueryState
every { observeAlmostAllMailSettings.invoke(any()) } returns flowOf(true)
coEvery { deleteSearchResults.invoke(any()) } just runs
mailboxViewModel.items.test {
// Then
@@ -44,6 +44,11 @@ interface MessageLocalDataSource {
*/
suspend fun deleteAllMessages(userId: UserId)
/**
* Delete all search intervals for [userId]
*/
suspend fun deleteSearchIntervals(userId: UserId)
/**
* Delete Message(s) for [userId], by [ids].
*/
@@ -71,6 +71,10 @@ class MessageLocalDataSourceImpl @Inject constructor(
pageIntervalDao.deleteAll(userId, PageItemType.Message)
}
override suspend fun deleteSearchIntervals(userId: UserId) {
pageIntervalDao.deleteSearchedIntervals()
}
override suspend fun deleteAllMessagesExcept(userId: UserId, messageIdsToExclude: List<MessageId>) =
db.inTransaction {
messageBodyFileStorage.deleteAllMessageBodies(userId)
@@ -29,4 +29,6 @@ interface SearchResultsLocalDataSource {
)
suspend fun deleteResults(userId: UserId, keyword: String)
suspend fun deleteAllResults(userId: UserId)
}
@@ -40,5 +40,8 @@ class SearchResultsLocalDataSourceImpl @Inject constructor(private val db: Searc
)
}
override suspend fun deleteResults(userId: UserId, keyword: String) = searchResultDao.deleteAll(userId, keyword)
override suspend fun deleteResults(userId: UserId, keyword: String) =
searchResultDao.deleteAllForKeyword(userId, keyword)
override suspend fun deleteAllResults(userId: UserId) = searchResultDao.deleteAll(userId)
}
@@ -28,6 +28,9 @@ import me.proton.core.domain.entity.UserId
abstract class SearchResultDao : BaseDao<SearchResultEntity>() {
@Query("DELETE FROM SearchResultEntity WHERE keyword = :keyword AND userId = :userId")
abstract suspend fun deleteAll(userId: UserId, keyword: String)
abstract suspend fun deleteAllForKeyword(userId: UserId, keyword: String)
@Query("DELETE FROM SearchResultEntity WHERE userId = :userId")
abstract suspend fun deleteAll(userId: UserId)
}
@@ -18,16 +18,19 @@
package ch.protonmail.android.mailmessage.data.repository
import ch.protonmail.android.mailmessage.data.local.MessageLocalDataSource
import ch.protonmail.android.mailmessage.data.local.SearchResultsLocalDataSource
import ch.protonmail.android.mailmessage.domain.repository.SearchResultsRepository
import me.proton.core.domain.entity.UserId
import javax.inject.Inject
class SearchResultsRepositoryImpl @Inject constructor(
private val localDataSource: SearchResultsLocalDataSource
private val localDataSource: SearchResultsLocalDataSource,
private val messageLocalDataSource: MessageLocalDataSource
) : SearchResultsRepository {
override suspend fun deleteAll(userId: UserId, keyword: String) {
localDataSource.deleteResults(userId, keyword)
override suspend fun deleteAll(userId: UserId) {
localDataSource.deleteAllResults(userId)
messageLocalDataSource.deleteSearchIntervals(userId)
}
}
@@ -22,5 +22,5 @@ import me.proton.core.domain.entity.UserId
interface SearchResultsRepository {
suspend fun deleteAll(userId: UserId, keyword: String)
suspend fun deleteAll(userId: UserId)
}
@@ -26,7 +26,7 @@ class DeleteSearchResults @Inject constructor(
private val searchResultsRepository: SearchResultsRepository
) {
suspend operator fun invoke(userId: UserId, keyword: String) {
searchResultsRepository.deleteAll(userId, keyword)
suspend operator fun invoke(userId: UserId) {
searchResultsRepository.deleteAll(userId)
}
}
@@ -92,4 +92,11 @@ abstract class PageIntervalDao : BaseDao<PageIntervalEntity>() {
"""
)
abstract suspend fun deleteAll(userId: UserId, type: PageItemType)
@Query(
"""
DELETE FROM PageIntervalEntity WHERE keyword <> ''
"""
)
abstract suspend fun deleteSearchedIntervals()
}