desktop: local alias update (#3026)

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
Stanislav Dmitrenko 2023-09-07 22:32:47 +03:00 committed by GitHub
parent 82fd3b9004
commit e76440ee66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 21 deletions

View File

@ -24,6 +24,7 @@ import androidx.compose.ui.text.*
import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource import dev.icerock.moko.resources.compose.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -278,7 +279,7 @@ fun ChatInfoLayout(
ChatInfoHeader(chat.chatInfo, contact) ChatInfoHeader(chat.chatInfo, contact)
} }
LocalAliasEditor(localAlias, updateValue = onLocalAliasChanged) LocalAliasEditor(chat.id, localAlias, updateValue = onLocalAliasChanged)
SectionSpacer() SectionSpacer()
if (customUserProfile != null) { if (customUserProfile != null) {
SectionView(generalGetString(MR.strings.incognito).uppercase()) { SectionView(generalGetString(MR.strings.incognito).uppercase()) {
@ -403,13 +404,16 @@ fun ChatInfoHeader(cInfo: ChatInfo, contact: Contact) {
@Composable @Composable
fun LocalAliasEditor( fun LocalAliasEditor(
chatId: String,
initialValue: String, initialValue: String,
center: Boolean = true, center: Boolean = true,
leadingIcon: Boolean = false, leadingIcon: Boolean = false,
focus: Boolean = false, focus: Boolean = false,
updateValue: (String) -> Unit updateValue: (String) -> Unit
) { ) {
var value by rememberSaveable { mutableStateOf(initialValue) } val state = remember(chatId) {
mutableStateOf(TextFieldValue(initialValue))
}
var updatedValueAtLeastOnce = remember { false } var updatedValueAtLeastOnce = remember { false }
val modifier = if (center) val modifier = if (center)
Modifier.padding(horizontal = if (!leadingIcon) DEFAULT_PADDING else 0.dp).widthIn(min = 100.dp) Modifier.padding(horizontal = if (!leadingIcon) DEFAULT_PADDING else 0.dp).widthIn(min = 100.dp)
@ -418,7 +422,7 @@ fun LocalAliasEditor(
Row(Modifier.fillMaxWidth(), horizontalArrangement = if (center) Arrangement.Center else Arrangement.Start) { Row(Modifier.fillMaxWidth(), horizontalArrangement = if (center) Arrangement.Center else Arrangement.Start) {
DefaultBasicTextField( DefaultBasicTextField(
modifier, modifier,
value, state,
{ {
Text( Text(
generalGetString(MR.strings.text_field_set_contact_placeholder), generalGetString(MR.strings.text_field_set_contact_placeholder),
@ -431,27 +435,27 @@ fun LocalAliasEditor(
} else null, } else null,
color = MaterialTheme.colors.secondary, color = MaterialTheme.colors.secondary,
focus = focus, focus = focus,
textStyle = TextStyle.Default.copy(textAlign = if (value.isEmpty() || !center) TextAlign.Start else TextAlign.Center), textStyle = TextStyle.Default.copy(textAlign = if (state.value.text.isEmpty() || !center) TextAlign.Start else TextAlign.Center),
keyboardActions = KeyboardActions(onDone = { updateValue(value) }) keyboardActions = KeyboardActions(onDone = { updateValue(state.value.text) })
) { ) {
value = it state.value = it
updatedValueAtLeastOnce = true updatedValueAtLeastOnce = true
} }
} }
LaunchedEffect(Unit) { LaunchedEffect(chatId) {
var prevValue = value var prevValue = state.value
snapshotFlow { value } snapshotFlow { state.value }
.distinctUntilChanged() .distinctUntilChanged()
.onEach { delay(500) } // wait a little after every new character, don't emit until user stops typing .onEach { delay(500) } // wait a little after every new character, don't emit until user stops typing
.conflate() // get the latest value .conflate() // get the latest value
.filter { it == value && it != prevValue } // don't process old ones .filter { it == state.value && it != prevValue } // don't process old ones
.collect { .collect {
updateValue(it) updateValue(it.text)
prevValue = it prevValue = it
} }
} }
DisposableEffect(Unit) { DisposableEffect(chatId) {
onDispose { if (updatedValueAtLeastOnce) updateValue(value) } // just in case snapshotFlow will be canceled when user presses Back too fast onDispose { if (updatedValueAtLeastOnce) updateValue(state.value.text) } // just in case snapshotFlow will be canceled when user presses Back too fast
} }
} }

View File

@ -32,7 +32,7 @@ import kotlinx.coroutines.launch
@Composable @Composable
fun DefaultBasicTextField( fun DefaultBasicTextField(
modifier: Modifier, modifier: Modifier,
initialValue: String, state: MutableState<TextFieldValue>,
placeholder: (@Composable () -> Unit)? = null, placeholder: (@Composable () -> Unit)? = null,
leadingIcon: (@Composable () -> Unit)? = null, leadingIcon: (@Composable () -> Unit)? = null,
focus: Boolean = false, focus: Boolean = false,
@ -41,11 +41,8 @@ fun DefaultBasicTextField(
selectTextOnFocus: Boolean = false, selectTextOnFocus: Boolean = false,
keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), keyboardOptions: KeyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions: KeyboardActions = KeyboardActions(), keyboardActions: KeyboardActions = KeyboardActions(),
onValueChange: (String) -> Unit, onValueChange: (TextFieldValue) -> Unit,
) { ) {
val state = remember {
mutableStateOf(TextFieldValue(initialValue))
}
val focusRequester = remember { FocusRequester() } val focusRequester = remember { FocusRequester() }
val keyboard = LocalSoftwareKeyboardController.current val keyboard = LocalSoftwareKeyboardController.current
@ -83,8 +80,7 @@ fun DefaultBasicTextField(
minHeight = TextFieldDefaults.MinHeight minHeight = TextFieldDefaults.MinHeight
), ),
onValueChange = { onValueChange = {
state.value = it onValueChange(it)
onValueChange(it.text)
}, },
cursorBrush = SolidColor(colors.cursorColor(false).value), cursorBrush = SolidColor(colors.cursorColor(false).value),
visualTransformation = VisualTransformation.None, visualTransformation = VisualTransformation.None,

View File

@ -126,7 +126,7 @@ private fun ContactConnectionInfoLayout(
) )
if (contactConnection.groupLinkId == null) { if (contactConnection.groupLinkId == null) {
LocalAliasEditor(contactConnection.localAlias, center = false, leadingIcon = true, focus = focusAlias, updateValue = onLocalAliasChanged) LocalAliasEditor(contactConnection.id, contactConnection.localAlias, center = false, leadingIcon = true, focus = focusAlias, updateValue = onLocalAliasChanged)
} }
SectionView { SectionView {