Pinned events : clean up banner code and add small test.
This commit is contained in:
parent
a8115e0a21
commit
88c07511d8
6 changed files with 69 additions and 27 deletions
|
|
@ -41,7 +41,6 @@ import io.element.android.features.messages.impl.actionlist.model.TimelineItemAc
|
||||||
import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents
|
import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents
|
||||||
import io.element.android.features.messages.impl.messagecomposer.MessageComposerPresenter
|
import io.element.android.features.messages.impl.messagecomposer.MessageComposerPresenter
|
||||||
import io.element.android.features.messages.impl.messagecomposer.MessageComposerState
|
import io.element.android.features.messages.impl.messagecomposer.MessageComposerState
|
||||||
import io.element.android.features.messages.impl.pinned.banner.PinnedMessagesBannerPresenter
|
|
||||||
import io.element.android.features.messages.impl.pinned.banner.PinnedMessagesBannerState
|
import io.element.android.features.messages.impl.pinned.banner.PinnedMessagesBannerState
|
||||||
import io.element.android.features.messages.impl.timeline.TimelineController
|
import io.element.android.features.messages.impl.timeline.TimelineController
|
||||||
import io.element.android.features.messages.impl.timeline.TimelineEvents
|
import io.element.android.features.messages.impl.timeline.TimelineEvents
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import io.element.android.libraries.architecture.Presenter
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class PinnedMessagesBannerPresenter @Inject constructor() : Presenter<PinnedMessagesBannerState> {
|
class PinnedMessagesBannerPresenter @Inject constructor() : Presenter<PinnedMessagesBannerState> {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): PinnedMessagesBannerState {
|
override fun present(): PinnedMessagesBannerState {
|
||||||
var pinnedMessageCount by remember {
|
var pinnedMessageCount by remember {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ package io.element.android.features.messages.impl.pinned.banner
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
|
||||||
internal class PinnedMessagesBannerStateProvider : PreviewParameterProvider<PinnedMessagesBannerState> {
|
internal class PinnedMessagesBannerStateProvider : PreviewParameterProvider<PinnedMessagesBannerState> {
|
||||||
|
|
||||||
override val values: Sequence<PinnedMessagesBannerState>
|
override val values: Sequence<PinnedMessagesBannerState>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
aPinnedMessagesBannerState(pinnedMessagesCount = 1, currentPinnedMessageIndex = 0),
|
aPinnedMessagesBannerState(pinnedMessagesCount = 1, currentPinnedMessageIndex = 0),
|
||||||
|
|
|
||||||
|
|
@ -32,15 +32,12 @@ import androidx.compose.foundation.layout.heightIn
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.drawBehind
|
import androidx.compose.ui.draw.drawBehind
|
||||||
|
|
@ -138,7 +135,7 @@ private fun PinIndicators(
|
||||||
val viewportSize = lazyListState.layoutInfo.viewportSize
|
val viewportSize = lazyListState.layoutInfo.viewportSize
|
||||||
lazyListState.animateScrollToItem(
|
lazyListState.animateScrollToItem(
|
||||||
pinIndex,
|
pinIndex,
|
||||||
(indicatorHeight / 2 - viewportSize.height / 2)
|
indicatorHeight / 2 - viewportSize.height / 2
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
|
|
@ -192,13 +189,12 @@ private fun PinnedMessageItem(
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
fun PinnedMessagesBannerViewPreview(@PreviewParameter(PinnedMessagesBannerStateProvider::class) state: PinnedMessagesBannerState) = ElementPreview {
|
internal fun PinnedMessagesBannerViewPreview(@PreviewParameter(PinnedMessagesBannerStateProvider::class) state: PinnedMessagesBannerState) = ElementPreview {
|
||||||
PinnedMessagesBannerView(
|
PinnedMessagesBannerView(
|
||||||
state = state,
|
state = state,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@ import io.element.android.features.poll.test.actions.FakeEndPollAction
|
||||||
import io.element.android.features.poll.test.actions.FakeSendPollResponseAction
|
import io.element.android.features.poll.test.actions.FakeSendPollResponseAction
|
||||||
import io.element.android.libraries.androidutils.clipboard.FakeClipboardHelper
|
import io.element.android.libraries.androidutils.clipboard.FakeClipboardHelper
|
||||||
import io.element.android.libraries.architecture.AsyncData
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
import io.element.android.libraries.architecture.Presenter
|
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
import io.element.android.libraries.core.mimetype.MimeTypes
|
import io.element.android.libraries.core.mimetype.MimeTypes
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||||
|
|
@ -160,7 +159,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
assertThat(room.markAsReadCalls).isEmpty()
|
assertThat(room.markAsReadCalls).isEmpty()
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -181,7 +180,7 @@ class MessagesPresenterTest {
|
||||||
canRedactOtherResult = { Result.success(true) },
|
canRedactOtherResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
).apply {
|
).apply {
|
||||||
givenRoomInfo(aRoomInfo(hasRoomCall = true))
|
givenRoomInfo(aRoomInfo(hasRoomCall = true))
|
||||||
}
|
}
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
|
|
@ -210,7 +209,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
|
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -248,7 +247,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
|
val presenter = createMessagesPresenter(matrixRoom = room, coroutineDispatchers = coroutineDispatchers)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -307,7 +306,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(
|
val presenter = createMessagesPresenter(
|
||||||
clipboardHelper = clipboardHelper,
|
clipboardHelper = clipboardHelper,
|
||||||
matrixRoom = matrixRoom,
|
matrixRoom = matrixRoom,
|
||||||
|
|
@ -497,7 +496,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
|
|
||||||
val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(true) }
|
val redactEventLambda = lambdaRecorder { _: EventId?, _: TransactionId?, _: String? -> Result.success(true) }
|
||||||
liveTimeline.redactEventLambda = redactEventLambda
|
liveTimeline.redactEventLambda = redactEventLambda
|
||||||
|
|
@ -572,7 +571,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -608,7 +607,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -633,7 +632,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -658,7 +657,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
room.givenRoomMembersState(
|
room.givenRoomMembersState(
|
||||||
MatrixRoomMembersState.Ready(
|
MatrixRoomMembersState.Ready(
|
||||||
persistentListOf(
|
persistentListOf(
|
||||||
|
|
@ -694,7 +693,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
room.givenRoomMembersState(
|
room.givenRoomMembersState(
|
||||||
MatrixRoomMembersState.Error(
|
MatrixRoomMembersState.Error(
|
||||||
failure = Throwable(),
|
failure = Throwable(),
|
||||||
|
|
@ -731,7 +730,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
room.givenRoomMembersState(MatrixRoomMembersState.Unknown)
|
room.givenRoomMembersState(MatrixRoomMembersState.Unknown)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = room)
|
val presenter = createMessagesPresenter(matrixRoom = room)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
|
@ -758,7 +757,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
room.givenRoomMembersState(
|
room.givenRoomMembersState(
|
||||||
MatrixRoomMembersState.Ready(
|
MatrixRoomMembersState.Ready(
|
||||||
persistentListOf(
|
persistentListOf(
|
||||||
|
|
@ -799,7 +798,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -824,7 +823,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -846,7 +845,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
@ -867,7 +866,7 @@ class MessagesPresenterTest {
|
||||||
canUserJoinCallResult = { Result.success(true) },
|
canUserJoinCallResult = { Result.success(true) },
|
||||||
typingNoticeResult = { Result.success(Unit) },
|
typingNoticeResult = { Result.success(Unit) },
|
||||||
canUserPinUnpinResult = { Result.success(true) },
|
canUserPinUnpinResult = { Result.success(true) },
|
||||||
)
|
)
|
||||||
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
presenter.present()
|
presenter.present()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.element.android.features.messages.impl.pinned.banner
|
||||||
|
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.tests.testutils.test
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class PinnedMessagesBannerPresenterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `present - initial state`() = runTest {
|
||||||
|
val presenter = createPinnedMessagesBannerPresenter()
|
||||||
|
presenter.test {
|
||||||
|
val initialState = awaitItem()
|
||||||
|
assertThat(initialState.pinnedMessagesCount).isEqualTo(0)
|
||||||
|
assertThat(initialState.currentPinnedMessageIndex).isEqualTo(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `present - move to next pinned message when there is no pinned events`() = runTest {
|
||||||
|
val presenter = createPinnedMessagesBannerPresenter()
|
||||||
|
presenter.test {
|
||||||
|
val initialState = awaitItem()
|
||||||
|
initialState.eventSink(PinnedMessagesBannerEvents.MoveToNextPinned)
|
||||||
|
// Nothing is emitted
|
||||||
|
ensureAllEventsConsumed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createPinnedMessagesBannerPresenter(): PinnedMessagesBannerPresenter {
|
||||||
|
return PinnedMessagesBannerPresenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue