Update plugin ktlint to v12.1.0 (#2200)
* Update plugin ktlint to v12.1.0 * Run `./gradlew ktlintFormat` and fix some issues manually. * Fix other issues reproted by Ktlint * Limit false positives, KtLint removes unnecessary curly brace in String templates. * Remove useless Unit * Minor improvements over ktlint changes * Restore `AlertDialogContent` behaviour * Update screenshots --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Benoit Marty <benoit@matrix.org> Co-authored-by: Jorge Martín <jorgem@element.io> Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
parent
675cc525cf
commit
7e9cda3aa9
442 changed files with 1091 additions and 1081 deletions
|
|
@ -152,7 +152,8 @@ internal fun ExpandableBottomSheetScaffold(
|
|||
top.place(x = 0, y = 0)
|
||||
}
|
||||
},
|
||||
content = { sheetContent(false) })
|
||||
content = { sheetContent(false) }
|
||||
)
|
||||
}, sheetDragHandle, peekHeight)
|
||||
}.map { measurable: Measurable ->
|
||||
measurable.measure(constraints)
|
||||
|
|
@ -161,7 +162,8 @@ internal fun ExpandableBottomSheetScaffold(
|
|||
layout(constraints.maxWidth, constraints.maxHeight) {
|
||||
scaffoldPlaceable.place(0, 0)
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun CustomSheetState.getIntOffset(): Int? = try {
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@ import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPr
|
|||
import io.element.android.features.messages.impl.timeline.di.TimelineItemPresenterFactories
|
||||
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||
import io.element.android.libraries.core.bool.orFalse
|
||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||
import io.element.android.libraries.di.RoomScope
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||
import io.element.android.services.analytics.api.AnalyticsService
|
||||
import io.element.android.services.analytics.api.extensions.toAnalyticsViewRoom
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
|
|||
|
|
@ -172,9 +172,10 @@ private fun SheetContent(
|
|||
item {
|
||||
Column {
|
||||
MessageSummary(
|
||||
event = target.event, modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
event = target.event,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.height(14.dp))
|
||||
HorizontalDivider()
|
||||
|
|
@ -299,7 +300,11 @@ private fun EmojiReactionsRow(
|
|||
) {
|
||||
// TODO use most recently used emojis here when available from the Rust SDK
|
||||
val defaultEmojis = sequenceOf(
|
||||
"👍️", "👎️", "🔥", "❤️", "👏"
|
||||
"👍️",
|
||||
"👎️",
|
||||
"🔥",
|
||||
"❤️",
|
||||
"👏"
|
||||
)
|
||||
for (emoji in defaultEmojis) {
|
||||
val isHighlighted = highlightedEmojis.contains(emoji)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ class AttachmentsPreviewPresenter @AssistedInject constructor(
|
|||
|
||||
@Composable
|
||||
override fun present(): AttachmentsPreviewState {
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
val sendActionState = remember {
|
||||
|
|
|
|||
|
|
@ -34,4 +34,3 @@ sealed interface SendActionState {
|
|||
data class Failure(val error: Throwable) : SendActionState
|
||||
data object Done : SendActionState
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ open class AttachmentsPreviewStateProvider : PreviewParameterProvider<Attachment
|
|||
|
||||
fun anAttachmentsPreviewState(
|
||||
mediaInfo: MediaInfo = anImageInfo(),
|
||||
sendActionState: SendActionState = SendActionState.Idle) = AttachmentsPreviewState(
|
||||
sendActionState: SendActionState = SendActionState.Idle
|
||||
) = AttachmentsPreviewState(
|
||||
attachment = Attachment.Media(
|
||||
localMedia = LocalMedia("file://path".toUri(), mediaInfo),
|
||||
compressIfPossible = true
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ fun AttachmentsPreviewView(
|
|||
onDismiss: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
||||
fun postSendAttachment() {
|
||||
state.eventSink(AttachmentsPreviewEvents.SendAttachment)
|
||||
}
|
||||
|
|
@ -88,7 +87,6 @@ private fun AttachmentSendStateView(
|
|||
onDismissClicked: () -> Unit,
|
||||
onRetryClicked: () -> Unit
|
||||
) {
|
||||
|
||||
when (sendActionState) {
|
||||
is SendActionState.Sending -> {
|
||||
ProgressDialog(
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ object MentionSuggestionsProcessor {
|
|||
}
|
||||
|
||||
fun memberMatchesQuery(member: RoomMember, query: String): Boolean {
|
||||
return member.userId.value.contains(query, ignoreCase = true)
|
||||
|| member.displayName?.contains(query, ignoreCase = true) == true
|
||||
return member.userId.value.contains(query, ignoreCase = true) ||
|
||||
member.displayName?.contains(query, ignoreCase = true) == true
|
||||
}
|
||||
|
||||
val matchingMembers = roomMembers
|
||||
|
|
|
|||
|
|
@ -62,12 +62,12 @@ internal fun AttachmentsBottomSheet(
|
|||
}
|
||||
|
||||
LaunchedEffect(state.showAttachmentSourcePicker) {
|
||||
if (state.showAttachmentSourcePicker) {
|
||||
isVisible = if (state.showAttachmentSourcePicker) {
|
||||
// We need to use this instead of `LocalFocusManager.clearFocus()` to hide the keyboard when focus is on an Android View
|
||||
localView.hideKeyboard()
|
||||
isVisible = true
|
||||
true
|
||||
} else {
|
||||
isVisible = false
|
||||
false
|
||||
}
|
||||
}
|
||||
// Send 'DismissAttachmentMenu' event when the bottomsheet was just hidden
|
||||
|
|
@ -122,7 +122,7 @@ private fun AttachmentSourcePickerMenu(
|
|||
)
|
||||
ListItem(
|
||||
modifier = Modifier.clickable { state.eventSink(MessageComposerEvents.PickAttachmentSource.PhotoFromCamera) },
|
||||
leadingContent = ListItemContent.Icon(IconSource.Resource(CommonDrawables.ic_take_photo_camera, )),
|
||||
leadingContent = ListItemContent.Icon(IconSource.Resource(CommonDrawables.ic_take_photo_camera)),
|
||||
headlineContent = { Text(stringResource(R.string.screen_room_attachment_source_camera_photo)) },
|
||||
style = ListItemStyle.Primary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -456,4 +456,3 @@ class MessageComposerPresenter @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,4 +35,3 @@ class DefaultRichTextEditorStateFactory @Inject constructor() : RichTextEditorSt
|
|||
return rememberRichTextEditorState()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import javax.inject.Inject
|
|||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
@SingleIn(SessionScope::class)
|
||||
class DefaultHtmlConverterProvider @Inject constructor(): HtmlConverterProvider {
|
||||
class DefaultHtmlConverterProvider @Inject constructor() : HtmlConverterProvider {
|
||||
|
||||
private val htmlConverter: MutableState<HtmlConverter?> = mutableStateOf(null)
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ class DefaultHtmlConverterProvider @Inject constructor(): HtmlConverterProvider
|
|||
return TextDisplay.Custom(mentionSpanProvider.getMentionSpanFor(text, url))
|
||||
}
|
||||
},
|
||||
isMention = { _, url -> mentionDetector?.isMention(url).orFalse() }
|
||||
isMention = { _, url -> mentionDetector?.isMention(url).orFalse() }
|
||||
).apply {
|
||||
configureWith(editorStyle)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,7 +179,9 @@ internal fun aTimelineItemDebugInfo(
|
|||
originalJson: String? = null,
|
||||
latestEditedJson: String? = null,
|
||||
) = TimelineItemDebugInfo(
|
||||
model, originalJson, latestEditedJson
|
||||
model,
|
||||
originalJson,
|
||||
latestEditedJson
|
||||
)
|
||||
|
||||
internal fun aTimelineItemReadReceipts(): TimelineItemReadReceipts {
|
||||
|
|
|
|||
|
|
@ -120,8 +120,8 @@ fun TimelineView(
|
|||
timelineItem = timelineItem,
|
||||
timelineRoomInfo = state.timelineRoomInfo,
|
||||
showReadReceipts = state.showReadReceipts,
|
||||
isLastOutgoingMessage = (timelineItem as? TimelineItem.Event)?.isMine == true
|
||||
&& state.timelineItems.first().identifier() == timelineItem.identifier(),
|
||||
isLastOutgoingMessage = (timelineItem as? TimelineItem.Event)?.isMine == true &&
|
||||
state.timelineItems.first().identifier() == timelineItem.identifier(),
|
||||
highlightedItem = state.highlightedEventId?.value,
|
||||
onClick = onMessageClicked,
|
||||
onLongClick = onMessageLongClicked,
|
||||
|
|
|
|||
|
|
@ -165,8 +165,7 @@ private fun ReactionContent(
|
|||
model = MediaRequestData(MediaSource(reaction.key), MediaRequestData.Kind.Content),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Text(
|
||||
text = reaction.displayKey,
|
||||
style = ElementTheme.typography.fontBodyMdRegular.copy(
|
||||
|
|
@ -225,4 +224,3 @@ internal fun MessagesReactionExtraButtonsPreview() = ElementPreview {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
|
||||
|
|
|
|||
|
|
@ -419,7 +419,6 @@ private fun MessageEventBubbleContent(
|
|||
@Suppress("ModifierNaming")
|
||||
bubbleModifier: Modifier = Modifier, // need to rename this modifier to prevent linter false positives
|
||||
) {
|
||||
|
||||
// Long clicks are not not automatically propagated from a `clickable`
|
||||
// to its `combinedClickable` parent so we do it manually
|
||||
fun onTimestampLongClick() = onMessageLongClick()
|
||||
|
|
@ -578,7 +577,6 @@ private fun MessageEventBubbleContent(
|
|||
.clip(RoundedCornerShape(6.dp))
|
||||
.clickable(enabled = true, onClick = inReplyToClick),
|
||||
)
|
||||
|
||||
}
|
||||
if (inReplyToDetails != null) {
|
||||
// Use SubComposeLayout only if necessary as it can have consequences on the performance.
|
||||
|
|
@ -669,7 +667,7 @@ internal fun TimelineItemEventRowPreview() = ElementPreview {
|
|||
isMine = it,
|
||||
content = aTimelineItemTextContent().copy(
|
||||
body = "A long text which will be displayed on several lines and" +
|
||||
" hopefully can be manually adjusted to test different behaviors."
|
||||
" hopefully can be manually adjusted to test different behaviors."
|
||||
),
|
||||
groupPosition = TimelineItemGroupPosition.First,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -59,4 +59,3 @@ internal fun TimelineItemEventRowForDirectRoomPreview() = ElementPreview {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,4 +42,3 @@ internal fun TimelineItemEventRowWithManyReactionsPreview() = ElementPreview {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import io.element.android.features.messages.impl.R
|
||||
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
|
||||
import io.element.android.features.messages.impl.timeline.TimelineEvents
|
||||
import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
|
||||
import io.element.android.features.messages.impl.timeline.aGroupedEvents
|
||||
import io.element.android.features.messages.impl.timeline.aTimelineRoomInfo
|
||||
import io.element.android.features.messages.impl.timeline.components.group.GroupHeaderView
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ fun TimelineItemReactionsLayout(
|
|||
return rows
|
||||
}
|
||||
|
||||
/// Given a list of rows place them in the layout.
|
||||
// Given a list of rows place them in the layout.
|
||||
fun layoutRows(rows: List<List<Placeable>>): MeasureResult {
|
||||
var width = 0
|
||||
var height = 0
|
||||
|
|
|
|||
|
|
@ -75,11 +75,11 @@ private fun TimelineItemReactionsView(
|
|||
// In LTR languages we want an incoming message's reactions to be LTR and outgoing to be RTL.
|
||||
// For RTL languages it should be the opposite.
|
||||
val currentLayout = LocalLayoutDirection.current
|
||||
val reactionsLayoutDirection = if (!isOutgoing) currentLayout
|
||||
else if (currentLayout == LayoutDirection.Ltr)
|
||||
LayoutDirection.Rtl
|
||||
else
|
||||
LayoutDirection.Ltr
|
||||
val reactionsLayoutDirection = when {
|
||||
!isOutgoing -> currentLayout
|
||||
currentLayout == LayoutDirection.Ltr -> LayoutDirection.Rtl
|
||||
else -> LayoutDirection.Ltr
|
||||
}
|
||||
|
||||
return CompositionLocalProvider(LocalLayoutDirection provides reactionsLayoutDirection) {
|
||||
TimelineItemReactionsLayout(
|
||||
|
|
@ -104,7 +104,9 @@ private fun TimelineItemReactionsView(
|
|||
onLongClick = {}
|
||||
)
|
||||
}
|
||||
} else null,
|
||||
} else {
|
||||
null
|
||||
},
|
||||
reactions = {
|
||||
reactions.forEach { reaction ->
|
||||
CompositionLocalProvider(LocalLayoutDirection provides currentLayout) {
|
||||
|
|
@ -174,4 +176,3 @@ private fun ContentToPreview(
|
|||
onMoreReactionsClicked = {},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package io.element.android.features.messages.impl.timeline.components
|
|||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import io.element.android.features.messages.impl.timeline.session.SessionState
|
||||
import io.element.android.features.messages.impl.timeline.components.virtual.TimelineEncryptedHistoryBannerView
|
||||
import io.element.android.features.messages.impl.timeline.components.virtual.TimelineItemDaySeparatorView
|
||||
import io.element.android.features.messages.impl.timeline.components.virtual.TimelineItemReadMarkerView
|
||||
|
|
@ -26,6 +25,7 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
|||
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemDaySeparatorModel
|
||||
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemEncryptedHistoryBannerVirtualModel
|
||||
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemReadMarkerModel
|
||||
import io.element.android.features.messages.impl.timeline.session.SessionState
|
||||
|
||||
@Composable
|
||||
fun TimelineItemVirtualRow(
|
||||
|
|
@ -39,4 +39,3 @@ fun TimelineItemVirtualRow(
|
|||
is TimelineItemEncryptedHistoryBannerVirtualModel -> TimelineEncryptedHistoryBannerView(sessionState, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ import androidx.compose.runtime.MutableState
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import kotlinx.coroutines.launch
|
||||
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import kotlinx.collections.immutable.toImmutableSet
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class CustomReactionPresenter @Inject constructor(
|
||||
|
|
@ -59,7 +59,12 @@ class CustomReactionPresenter @Inject constructor(
|
|||
}
|
||||
}
|
||||
val event = (target.value as? CustomReactionState.Target.Success)?.event
|
||||
val selectedEmoji = event?.reactionsState?.reactions?.mapNotNull { if(it.isHighlighted) it.key else null }.orEmpty().toImmutableSet()
|
||||
val selectedEmoji = event
|
||||
?.reactionsState
|
||||
?.reactions
|
||||
?.mapNotNull { if (it.isHighlighted) it.key else null }
|
||||
.orEmpty()
|
||||
.toImmutableSet()
|
||||
return CustomReactionState(
|
||||
target = target.value,
|
||||
selectedEmoji = selectedEmoji,
|
||||
|
|
|
|||
|
|
@ -35,4 +35,3 @@ data class CustomReactionState(
|
|||
) : Target
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,9 @@ import android.content.Context
|
|||
import io.element.android.emojibasebindings.EmojibaseDatasource
|
||||
import io.element.android.emojibasebindings.EmojibaseStore
|
||||
|
||||
class DefaultEmojibaseProvider(val context: Context): EmojibaseProvider {
|
||||
class DefaultEmojibaseProvider(val context: Context) : EmojibaseProvider {
|
||||
|
||||
override val emojibaseStore: EmojibaseStore by lazy {
|
||||
EmojibaseDatasource().load(context)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ fun TimelineItem.Event.toExtraPadding(): ExtraPadding {
|
|||
private fun TextMeasurer.getExtraPadding(text: String, density: Density): Dp {
|
||||
val timestampTextStyle = ElementTheme.typography.fontBodyXsRegular
|
||||
val textWidth = measure(text = text, style = timestampTextStyle).size.width
|
||||
return (textWidth/density.density).dp
|
||||
return (textWidth / density.density).dp
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ fun TimelineItemInformativeView(
|
|||
) {
|
||||
Row(
|
||||
modifier = modifier.onSizeChanged { size ->
|
||||
onContentLayoutChanged(
|
||||
onContentLayoutChanged(
|
||||
ContentAvoidingLayoutData(
|
||||
contentWidth = size.width,
|
||||
contentHeight = size.height,
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ import androidx.compose.ui.unit.dp
|
|||
import io.element.android.features.location.api.StaticMapView
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContentProvider
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
|
||||
@Composable
|
||||
|
|
@ -62,4 +62,3 @@ internal fun TimelineItemLocationViewPreview(@PreviewParameter(TimelineItemLocat
|
|||
ElementPreview {
|
||||
TimelineItemLocationView(content)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ import androidx.compose.material3.MaterialTheme
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemStateEventContent
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
|
||||
@Composable
|
||||
fun TimelineItemStateView(
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ fun TimelineItemTextView(
|
|||
LocalContentColor provides ElementTheme.colors.textPrimary,
|
||||
LocalTextStyle provides ElementTheme.typography.fontBodyLgRegular
|
||||
) {
|
||||
|
||||
val formattedBody = content.formattedBody
|
||||
val body = SpannableString(formattedBody ?: content.body)
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContentProvider
|
||||
import io.element.android.libraries.designsystem.components.BlurHashAsyncImage
|
||||
import io.element.android.libraries.designsystem.modifiers.roundedBackground
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.matrix.ui.media.MediaRequestData
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
|
|
|
|||
|
|
@ -65,18 +65,17 @@ class ReactionSummaryPresenter @Inject constructor(
|
|||
derivedStateOf {
|
||||
summary?.let { summary ->
|
||||
summary.copy(reactions = summary.reactions.map { reaction ->
|
||||
reaction.copy(senders = reaction.senders.map { sender ->
|
||||
val member = members.firstOrNull { it.userId == sender.senderId }
|
||||
val user = MatrixUser(
|
||||
userId = sender.senderId,
|
||||
displayName = member?.displayName,
|
||||
avatarUrl = member?.avatarUrl
|
||||
)
|
||||
sender.copy(user = user)
|
||||
})
|
||||
reaction.copy(senders = reaction.senders.map { sender ->
|
||||
val member = members.firstOrNull { it.userId == sender.senderId }
|
||||
val user = MatrixUser(
|
||||
userId = sender.senderId,
|
||||
displayName = member?.displayName,
|
||||
avatarUrl = member?.avatarUrl
|
||||
)
|
||||
sender.copy(user = user)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,11 +22,10 @@ import io.element.android.libraries.matrix.api.core.EventId
|
|||
data class ReactionSummaryState(
|
||||
val target: Summary?,
|
||||
val eventSink: (ReactionSummaryEvents) -> Unit
|
||||
){
|
||||
) {
|
||||
data class Summary(
|
||||
val reactions: List<AggregatedReaction>,
|
||||
val selectedKey: String,
|
||||
val selectedEventId: EventId
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ private fun SheetContent(
|
|||
|
||||
LaunchedEffect(pagerState.currentPage) {
|
||||
selectedReactionKey = summary.reactions[pagerState.currentPage].key
|
||||
val visibleInfo = reactionListState.layoutInfo.visibleItemsInfo
|
||||
val visibleInfo = reactionListState.layoutInfo.visibleItemsInfo
|
||||
if (selectedReactionIndex <= visibleInfo.first().index || selectedReactionIndex >= visibleInfo.last().index) {
|
||||
reactionListState.animateScrollToItem(selectedReactionIndex)
|
||||
}
|
||||
|
|
@ -174,7 +174,6 @@ private fun AggregatedReactionButton(
|
|||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
|
||||
val buttonColor = if (isHighlighted) {
|
||||
ElementTheme.colors.bgActionPrimaryRest
|
||||
} else {
|
||||
|
|
@ -209,8 +208,7 @@ private fun AggregatedReactionButton(
|
|||
model = MediaRequestData(MediaSource(reaction.key), MediaRequestData.Kind.Content),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Text(
|
||||
text = reaction.displayKey,
|
||||
style = ElementTheme.typography.fontBodyMdRegular.copy(
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.zIndex
|
||||
import io.element.android.appconfig.TimelineConfig
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.features.messages.impl.timeline.model.ReadReceiptData
|
||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
|
|
@ -50,7 +51,6 @@ import io.element.android.libraries.designsystem.theme.components.Icon
|
|||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.libraries.ui.strings.CommonPlurals
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
@ -76,33 +76,35 @@ fun TimelineItemReadReceiptView(
|
|||
)
|
||||
}
|
||||
}
|
||||
} else when (state.sendState) {
|
||||
LocalEventSendState.NotSentYet -> {
|
||||
ReadReceiptsRow(modifier) {
|
||||
Icon(
|
||||
modifier = Modifier.padding(2.dp),
|
||||
resourceId = CommonDrawables.ic_sending,
|
||||
contentDescription = stringResource(id = CommonStrings.common_sending),
|
||||
tint = ElementTheme.colors.iconSecondary
|
||||
)
|
||||
}
|
||||
}
|
||||
LocalEventSendState.Canceled -> Unit
|
||||
is LocalEventSendState.SendingFailed -> {
|
||||
// Error? The timestamp is already displayed in red
|
||||
}
|
||||
null,
|
||||
is LocalEventSendState.Sent -> {
|
||||
if (state.isLastOutgoingMessage) {
|
||||
ReadReceiptsRow(modifier = modifier) {
|
||||
} else {
|
||||
when (state.sendState) {
|
||||
LocalEventSendState.NotSentYet -> {
|
||||
ReadReceiptsRow(modifier) {
|
||||
Icon(
|
||||
modifier = Modifier.padding(2.dp),
|
||||
resourceId = CommonDrawables.ic_sent,
|
||||
contentDescription = stringResource(id = CommonStrings.common_sent),
|
||||
resourceId = CommonDrawables.ic_sending,
|
||||
contentDescription = stringResource(id = CommonStrings.common_sending),
|
||||
tint = ElementTheme.colors.iconSecondary
|
||||
)
|
||||
}
|
||||
}
|
||||
LocalEventSendState.Canceled -> Unit
|
||||
is LocalEventSendState.SendingFailed -> {
|
||||
// Error? The timestamp is already displayed in red
|
||||
}
|
||||
null,
|
||||
is LocalEventSendState.Sent -> {
|
||||
if (state.isLastOutgoingMessage) {
|
||||
ReadReceiptsRow(modifier = modifier) {
|
||||
Icon(
|
||||
modifier = Modifier.padding(2.dp),
|
||||
resourceId = CommonDrawables.ic_sent,
|
||||
contentDescription = stringResource(id = CommonStrings.common_sent),
|
||||
tint = ElementTheme.colors.iconSecondary
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,7 @@ import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
|||
import io.element.android.libraries.architecture.Presenter
|
||||
import javax.inject.Inject
|
||||
|
||||
class ReadReceiptBottomSheetPresenter @Inject constructor(
|
||||
) : Presenter<ReadReceiptBottomSheetState> {
|
||||
class ReadReceiptBottomSheetPresenter @Inject constructor() : Presenter<ReadReceiptBottomSheetState> {
|
||||
|
||||
@Composable
|
||||
override fun present(): ReadReceiptBottomSheetState {
|
||||
|
|
|
|||
|
|
@ -22,5 +22,5 @@ sealed interface RetrySendMenuEvents {
|
|||
data class EventSelected(val event: TimelineItem.Event) : RetrySendMenuEvents
|
||||
data object RetrySend : RetrySendMenuEvents
|
||||
data object RemoveFailed : RetrySendMenuEvents
|
||||
data object Dismiss: RetrySendMenuEvents
|
||||
data object Dismiss : RetrySendMenuEvents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,12 +33,12 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.features.messages.impl.R
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.ModalBottomSheet
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemDaySeparatorModel
|
||||
import io.element.android.features.messages.impl.timeline.model.virtual.TimelineItemDaySeparatorModelProvider
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
|
||||
@Composable
|
||||
internal fun TimelineItemDaySeparatorView(
|
||||
|
|
|
|||
|
|
@ -25,12 +25,12 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.features.messages.impl.R
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.HorizontalDivider
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
|
||||
@Composable
|
||||
internal fun TimelineItemReadMarkerView(
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
import io.element.android.features.messages.impl.R
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.compound.theme.ElementTheme
|
||||
|
||||
@Composable
|
||||
fun TimelineItemRoomBeginningView(
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
|||
TimelineItemNoticeContent(
|
||||
body = body,
|
||||
htmlDocument = messageType.formatted?.toHtmlDocument(),
|
||||
formattedBody = parseHtml(messageType.formatted) ?:body.withLinks(),
|
||||
formattedBody = parseHtml(messageType.formatted) ?: body.withLinks(),
|
||||
isEdited = content.isEdited,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ class TimelineItemContentStickerFactory @Inject constructor(
|
|||
}
|
||||
|
||||
fun create(content: StickerContent): TimelineItemEventContent {
|
||||
|
||||
val aspectRatio = aspectRatioOf(content.info.width, content.info.height)
|
||||
|
||||
return TimelineItemStickerContent(
|
||||
|
|
|
|||
|
|
@ -65,4 +65,3 @@ sealed interface TimelineItemGroupPosition {
|
|||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,4 +36,3 @@ fun aTimelineItemLocationContent(description: String? = null) = TimelineItemLoca
|
|||
),
|
||||
description = description,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,12 +18,15 @@ package io.element.android.features.messages.impl.voicemessages
|
|||
|
||||
internal sealed class VoiceMessageException : Exception() {
|
||||
data class FileException(
|
||||
override val message: String?, override val cause: Throwable? = null
|
||||
override val message: String?,
|
||||
override val cause: Throwable? = null
|
||||
) : VoiceMessageException()
|
||||
data class PermissionMissing(
|
||||
override val message: String?, override val cause: Throwable?
|
||||
override val message: String?,
|
||||
override val cause: Throwable?
|
||||
) : VoiceMessageException()
|
||||
data class PlayMessageError(
|
||||
override val message: String?, override val cause: Throwable?
|
||||
override val message: String?,
|
||||
override val cause: Throwable?
|
||||
) : VoiceMessageException()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,20 +17,20 @@
|
|||
package io.element.android.features.messages.impl.voicemessages.composer
|
||||
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import io.element.android.libraries.textcomposer.model.VoiceMessageRecorderEvent
|
||||
import io.element.android.libraries.textcomposer.model.VoiceMessagePlayerEvent
|
||||
import io.element.android.libraries.textcomposer.model.VoiceMessageRecorderEvent
|
||||
|
||||
sealed interface VoiceMessageComposerEvents {
|
||||
data class RecorderEvent(
|
||||
val recorderEvent: VoiceMessageRecorderEvent
|
||||
): VoiceMessageComposerEvents
|
||||
) : VoiceMessageComposerEvents
|
||||
data class PlayerEvent(
|
||||
val playerEvent: VoiceMessagePlayerEvent,
|
||||
): VoiceMessageComposerEvents
|
||||
data object SendVoiceMessage: VoiceMessageComposerEvents
|
||||
data object DeleteVoiceMessage: VoiceMessageComposerEvents
|
||||
data object AcceptPermissionRationale: VoiceMessageComposerEvents
|
||||
data object DismissPermissionsRationale: VoiceMessageComposerEvents
|
||||
data class LifecycleEvent(val event: Lifecycle.Event): VoiceMessageComposerEvents
|
||||
data object DismissSendFailureDialog: VoiceMessageComposerEvents
|
||||
) : VoiceMessageComposerEvents
|
||||
data object SendVoiceMessage : VoiceMessageComposerEvents
|
||||
data object DeleteVoiceMessage : VoiceMessageComposerEvents
|
||||
data object AcceptPermissionRationale : VoiceMessageComposerEvents
|
||||
data object DismissPermissionsRationale : VoiceMessageComposerEvents
|
||||
data class LifecycleEvent(val event: Lifecycle.Event) : VoiceMessageComposerEvents
|
||||
data object DismissSendFailureDialog : VoiceMessageComposerEvents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,4 +247,3 @@ class VoiceMessageComposerPlayer @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ import io.element.android.libraries.di.SingleIn
|
|||
import io.element.android.libraries.mediaupload.api.MediaSender
|
||||
import io.element.android.libraries.permissions.api.PermissionsEvents
|
||||
import io.element.android.libraries.permissions.api.PermissionsPresenter
|
||||
import io.element.android.libraries.textcomposer.model.VoiceMessageRecorderEvent
|
||||
import io.element.android.libraries.textcomposer.model.VoiceMessagePlayerEvent
|
||||
import io.element.android.libraries.textcomposer.model.VoiceMessageRecorderEvent
|
||||
import io.element.android.libraries.textcomposer.model.VoiceMessageState
|
||||
import io.element.android.libraries.voicerecorder.api.VoiceRecorder
|
||||
import io.element.android.libraries.voicerecorder.api.VoiceRecorderState
|
||||
|
|
@ -216,7 +216,7 @@ class VoiceMessageComposerPresenter @Inject constructor(
|
|||
recorderState: VoiceRecorderState,
|
||||
isSending: Boolean,
|
||||
): VoiceMessageState {
|
||||
val showCursor by remember(playerState.isStopped, isSending) { derivedStateOf { !playerState.isStopped && !isSending }}
|
||||
val showCursor by remember(playerState.isStopped, isSending) { derivedStateOf { !playerState.isStopped && !isSending } }
|
||||
val playerTime by remember(playerState, recorderState) { derivedStateOf { displayTime(playerState, recorderState) } }
|
||||
val waveform by remember(recorderState) { derivedStateOf { recorderState.finishedWaveform() } }
|
||||
|
||||
|
|
|
|||
|
|
@ -27,4 +27,3 @@ data class VoiceMessageComposerState(
|
|||
val keepScreenOn: Boolean,
|
||||
val eventSink: (VoiceMessageComposerEvents) -> Unit,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -52,5 +52,3 @@ internal fun aVoiceMessagePreviewState() = VoiceMessageState.Preview(
|
|||
)
|
||||
|
||||
internal var aWaveformLevels = List(100) { it.toFloat() / 100 }.toPersistentList()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@ class VoiceMessagePresenter @AssistedInject constructor(
|
|||
|
||||
@Composable
|
||||
override fun present(): VoiceMessageState {
|
||||
|
||||
val playerState by player.state.collectAsState(
|
||||
VoiceMessagePlayer.State(
|
||||
isReady = false,
|
||||
|
|
|
|||
|
|
@ -564,4 +564,3 @@ private fun createActionListPresenter(isDeveloperModeEnabled: Boolean): ActionLi
|
|||
val preferencesStore = InMemoryPreferencesStore(isDeveloperModeEnabled = isDeveloperModeEnabled)
|
||||
return ActionListPresenter(preferencesStore = preferencesStore)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ class CustomReactionPresenterTests {
|
|||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
|
||||
val event = aTimelineItemEvent(eventId = AN_EVENT_ID)
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.target).isEqualTo(CustomReactionState.Target.None)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package io.element.android.features.messages.impl.timeline.components.customreac
|
|||
|
||||
import io.element.android.emojibasebindings.EmojibaseStore
|
||||
|
||||
class FakeEmojibaseProvider: EmojibaseProvider {
|
||||
class FakeEmojibaseProvider : EmojibaseProvider {
|
||||
override val emojibaseStore: EmojibaseStore
|
||||
get() = EmojibaseStore(mapOf())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class ReactionSummaryPresenterTests {
|
|||
val warmUpRule = WarmUpRule()
|
||||
|
||||
private val aggregatedReaction = anAggregatedReaction(userId = A_USER_ID, key = "👍", isHighlighted = true)
|
||||
private val roomMember = aRoomMember(userId = A_USER_ID, avatarUrl = AN_AVATAR_URL, displayName = A_USER_NAME)
|
||||
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(persistentListOf(roomMember)))
|
||||
|
|
@ -81,5 +81,4 @@ class ReactionSummaryPresenterTests {
|
|||
assertThat(reactions?.first()?.senders?.first()?.user?.displayName).isEqualTo(A_USER_NAME)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -447,7 +447,8 @@ class TimelineItemContentMessageFactoryTest {
|
|||
content = createStickerContent(
|
||||
"body",
|
||||
ImageInfo(32, 32, "image/webp", 8192, null, MediaSource("thumbnail://url"), null),
|
||||
"url")
|
||||
"url"
|
||||
)
|
||||
)
|
||||
val expected = TimelineItemStickerContent(
|
||||
body = "body",
|
||||
|
|
@ -659,7 +660,7 @@ class TimelineItemContentMessageFactoryTest {
|
|||
inImageInfo: ImageInfo,
|
||||
inUrl: String
|
||||
): StickerContent {
|
||||
return StickerContent (
|
||||
return StickerContent(
|
||||
body = body,
|
||||
info = inImageInfo,
|
||||
url = inUrl
|
||||
|
|
|
|||
|
|
@ -463,7 +463,6 @@ class VoiceMessageComposerPresenterTest {
|
|||
assertThat(showSendFailureDialog).isFalse()
|
||||
}
|
||||
|
||||
|
||||
assertThat(matrixRoom.sendMediaCount).isEqualTo(0)
|
||||
testPauseAndDestroy(finalState)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ class DefaultVoiceMessagePlayerTest {
|
|||
assertThat(it.currentPosition).isEqualTo(1000)
|
||||
assertThat(it.duration).isEqualTo(1000)
|
||||
}
|
||||
awaitItem().let {// Additional spurious state due to MediaPlayer owner change.
|
||||
awaitItem().let { // Additional spurious state due to MediaPlayer owner change.
|
||||
assertThat(it.isReady).isFalse()
|
||||
assertThat(it.isPlaying).isFalse()
|
||||
assertThat(it.isEnded).isFalse()
|
||||
|
|
@ -164,7 +164,7 @@ class DefaultVoiceMessagePlayerTest {
|
|||
|
||||
// Play player1 again.
|
||||
player1.state.test {
|
||||
awaitItem().let {// Last previous state/
|
||||
awaitItem().let { // Last previous state/
|
||||
assertThat(it.isReady).isFalse()
|
||||
assertThat(it.isPlaying).isFalse()
|
||||
assertThat(it.isEnded).isTrue()
|
||||
|
|
@ -172,7 +172,7 @@ class DefaultVoiceMessagePlayerTest {
|
|||
assertThat(it.duration).isEqualTo(1000)
|
||||
}
|
||||
assertThat(player1.prepare().isSuccess).isTrue()
|
||||
awaitItem().let {// Additional spurious state due to MediaPlayer owner change.
|
||||
awaitItem().let { // Additional spurious state due to MediaPlayer owner change.
|
||||
assertThat(it.isReady).isFalse()
|
||||
assertThat(it.isPlaying).isFalse()
|
||||
assertThat(it.isEnded).isFalse()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue