mobile: group welcome message layout (#2388)

This commit is contained in:
spaced4ndy
2023-05-05 15:49:10 +04:00
committed by GitHub
parent 1038acd2ea
commit b95a351222
3 changed files with 50 additions and 38 deletions

View File

@@ -3,12 +3,11 @@ package chat.simplex.app.views.chat.group
import SectionBottomSpacer
import SectionDividerSpaced
import SectionItemView
import SectionSpacer
import SectionView
import TextIconSpaced
import android.util.Log
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.*
import androidx.compose.runtime.*
@@ -18,18 +17,19 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.simplex.app.*
import chat.simplex.app.R
import chat.simplex.app.model.*
import chat.simplex.app.ui.theme.DEFAULT_PADDING
import chat.simplex.app.views.chat.item.MarkdownText
import chat.simplex.app.views.helpers.*
import kotlinx.coroutines.delay
import kotlinx.serialization.Serializable
import java.lang.Exception
@Composable
fun GroupWelcomeView(m: ChatModel, groupInfo: GroupInfo, close: () -> Unit) {
var groupInfo by remember { mutableStateOf(groupInfo) }
val welcomeText = remember { mutableStateOf(groupInfo.groupProfile.description ?: "") }
var gInfo by remember { mutableStateOf(groupInfo) }
val welcomeText = remember { mutableStateOf(gInfo.groupProfile.description ?: "") }
fun save(afterSave: () -> Unit = {}) {
withApi {
@@ -37,10 +37,10 @@ fun GroupWelcomeView(m: ChatModel, groupInfo: GroupInfo, close: () -> Unit) {
if (welcome?.length == 0) {
welcome = null
}
val groupProfileUpdated = groupInfo.groupProfile.copy(description = welcome)
val res = m.controller.apiUpdateGroup(groupInfo.groupId, groupProfileUpdated)
val groupProfileUpdated = gInfo.groupProfile.copy(description = welcome)
val res = m.controller.apiUpdateGroup(gInfo.groupId, groupProfileUpdated)
if (res != null) {
groupInfo = res
gInfo = res
m.updateGroup(res)
welcomeText.value = welcome ?: ""
}
@@ -50,13 +50,13 @@ fun GroupWelcomeView(m: ChatModel, groupInfo: GroupInfo, close: () -> Unit) {
ModalView(
close = {
if (welcomeText.value == groupInfo.groupProfile.description || (welcomeText.value == "" && groupInfo.groupProfile.description == null)) close()
if (welcomeText.value == gInfo.groupProfile.description || (welcomeText.value == "" && gInfo.groupProfile.description == null)) close()
else showUnsavedChangesAlert({ save(close) }, close)
},
) {
GroupWelcomeLayout(
welcomeText,
groupInfo,
gInfo,
m.controller.appPrefs.simplexLinkMode.get(),
save = ::save
)
@@ -75,39 +75,62 @@ private fun GroupWelcomeLayout(
) {
val editMode = remember { mutableStateOf(true) }
AppBarTitle(stringResource(R.string.group_welcome_title))
val welcomeText = rememberSaveable { welcomeText }
val wt = rememberSaveable { welcomeText }
if (groupInfo.canEdit) {
if (editMode.value) {
val focusRequester = remember { FocusRequester() }
TextEditor(welcomeText, Modifier.heightIn(min = 100.dp), stringResource(R.string.enter_welcome_message), focusRequester = focusRequester)
TextEditor(
wt,
Modifier.height(140.dp), stringResource(R.string.enter_welcome_message),
focusRequester = focusRequester
)
LaunchedEffect(Unit) {
delay(300)
focusRequester.requestFocus()
}
} else {
TextEditorPreview(welcomeText.value, linkMode)
TextPreview(wt.value, linkMode)
}
ChangeModeButton(
editMode.value,
click = {
editMode.value = !editMode.value
},
welcomeText.value.isEmpty()
wt.value.isEmpty()
)
CopyTextButton { copyText(SimplexApp.context, welcomeText.value) }
CopyTextButton { copyText(SimplexApp.context, wt.value) }
SectionDividerSpaced(maxBottomPadding = false)
SaveButton(
save = save,
disabled = welcomeText.value == groupInfo.groupProfile.description || (welcomeText.value == "" && groupInfo.groupProfile.description == null)
disabled = wt.value == groupInfo.groupProfile.description || (wt.value == "" && groupInfo.groupProfile.description == null)
)
} else {
TextEditorPreview(welcomeText.value, linkMode)
CopyTextButton { copyText(SimplexApp.context, welcomeText.value) }
TextPreview(wt.value, linkMode)
CopyTextButton { copyText(SimplexApp.context, wt.value) }
}
SectionBottomSpacer()
}
}
@Composable
private fun TextPreview(text: String, linkMode: SimplexLinkMode, markdown: Boolean = true) {
Column(
Modifier.height(140.dp)
) {
SelectionContainer(
Modifier.verticalScroll(rememberScrollState())
) {
MarkdownText(
text,
formattedText = if (markdown) remember(text) { parseToMarkdown(text) } else null,
modifier = Modifier.fillMaxHeight().padding(horizontal = DEFAULT_PADDING),
linkMode = linkMode,
style = MaterialTheme.typography.body1.copy(color = MaterialTheme.colors.onBackground, lineHeight = 22.sp)
)
}
}
}
@Composable
private fun SaveButton(save: () -> Unit, disabled: Boolean) {
SectionView {

View File

@@ -66,7 +66,7 @@ fun TextEditor(
value = value.value,
onValueChange = { value.value = it },
modifier = if (focusRequester == null) modifier else modifier.focusRequester(focusRequester),
textStyle = TextStyle(fontSize = 18.sp, color = MaterialTheme.colors.onBackground),
textStyle = MaterialTheme.typography.body1.copy(color = MaterialTheme.colors.onBackground, lineHeight = 22.sp),
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.None,
autoCorrect = false
@@ -78,7 +78,7 @@ fun TextEditor(
TextFieldDefaults.TextFieldDecorationBox(
value = value.value,
innerTextField = innerTextField,
placeholder = if (placeholder != null) {{ Text(placeholder, fontSize = 18.sp, color = MaterialTheme.colors.secondary) }} else null,
placeholder = if (placeholder != null) {{ Text(placeholder, style = MaterialTheme.typography.body1.copy(color = MaterialTheme.colors.secondary, lineHeight = 22.sp)) }} else null,
contentPadding = PaddingValues(),
label = null,
visualTransformation = VisualTransformation.None,
@@ -101,19 +101,6 @@ fun TextEditor(
}
}
@Composable
fun TextEditorPreview(text: String, linkMode: SimplexLinkMode, markdown: Boolean = true) {
SelectionContainer {
MarkdownText(
text,
formattedText = if (markdown) remember(text) { parseToMarkdown(text) } else null,
modifier = Modifier.heightIn(min = 100.dp).padding(horizontal = DEFAULT_PADDING),
linkMode = linkMode,
style = TextStyle(fontSize = 18.sp, color = MaterialTheme.colors.onBackground)
)
}
}
@Serializable
data class ParsedFormattedText(
val formattedText: List<FormattedText>? = null

View File

@@ -53,8 +53,10 @@ struct GroupWelcomeView: View {
}
private func textPreview() -> some View {
messageText(welcomeText, parseSimpleXMarkdown(welcomeText), nil)
.allowsHitTesting(false)
ScrollView {
messageText(welcomeText, parseSimpleXMarkdown(welcomeText), nil)
.allowsHitTesting(false)
}
}
private func editorView() -> some View {
@@ -73,12 +75,12 @@ struct GroupWelcomeView: View {
}
.padding(.horizontal, -5)
.padding(.top, -8)
.frame(height: 90, alignment: .topLeading)
.frame(height: 140, alignment: .topLeading)
.frame(maxWidth: .infinity, alignment: .leading)
}
} else {
textPreview()
.frame(height: 90, alignment: .topLeading)
.frame(height: 140, alignment: .topLeading)
}
Button {