Skip to content
Open
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 @@ -328,7 +328,6 @@ sealed interface ConversationDetails {
) : ConversationDetails

sealed interface Group : ConversationDetails {
val hasOngoingCall: Boolean
val isSelfUserMember: Boolean
val selfRole: Conversation.Member.Role?
val isFavorite: Boolean
Expand All @@ -338,7 +337,6 @@ sealed interface ConversationDetails {

data class Regular(
override val conversation: Conversation,
override val hasOngoingCall: Boolean = false,
override val isSelfUserMember: Boolean,
override val selfRole: Conversation.Member.Role?,
override val isFavorite: Boolean = false,
Expand All @@ -349,7 +347,6 @@ sealed interface ConversationDetails {

data class Channel(
override val conversation: Conversation,
override val hasOngoingCall: Boolean = false,
override val isSelfUserMember: Boolean,
override val selfRole: Conversation.Member.Role?,
override val isFavorite: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ CASE (Conversation.type)
ELSE Conversation.name
END AS name,
Conversation.type,
Call.status AS callStatus,
CASE (Conversation.type)
WHEN 'ONE_ON_ONE' THEN User.preview_asset_id
WHEN 'CONNECTION_PENDING' THEN connection_user.preview_asset_id
Expand Down Expand Up @@ -128,7 +127,6 @@ LEFT JOIN Connection ON Connection.qualified_conversation = Conversation.qualifi
OR Connection.status = 'NOT_CONNECTED'
AND Conversation.type IS 'CONNECTION_PENDING')
LEFT JOIN User AS connection_user ON Connection.qualified_to = connection_user.qualified_id
LEFT JOIN Call ON Call.id IS (SELECT id FROM Call WHERE Call.conversation_id = Conversation.qualified_id ORDER BY created_at DESC LIMIT 1) AND Call.status IS 'STILL_ONGOING'
LEFT JOIN ConversationFolder AS FavoriteFolder ON FavoriteFolder.folder_type IS 'FAVORITE'
LEFT JOIN LabeledConversation ON LabeledConversation.conversation_id = Conversation.qualified_id AND LabeledConversation.folder_id = FavoriteFolder.id
LEFT JOIN LabeledConversation AS ConversationLabel ON ConversationLabel.conversation_id = Conversation.qualified_id AND ConversationLabel.folder_id IS NOT FavoriteFolder.id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ SELECT
UnreadEventCountsGrouped.repliesCount AS unreadRepliesCount,
UnreadEventCountsGrouped.messagesCount AS unreadMessagesCount,
CASE
WHEN ConversationDetails.callStatus = 'STILL_ONGOING' AND ConversationDetails.type = 'GROUP' THEN 1 -- if ongoing call in a group, move it to the top
WHEN ConversationDetails.mutedStatus = 'ALL_ALLOWED' THEN
CASE
WHEN (UnreadEventCountsGrouped.knocksCount + UnreadEventCountsGrouped.missedCallsCount + UnreadEventCountsGrouped.mentionsCount + UnreadEventCountsGrouped.repliesCount + UnreadEventCountsGrouped.messagesCount) > 0 THEN 1 -- if any unread events, move it to the top
Expand Down Expand Up @@ -91,7 +90,11 @@ WHERE archived = :fromArchive
)
AND CASE WHEN :onlyInteractionsEnabled THEN interactionEnabled = 1 ELSE 1 END
ORDER BY
CASE WHEN :newActivitiesOnTop THEN hasNewActivitiesToShow ELSE 0 END DESC,
CASE
WHEN :newActivitiesOnTop THEN
CASE WHEN qualifiedId IN :activeCallConversationIds THEN 1 ELSE hasNewActivitiesToShow END
ELSE 0
END DESC,
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now this is needed just for order but moving forward we can change this to not move a conv to the top of the list because of calls

lastModifiedDate DESC,
name IS NULL,
name COLLATE NOCASE ASC;
Expand Down Expand Up @@ -123,7 +126,11 @@ WHERE
END
AND CASE WHEN :onlyInteractionsEnabled THEN interactionEnabled = 1 ELSE 1 END
ORDER BY
CASE WHEN :newActivitiesOnTop THEN hasNewActivitiesToShow ELSE 0 END DESC,
CASE
WHEN :newActivitiesOnTop THEN
CASE WHEN qualifiedId IN :activeCallConversationIds THEN 1 ELSE hasNewActivitiesToShow END
ELSE 0
END DESC,
lastModifiedDate DESC,
name IS NULL,
name COLLATE NOCASE ASC
Expand Down Expand Up @@ -158,7 +165,11 @@ WHERE
AND CASE WHEN :onlyInteractionsEnabled THEN interactionEnabled = 1 ELSE 1 END
AND name LIKE ('%' || :searchQuery || '%')
ORDER BY
CASE WHEN :newActivitiesOnTop THEN hasNewActivitiesToShow ELSE 0 END DESC,
CASE
WHEN :newActivitiesOnTop THEN
CASE WHEN qualifiedId IN :activeCallConversationIds THEN 1 ELSE hasNewActivitiesToShow END
ELSE 0
END DESC,
lastModifiedDate DESC,
name IS NULL,
name COLLATE NOCASE ASC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ data class CallEntity(

@Suppress("TooManyFunctions")
interface CallDAO {
suspend fun insertCall(call: CallEntity)
suspend fun insertCall(call: CallEntity, createdAt: String? = null)
suspend fun observeCalls(): Flow<List<CallEntity>>
suspend fun observeIncomingCalls(): Flow<List<CallEntity>>
suspend fun observeOutgoingCalls(): Flow<List<CallEntity>>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,17 @@ internal class CallDAOImpl(
private val mapper: CallMapper = CallMapper,
) : CallDAO {

override suspend fun insertCall(call: CallEntity) {
override suspend fun insertCall(call: CallEntity, createdAt: String?) {
withContext(writeDispatcher.value) {
val createdTime: Long = DateTimeUtil.currentInstant().toEpochMilliseconds()
val createdTime = createdAt ?: DateTimeUtil.currentInstant().toEpochMilliseconds().toString()

callsQueries.insertCall(
conversation_id = call.conversationId,
id = call.id,
status = call.status,
caller_id = call.callerId,
conversation_type = call.conversationType,
created_at = createdTime.toString(),
created_at = createdTime,
type = call.type
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ internal class ConversationDAOImpl internal constructor(
fromArchive = fromArchive,
onlyInteractionsEnabled = onlyInteractionEnabled,
newActivitiesOnTop = newActivitiesOnTop,
activeCallConversationIds = emptySet(),
strict_mls = if (strictMLSFilter) 1 else 0,
mapper = conversationDetailsWithEventsMapper::fromViewToModel
).asFlow()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import com.wire.kalium.persistence.dao.QualifiedIDEntity
import com.wire.kalium.persistence.dao.SupportedProtocolEntity
import com.wire.kalium.persistence.dao.UserAvailabilityStatusEntity
import com.wire.kalium.persistence.dao.UserTypeEntity
import com.wire.kalium.persistence.dao.call.CallEntity
import com.wire.kalium.persistence.dao.member.MemberEntity
import com.wire.kalium.persistence.dao.message.MessageEntity
import com.wire.kalium.persistence.dao.message.MessageMapper
Expand All @@ -38,7 +37,6 @@ data object ConversationDetailsWithEventsMapper {
qualifiedId: QualifiedIDEntity,
name: String?,
type: ConversationEntity.Type,
callStatus: CallEntity.Status?,
previewAssetId: QualifiedIDEntity?,
mutedStatus: ConversationEntity.MutedStatus,
teamId: String?,
Expand Down Expand Up @@ -120,7 +118,6 @@ data object ConversationDetailsWithEventsMapper {
qualifiedId = qualifiedId,
name = name,
type = type,
callStatus = callStatus,
previewAssetId = previewAssetId,
mutedStatus = mutedStatus,
teamId = teamId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.paging.Pager
import androidx.paging.PagingConfig
import app.cash.sqldelight.paging3.QueryPagingSource
import com.wire.kalium.persistence.ConversationDetailsWithEventsQueries
import com.wire.kalium.persistence.dao.QualifiedIDEntity
import com.wire.kalium.persistence.dao.conversation.ConversationExtensions.QueryConfig
import com.wire.kalium.persistence.dao.message.KaliumPager
import com.wire.kalium.persistence.db.ReadDispatcher
Expand All @@ -37,6 +38,7 @@ interface ConversationExtensions {
val fromArchive: Boolean = false,
val onlyInteractionEnabled: Boolean = false,
val newActivitiesOnTop: Boolean = false,
val activeCallConversationIds: Set<QualifiedIDEntity> = emptySet(),
val conversationFilter: ConversationFilterEntity = ConversationFilterEntity.ALL,
val strictMlsFilter: Boolean = true,
)
Expand Down Expand Up @@ -100,6 +102,7 @@ internal class ConversationExtensionsImpl internal constructor(
onlyInteractionsEnabled = onlyInteractionEnabled,
conversationFilter = conversationFilter.name,
newActivitiesOnTop = newActivitiesOnTop,
activeCallConversationIds = activeCallConversationIds,
limit = limit,
offset = offset,
strict_mls = if (queryConfig.strictMlsFilter) 1 else 0,
Expand All @@ -112,6 +115,7 @@ internal class ConversationExtensionsImpl internal constructor(
conversationFilter = conversationFilter.name,
searchQuery = searchQuery,
newActivitiesOnTop = newActivitiesOnTop,
activeCallConversationIds = activeCallConversationIds,
limit = limit,
offset = offset,
strict_mls = if (queryConfig.strictMlsFilter) 1 else 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import com.wire.kalium.persistence.dao.QualifiedIDEntity
import com.wire.kalium.persistence.dao.SupportedProtocolEntity
import com.wire.kalium.persistence.dao.UserAvailabilityStatusEntity
import com.wire.kalium.persistence.dao.UserTypeEntity
import com.wire.kalium.persistence.dao.call.CallEntity
import com.wire.kalium.persistence.dao.member.MemberEntity
import kotlinx.datetime.Instant

Expand All @@ -34,7 +33,6 @@ data object ConversationMapper {
qualifiedId: QualifiedIDEntity,
name: String?,
type: ConversationEntity.Type,
callStatus: CallEntity.Status?,
previewAssetId: QualifiedIDEntity?,
mutedStatus: ConversationEntity.MutedStatus,
teamId: String?,
Expand Down Expand Up @@ -112,7 +110,6 @@ data object ConversationMapper {
mlsLastKeyingMaterialUpdateDate = mlsLastKeyingMaterialUpdateDate,
mlsGroupState = mlsGroupState,
mlsProposalTimer = mlsProposalTimer,
callStatus = callStatus,
previewAssetId = previewAssetId,
userAvailabilityStatus = userAvailabilityStatus,
userType = userType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import com.wire.kalium.persistence.dao.SupportedProtocolEntity
import com.wire.kalium.persistence.dao.UserAvailabilityStatusEntity
import com.wire.kalium.persistence.dao.UserIDEntity
import com.wire.kalium.persistence.dao.UserTypeEntity
import com.wire.kalium.persistence.dao.call.CallEntity
import com.wire.kalium.persistence.dao.conversation.ConversationEntity.ChannelAccess
import com.wire.kalium.persistence.dao.conversation.ConversationEntity.ChannelAddPermission
import com.wire.kalium.persistence.dao.member.MemberEntity
Expand All @@ -36,7 +35,6 @@ data class ConversationViewEntity(
val id: QualifiedIDEntity,
val name: String?,
val type: ConversationEntity.Type,
val callStatus: CallEntity.Status?,
val previewAssetId: QualifiedIDEntity?,
val mutedStatus: ConversationEntity.MutedStatus,
val teamId: String?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2794,7 +2794,6 @@ class ConversationDAOTest : BaseDatabaseTest() {
id = id,
name = if (type == ConversationEntity.Type.ONE_ON_ONE) userEntity?.name else name,
type = type,
callStatus = null,
previewAssetId = null,
mutedStatus = mutedStatus,
teamId = if (type == ConversationEntity.Type.ONE_ON_ONE) userEntity?.team else teamId,
Expand Down Expand Up @@ -3132,7 +3131,7 @@ class ConversationDAOTest : BaseDatabaseTest() {
}

@Test
fun givenSomePreviousCallIsWronglyStillOngoingButLastOneIsAlreadyClosed_whenFetchingConversationDetails_thenReturnStateOfLastCall() =
fun givenCallsExist_whenFetchingConversationDetails_thenReturnConversationDetailsWithoutCallState() =
runTest(dispatcher) {
val conversationEntity1 = conversationEntity1.copy(
id = ConversationIDEntity("conversation1", "domain"),
Expand All @@ -3146,7 +3145,7 @@ class ConversationDAOTest : BaseDatabaseTest() {
callDAO.insertCall(callEntity1.copy(id = "2", status = CallEntity.Status.CLOSED)) // last call already closed
conversationDAO.getConversationDetailsById(conversationEntity1.id).let {
assertNotNull(it)
assertEquals(null, it.callStatus) // no call status because the last call is already closed
assertEquals(conversationEntity1.id, it.id)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.wire.kalium.logic.feature.conversation

import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.wire.kalium.logic.data.call.CallRepository
import com.wire.kalium.logic.data.conversation.ConversationDetailsWithEvents
import com.wire.kalium.logic.data.conversation.ConversationQueryConfig
import com.wire.kalium.logic.data.conversation.ConversationRepository
Expand All @@ -32,7 +33,8 @@ import dev.mokkery.mock
import dev.mokkery.verify.VerifyMode
import dev.mokkery.verifySuspend
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.junit.Test

Expand All @@ -42,21 +44,22 @@ internal class GetPaginatedFlowOfConversationDetailsWithEventsBySearchQueryUseCa
@Test
fun givenSearchQuery_whenGettingPaginatedList_thenCallUseCaseWithProperParams() = runTest(dispatcher.default) {
// Given
val (arrangement, useCase) = Arrangement().withPaginatedConversationResult(emptyFlow()).arrange()
val (arrangement, useCase) = Arrangement().withPaginatedConversationResult(flowOf(PagingData.empty())).arrange()
with(arrangement) {
// When
useCase(queryConfig = queryConfig, pagingConfig = pagingConfig, startingOffset = startingOffset, strictMlsFilter = false)
useCase(queryConfig = queryConfig, pagingConfig = pagingConfig, startingOffset = startingOffset, strictMlsFilter = false).first()
// Then
verifySuspend(VerifyMode.exactly(1)) {
conversationRepository.extensions
.getPaginatedConversationDetailsWithEventsBySearchQuery(queryConfig, pagingConfig, startingOffset, false)
.getPaginatedConversationDetailsWithEventsBySearchQuery(queryConfig, emptyList(), pagingConfig, startingOffset, false)
}
}
}

inner class Arrangement {
val conversationRepository = mock<ConversationRepository>()
val conversationRepositoryExtensions = mock<ConversationRepositoryExtensions>()
val callRepository = mock<CallRepository>()

val queryConfig = ConversationQueryConfig("search")
val pagingConfig = PagingConfig(20)
Expand All @@ -66,14 +69,21 @@ internal class GetPaginatedFlowOfConversationDetailsWithEventsBySearchQueryUseCa
every {
conversationRepository.extensions
}.returns(conversationRepositoryExtensions)
everySuspend {
callRepository.ongoingCallsFlow()
} returns flowOf(emptyList())
}

suspend fun withPaginatedConversationResult(result: Flow<PagingData<ConversationDetailsWithEvents>>) = apply {
everySuspend {
conversationRepositoryExtensions.getPaginatedConversationDetailsWithEventsBySearchQuery(any(), any(), any(), any())
conversationRepositoryExtensions.getPaginatedConversationDetailsWithEventsBySearchQuery(any(), any(), any(), any(), any())
} returns result
}

fun arrange() = this to GetPaginatedFlowOfConversationDetailsWithEventsBySearchQueryUseCase(dispatcher, conversationRepository)
fun arrange() = this to GetPaginatedFlowOfConversationDetailsWithEventsBySearchQueryUseCase(
dispatcher,
conversationRepository,
callRepository
)
}
}
Loading
Loading