Merge branch 'develop' into feature/fga/user_detail_direct_chat
This commit is contained in:
commit
03a2e31d46
76 changed files with 329 additions and 148 deletions
|
|
@ -79,6 +79,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom
|
|||
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState
|
||||
import io.element.android.libraries.matrix.api.room.MessageEventType
|
||||
import io.element.android.libraries.matrix.api.user.CurrentSessionIdHolder
|
||||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo
|
||||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType
|
||||
import io.element.android.libraries.matrix.ui.room.canRedactAsState
|
||||
|
|
@ -108,6 +109,7 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
private val featureFlagsService: FeatureFlagService,
|
||||
@Assisted private val navigator: MessagesNavigator,
|
||||
private val buildMeta: BuildMeta,
|
||||
private val currentSessionIdHolder: CurrentSessionIdHolder,
|
||||
) : Presenter<MessagesState> {
|
||||
|
||||
private val timelinePresenter = timelinePresenterFactory.create(navigator = navigator)
|
||||
|
|
@ -133,10 +135,10 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
||||
val userHasPermissionToSendMessage by room.canSendMessageAsState(type = MessageEventType.ROOM_MESSAGE, updateKey = syncUpdateFlow.value)
|
||||
val userHasPermissionToRedact by room.canRedactAsState(updateKey = syncUpdateFlow.value)
|
||||
val roomName: Async<String> by remember(roomInfo?.name) {
|
||||
val roomName: Async<String> by remember {
|
||||
derivedStateOf { roomInfo?.name?.let { Async.Success(it) } ?: Async.Uninitialized }
|
||||
}
|
||||
val roomAvatar: Async<AvatarData> by remember(roomInfo?.avatarUrl) {
|
||||
val roomAvatar: Async<AvatarData> by remember {
|
||||
derivedStateOf { roomInfo?.avatarData()?.let { Async.Success(it) } ?: Async.Uninitialized }
|
||||
}
|
||||
|
||||
|
|
@ -144,6 +146,16 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
var canJoinCall by rememberSaveable {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
LaunchedEffect(currentSessionIdHolder.current) {
|
||||
withContext(dispatchers.io) {
|
||||
canJoinCall = room.canUserJoinCall(userId = currentSessionIdHolder.current).getOrDefault(false)
|
||||
}
|
||||
}
|
||||
|
||||
val inviteProgress = remember { mutableStateOf<Async<Unit>>(Async.Uninitialized) }
|
||||
var showReinvitePrompt by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(hasDismissedInviteDialog, composerState.hasFocus, syncUpdateFlow) {
|
||||
|
|
@ -162,8 +174,6 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
val enableTextFormatting by preferencesStore.isRichTextEditorEnabledFlow().collectAsState(initial = true)
|
||||
|
||||
var enableVoiceMessages by remember { mutableStateOf(false) }
|
||||
// TODO add min power level to use this feature in the future?
|
||||
val enableInRoomCalls = true
|
||||
LaunchedEffect(featureFlagsService) {
|
||||
enableVoiceMessages = featureFlagsService.isFeatureEnabled(FeatureFlags.VoiceMessages)
|
||||
}
|
||||
|
|
@ -193,6 +203,12 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
val callState = when {
|
||||
!canJoinCall -> RoomCallState.DISABLED
|
||||
roomInfo?.hasRoomCall == true -> RoomCallState.ONGOING
|
||||
else -> RoomCallState.ENABLED
|
||||
}
|
||||
|
||||
return MessagesState(
|
||||
roomId = room.roomId,
|
||||
roomName = roomName,
|
||||
|
|
@ -213,9 +229,8 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
inviteProgress = inviteProgress.value,
|
||||
enableTextFormatting = enableTextFormatting,
|
||||
enableVoiceMessages = enableVoiceMessages,
|
||||
enableInRoomCalls = enableInRoomCalls,
|
||||
appName = buildMeta.applicationName,
|
||||
isCallOngoing = roomInfo?.hasRoomCall ?: false,
|
||||
callState = callState,
|
||||
eventSink = { handleEvents(it) }
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,8 +51,13 @@ data class MessagesState(
|
|||
val showReinvitePrompt: Boolean,
|
||||
val enableTextFormatting: Boolean,
|
||||
val enableVoiceMessages: Boolean,
|
||||
val enableInRoomCalls: Boolean,
|
||||
val isCallOngoing: Boolean,
|
||||
val callState: RoomCallState,
|
||||
val appName: String,
|
||||
val eventSink: (MessagesEvents) -> Unit
|
||||
)
|
||||
|
||||
enum class RoomCallState {
|
||||
ENABLED,
|
||||
ONGOING,
|
||||
DISABLED
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ open class MessagesStateProvider : PreviewParameterProvider<MessagesState> {
|
|||
),
|
||||
),
|
||||
aMessagesState().copy(
|
||||
isCallOngoing = true,
|
||||
callState = RoomCallState.ONGOING,
|
||||
),
|
||||
aMessagesState().copy(
|
||||
enableVoiceMessages = true,
|
||||
|
|
@ -75,6 +75,9 @@ open class MessagesStateProvider : PreviewParameterProvider<MessagesState> {
|
|||
showSendFailureDialog = true
|
||||
),
|
||||
),
|
||||
aMessagesState().copy(
|
||||
callState = RoomCallState.DISABLED,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -117,8 +120,7 @@ fun aMessagesState() = MessagesState(
|
|||
showReinvitePrompt = false,
|
||||
enableTextFormatting = true,
|
||||
enableVoiceMessages = true,
|
||||
enableInRoomCalls = true,
|
||||
isCallOngoing = false,
|
||||
callState = RoomCallState.ENABLED,
|
||||
appName = "Element",
|
||||
eventSink = {}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -191,10 +191,9 @@ fun MessagesView(
|
|||
MessagesViewTopBar(
|
||||
roomName = state.roomName.dataOrNull(),
|
||||
roomAvatar = state.roomAvatar.dataOrNull(),
|
||||
inRoomCallsEnabled = state.enableInRoomCalls,
|
||||
callState = state.callState,
|
||||
onBackPressed = onBackPressed,
|
||||
onRoomDetailsClicked = onRoomDetailsClicked,
|
||||
isCallOngoing = state.isCallOngoing,
|
||||
onJoinCallClicked = onJoinCallClicked,
|
||||
)
|
||||
}
|
||||
|
|
@ -449,8 +448,7 @@ private fun MessagesViewComposerBottomSheetContents(
|
|||
private fun MessagesViewTopBar(
|
||||
roomName: String?,
|
||||
roomAvatar: AvatarData?,
|
||||
inRoomCallsEnabled: Boolean,
|
||||
isCallOngoing: Boolean,
|
||||
callState: RoomCallState,
|
||||
onRoomDetailsClicked: () -> Unit,
|
||||
onJoinCallClicked: () -> Unit,
|
||||
onBackPressed: () -> Unit,
|
||||
|
|
@ -477,13 +475,11 @@ private fun MessagesViewTopBar(
|
|||
}
|
||||
},
|
||||
actions = {
|
||||
if (inRoomCallsEnabled) {
|
||||
if (isCallOngoing) {
|
||||
JoinCallMenuItem(onJoinCallClicked = onJoinCallClicked)
|
||||
} else {
|
||||
IconButton(onClick = onJoinCallClicked) {
|
||||
Icon(CompoundIcons.VideoCall, contentDescription = stringResource(CommonStrings.a11y_start_call))
|
||||
}
|
||||
if (callState == RoomCallState.ONGOING) {
|
||||
JoinCallMenuItem(onJoinCallClicked = onJoinCallClicked)
|
||||
} else {
|
||||
IconButton(onClick = onJoinCallClicked, enabled = callState != RoomCallState.DISABLED) {
|
||||
Icon(CompoundIcons.VideoCall, contentDescription = stringResource(CommonStrings.a11y_start_call))
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.width(8.dp))
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
|||
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageType
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
|
|
@ -127,8 +129,8 @@ class InReplyToDetailsProvider : PreviewParameterProvider<InReplyToDetails> {
|
|||
question = "Poll which are being replied.",
|
||||
kind = PollKind.Disclosed,
|
||||
maxSelections = 1u,
|
||||
answers = emptyList(),
|
||||
votes = emptyMap(),
|
||||
answers = persistentListOf(),
|
||||
votes = persistentMapOf(),
|
||||
endTime = null
|
||||
),
|
||||
).map {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package io.element.android.features.messages.impl.timeline.components.reactionsummary
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
|
|
@ -38,10 +37,6 @@ class ReactionSummaryPresenter @Inject constructor(
|
|||
) : Presenter<ReactionSummaryState> {
|
||||
@Composable
|
||||
override fun present(): ReactionSummaryState {
|
||||
LaunchedEffect(Unit) {
|
||||
room.updateMembers()
|
||||
}
|
||||
|
||||
val membersState by room.membersStateFlow.collectAsState()
|
||||
|
||||
val target: MutableState<ReactionSummaryState.Summary?> = remember {
|
||||
|
|
|
|||
|
|
@ -92,12 +92,14 @@ import io.element.android.tests.testutils.consumeItemsUntilTimeout
|
|||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import io.element.android.tests.testutils.waitForPredicate
|
||||
import io.mockk.mockk
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
@Suppress("LargeClass")
|
||||
class MessagesPresenterTest {
|
||||
|
||||
@get:Rule
|
||||
|
|
@ -125,6 +127,21 @@ class MessagesPresenterTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - call is disabled if user cannot join it even if there is an ongoing call`() = runTest {
|
||||
val room = FakeMatrixRoom().apply {
|
||||
givenCanUserJoinCall(Result.success(false))
|
||||
givenRoomInfo(aRoomInfo(hasRoomCall = true))
|
||||
}
|
||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = consumeItemsUntilTimeout().last()
|
||||
assertThat(initialState.callState).isEqualTo(RoomCallState.DISABLED)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - handle toggling a reaction`() = runTest {
|
||||
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||
|
|
@ -462,7 +479,7 @@ class MessagesPresenterTest {
|
|||
val room = FakeMatrixRoom(sessionId = A_SESSION_ID)
|
||||
room.givenRoomMembersState(
|
||||
MatrixRoomMembersState.Ready(
|
||||
listOf(
|
||||
persistentListOf(
|
||||
aRoomMember(userId = A_SESSION_ID, membership = RoomMembershipState.JOIN),
|
||||
aRoomMember(userId = A_SESSION_ID_2, membership = RoomMembershipState.LEAVE),
|
||||
)
|
||||
|
|
@ -489,7 +506,7 @@ class MessagesPresenterTest {
|
|||
room.givenRoomMembersState(
|
||||
MatrixRoomMembersState.Error(
|
||||
failure = Throwable(),
|
||||
prevRoomMembers = listOf(
|
||||
prevRoomMembers = persistentListOf(
|
||||
aRoomMember(userId = A_SESSION_ID, membership = RoomMembershipState.JOIN),
|
||||
aRoomMember(userId = A_SESSION_ID_2, membership = RoomMembershipState.LEAVE),
|
||||
)
|
||||
|
|
@ -535,7 +552,7 @@ class MessagesPresenterTest {
|
|||
val room = FakeMatrixRoom(sessionId = A_SESSION_ID)
|
||||
room.givenRoomMembersState(
|
||||
MatrixRoomMembersState.Ready(
|
||||
listOf(
|
||||
persistentListOf(
|
||||
aRoomMember(userId = A_SESSION_ID, membership = RoomMembershipState.JOIN),
|
||||
aRoomMember(userId = A_SESSION_ID_2, membership = RoomMembershipState.LEAVE),
|
||||
)
|
||||
|
|
@ -655,6 +672,7 @@ class MessagesPresenterTest {
|
|||
clipboardHelper: FakeClipboardHelper = FakeClipboardHelper(),
|
||||
analyticsService: FakeAnalyticsService = FakeAnalyticsService(),
|
||||
permissionsPresenter: PermissionsPresenter = FakePermissionsPresenter(),
|
||||
currentSessionIdHolder: CurrentSessionIdHolder = CurrentSessionIdHolder(FakeMatrixClient(A_SESSION_ID)),
|
||||
): MessagesPresenter {
|
||||
val mediaSender = MediaSender(FakeMediaPreProcessor(), matrixRoom)
|
||||
val permissionsPresenterFactory = FakePermissionsPresenterFactory(permissionsPresenter)
|
||||
|
|
@ -723,6 +741,7 @@ class MessagesPresenterTest {
|
|||
featureFlagsService = FakeFeatureFlagService(),
|
||||
buildMeta = aBuildMeta(),
|
||||
dispatchers = coroutineDispatchers,
|
||||
currentSessionIdHolder = currentSessionIdHolder,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,11 +78,11 @@ import io.element.android.services.analytics.test.FakeAnalyticsService
|
|||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.waitForPredicate
|
||||
import io.mockk.mockk
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import okhttp3.internal.immutableListOf
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import uniffi.wysiwyg_composer.MentionsState
|
||||
|
|
@ -734,7 +734,7 @@ class MessageComposerPresenterTest {
|
|||
isOneToOne = false,
|
||||
).apply {
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(
|
||||
immutableListOf(currentUser, invitedUser, bob, david),
|
||||
persistentListOf(currentUser, invitedUser, bob, david),
|
||||
))
|
||||
givenCanTriggerRoomNotification(Result.success(true))
|
||||
}
|
||||
|
|
@ -798,7 +798,7 @@ class MessageComposerPresenterTest {
|
|||
isOneToOne = true,
|
||||
).apply {
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(
|
||||
immutableListOf(currentUser, invitedUser, bob, david),
|
||||
persistentListOf(currentUser, invitedUser, bob, david),
|
||||
))
|
||||
givenCanTriggerRoomNotification(Result.success(true))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import io.element.android.tests.testutils.awaitWithLatch
|
|||
import io.element.android.tests.testutils.consumeItemsUntilPredicate
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import io.element.android.tests.testutils.waitForPredicate
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
|
|
@ -254,18 +255,18 @@ class TimelinePresenterTest {
|
|||
val (alice, bob, charlie) = aMatrixUserList().take(3).mapIndexed { i, user ->
|
||||
ReactionSender(senderId = user.userId, timestamp = now + i * minuteInMillis)
|
||||
}
|
||||
val oneReaction = listOf(
|
||||
val oneReaction = persistentListOf(
|
||||
EventReaction(
|
||||
key = "❤️",
|
||||
senders = listOf(alice, charlie)
|
||||
senders = persistentListOf(alice, charlie)
|
||||
),
|
||||
EventReaction(
|
||||
key = "👍",
|
||||
senders = listOf(alice, bob)
|
||||
senders = persistentListOf(alice, bob)
|
||||
),
|
||||
EventReaction(
|
||||
key = "🐶",
|
||||
senders = listOf(charlie)
|
||||
senders = persistentListOf(charlie)
|
||||
),
|
||||
)
|
||||
timeline.updateTimelineItems {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import io.element.android.libraries.matrix.test.A_USER_NAME
|
|||
import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
||||
import io.element.android.libraries.matrix.test.room.aRoomMember
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
|
|
@ -42,7 +43,7 @@ class ReactionSummaryPresenterTests {
|
|||
private val roomMember = aRoomMember(userId = A_USER_ID, avatarUrl = AN_AVATAR_URL, displayName = A_USER_NAME)
|
||||
private val summaryEvent = ReactionSummaryEvents.ShowReactionSummary(AN_EVENT_ID, listOf(aggregatedReaction), aggregatedReaction.key)
|
||||
private val room = FakeMatrixRoom().apply {
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(listOf(roomMember)))
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
|
||||
}
|
||||
private val presenter = ReactionSummaryPresenter(room)
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageT
|
|||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||
import io.element.android.libraries.matrix.ui.components.A_BLUR_HASH
|
||||
import io.element.android.libraries.mediaviewer.api.util.FileExtensionExtractorWithoutValidation
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -280,7 +281,7 @@ class TimelineItemContentMessageFactoryTest {
|
|||
),
|
||||
details = AudioDetails(
|
||||
duration = 1.minutes,
|
||||
waveform = listOf(1f, 2f),
|
||||
waveform = persistentListOf(1f, 2f),
|
||||
),
|
||||
)
|
||||
),
|
||||
|
|
@ -293,7 +294,7 @@ class TimelineItemContentMessageFactoryTest {
|
|||
duration = 1.minutes,
|
||||
mediaSource = MediaSource(url = "url", json = null),
|
||||
mimeType = MimeTypes.Ogg,
|
||||
waveform = listOf(1f, 2f).toImmutableList()
|
||||
waveform = persistentListOf(1f, 2f)
|
||||
)
|
||||
assertThat(result).isEqualTo(expected)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,11 @@ import io.element.android.libraries.matrix.test.A_USER_ID_7
|
|||
import io.element.android.libraries.matrix.test.A_USER_ID_8
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID_9
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.ImmutableMap
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import kotlinx.collections.immutable.toImmutableMap
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
||||
|
|
@ -55,7 +60,7 @@ internal class TimelineItemContentPollFactoryTest {
|
|||
|
||||
@Test
|
||||
fun `Disclosed poll - not ended, some votes, including one from current user`() = runTest {
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
Truth.assertThat(
|
||||
factory.create(aPollContent(votes = votes), eventId = null)
|
||||
)
|
||||
|
|
@ -87,7 +92,7 @@ internal class TimelineItemContentPollFactoryTest {
|
|||
|
||||
@Test
|
||||
fun `Disclosed poll - ended, some votes, including one from current user (winner)`() = runTest {
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
Truth.assertThat(
|
||||
factory.create(aPollContent(votes = votes, endTime = 1UL), eventId = null)
|
||||
)
|
||||
|
|
@ -106,7 +111,7 @@ internal class TimelineItemContentPollFactoryTest {
|
|||
|
||||
@Test
|
||||
fun `Disclosed poll - ended, some votes, including one from current user (not winner) and two winning votes`() = runTest {
|
||||
val votes = OTHER_WINNING_VOTES.mapKeys { it.key.id }
|
||||
val votes = OTHER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
Truth.assertThat(
|
||||
factory.create(aPollContent(votes = votes, endTime = 1UL), eventId = null)
|
||||
)
|
||||
|
|
@ -136,7 +141,7 @@ internal class TimelineItemContentPollFactoryTest {
|
|||
|
||||
@Test
|
||||
fun `Undisclosed poll - not ended, some votes, including one from current user`() = runTest {
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
Truth.assertThat(
|
||||
factory.create(aPollContent(pollKind = PollKind.Undisclosed, votes = votes), eventId = null)
|
||||
)
|
||||
|
|
@ -172,7 +177,7 @@ internal class TimelineItemContentPollFactoryTest {
|
|||
|
||||
@Test
|
||||
fun `Undisclosed poll - ended, some votes, including one from current user (winner)`() = runTest {
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }
|
||||
val votes = MY_USER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
Truth.assertThat(
|
||||
factory.create(aPollContent(pollKind = PollKind.Undisclosed, votes = votes, endTime = 1UL), eventId = null)
|
||||
)
|
||||
|
|
@ -192,7 +197,7 @@ internal class TimelineItemContentPollFactoryTest {
|
|||
|
||||
@Test
|
||||
fun `Undisclosed poll - ended, some votes, including one from current user (not winner) and two winning votes`() = runTest {
|
||||
val votes = OTHER_WINNING_VOTES.mapKeys { it.key.id }
|
||||
val votes = OTHER_WINNING_VOTES.mapKeys { it.key.id }.toImmutableMap()
|
||||
Truth.assertThat(
|
||||
factory.create(aPollContent(PollKind.Undisclosed).copy(votes = votes, endTime = 1UL), eventId = null)
|
||||
)
|
||||
|
|
@ -221,13 +226,13 @@ internal class TimelineItemContentPollFactoryTest {
|
|||
|
||||
private fun aPollContent(
|
||||
pollKind: PollKind = PollKind.Disclosed,
|
||||
votes: Map<String, List<UserId>> = emptyMap(),
|
||||
votes: ImmutableMap<String, ImmutableList<UserId>> = persistentMapOf(),
|
||||
endTime: ULong? = null,
|
||||
): PollContent = PollContent(
|
||||
question = A_POLL_QUESTION,
|
||||
kind = pollKind,
|
||||
maxSelections = 1UL,
|
||||
answers = listOf(A_POLL_ANSWER_1, A_POLL_ANSWER_2, A_POLL_ANSWER_3, A_POLL_ANSWER_4),
|
||||
answers = persistentListOf(A_POLL_ANSWER_1, A_POLL_ANSWER_2, A_POLL_ANSWER_3, A_POLL_ANSWER_4),
|
||||
votes = votes,
|
||||
endTime = endTime,
|
||||
)
|
||||
|
|
@ -275,17 +280,17 @@ internal class TimelineItemContentPollFactoryTest {
|
|||
private val A_POLL_ANSWER_3 = PollAnswer("id_3", "French Fries")
|
||||
private val A_POLL_ANSWER_4 = PollAnswer("id_4", "Hamburger")
|
||||
|
||||
private val MY_USER_WINNING_VOTES = mapOf(
|
||||
A_POLL_ANSWER_1 to listOf(A_USER_ID_2, A_USER_ID_3, A_USER_ID_4),
|
||||
A_POLL_ANSWER_2 to listOf(A_USER_ID /* my vote */, A_USER_ID_5, A_USER_ID_6, A_USER_ID_7, A_USER_ID_8, A_USER_ID_9), // winner
|
||||
A_POLL_ANSWER_3 to emptyList(),
|
||||
A_POLL_ANSWER_4 to listOf(A_USER_ID_10),
|
||||
private val MY_USER_WINNING_VOTES = persistentMapOf(
|
||||
A_POLL_ANSWER_1 to persistentListOf(A_USER_ID_2, A_USER_ID_3, A_USER_ID_4),
|
||||
A_POLL_ANSWER_2 to persistentListOf(A_USER_ID /* my vote */, A_USER_ID_5, A_USER_ID_6, A_USER_ID_7, A_USER_ID_8, A_USER_ID_9), // winner
|
||||
A_POLL_ANSWER_3 to persistentListOf(),
|
||||
A_POLL_ANSWER_4 to persistentListOf(A_USER_ID_10),
|
||||
)
|
||||
private val OTHER_WINNING_VOTES = mapOf(
|
||||
A_POLL_ANSWER_1 to listOf(A_USER_ID_2, A_USER_ID_3, A_USER_ID_4, A_USER_ID_5), // winner
|
||||
A_POLL_ANSWER_2 to listOf(A_USER_ID /* my vote */, A_USER_ID_6),
|
||||
A_POLL_ANSWER_3 to emptyList(),
|
||||
A_POLL_ANSWER_4 to listOf(A_USER_ID_7, A_USER_ID_8, A_USER_ID_9, A_USER_ID_10), // winner
|
||||
private val OTHER_WINNING_VOTES = persistentMapOf(
|
||||
A_POLL_ANSWER_1 to persistentListOf(A_USER_ID_2, A_USER_ID_3, A_USER_ID_4, A_USER_ID_5), // winner
|
||||
A_POLL_ANSWER_2 to persistentListOf(A_USER_ID /* my vote */, A_USER_ID_6),
|
||||
A_POLL_ANSWER_3 to persistentListOf(),
|
||||
A_POLL_ANSWER_4 to persistentListOf(A_USER_ID_7, A_USER_ID_8, A_USER_ID_9, A_USER_ID_10), // winner
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID
|
|||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
|
|
@ -88,8 +89,8 @@ fun aRedactedMatrixTimeline(eventId: EventId) = listOf<MatrixTimelineItem>(
|
|||
isOwn = false,
|
||||
isRemote = false,
|
||||
localSendState = null,
|
||||
reactions = listOf(),
|
||||
receipts = listOf(),
|
||||
reactions = persistentListOf(),
|
||||
receipts = persistentListOf(),
|
||||
sender = A_USER_ID,
|
||||
senderProfile = ProfileTimelineDetails.Unavailable,
|
||||
timestamp = 9442,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import io.element.android.libraries.matrix.test.room.anEventTimelineItem
|
|||
import io.element.android.libraries.matrix.test.timeline.FakeMatrixTimeline
|
||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
|
|
@ -539,7 +540,7 @@ class CreatePollPresenterTest {
|
|||
|
||||
private fun anExistingPoll() = aPollContent(
|
||||
question = "Do you like polls?",
|
||||
answers = listOf(
|
||||
answers = persistentListOf(
|
||||
PollAnswer("1", "Yes"),
|
||||
PollAnswer("2", "No"),
|
||||
PollAnswer("2", "Maybe"),
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import io.element.android.libraries.matrix.api.notificationsettings.Notification
|
|||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomListService
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
|
|
@ -84,7 +85,7 @@ class EditDefaultNotificationSettingPresenter @AssistedInject constructor(
|
|||
return EditDefaultNotificationSettingState(
|
||||
isOneToOne = isOneToOne,
|
||||
mode = mode.value,
|
||||
roomsWithUserDefinedMode = roomsWithUserDefinedMode.value,
|
||||
roomsWithUserDefinedMode = roomsWithUserDefinedMode.value.toImmutableList(),
|
||||
changeNotificationSettingAction = changeNotificationSettingAction.value,
|
||||
eventSink = ::handleEvents
|
||||
)
|
||||
|
|
|
|||
|
|
@ -19,11 +19,12 @@ package io.element.android.features.preferences.impl.notifications.edit
|
|||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
data class EditDefaultNotificationSettingState(
|
||||
val isOneToOne: Boolean,
|
||||
val mode: RoomNotificationMode?,
|
||||
val roomsWithUserDefinedMode: List<RoomSummary.Filled>,
|
||||
val roomsWithUserDefinedMode: ImmutableList<RoomSummary.Filled>,
|
||||
val changeNotificationSettingAction: Async<Unit>,
|
||||
val eventSink: (EditDefaultNotificationSettingStateEvents) -> Unit,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
|||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomSummaryDetails
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
open class EditDefaultNotificationSettingStateProvider: PreviewParameterProvider<EditDefaultNotificationSettingState> {
|
||||
override val values: Sequence<EditDefaultNotificationSettingState>
|
||||
|
|
@ -39,7 +40,7 @@ private fun anEditDefaultNotificationSettingsState(
|
|||
) = EditDefaultNotificationSettingState(
|
||||
isOneToOne = isOneToOne,
|
||||
mode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
|
||||
roomsWithUserDefinedMode = listOf(aRoomSummary()),
|
||||
roomsWithUserDefinedMode = persistentListOf(aRoomSummary()),
|
||||
changeNotificationSettingAction = changeNotificationSettingAction,
|
||||
eventSink = {}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ fun aRoomMember(
|
|||
isIgnored = isIgnored,
|
||||
)
|
||||
|
||||
fun aRoomMemberList() = listOf(
|
||||
fun aRoomMemberList() = persistentListOf(
|
||||
anAlice(),
|
||||
aBob(),
|
||||
aRoomMember(UserId("@carol:server.org"), "Carol"),
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import io.element.android.libraries.matrix.test.room.FakeMatrixRoom
|
|||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.consumeItemsUntilPredicate
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
|
|
@ -129,7 +130,7 @@ class RoomDetailsPresenterTests {
|
|||
isEncrypted = true,
|
||||
isDirect = true,
|
||||
).apply {
|
||||
val roomMembers = listOf(myRoomMember, otherRoomMember)
|
||||
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
|
||||
}
|
||||
val presenter = createRoomDetailsPresenter(room)
|
||||
|
|
@ -220,7 +221,7 @@ class RoomDetailsPresenterTests {
|
|||
isEncrypted = true,
|
||||
isDirect = true,
|
||||
).apply {
|
||||
val roomMembers = listOf(myRoomMember, otherRoomMember)
|
||||
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
|
||||
|
||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
|
||||
|
|
@ -253,7 +254,7 @@ class RoomDetailsPresenterTests {
|
|||
isDirect = true,
|
||||
topic = null,
|
||||
).apply {
|
||||
val roomMembers = listOf(myRoomMember, otherRoomMember)
|
||||
val roomMembers = persistentListOf(myRoomMember, otherRoomMember)
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(roomMembers))
|
||||
|
||||
givenCanSendStateResult(StateEventType.ROOM_TOPIC, Result.success(true))
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import io.element.android.libraries.usersearch.test.FakeUserRepository
|
|||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
|
|
@ -167,7 +168,7 @@ internal class RoomInviteMembersPresenterTest {
|
|||
matrixRoom = FakeMatrixRoom().apply {
|
||||
givenRoomMembersState(
|
||||
MatrixRoomMembersState.Ready(
|
||||
listOf(
|
||||
persistentListOf(
|
||||
aRoomMember(userId = joinedUser.userId, membership = RoomMembershipState.JOIN),
|
||||
aRoomMember(userId = invitedUser.userId, membership = RoomMembershipState.INVITE),
|
||||
)
|
||||
|
|
@ -227,7 +228,7 @@ internal class RoomInviteMembersPresenterTest {
|
|||
roomMemberListDataSource = createDataSource(FakeMatrixRoom().apply {
|
||||
givenRoomMembersState(
|
||||
MatrixRoomMembersState.Ready(
|
||||
listOf(
|
||||
persistentListOf(
|
||||
aRoomMember(userId = joinedUser.userId, membership = RoomMembershipState.JOIN),
|
||||
aRoomMember(userId = invitedUser.userId, membership = RoomMembershipState.INVITE),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID
|
|||
import io.element.android.libraries.matrix.test.A_THROWABLE
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
|
|
@ -56,7 +57,7 @@ class RoomMemberDetailsPresenterTests {
|
|||
val room = aMatrixRoom().apply {
|
||||
givenUserDisplayNameResult(Result.success("A custom name"))
|
||||
givenUserAvatarUrlResult(Result.success("A custom avatar"))
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(listOf(roomMember)))
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
|
||||
}
|
||||
val presenter = createRoomMemberDetailsPresenter(
|
||||
room = room,
|
||||
|
|
@ -83,7 +84,7 @@ class RoomMemberDetailsPresenterTests {
|
|||
val room = aMatrixRoom().apply {
|
||||
givenUserDisplayNameResult(Result.failure(Throwable()))
|
||||
givenUserAvatarUrlResult(Result.failure(Throwable()))
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(listOf(roomMember)))
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
|
||||
}
|
||||
val presenter = createRoomMemberDetailsPresenter(
|
||||
room = room,
|
||||
|
|
@ -106,7 +107,7 @@ class RoomMemberDetailsPresenterTests {
|
|||
val room = aMatrixRoom().apply {
|
||||
givenUserDisplayNameResult(Result.success(null))
|
||||
givenUserAvatarUrlResult(Result.success(null))
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(listOf(roomMember)))
|
||||
givenRoomMembersState(MatrixRoomMembersState.Ready(persistentListOf(roomMember)))
|
||||
}
|
||||
val presenter = createRoomMemberDetailsPresenter(
|
||||
room = room,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import io.element.android.libraries.matrix.api.core.RoomId
|
|||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||
|
||||
@Immutable
|
||||
data class RoomListRoomSummary constructor(
|
||||
data class RoomListRoomSummary(
|
||||
val id: String,
|
||||
val roomId: RoomId,
|
||||
val name: String = "",
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import io.element.android.libraries.matrix.api.verification.VerificationEmoji
|
|||
import io.element.android.libraries.matrix.api.verification.VerificationFlowState
|
||||
import io.element.android.libraries.matrix.test.verification.FakeSessionVerificationService
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
|
|
@ -132,7 +133,7 @@ class VerifySelfSessionPresenterTests {
|
|||
presenter.present()
|
||||
}.test {
|
||||
requestVerificationAndAwaitVerifyingState(service)
|
||||
service.givenVerificationFlowState(VerificationFlowState.ReceivedVerificationData(emptyList()))
|
||||
service.givenVerificationFlowState(VerificationFlowState.ReceivedVerificationData(persistentListOf()))
|
||||
ensureAllEventsConsumed()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue