Extract Provider (and rename them) to their own file and move fixture(s) there.

This commit is contained in:
Benoit Marty 2023-02-13 11:23:30 +01:00 committed by Benoit Marty
parent 41965a8bcc
commit e120ca7163
46 changed files with 593 additions and 302 deletions

View file

@ -49,8 +49,8 @@ import io.element.android.features.messages.textcomposer.MessageComposerView
import io.element.android.features.messages.textcomposer.aMessageComposerState
import io.element.android.features.messages.timeline.TimelineView
import io.element.android.features.messages.timeline.aTimelineState
import io.element.android.features.messages.timeline.createTimelineItemContent
import io.element.android.features.messages.timeline.createTimelineItems
import io.element.android.features.messages.timeline.aTimelineItemContent
import io.element.android.features.messages.timeline.aTimelineItemList
import io.element.android.features.messages.timeline.model.TimelineItem
import io.element.android.libraries.core.data.StableCharSequence
import io.element.android.libraries.designsystem.components.avatar.Avatar
@ -217,7 +217,7 @@ private fun ContentToPreview() {
mode = MessageComposerMode.Normal("Hello"),
),
timelineState = aTimelineState().copy(
timelineItems = createTimelineItems(createTimelineItemContent()),
timelineItems = aTimelineItemList(aTimelineItemContent()),
hasMoreToLoad = false,
),
actionListState = anActionListState(),

View file

@ -26,7 +26,6 @@ data class ActionListState(
val target: Target,
val eventSink: (ActionListEvents) -> Unit,
) {
sealed interface Target {
object None : Target
data class Loading(val messageEvent: TimelineItem.MessageEvent) : Target
@ -36,8 +35,3 @@ data class ActionListState(
) : Target
}
}
fun anActionListState() = ActionListState(
target = ActionListState.Target.None,
eventSink = {}
)

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2023 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
*
* http://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.actionlist
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.messages.actionlist.model.TimelineItemAction
import io.element.android.features.messages.timeline.aMessageEvent
import kotlinx.collections.immutable.persistentListOf
open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
override val values: Sequence<ActionListState>
get() = sequenceOf(
anActionListState(),
anActionListState().copy(target = ActionListState.Target.Loading(aMessageEvent())),
anActionListState().copy(
target = ActionListState.Target.Success(
messageEvent = aMessageEvent(),
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Copy,
TimelineItemAction.Edit,
TimelineItemAction.Redact,
)
)
)
)
}
fun anActionListState() = ActionListState(
target = ActionListState.Target.None,
eventSink = {}
)

View file

@ -39,16 +39,13 @@ import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import io.element.android.features.messages.actionlist.model.TimelineItemAction
import io.element.android.features.messages.timeline.createMessageEvent
import io.element.android.features.messages.timeline.model.TimelineItem
import io.element.android.libraries.designsystem.components.VectorIcon
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.ModalBottomSheetLayout
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch
@ -136,34 +133,14 @@ private fun SheetContent(
}
}
open class ActionListStatePreviewParameterProvider : PreviewParameterProvider<ActionListState> {
override val values: Sequence<ActionListState>
get() = sequenceOf(
anActionListState(),
anActionListState().copy(target = ActionListState.Target.Loading(createMessageEvent())),
anActionListState().copy(
target = ActionListState.Target.Success(
messageEvent = createMessageEvent(),
actions = persistentListOf(
TimelineItemAction.Reply,
TimelineItemAction.Forward,
TimelineItemAction.Copy,
TimelineItemAction.Edit,
TimelineItemAction.Redact,
)
)
)
)
}
@Preview
@Composable
fun SheetContentLightPreview(@PreviewParameter(ActionListStatePreviewParameterProvider::class) state: ActionListState) =
fun SheetContentLightPreview(@PreviewParameter(ActionListStateProvider::class) state: ActionListState) =
ElementPreviewLight { ContentToPreview(state) }
@Preview
@Composable
fun SheetContentDarkPreview(@PreviewParameter(ActionListStatePreviewParameterProvider::class) state: ActionListState) =
fun SheetContentDarkPreview(@PreviewParameter(ActionListStateProvider::class) state: ActionListState) =
ElementPreviewDark { ContentToPreview(state) }
@Composable

View file

@ -20,7 +20,6 @@ import androidx.compose.runtime.Immutable
import io.element.android.features.messages.timeline.model.TimelineItem
import io.element.android.libraries.matrix.core.EventId
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
@Immutable
data class TimelineState(
@ -29,10 +28,3 @@ data class TimelineState(
val highlightedEventId: EventId?,
val eventSink: (TimelineEvents) -> Unit
)
fun aTimelineState() = TimelineState(
timelineItems = persistentListOf(),
hasMoreToLoad = false,
highlightedEventId = null,
eventSink = {}
)

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2023 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
*
* http://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.timeline
import io.element.android.features.messages.timeline.model.AggregatedReaction
import io.element.android.features.messages.timeline.model.MessagesItemGroupPosition
import io.element.android.features.messages.timeline.model.TimelineItem
import io.element.android.features.messages.timeline.model.TimelineItemReactions
import io.element.android.features.messages.timeline.model.content.TimelineItemContent
import io.element.android.features.messages.timeline.model.content.TimelineItemTextContent
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.matrix.core.EventId
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
fun aTimelineState() = TimelineState(
timelineItems = persistentListOf(),
hasMoreToLoad = false,
highlightedEventId = null,
eventSink = {}
)
internal fun aTimelineItemList(content: TimelineItemContent): ImmutableList<TimelineItem> {
return persistentListOf(
// 3 items (First Middle Last) with isMine = false
aMessageEvent(
isMine = false,
content = content,
groupPosition = MessagesItemGroupPosition.Last
),
aMessageEvent(
isMine = false,
content = content,
groupPosition = MessagesItemGroupPosition.Middle
),
aMessageEvent(
isMine = false,
content = content,
groupPosition = MessagesItemGroupPosition.First
),
// 3 items (First Middle Last) with isMine = true
aMessageEvent(
isMine = true,
content = content,
groupPosition = MessagesItemGroupPosition.Last
),
aMessageEvent(
isMine = true,
content = content,
groupPosition = MessagesItemGroupPosition.Middle
),
aMessageEvent(
isMine = true,
content = content,
groupPosition = MessagesItemGroupPosition.First
),
)
}
internal fun aMessageEvent(
isMine: Boolean = false,
content: TimelineItemContent = aTimelineItemContent(),
groupPosition: MessagesItemGroupPosition = MessagesItemGroupPosition.First
): TimelineItem.MessageEvent {
return TimelineItem.MessageEvent(
id = EventId(Math.random().toString()),
senderId = "@senderId",
senderAvatar = AvatarData("@senderId", "sender"),
content = content,
reactionsState = TimelineItemReactions(
persistentListOf(
AggregatedReaction("👍", "1")
)
),
isMine = isMine,
senderDisplayName = "sender",
groupPosition = groupPosition,
)
}
internal fun aTimelineItemContent(): TimelineItemContent {
return TimelineItemTextContent(
body = "Text",
htmlDocument = null
)
}

View file

@ -61,17 +61,13 @@ import io.element.android.features.messages.timeline.components.TimelineItemReac
import io.element.android.features.messages.timeline.components.TimelineItemRedactedView
import io.element.android.features.messages.timeline.components.TimelineItemTextView
import io.element.android.features.messages.timeline.components.TimelineItemUnknownView
import io.element.android.features.messages.timeline.model.AggregatedReaction
import io.element.android.features.messages.timeline.model.MessagesItemGroupPosition
import io.element.android.features.messages.timeline.model.TimelineItem
import io.element.android.features.messages.timeline.model.TimelineItemReactions
import io.element.android.features.messages.timeline.model.content.MessagesTimelineItemContentProvider
import io.element.android.features.messages.timeline.model.content.TimelineItemContentProvider
import io.element.android.features.messages.timeline.model.content.TimelineItemContent
import io.element.android.features.messages.timeline.model.content.TimelineItemEncryptedContent
import io.element.android.features.messages.timeline.model.content.TimelineItemImageContent
import io.element.android.features.messages.timeline.model.content.TimelineItemRedactedContent
import io.element.android.features.messages.timeline.model.content.TimelineItemTextBasedContent
import io.element.android.features.messages.timeline.model.content.TimelineItemTextContent
import io.element.android.features.messages.timeline.model.content.TimelineItemUnknownContent
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarData
@ -81,9 +77,7 @@ import io.element.android.libraries.designsystem.theme.components.CircularProgre
import io.element.android.libraries.designsystem.theme.components.FloatingActionButton
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.core.EventId
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
@ -354,18 +348,18 @@ internal fun TimelineLoadingMoreIndicator() {
@Preview
@Composable
fun LoginRootScreenLightPreview(
@PreviewParameter(MessagesTimelineItemContentProvider::class) content: TimelineItemContent
@PreviewParameter(TimelineItemContentProvider::class) content: TimelineItemContent
) = ElementPreviewLight { ContentToPreview(content) }
@Preview
@Composable
fun LoginRootScreenDarkPreview(
@PreviewParameter(MessagesTimelineItemContentProvider::class) content: TimelineItemContent
@PreviewParameter(TimelineItemContentProvider::class) content: TimelineItemContent
) = ElementPreviewDark { ContentToPreview(content) }
@Composable
private fun ContentToPreview(content: TimelineItemContent) {
val timelineItems = createTimelineItems(content)
val timelineItems = aTimelineItemList(content)
TimelineView(
state = aTimelineState().copy(
timelineItems = timelineItems,
@ -373,68 +367,3 @@ private fun ContentToPreview(content: TimelineItemContent) {
)
)
}
internal fun createTimelineItems(content: TimelineItemContent): ImmutableList<TimelineItem> {
return persistentListOf(
// 3 items (First Middle Last) with isMine = false
createMessageEvent(
isMine = false,
content = content,
groupPosition = MessagesItemGroupPosition.Last
),
createMessageEvent(
isMine = false,
content = content,
groupPosition = MessagesItemGroupPosition.Middle
),
createMessageEvent(
isMine = false,
content = content,
groupPosition = MessagesItemGroupPosition.First
),
// 3 items (First Middle Last) with isMine = true
createMessageEvent(
isMine = true,
content = content,
groupPosition = MessagesItemGroupPosition.Last
),
createMessageEvent(
isMine = true,
content = content,
groupPosition = MessagesItemGroupPosition.Middle
),
createMessageEvent(
isMine = true,
content = content,
groupPosition = MessagesItemGroupPosition.First
),
)
}
internal fun createMessageEvent(
isMine: Boolean = false,
content: TimelineItemContent = createTimelineItemContent(),
groupPosition: MessagesItemGroupPosition = MessagesItemGroupPosition.First
): TimelineItem.MessageEvent {
return TimelineItem.MessageEvent(
id = EventId(Math.random().toString()),
senderId = "@senderId",
senderAvatar = AvatarData("@senderId", "sender"),
content = content,
reactionsState = TimelineItemReactions(
persistentListOf(
AggregatedReaction("👍", "1")
)
),
isMine = isMine,
senderDisplayName = "sender",
groupPosition = groupPosition,
)
}
internal fun createTimelineItemContent(): TimelineItemContent {
return TimelineItemTextContent(
body = "Text",
htmlDocument = null
)
}

View file

@ -17,7 +17,6 @@
package io.element.android.features.messages.timeline.model
import androidx.compose.runtime.Immutable
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
@Immutable
sealed interface MessagesItemGroupPosition {
@ -32,11 +31,3 @@ sealed interface MessagesItemGroupPosition {
}
}
internal class TimelineItemGroupPositionProvider : PreviewParameterProvider<MessagesItemGroupPosition> {
override val values = sequenceOf(
MessagesItemGroupPosition.First,
MessagesItemGroupPosition.Middle,
MessagesItemGroupPosition.Last,
MessagesItemGroupPosition.None,
)
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2023 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
*
* http://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.timeline.model
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
internal class TimelineItemGroupPositionProvider : PreviewParameterProvider<MessagesItemGroupPosition> {
override val values = sequenceOf(
MessagesItemGroupPosition.First,
MessagesItemGroupPosition.Middle,
MessagesItemGroupPosition.Last,
MessagesItemGroupPosition.None,
)
}

View file

@ -16,30 +16,4 @@
package io.element.android.features.messages.timeline.model.content
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import org.matrix.rustcomponents.sdk.EncryptedMessage
sealed interface TimelineItemContent
class MessagesTimelineItemContentProvider : PreviewParameterProvider<TimelineItemContent> {
override val values = sequenceOf(
TimelineItemEmoteContent(
body = "Emote",
htmlDocument = null
),
TimelineItemEncryptedContent(
encryptedMessage = EncryptedMessage.Unknown
),
// TODO MessagesTimelineItemImageContent(),
TimelineItemNoticeContent(
body = "Notice",
htmlDocument = null
),
TimelineItemRedactedContent,
TimelineItemTextContent(
body = "Text",
htmlDocument = null
),
TimelineItemUnknownContent,
)
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 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
*
* http://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.timeline.model.content
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import org.matrix.rustcomponents.sdk.EncryptedMessage
class TimelineItemContentProvider : PreviewParameterProvider<TimelineItemContent> {
override val values = sequenceOf(
TimelineItemEmoteContent(
body = "Emote",
htmlDocument = null
),
TimelineItemEncryptedContent(
encryptedMessage = EncryptedMessage.Unknown
),
// TODO MessagesTimelineItemImageContent(),
TimelineItemNoticeContent(
body = "Notice",
htmlDocument = null
),
TimelineItemRedactedContent,
TimelineItemTextContent(
body = "Text",
htmlDocument = null
),
TimelineItemUnknownContent,
)
}