Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ interface ConversationDAO {
)

suspend fun updateConversationModifiedDate(qualifiedID: QualifiedIDEntity, date: Instant)
suspend fun updateConversationNotificationDate(qualifiedID: QualifiedIDEntity)
suspend fun updateConversationNotificationDate(qualifiedID: QualifiedIDEntity, date: Instant? = null)
suspend fun updateConversationReadDate(conversationID: QualifiedIDEntity, date: Instant)
suspend fun updateAllConversationsNotificationDate()
suspend fun getAllConversations(): Flow<List<ConversationEntity>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,13 @@ internal class ConversationDAOImpl internal constructor(
}
}

override suspend fun updateConversationNotificationDate(qualifiedID: QualifiedIDEntity) {
override suspend fun updateConversationNotificationDate(qualifiedID: QualifiedIDEntity, date: Instant?) {
withContext(writeDispatcher.value) {
conversationQueries.updateConversationNotificationsDateWithTheLastMessage(qualifiedID)
if (date != null) {
conversationQueries.updateConversationNotificationsDate(date, qualifiedID)
} else {
conversationQueries.updateConversationNotificationsDateWithTheLastMessage(qualifiedID)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ internal interface ConversationRepository {
): Either<StorageFailure, List<Conversation>>

suspend fun updateConversationGroupState(groupID: GroupID, groupState: GroupState): Either<StorageFailure, Unit>
suspend fun updateConversationNotificationDate(qualifiedID: QualifiedID): Either<StorageFailure, Unit>
suspend fun updateConversationNotificationDate(qualifiedID: QualifiedID, date: Instant? = null): Either<StorageFailure, Unit>
suspend fun updateAllConversationsNotificationDate(): Either<StorageFailure, Unit>
suspend fun updateConversationModifiedDate(qualifiedID: QualifiedID, date: Instant): Either<StorageFailure, Unit>
suspend fun updateConversationReadDate(qualifiedID: QualifiedID, date: Instant): Either<StorageFailure, Unit>
Expand Down Expand Up @@ -592,10 +592,11 @@ internal class ConversationDataSource internal constructor(
}

override suspend fun updateConversationNotificationDate(
qualifiedID: QualifiedID
qualifiedID: QualifiedID,
date: Instant?,
): Either<StorageFailure, Unit> =
wrapStorageRequest {
conversationDAO.updateConversationNotificationDate(qualifiedID.toDao())
conversationDAO.updateConversationNotificationDate(qualifiedID.toDao(), date)
}

override suspend fun updateAllConversationsNotificationDate(): Either<StorageFailure, Unit> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.wire.kalium.common.error.StorageFailure
import com.wire.kalium.logic.data.conversation.ConversationRepository
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.common.functional.fold
import kotlinx.datetime.Instant

/**
* Marks conversations in one or all conversations as notified, so the notifications for these messages won't show up again.
Expand All @@ -39,8 +40,17 @@ public class MarkMessagesAsNotifiedUseCase internal constructor(
when (conversationsToUpdate) {
UpdateTarget.AllConversations -> conversationRepository.updateAllConversationsNotificationDate()

is UpdateTarget.SingleConversation ->
conversationRepository.updateConversationNotificationDate(conversationsToUpdate.conversationId)
is UpdateTarget.SingleConversation -> {
val notifiedDate = conversationsToUpdate.notifiedDate
if (notifiedDate != null) {
conversationRepository.updateConversationNotificationDate(
conversationsToUpdate.conversationId,
notifiedDate
)
} else {
conversationRepository.updateConversationNotificationDate(conversationsToUpdate.conversationId)
}
}
}.fold({ Result.Failure(it) }) { Result.Success }

/**
Expand All @@ -53,9 +63,17 @@ public class MarkMessagesAsNotifiedUseCase internal constructor(
public data object AllConversations : UpdateTarget

/**
* A specific conversation, represented by its [conversationId], should be marked as notified
* A specific conversation, represented by its [conversationId], should be marked as notified.
* @param conversationId The conversation to mark as notified
* @param notifiedDate The timestamp of the last notified message. When provided, this exact
* timestamp is used instead of looking up the latest message in the database. This prevents
* race conditions where new messages arrive between displaying notifications and marking them
* as notified.
*/
public data class SingleConversation(val conversationId: ConversationId) : UpdateTarget
public data class SingleConversation(
val conversationId: ConversationId,
val notifiedDate: Instant? = null
) : UpdateTarget
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ class GetNotificationsUseCaseTest {
)
}.also {
coEvery {
conversationRepository.updateConversationNotificationDate(any())
conversationRepository.updateConversationNotificationDate(any(), any())
}.returns(Either.Right(Unit))

coEvery {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class MarkMessagesAsNotifiedUseCaseTest {
}.wasInvoked(exactly = once)

coVerify {
arrangement.conversationRepository.updateConversationNotificationDate(any())
arrangement.conversationRepository.updateConversationNotificationDate(any(), any())
}.wasNotInvoked()

assertEquals(result, Result.Success)
Expand All @@ -63,7 +63,7 @@ class MarkMessagesAsNotifiedUseCaseTest {
val result = markMessagesAsNotified(UpdateTarget.SingleConversation(CONVERSATION_ID))

coVerify {
arrangement.conversationRepository.updateConversationNotificationDate(eq(CONVERSATION_ID))
arrangement.conversationRepository.updateConversationNotificationDate(eq(CONVERSATION_ID), any())
}.wasInvoked(exactly = once)

coVerify {
Expand Down Expand Up @@ -111,7 +111,7 @@ class MarkMessagesAsNotifiedUseCaseTest {

suspend fun withUpdatingOneConversationReturning(result: Either<StorageFailure, Unit>) = apply {
coEvery {
conversationRepository.updateConversationNotificationDate(any())
conversationRepository.updateConversationNotificationDate(any(), any())
}.returns(result)
}

Expand Down
Loading