Merge branch 'develop' of https://github.com/vector-im/element-x-android into langleyd/live_waveform

This commit is contained in:
David Langley 2023-10-27 12:28:46 +01:00
commit 37f8195956
352 changed files with 2007 additions and 254 deletions

View file

@ -37,6 +37,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@ -75,6 +76,7 @@ import io.element.android.libraries.textcomposer.model.Message
import io.element.android.libraries.textcomposer.model.MessageComposerMode
import io.element.android.libraries.textcomposer.model.PressEvent
import io.element.android.libraries.textcomposer.model.VoiceMessagePlayerEvent
import io.element.android.libraries.textcomposer.model.Suggestion
import io.element.android.libraries.textcomposer.model.VoiceMessageState
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.ui.strings.CommonStrings
@ -84,6 +86,7 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toPersistentList
import kotlin.time.Duration.Companion.seconds
import uniffi.wysiwyg_composer.MenuAction
@Composable
fun TextComposer(
@ -105,6 +108,7 @@ fun TextComposer(
onSendVoiceMessage: () -> Unit = {},
onDeleteVoiceMessage: () -> Unit = {},
onError: (Throwable) -> Unit = {},
onSuggestionReceived: (Suggestion?) -> Unit = {},
) {
val onSendClicked = {
val html = if (enableTextFormatting) state.messageHtml else null
@ -123,27 +127,31 @@ fun TextComposer(
.fillMaxSize()
.height(IntrinsicSize.Min)
val composerOptionsButton = @Composable {
ComposerOptionsButton(
modifier = Modifier
.size(48.dp),
onClick = onAddAttachment
)
val composerOptionsButton: @Composable () -> Unit = remember {
@Composable {
ComposerOptionsButton(
modifier = Modifier
.size(48.dp),
onClick = onAddAttachment
)
}
}
val textInput = @Composable {
TextInput(
state = state,
subcomposing = subcomposing,
placeholder = if (composerMode.inThread) {
stringResource(id = CommonStrings.action_reply_in_thread)
} else {
stringResource(id = R.string.rich_text_editor_composer_placeholder)
},
composerMode = composerMode,
onResetComposerMode = onResetComposerMode,
onError = onError,
)
val textInput: @Composable () -> Unit = remember(state, subcomposing, composerMode, onResetComposerMode, onError) {
@Composable {
TextInput(
state = state,
subcomposing = subcomposing,
placeholder = if (composerMode.inThread) {
stringResource(id = CommonStrings.action_reply_in_thread)
} else {
stringResource(id = R.string.rich_text_editor_composer_placeholder)
},
composerMode = composerMode,
onResetComposerMode = onResetComposerMode,
onError = onError,
)
}
}
val canSendMessage by remember { derivedStateOf { state.messageHtml.isNotEmpty() } }
@ -250,6 +258,16 @@ fun TextComposer(
SoftKeyboardEffect(showTextFormatting, onRequestFocus) { it }
}
val menuAction = state.menuAction
LaunchedEffect(menuAction) {
if (menuAction is MenuAction.Suggestion) {
val suggestion = Suggestion(menuAction.suggestionPattern)
onSuggestionReceived(suggestion)
} else {
onSuggestionReceived(null)
}
}
}
@Composable

View file

@ -0,0 +1,50 @@
/*
* 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.libraries.textcomposer.model
import uniffi.wysiwyg_composer.PatternKey
import uniffi.wysiwyg_composer.SuggestionPattern
data class Suggestion(
val start: Int,
val end: Int,
val type: SuggestionType,
val text: String,
) {
constructor(suggestion: SuggestionPattern): this(
suggestion.start.toInt(),
suggestion.end.toInt(),
SuggestionType.fromPatternKey(suggestion.key),
suggestion.text,
)
}
enum class SuggestionType {
Mention,
Command,
Room;
companion object {
fun fromPatternKey(key: PatternKey): SuggestionType {
return when (key) {
PatternKey.AT -> Mention
PatternKey.SLASH -> Command
PatternKey.HASH -> Room
}
}
}
}