Merge pull request #5160 from element-hq/feature/bma/cleanupFeatureFlags
Remove old feature flags
This commit is contained in:
commit
58ce545d98
77 changed files with 310 additions and 1243 deletions
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
package io.element.android.libraries.featureflag.api
|
||||
|
||||
import io.element.android.appconfig.OnBoardingConfig
|
||||
import io.element.android.libraries.core.meta.BuildMeta
|
||||
import io.element.android.libraries.core.meta.BuildType
|
||||
|
||||
|
|
@ -21,46 +20,6 @@ enum class FeatureFlags(
|
|||
override val defaultValue: (BuildMeta) -> Boolean,
|
||||
override val isFinished: Boolean,
|
||||
) : Feature {
|
||||
LocationSharing(
|
||||
key = "feature.locationsharing",
|
||||
title = "Allow user to share location",
|
||||
defaultValue = { true },
|
||||
isFinished = true,
|
||||
),
|
||||
Polls(
|
||||
key = "feature.polls",
|
||||
title = "Polls",
|
||||
description = "Create poll and render poll events in the timeline",
|
||||
defaultValue = { true },
|
||||
isFinished = true,
|
||||
),
|
||||
NotificationSettings(
|
||||
key = "feature.notificationsettings",
|
||||
title = "Show notification settings",
|
||||
defaultValue = { true },
|
||||
isFinished = true,
|
||||
),
|
||||
VoiceMessages(
|
||||
key = "feature.voicemessages",
|
||||
title = "Voice messages",
|
||||
description = "Send and receive voice messages",
|
||||
defaultValue = { true },
|
||||
isFinished = true,
|
||||
),
|
||||
PinUnlock(
|
||||
key = "feature.pinunlock",
|
||||
title = "Pin unlock",
|
||||
description = "Allow user to lock/unlock the app with a pin code or biometrics",
|
||||
defaultValue = { true },
|
||||
isFinished = true,
|
||||
),
|
||||
MarkAsUnread(
|
||||
key = "feature.markAsUnread",
|
||||
title = "Mark as unread",
|
||||
description = "Allow user to mark a room as unread",
|
||||
defaultValue = { true },
|
||||
isFinished = false,
|
||||
),
|
||||
RoomDirectorySearch(
|
||||
key = "feature.roomdirectorysearch",
|
||||
title = "Room directory search",
|
||||
|
|
@ -75,27 +34,6 @@ enum class FeatureFlags(
|
|||
defaultValue = { false },
|
||||
isFinished = false,
|
||||
),
|
||||
QrCodeLogin(
|
||||
key = "feature.qrCodeLogin",
|
||||
title = "Enable login using QR code",
|
||||
description = "Allow the user to login using the QR code flow",
|
||||
defaultValue = { OnBoardingConfig.CAN_LOGIN_WITH_QR_CODE },
|
||||
isFinished = false,
|
||||
),
|
||||
IncomingShare(
|
||||
key = "feature.incomingShare",
|
||||
title = "Incoming Share support",
|
||||
description = "Allow the application to receive data from other applications",
|
||||
defaultValue = { true },
|
||||
isFinished = false,
|
||||
),
|
||||
PinnedEvents(
|
||||
key = "feature.pinnedEvents",
|
||||
title = "Pinned Events",
|
||||
description = "Allow user to pin events in a room",
|
||||
defaultValue = { true },
|
||||
isFinished = false,
|
||||
),
|
||||
SyncOnPush(
|
||||
key = "feature.syncOnPush",
|
||||
title = "Sync on push",
|
||||
|
|
@ -137,34 +75,6 @@ enum class FeatureFlags(
|
|||
defaultValue = { false },
|
||||
isFinished = false,
|
||||
),
|
||||
MediaUploadOnSendQueue(
|
||||
key = "feature.media_upload_through_send_queue",
|
||||
title = "Media upload through send queue",
|
||||
description = "Support for treating media uploads as regular events, with an improved retry and cancellation implementation.",
|
||||
defaultValue = { true },
|
||||
isFinished = true,
|
||||
),
|
||||
MediaCaptionCreation(
|
||||
key = "feature.media_caption_creation",
|
||||
title = "Allow creation of media captions",
|
||||
description = null,
|
||||
defaultValue = { true },
|
||||
isFinished = false,
|
||||
),
|
||||
MediaCaptionWarning(
|
||||
key = "feature.media_caption_creation_warning",
|
||||
title = "Show a compatibility warning on media captions creation",
|
||||
description = null,
|
||||
defaultValue = { true },
|
||||
isFinished = false,
|
||||
),
|
||||
MediaGallery(
|
||||
key = "feature.media_gallery",
|
||||
title = "Allow user to open the media gallery",
|
||||
description = null,
|
||||
defaultValue = { true },
|
||||
isFinished = false,
|
||||
),
|
||||
PrintLogsToLogcat(
|
||||
key = "feature.print_logs_to_logcat",
|
||||
title = "Print logs to logcat",
|
||||
|
|
@ -175,15 +85,6 @@ enum class FeatureFlags(
|
|||
// False so it's displayed in the developer options screen
|
||||
isFinished = false,
|
||||
),
|
||||
SharePos(
|
||||
key = "feature.share_pos_v2",
|
||||
title = "Share pos in sliding sync",
|
||||
description = "Keep the sliding sync pos to make initial syncs faster. Requires an app restart to take effect." +
|
||||
"\n\nWARNING: this may cause issues with syncs.",
|
||||
defaultValue = { true },
|
||||
// False so it's displayed in the developer options screen
|
||||
isFinished = false,
|
||||
),
|
||||
SelectableMediaQuality(
|
||||
key = "feature.selectable_media_quality",
|
||||
title = "Select media quality per upload",
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ class DefaultFeatureFlagServiceTest {
|
|||
fun `given service without provider when feature is checked then it returns the default value`() = runTest {
|
||||
val buildMeta = aBuildMeta()
|
||||
val featureFlagService = DefaultFeatureFlagService(emptySet(), buildMeta)
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.LocationSharing).test {
|
||||
assertThat(awaitItem()).isEqualTo(FeatureFlags.LocationSharing.defaultValue(buildMeta))
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Space).test {
|
||||
assertThat(awaitItem()).isEqualTo(FeatureFlags.Space.defaultValue(buildMeta))
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ class DefaultFeatureFlagServiceTest {
|
|||
@Test
|
||||
fun `given service without provider when set enabled feature is called then it returns false`() = runTest {
|
||||
val featureFlagService = DefaultFeatureFlagService(emptySet(), aBuildMeta())
|
||||
val result = featureFlagService.setFeatureEnabled(FeatureFlags.LocationSharing, true)
|
||||
val result = featureFlagService.setFeatureEnabled(FeatureFlags.Space, true)
|
||||
assertThat(result).isFalse()
|
||||
}
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ class DefaultFeatureFlagServiceTest {
|
|||
val buildMeta = aBuildMeta()
|
||||
val featureFlagProvider = FakeMutableFeatureFlagProvider(0, buildMeta)
|
||||
val featureFlagService = DefaultFeatureFlagService(setOf(featureFlagProvider), buildMeta)
|
||||
val result = featureFlagService.setFeatureEnabled(FeatureFlags.LocationSharing, true)
|
||||
val result = featureFlagService.setFeatureEnabled(FeatureFlags.Space, true)
|
||||
assertThat(result).isTrue()
|
||||
}
|
||||
|
||||
|
|
@ -46,10 +46,10 @@ class DefaultFeatureFlagServiceTest {
|
|||
val buildMeta = aBuildMeta()
|
||||
val featureFlagProvider = FakeMutableFeatureFlagProvider(0, buildMeta)
|
||||
val featureFlagService = DefaultFeatureFlagService(setOf(featureFlagProvider), buildMeta)
|
||||
featureFlagService.setFeatureEnabled(FeatureFlags.LocationSharing, true)
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.LocationSharing).test {
|
||||
featureFlagService.setFeatureEnabled(FeatureFlags.Space, true)
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Space).test {
|
||||
assertThat(awaitItem()).isTrue()
|
||||
featureFlagService.setFeatureEnabled(FeatureFlags.LocationSharing, false)
|
||||
featureFlagService.setFeatureEnabled(FeatureFlags.Space, false)
|
||||
assertThat(awaitItem()).isFalse()
|
||||
}
|
||||
}
|
||||
|
|
@ -60,9 +60,9 @@ class DefaultFeatureFlagServiceTest {
|
|||
val lowPriorityFeatureFlagProvider = FakeMutableFeatureFlagProvider(LOW_PRIORITY, buildMeta)
|
||||
val highPriorityFeatureFlagProvider = FakeMutableFeatureFlagProvider(HIGH_PRIORITY, buildMeta)
|
||||
val featureFlagService = DefaultFeatureFlagService(setOf(lowPriorityFeatureFlagProvider, highPriorityFeatureFlagProvider), buildMeta)
|
||||
lowPriorityFeatureFlagProvider.setFeatureEnabled(FeatureFlags.LocationSharing, false)
|
||||
highPriorityFeatureFlagProvider.setFeatureEnabled(FeatureFlags.LocationSharing, true)
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.LocationSharing).test {
|
||||
lowPriorityFeatureFlagProvider.setFeatureEnabled(FeatureFlags.Space, false)
|
||||
highPriorityFeatureFlagProvider.setFeatureEnabled(FeatureFlags.Space, true)
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.Space).test {
|
||||
assertThat(awaitItem()).isTrue()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import io.element.android.libraries.core.coroutine.childScope
|
|||
import io.element.android.libraries.core.data.tryOrNull
|
||||
import io.element.android.libraries.core.extensions.mapFailure
|
||||
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.DeviceId
|
||||
import io.element.android.libraries.matrix.api.core.ProgressCallback
|
||||
|
|
@ -136,7 +135,6 @@ class RustMatrixClient(
|
|||
baseCacheDirectory: File,
|
||||
clock: SystemClock,
|
||||
timelineEventTypeFilterFactory: TimelineEventTypeFilterFactory,
|
||||
featureFlagService: FeatureFlagService,
|
||||
) : MatrixClient {
|
||||
override val sessionId: UserId = UserId(innerClient.userId())
|
||||
override val deviceId: DeviceId = DeviceId(innerClient.deviceId())
|
||||
|
|
@ -205,7 +203,6 @@ class RustMatrixClient(
|
|||
roomContentForwarder = RoomContentForwarder(innerRoomListService),
|
||||
roomSyncSubscriber = roomSyncSubscriber,
|
||||
timelineEventTypeFilterFactory = timelineEventTypeFilterFactory,
|
||||
featureFlagService = featureFlagService,
|
||||
roomMembershipObserver = roomMembershipObserver,
|
||||
roomInfoMapper = roomInfoMapper,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ class RustMatrixClientFactory @Inject constructor(
|
|||
client.setUtdDelegate(UtdTracker(analyticsService))
|
||||
|
||||
val syncService = client.syncService()
|
||||
.withSharePos(enable = featureFlagService.isFeatureEnabled(FeatureFlags.SharePos))
|
||||
.withSharePos(true)
|
||||
.withOfflineMode()
|
||||
.finish()
|
||||
|
||||
|
|
@ -93,7 +93,6 @@ class RustMatrixClientFactory @Inject constructor(
|
|||
baseCacheDirectory = cacheDirectory,
|
||||
clock = clock,
|
||||
timelineEventTypeFilterFactory = timelineEventTypeFilterFactory,
|
||||
featureFlagService = featureFlagService,
|
||||
).also {
|
||||
Timber.tag(it.toString()).d("Creating Client with access token '$anonymizedAccessToken' and refresh token '$anonymizedRefreshToken'")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
|||
import io.element.android.libraries.core.coroutine.childScope
|
||||
import io.element.android.libraries.core.extensions.mapFailure
|
||||
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.matrix.api.core.DeviceId
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomAlias
|
||||
|
|
@ -84,7 +83,6 @@ class JoinedRustRoom(
|
|||
private val coroutineDispatchers: CoroutineDispatchers,
|
||||
private val systemClock: SystemClock,
|
||||
private val roomContentForwarder: RoomContentForwarder,
|
||||
private val featureFlagService: FeatureFlagService,
|
||||
) : JoinedRoom, BaseRoom by baseRoom {
|
||||
// Create a dispatcher for all room methods...
|
||||
private val roomDispatcher = coroutineDispatchers.io.limitedParallelism(32)
|
||||
|
|
@ -478,7 +476,6 @@ class JoinedRustRoom(
|
|||
dispatcher = roomDispatcher,
|
||||
roomContentForwarder = roomContentForwarder,
|
||||
onNewSyncedEvent = onNewSyncedEvent,
|
||||
featureFlagsService = featureFlagService,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ package io.element.android.libraries.matrix.impl.room
|
|||
|
||||
import io.element.android.appconfig.TimelineConfig
|
||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.matrix.api.core.DeviceId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
|
|
@ -49,7 +48,6 @@ class RustRoomFactory(
|
|||
private val innerRoomListService: InnerRoomListService,
|
||||
private val roomSyncSubscriber: RoomSyncSubscriber,
|
||||
private val timelineEventTypeFilterFactory: TimelineEventTypeFilterFactory,
|
||||
private val featureFlagService: FeatureFlagService,
|
||||
private val roomMembershipObserver: RoomMembershipObserver,
|
||||
private val roomInfoMapper: RoomInfoMapper,
|
||||
) {
|
||||
|
|
@ -127,7 +125,6 @@ class RustRoomFactory(
|
|||
liveInnerTimeline = timeline,
|
||||
coroutineDispatchers = dispatchers,
|
||||
systemClock = systemClock,
|
||||
featureFlagService = featureFlagService,
|
||||
)
|
||||
)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
package io.element.android.libraries.matrix.impl.timeline
|
||||
|
||||
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.ProgressCallback
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
|
|
@ -89,7 +87,6 @@ class RustTimeline(
|
|||
private val coroutineScope: CoroutineScope,
|
||||
private val dispatcher: CoroutineDispatcher,
|
||||
private val roomContentForwarder: RoomContentForwarder,
|
||||
private val featureFlagsService: FeatureFlagService,
|
||||
onNewSyncedEvent: () -> Unit,
|
||||
) : Timeline {
|
||||
private val _timelineItems: MutableSharedFlow<List<MatrixTimelineItem>> =
|
||||
|
|
@ -342,7 +339,6 @@ class RustTimeline(
|
|||
progressCallback: ProgressCallback?,
|
||||
inReplyToEventId: EventId?,
|
||||
): Result<MediaUploadHandler> {
|
||||
val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue)
|
||||
return sendAttachment(listOfNotNull(file, thumbnailFile)) {
|
||||
inner.sendImage(
|
||||
params = UploadParameters(
|
||||
|
|
@ -351,7 +347,7 @@ class RustTimeline(
|
|||
formattedCaption = formattedCaption?.let {
|
||||
FormattedBody(body = it, format = MessageFormat.Html)
|
||||
},
|
||||
useSendQueue = useSendQueue,
|
||||
useSendQueue = true,
|
||||
mentions = null,
|
||||
inReplyTo = inReplyToEventId?.value,
|
||||
),
|
||||
|
|
@ -371,7 +367,6 @@ class RustTimeline(
|
|||
progressCallback: ProgressCallback?,
|
||||
inReplyToEventId: EventId?,
|
||||
): Result<MediaUploadHandler> {
|
||||
val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue)
|
||||
return sendAttachment(listOfNotNull(file, thumbnailFile)) {
|
||||
inner.sendVideo(
|
||||
params = UploadParameters(
|
||||
|
|
@ -380,7 +375,7 @@ class RustTimeline(
|
|||
formattedCaption = formattedCaption?.let {
|
||||
FormattedBody(body = it, format = MessageFormat.Html)
|
||||
},
|
||||
useSendQueue = useSendQueue,
|
||||
useSendQueue = true,
|
||||
mentions = null,
|
||||
inReplyTo = inReplyToEventId?.value,
|
||||
),
|
||||
|
|
@ -399,7 +394,6 @@ class RustTimeline(
|
|||
progressCallback: ProgressCallback?,
|
||||
inReplyToEventId: EventId?,
|
||||
): Result<MediaUploadHandler> {
|
||||
val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue)
|
||||
return sendAttachment(listOf(file)) {
|
||||
inner.sendAudio(
|
||||
params = UploadParameters(
|
||||
|
|
@ -408,7 +402,7 @@ class RustTimeline(
|
|||
formattedCaption = formattedCaption?.let {
|
||||
FormattedBody(body = it, format = MessageFormat.Html)
|
||||
},
|
||||
useSendQueue = useSendQueue,
|
||||
useSendQueue = true,
|
||||
mentions = null,
|
||||
inReplyTo = inReplyToEventId?.value,
|
||||
),
|
||||
|
|
@ -426,7 +420,6 @@ class RustTimeline(
|
|||
progressCallback: ProgressCallback?,
|
||||
inReplyToEventId: EventId?,
|
||||
): Result<MediaUploadHandler> {
|
||||
val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue)
|
||||
return sendAttachment(listOf(file)) {
|
||||
inner.sendFile(
|
||||
params = UploadParameters(
|
||||
|
|
@ -435,7 +428,7 @@ class RustTimeline(
|
|||
formattedCaption = formattedCaption?.let {
|
||||
FormattedBody(body = it, format = MessageFormat.Html)
|
||||
},
|
||||
useSendQueue = useSendQueue,
|
||||
useSendQueue = true,
|
||||
mentions = null,
|
||||
inReplyTo = inReplyToEventId?.value,
|
||||
),
|
||||
|
|
@ -489,7 +482,6 @@ class RustTimeline(
|
|||
progressCallback: ProgressCallback?,
|
||||
inReplyToEventId: EventId?,
|
||||
): Result<MediaUploadHandler> {
|
||||
val useSendQueue = featureFlagsService.isFeatureEnabled(FeatureFlags.MediaUploadOnSendQueue)
|
||||
return sendAttachment(listOf(file)) {
|
||||
inner.sendVoiceMessage(
|
||||
params = UploadParameters(
|
||||
|
|
@ -497,7 +489,7 @@ class RustTimeline(
|
|||
// Maybe allow a caption in the future?
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
useSendQueue = useSendQueue,
|
||||
useSendQueue = true,
|
||||
mentions = null,
|
||||
inReplyTo = inReplyToEventId?.value,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
package io.element.android.libraries.matrix.impl
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClient
|
||||
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiSyncService
|
||||
import io.element.android.libraries.matrix.impl.room.FakeTimelineEventTypeFilterFactory
|
||||
|
|
@ -67,6 +66,5 @@ class RustMatrixClientTest {
|
|||
baseCacheDirectory = File(""),
|
||||
clock = FakeSystemClock(),
|
||||
timelineEventTypeFilterFactory = FakeTimelineEventTypeFilterFactory(),
|
||||
featureFlagService = FakeFeatureFlagService(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ package io.element.android.libraries.matrix.impl.timeline
|
|||
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
||||
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
|
|
@ -98,7 +96,6 @@ private fun TestScope.createRustTimeline(
|
|||
coroutineScope: CoroutineScope = backgroundScope,
|
||||
dispatcher: CoroutineDispatcher = testCoroutineDispatchers().io,
|
||||
roomContentForwarder: RoomContentForwarder = RoomContentForwarder(FakeFfiRoomListService()),
|
||||
featureFlagsService: FeatureFlagService = FakeFeatureFlagService(),
|
||||
onNewSyncedEvent: () -> Unit = {},
|
||||
): RustTimeline {
|
||||
return RustTimeline(
|
||||
|
|
@ -109,7 +106,6 @@ private fun TestScope.createRustTimeline(
|
|||
coroutineScope = coroutineScope,
|
||||
dispatcher = dispatcher,
|
||||
roomContentForwarder = roomContentForwarder,
|
||||
featureFlagsService = featureFlagsService,
|
||||
onNewSyncedEvent = onNewSyncedEvent,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ import io.element.android.wysiwyg.compose.RichTextEditor
|
|||
import io.element.android.wysiwyg.display.TextDisplay
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.launch
|
||||
import uniffi.wysiwyg_composer.MenuAction
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
|
@ -101,7 +100,6 @@ fun TextComposer(
|
|||
state: TextEditorState,
|
||||
voiceMessageState: VoiceMessageState,
|
||||
composerMode: MessageComposerMode,
|
||||
enableVoiceMessages: Boolean,
|
||||
onRequestFocus: () -> Unit,
|
||||
onSendMessage: () -> Unit,
|
||||
onResetComposerMode: () -> Unit,
|
||||
|
|
@ -141,8 +139,8 @@ fun TextComposer(
|
|||
}
|
||||
|
||||
val layoutModifier = modifier
|
||||
.fillMaxSize()
|
||||
.height(IntrinsicSize.Min)
|
||||
.fillMaxSize()
|
||||
.height(IntrinsicSize.Min)
|
||||
|
||||
val composerOptionsButton: @Composable () -> Unit = remember(composerMode) {
|
||||
@Composable {
|
||||
|
|
@ -171,22 +169,17 @@ fun TextComposer(
|
|||
} else {
|
||||
stringResource(id = R.string.rich_text_editor_composer_placeholder)
|
||||
}
|
||||
val textInput: @Composable () -> Unit = if ((composerMode as? MessageComposerMode.Attachment)?.allowCaption == false) {
|
||||
{
|
||||
// No text input when in attachment mode and caption not allowed.
|
||||
}
|
||||
} else {
|
||||
when (state) {
|
||||
is TextEditorState.Rich -> {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val view = LocalView.current
|
||||
remember(state.richTextEditorState, composerMode, onResetComposerMode, onError) {
|
||||
@Composable {
|
||||
TextInputBox(
|
||||
modifier = Modifier
|
||||
val textInput: @Composable () -> Unit = when (state) {
|
||||
is TextEditorState.Rich -> {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val view = LocalView.current
|
||||
remember(state.richTextEditorState, composerMode, onResetComposerMode, onError) {
|
||||
@Composable {
|
||||
TextInputBox(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null,
|
||||
) {
|
||||
coroutineScope.launch {
|
||||
state.requestFocus()
|
||||
|
|
@ -196,46 +189,45 @@ fun TextComposer(
|
|||
.semantics {
|
||||
hideFromAccessibility()
|
||||
},
|
||||
composerMode = composerMode,
|
||||
onResetComposerMode = onResetComposerMode,
|
||||
isTextEmpty = state.richTextEditorState.messageHtml.isEmpty(),
|
||||
) {
|
||||
RichTextEditor(
|
||||
state = state.richTextEditorState,
|
||||
placeholder = placeholder,
|
||||
registerStateUpdates = true,
|
||||
modifier = Modifier
|
||||
composerMode = composerMode,
|
||||
onResetComposerMode = onResetComposerMode,
|
||||
isTextEmpty = state.richTextEditorState.messageHtml.isEmpty(),
|
||||
) {
|
||||
RichTextEditor(
|
||||
state = state.richTextEditorState,
|
||||
placeholder = placeholder,
|
||||
registerStateUpdates = true,
|
||||
modifier = Modifier
|
||||
.padding(top = 6.dp, bottom = 6.dp)
|
||||
.fillMaxWidth(),
|
||||
style = ElementRichTextEditorStyle.composerStyle(hasFocus = state.richTextEditorState.hasFocus),
|
||||
resolveMentionDisplay = resolveMentionDisplay,
|
||||
resolveRoomMentionDisplay = resolveAtRoomMentionDisplay,
|
||||
onError = onError,
|
||||
onRichContentSelected = onSelectRichContent,
|
||||
onTyping = onTyping,
|
||||
)
|
||||
}
|
||||
style = ElementRichTextEditorStyle.composerStyle(hasFocus = state.richTextEditorState.hasFocus),
|
||||
resolveMentionDisplay = resolveMentionDisplay,
|
||||
resolveRoomMentionDisplay = resolveAtRoomMentionDisplay,
|
||||
onError = onError,
|
||||
onRichContentSelected = onSelectRichContent,
|
||||
onTyping = onTyping,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
is TextEditorState.Markdown -> {
|
||||
@Composable {
|
||||
val style = ElementRichTextEditorStyle.composerStyle(hasFocus = state.hasFocus())
|
||||
TextInputBox(
|
||||
composerMode = composerMode,
|
||||
onResetComposerMode = onResetComposerMode,
|
||||
isTextEmpty = state.state.text.value().isEmpty(),
|
||||
) {
|
||||
MarkdownTextInput(
|
||||
state = state.state,
|
||||
placeholder = placeholder,
|
||||
placeholderColor = ElementTheme.colors.textSecondary,
|
||||
onTyping = onTyping,
|
||||
onReceiveSuggestion = onReceiveSuggestion,
|
||||
richTextEditorStyle = style,
|
||||
onSelectRichContent = onSelectRichContent,
|
||||
)
|
||||
}
|
||||
}
|
||||
is TextEditorState.Markdown -> {
|
||||
@Composable {
|
||||
val style = ElementRichTextEditorStyle.composerStyle(hasFocus = state.hasFocus())
|
||||
TextInputBox(
|
||||
composerMode = composerMode,
|
||||
onResetComposerMode = onResetComposerMode,
|
||||
isTextEmpty = state.state.text.value().isEmpty(),
|
||||
) {
|
||||
MarkdownTextInput(
|
||||
state = state.state,
|
||||
placeholder = placeholder,
|
||||
placeholderColor = ElementTheme.colors.textSecondary,
|
||||
onTyping = onTyping,
|
||||
onReceiveSuggestion = onReceiveSuggestion,
|
||||
richTextEditorStyle = style,
|
||||
onSelectRichContent = onSelectRichContent,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -273,7 +265,7 @@ fun TextComposer(
|
|||
}
|
||||
|
||||
val sendOrRecordButton = when {
|
||||
enableVoiceMessages && !canSendMessage ->
|
||||
!canSendMessage ->
|
||||
when (voiceMessageState) {
|
||||
VoiceMessageState.Idle,
|
||||
is VoiceMessageState.Recording -> recordVoiceButton
|
||||
|
|
@ -288,7 +280,6 @@ fun TextComposer(
|
|||
val endButtonA11y = endButtonA11y(
|
||||
composerMode = composerMode,
|
||||
voiceMessageState = voiceMessageState,
|
||||
enableVoiceMessages = enableVoiceMessages,
|
||||
canSendMessage = canSendMessage,
|
||||
)
|
||||
|
||||
|
|
@ -341,7 +332,6 @@ fun TextComposer(
|
|||
} else {
|
||||
StandardLayout(
|
||||
voiceMessageState = voiceMessageState,
|
||||
enableVoiceMessages = enableVoiceMessages,
|
||||
isRoomEncrypted = state.isRoomEncrypted,
|
||||
modifier = layoutModifier,
|
||||
composerOptionsButton = composerOptionsButton,
|
||||
|
|
@ -378,12 +368,11 @@ fun TextComposer(
|
|||
private fun endButtonA11y(
|
||||
composerMode: MessageComposerMode,
|
||||
voiceMessageState: VoiceMessageState,
|
||||
enableVoiceMessages: Boolean,
|
||||
canSendMessage: Boolean,
|
||||
): (SemanticsPropertyReceiver) -> Unit {
|
||||
val a11ySendButtonDescription = stringResource(
|
||||
id = when {
|
||||
enableVoiceMessages && !canSendMessage ->
|
||||
!canSendMessage ->
|
||||
when (voiceMessageState) {
|
||||
VoiceMessageState.Idle,
|
||||
is VoiceMessageState.Recording -> if (voiceMessageState is VoiceMessageState.Recording) {
|
||||
|
|
@ -410,7 +399,6 @@ private fun endButtonA11y(
|
|||
@Composable
|
||||
private fun StandardLayout(
|
||||
voiceMessageState: VoiceMessageState,
|
||||
enableVoiceMessages: Boolean,
|
||||
isRoomEncrypted: Boolean?,
|
||||
textInput: @Composable () -> Unit,
|
||||
composerOptionsButton: @Composable () -> Unit,
|
||||
|
|
@ -427,12 +415,12 @@ private fun StandardLayout(
|
|||
Spacer(Modifier.height(4.dp))
|
||||
}
|
||||
Row(verticalAlignment = Alignment.Bottom) {
|
||||
if (enableVoiceMessages && voiceMessageState !is VoiceMessageState.Idle) {
|
||||
if (voiceMessageState !is VoiceMessageState.Idle) {
|
||||
if (voiceMessageState is VoiceMessageState.Preview || voiceMessageState is VoiceMessageState.Recording) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 5.dp, top = 5.dp, end = 3.dp, start = 3.dp)
|
||||
.size(48.dp),
|
||||
.padding(bottom = 5.dp, top = 5.dp, end = 3.dp, start = 3.dp)
|
||||
.size(48.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
voiceDeleteButton()
|
||||
|
|
@ -442,8 +430,8 @@ private fun StandardLayout(
|
|||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 8.dp, top = 8.dp)
|
||||
.weight(1f)
|
||||
.padding(bottom = 8.dp, top = 8.dp)
|
||||
.weight(1f)
|
||||
) {
|
||||
voiceRecording()
|
||||
}
|
||||
|
|
@ -456,17 +444,17 @@ private fun StandardLayout(
|
|||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 8.dp, top = 8.dp)
|
||||
.weight(1f)
|
||||
.padding(bottom = 8.dp, top = 8.dp)
|
||||
.weight(1f)
|
||||
) {
|
||||
textInput()
|
||||
}
|
||||
}
|
||||
Box(
|
||||
Modifier
|
||||
.padding(bottom = 5.dp, top = 5.dp, end = 6.dp, start = 6.dp)
|
||||
.size(48.dp)
|
||||
.clearAndSetSemantics(endButtonA11y),
|
||||
.padding(bottom = 5.dp, top = 5.dp, end = 6.dp, start = 6.dp)
|
||||
.size(48.dp)
|
||||
.clearAndSetSemantics(endButtonA11y),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
endButton()
|
||||
|
|
@ -517,8 +505,8 @@ private fun TextFormattingLayout(
|
|||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(horizontal = 12.dp)
|
||||
.weight(1f)
|
||||
.padding(horizontal = 12.dp)
|
||||
) {
|
||||
textInput()
|
||||
}
|
||||
|
|
@ -537,11 +525,11 @@ private fun TextFormattingLayout(
|
|||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
start = 14.dp,
|
||||
end = 6.dp,
|
||||
)
|
||||
.clearAndSetSemantics(endButtonA11y)
|
||||
.padding(
|
||||
start = 14.dp,
|
||||
end = 6.dp,
|
||||
)
|
||||
.clearAndSetSemantics(endButtonA11y)
|
||||
) {
|
||||
sendButton()
|
||||
}
|
||||
|
|
@ -563,12 +551,12 @@ private fun TextInputBox(
|
|||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clip(roundedCorners)
|
||||
.border(0.5.dp, borderColor, roundedCorners)
|
||||
.background(color = bgColor)
|
||||
.requiredHeightIn(min = 42.dp)
|
||||
.fillMaxSize()
|
||||
.then(modifier),
|
||||
.clip(roundedCorners)
|
||||
.border(0.5.dp, borderColor, roundedCorners)
|
||||
.background(color = bgColor)
|
||||
.requiredHeightIn(min = 42.dp)
|
||||
.fillMaxSize()
|
||||
.then(modifier),
|
||||
) {
|
||||
if (composerMode is MessageComposerMode.Special) {
|
||||
ComposerModeView(
|
||||
|
|
@ -578,8 +566,8 @@ private fun TextInputBox(
|
|||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(top = 4.dp, bottom = 4.dp, start = 12.dp, end = 12.dp)
|
||||
.then(Modifier.testTag(TestTags.textEditor)),
|
||||
.padding(top = 4.dp, bottom = 4.dp, start = 12.dp, end = 12.dp)
|
||||
.then(Modifier.testTag(TestTags.textEditor)),
|
||||
contentAlignment = Alignment.CenterStart,
|
||||
) {
|
||||
textInput()
|
||||
|
|
@ -587,9 +575,9 @@ private fun TextInputBox(
|
|||
var showBottomSheet by remember { mutableStateOf(false) }
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.clickable { showBottomSheet = true }
|
||||
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||
.align(Alignment.CenterEnd),
|
||||
.clickable { showBottomSheet = true }
|
||||
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||
.align(Alignment.CenterEnd),
|
||||
imageVector = CompoundIcons.InfoSolid(),
|
||||
tint = ElementTheme.colors.iconCriticalPrimary,
|
||||
contentDescription = null,
|
||||
|
|
@ -631,12 +619,11 @@ private fun aTextEditorStateRichList(isRoomEncrypted: Boolean? = null) = persist
|
|||
internal fun TextComposerSimplePreview() = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateMarkdownList()
|
||||
) { _, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
composerMode = MessageComposerMode.Normal,
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -646,12 +633,11 @@ internal fun TextComposerSimplePreview() = ElementPreview {
|
|||
internal fun TextComposerSimpleNotEncryptedPreview() = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateMarkdownList(isRoomEncrypted = false),
|
||||
) { _, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
composerMode = MessageComposerMode.Normal,
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -661,13 +647,12 @@ internal fun TextComposerSimpleNotEncryptedPreview() = ElementPreview {
|
|||
internal fun TextComposerFormattingPreview() = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateRichList()
|
||||
) { _, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
showTextFormatting = true,
|
||||
composerMode = MessageComposerMode.Normal,
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -677,13 +662,12 @@ internal fun TextComposerFormattingPreview() = ElementPreview {
|
|||
internal fun TextComposerFormattingNotEncryptedPreview() = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateRichList(isRoomEncrypted = false)
|
||||
) { _, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
showTextFormatting = true,
|
||||
composerMode = MessageComposerMode.Normal,
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -693,12 +677,11 @@ internal fun TextComposerFormattingNotEncryptedPreview() = ElementPreview {
|
|||
internal fun TextComposerEditPreview() = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateRichList()
|
||||
) { _, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
composerMode = aMessageComposerModeEdit(),
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -708,12 +691,11 @@ internal fun TextComposerEditPreview() = ElementPreview {
|
|||
internal fun TextComposerEditNotEncryptedPreview() = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateRichList(isRoomEncrypted = false)
|
||||
) { _, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
composerMode = aMessageComposerModeEdit(),
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -723,7 +705,7 @@ internal fun TextComposerEditNotEncryptedPreview() = ElementPreview {
|
|||
internal fun TextComposerEditCaptionPreview() = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateRichList()
|
||||
) { _, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
|
|
@ -731,7 +713,6 @@ internal fun TextComposerEditCaptionPreview() = ElementPreview {
|
|||
// Set an existing caption so that the UI will be in edit caption mode
|
||||
content = "An existing caption",
|
||||
),
|
||||
enableVoiceMessages = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -741,16 +722,14 @@ internal fun TextComposerEditCaptionPreview() = ElementPreview {
|
|||
internal fun TextComposerAddCaptionPreview() = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateRichList()
|
||||
) { index, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
composerMode = aMessageComposerModeEditCaption(
|
||||
// No caption so that the UI will be in add caption mode
|
||||
content = "",
|
||||
showCompatibilityWarning = index == 0,
|
||||
),
|
||||
enableVoiceMessages = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -760,12 +739,11 @@ internal fun TextComposerAddCaptionPreview() = ElementPreview {
|
|||
internal fun MarkdownTextComposerEditPreview() = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateMarkdownList()
|
||||
) { _, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
composerMode = aMessageComposerModeEdit(),
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -775,14 +753,13 @@ internal fun MarkdownTextComposerEditPreview() = ElementPreview {
|
|||
internal fun TextComposerReplyPreview(@PreviewParameter(InReplyToDetailsProvider::class) inReplyToDetails: InReplyToDetails) = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateRichList()
|
||||
) { _, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
composerMode = aMessageComposerModeReply(
|
||||
replyToDetails = inReplyToDetails,
|
||||
),
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -800,14 +777,13 @@ internal fun TextComposerReplyPreview(@PreviewParameter(InReplyToDetailsProvider
|
|||
internal fun TextComposerReplyNotEncryptedPreview(@PreviewParameter(InReplyToDetailsProvider::class) inReplyToDetails: InReplyToDetails) = ElementPreview {
|
||||
PreviewColumn(
|
||||
items = aTextEditorStateRichList(isRoomEncrypted = false)
|
||||
) { _, textEditorState ->
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
composerMode = aMessageComposerModeReply(
|
||||
replyToDetails = inReplyToDetails,
|
||||
),
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -817,16 +793,12 @@ internal fun TextComposerReplyNotEncryptedPreview(@PreviewParameter(InReplyToDet
|
|||
internal fun TextComposerCaptionPreview() = ElementPreview {
|
||||
val list = aTextEditorStateMarkdownList()
|
||||
PreviewColumn(
|
||||
items = (list + aTextEditorStateMarkdown(initialText = "NO_CAPTION", initialFocus = true)).toPersistentList()
|
||||
) { index, textEditorState ->
|
||||
items = list,
|
||||
) { textEditorState ->
|
||||
ATextComposer(
|
||||
state = textEditorState,
|
||||
voiceMessageState = VoiceMessageState.Idle,
|
||||
composerMode = MessageComposerMode.Attachment(
|
||||
allowCaption = index < list.size,
|
||||
showCaptionCompatibilityWarning = index == 0,
|
||||
),
|
||||
enableVoiceMessages = false,
|
||||
composerMode = MessageComposerMode.Attachment,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -862,12 +834,11 @@ internal fun TextComposerVoicePreview() = ElementPreview {
|
|||
playbackProgress = 0.0f
|
||||
),
|
||||
)
|
||||
) { _, voiceMessageState ->
|
||||
) { voiceMessageState ->
|
||||
ATextComposer(
|
||||
state = aTextEditorStateRich(initialFocus = true),
|
||||
voiceMessageState = voiceMessageState,
|
||||
composerMode = MessageComposerMode.Normal,
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -903,12 +874,11 @@ internal fun TextComposerVoiceNotEncryptedPreview() = ElementPreview {
|
|||
playbackProgress = 0.0f
|
||||
),
|
||||
)
|
||||
) { _, voiceMessageState ->
|
||||
) { voiceMessageState ->
|
||||
ATextComposer(
|
||||
state = aTextEditorStateRich(initialFocus = true, isRoomEncrypted = false),
|
||||
voiceMessageState = voiceMessageState,
|
||||
composerMode = MessageComposerMode.Normal,
|
||||
enableVoiceMessages = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -916,15 +886,15 @@ internal fun TextComposerVoiceNotEncryptedPreview() = ElementPreview {
|
|||
@Composable
|
||||
private fun <T> PreviewColumn(
|
||||
items: ImmutableList<T>,
|
||||
view: @Composable (Int, T) -> Unit,
|
||||
view: @Composable (T) -> Unit,
|
||||
) {
|
||||
Column {
|
||||
items.forEachIndexed { index, item ->
|
||||
items.forEach { item ->
|
||||
HorizontalDivider()
|
||||
Box(
|
||||
modifier = Modifier.height(IntrinsicSize.Min)
|
||||
) {
|
||||
view(index, item)
|
||||
view(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -935,7 +905,6 @@ private fun ATextComposer(
|
|||
state: TextEditorState,
|
||||
voiceMessageState: VoiceMessageState,
|
||||
composerMode: MessageComposerMode,
|
||||
enableVoiceMessages: Boolean,
|
||||
showTextFormatting: Boolean = false,
|
||||
) {
|
||||
TextComposer(
|
||||
|
|
@ -943,7 +912,6 @@ private fun ATextComposer(
|
|||
showTextFormatting = showTextFormatting,
|
||||
voiceMessageState = voiceMessageState,
|
||||
composerMode = composerMode,
|
||||
enableVoiceMessages = enableVoiceMessages,
|
||||
onRequestFocus = {},
|
||||
onSendMessage = {},
|
||||
onResetComposerMode = {},
|
||||
|
|
@ -973,11 +941,9 @@ fun aMessageComposerModeEdit(
|
|||
fun aMessageComposerModeEditCaption(
|
||||
eventOrTransactionId: EventOrTransactionId = EventId("$1234").toEventOrTransactionId(),
|
||||
content: String,
|
||||
showCompatibilityWarning: Boolean = false,
|
||||
) = MessageComposerMode.EditCaption(
|
||||
eventOrTransactionId = eventOrTransactionId,
|
||||
content = content,
|
||||
showCaptionCompatibilityWarning = showCompatibilityWarning,
|
||||
)
|
||||
|
||||
fun aMessageComposerModeReply(
|
||||
|
|
|
|||
|
|
@ -18,10 +18,7 @@ import io.element.android.libraries.matrix.ui.messages.reply.eventId
|
|||
sealed interface MessageComposerMode {
|
||||
data object Normal : MessageComposerMode
|
||||
|
||||
data class Attachment(
|
||||
val allowCaption: Boolean,
|
||||
val showCaptionCompatibilityWarning: Boolean,
|
||||
) : MessageComposerMode
|
||||
data object Attachment : MessageComposerMode
|
||||
|
||||
sealed interface Special : MessageComposerMode
|
||||
|
||||
|
|
@ -33,7 +30,6 @@ sealed interface MessageComposerMode {
|
|||
data class EditCaption(
|
||||
val eventOrTransactionId: EventOrTransactionId,
|
||||
val content: String,
|
||||
val showCaptionCompatibilityWarning: Boolean,
|
||||
) : Special
|
||||
|
||||
data class Reply(
|
||||
|
|
@ -58,8 +54,8 @@ sealed interface MessageComposerMode {
|
|||
|
||||
fun MessageComposerMode.showCaptionCompatibilityWarning(): Boolean {
|
||||
return when (this) {
|
||||
is MessageComposerMode.Attachment -> showCaptionCompatibilityWarning
|
||||
is MessageComposerMode.EditCaption -> showCaptionCompatibilityWarning && content.isEmpty()
|
||||
is MessageComposerMode.Attachment -> true
|
||||
is MessageComposerMode.EditCaption -> content.isEmpty()
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue