android, desktop: group member mentions (#5574)

* initial wip

* initial parser

* limit mentions

* wip types and ohter changes

* small animation

* better limit

* show mentioned member when mention is in selectable area

* better space handling

* animation working

* changes

* auto tagging

* centralize state

* focus in desktop fix

* close picker on click outside

* use profile display name, avoid local

* show box with max number of mentions

* scrollbar in group mentions desktop

* sending and displaying mentions in views based on latest core code

* latest types and updates new api

* desktop selection area fix

* show mentions correctly

* new notifications UI changes

* local alias support

* mention notifications working

* mentions markdown changes

* fix notifications

* Revert "fix notifications"

This reverts commit 59643c24725d3caee3c629df6732f4b5bc294f8f.

* simple cleanup

* mentions in info view

* refactor/renames

* show member name to replies of my messages as primary

* show local alias and display name for mentions

* show 4 rows and almost all of 5th as picker max height

* only call list members api on new @ and searchn in all names

* fix

* correction

* fixes

* unread mentions chat stats

* unread indication in chat

* filtering of unread

* show @ in chat previews

* @ style

* alone @

* forgotten change

* deleted

* remove whitespace

* fix to make clear chat mark tags red

* comments changes

* @ as icon to avoid issues

* change

* simplify like ios

* renames

* wip using haskell parser

* show mention name containing @ in quotes

* cleanup and position of cursor after replace

* move

* show selected tick and edits working

* cimention in map

* eol

* text selection

* refactor

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
Co-authored-by: Avently <7953703+avently@users.noreply.github.com>
This commit is contained in:
Diogo
2025-02-03 18:05:40 +00:00
committed by GitHub
parent 82dffd55a9
commit 760ea17fb9
29 changed files with 830 additions and 225 deletions
@@ -15,10 +15,12 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.unit.LayoutDirection
@@ -55,9 +57,10 @@ actual fun PlatformTextField(
userIsObserver: Boolean,
placeholder: String,
showVoiceButton: Boolean,
onMessageChange: (String) -> Unit,
onMessageChange: (ComposeMessage) -> Unit,
onUpArrow: () -> Unit,
onFilesPasted: (List<URI>) -> Unit,
focusRequester: FocusRequester?,
onDone: () -> Unit,
) {
val cs = composeState.value
@@ -117,6 +120,11 @@ actual fun PlatformTextField(
}
return InputConnectionCompat.createWrapper(connection, editorInfo, onCommit)
}
override fun onSelectionChanged(selStart: Int, selEnd: Int) {
onMessageChange(ComposeMessage(text.toString(), TextRange(minOf(selStart, selEnd), maxOf(selStart, selEnd))))
super.onSelectionChanged(selStart, selEnd)
}
}
editText.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
editText.maxLines = 16
@@ -126,7 +134,8 @@ actual fun PlatformTextField(
editText.background = ColorDrawable(Color.Transparent.toArgb())
editText.textDirection = if (isRtl) EditText.TEXT_DIRECTION_LOCALE else EditText.TEXT_DIRECTION_ANY_RTL
editText.setPaddingRelative(paddingStart, paddingTop, paddingEnd, paddingBottom)
editText.setText(cs.message)
editText.setText(cs.message.text)
editText.setSelection(cs.message.selection.start, cs.message.selection.end)
editText.hint = placeholder
editText.setHintTextColor(hintColor.toArgb())
if (Build.VERSION.SDK_INT >= 29) {
@@ -149,9 +158,10 @@ actual fun PlatformTextField(
}
editText.doOnTextChanged { text, _, _, _ ->
if (!composeState.value.inProgress) {
onMessageChange(text.toString())
} else if (text.toString() != composeState.value.message) {
editText.setText(composeState.value.message)
onMessageChange(ComposeMessage(text.toString(), TextRange(minOf(editText.selectionStart, editText.selectionEnd), maxOf(editText.selectionStart, editText.selectionEnd))))
} else if (text.toString() != composeState.value.message.text) {
editText.setText(composeState.value.message.text)
editText.setSelection(composeState.value.message.selection.start, composeState.value.message.selection.end)
}
}
editText.doAfterTextChanged { text -> if (composeState.value.preview is ComposePreview.VoicePreview && text.toString() != "") editText.setText("") }
@@ -167,10 +177,9 @@ actual fun PlatformTextField(
it.textSize = textStyle.value.fontSize.value * appPrefs.fontScale.get()
it.isFocusable = composeState.value.preview !is ComposePreview.VoicePreview
it.isFocusableInTouchMode = it.isFocusable
if (cs.message != it.text.toString()) {
it.setText(cs.message)
// Set cursor to the end of the text
it.setSelection(it.text.length)
if (cs.message.text != it.text.toString() || cs.message.selection.start != it.selectionStart || cs.message.selection.end != it.selectionEnd) {
it.setText(cs.message.text)
it.setSelection(cs.message.selection.start, cs.message.selection.end)
}
if (showKeyboard) {
it.requestFocus()
@@ -95,8 +95,10 @@ actual fun LazyColumnWithScrollBarNoAppBar(
additionalBarOffset: State<Dp>?,
additionalTopBar: State<Boolean>,
chatBottomBar: State<Boolean>,
maxHeight: State<Dp>?,
containerAlignment: Alignment,
content: LazyListScope.() -> Unit
) {
) {
val state = state ?: rememberLazyListState()
LazyColumn(modifier, state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled) {
content()