From 6a6d246dc5fd34a629485296bc9bcc36c48cf8c5 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Thu, 22 Sep 2022 23:50:12 +0300 Subject: [PATCH] android: UI fixes (#1099) * UI fixes * eol --- .../java/chat/simplex/app/model/ChatModel.kt | 1 + .../app/views/chat/group/GroupChatInfoView.kt | 4 +- .../app/views/database/DatabaseView.kt | 9 +- .../helpers/ExposedDropDownSettingRow.kt | 95 +++++++++++++++++++ .../chat/simplex/app/views/helpers/Section.kt | 8 +- .../app/views/usersettings/CallSettings.kt | 35 +++++-- .../views/usersettings/NetworkAndServers.kt | 3 +- .../{RTCSettings.kt => RTCServers.kt} | 5 +- .../app/views/usersettings/SMPServers.kt | 5 +- 9 files changed, 141 insertions(+), 24 deletions(-) create mode 100644 apps/android/app/src/main/java/chat/simplex/app/views/helpers/ExposedDropDownSettingRow.kt rename apps/android/app/src/main/java/chat/simplex/app/views/usersettings/{RTCSettings.kt => RTCServers.kt} (98%) diff --git a/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt b/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt index 385744ff8..37affd8bd 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/model/ChatModel.kt @@ -30,6 +30,7 @@ class ChatModel(val controller: ChatController) { val chatDbChanged = mutableStateOf(false) val chatDbEncrypted = mutableStateOf(false) val chatDbStatus = mutableStateOf(null) + val chatDbDeleted = mutableStateOf(false) val chats = mutableStateListOf() // current chat diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt index 4065478ba..538cd5a3c 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/chat/group/GroupChatInfoView.kt @@ -151,7 +151,7 @@ fun GroupChatInfoLayout( } SectionDivider() } - SectionItemView(height = 50.dp) { + SectionItemView(minHeight = 50.dp) { MemberRow(groupInfo.membership, user = true) } if (members.isNotEmpty()) { @@ -243,7 +243,7 @@ fun AddMembersButton(tint: Color = MaterialTheme.colors.primary, addMembers: () fun MembersList(members: List, showMemberInfo: (GroupMember) -> Unit) { Column { members.forEachIndexed { index, member -> - SectionItemView(height = 50.dp) { + SectionItemView(minHeight = 50.dp) { MemberRow(member, showMemberInfo) } if (index < members.lastIndex) { diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/database/DatabaseView.kt b/apps/android/app/src/main/java/chat/simplex/app/views/database/DatabaseView.kt index 361100673..5e9a66118 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/database/DatabaseView.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/database/DatabaseView.kt @@ -62,6 +62,7 @@ fun DatabaseView( importArchiveAlert(m, context, uri, progressIndicator) } } + val chatDbDeleted = remember { m.chatDbDeleted } val appFilesCountAndSize = remember { mutableStateOf(directoryFileCountAndSize(getAppFilesDirectory(context))) } LaunchedEffect(m.chatRunning) { runChat.value = m.chatRunning.value ?: true @@ -79,6 +80,7 @@ fun DatabaseView( chatArchiveName, chatArchiveTime, chatLastStart, + chatDbDeleted.value, appFilesCountAndSize, startChat = { startChat(m, runChat, chatLastStart, m.chatDbChanged) }, stopChatAlert = { stopChatAlert(m, runChat, context) }, @@ -115,6 +117,7 @@ fun DatabaseLayout( chatArchiveName: MutableState, chatArchiveTime: MutableState, chatLastStart: MutableState, + chatDbDeleted: Boolean, appFilesCountAndSize: MutableState>, startChat: () -> Unit, stopChatAlert: () -> Unit, @@ -137,7 +140,7 @@ fun DatabaseLayout( ) SectionView(stringResource(R.string.run_chat_section)) { - RunChatSetting(runChat, stopped, startChat, stopChatAlert) + RunChatSetting(runChat, stopped, chatDbDeleted, startChat, stopChatAlert) } SectionSpacer() @@ -230,6 +233,7 @@ fun DatabaseLayout( fun RunChatSetting( runChat: Boolean, stopped: Boolean, + chatDbDeleted: Boolean, startChat: () -> Unit, stopChatAlert: () -> Unit ) { @@ -248,6 +252,7 @@ fun RunChatSetting( ) Spacer(Modifier.fillMaxWidth().weight(1f)) Switch( + enabled= !chatDbDeleted, checked = runChat, onCheckedChange = { runChatSwitch -> if (runChatSwitch) { @@ -516,6 +521,7 @@ private fun deleteChat(m: ChatModel, progressIndicator: MutableState) { withApi { try { m.controller.apiDeleteStorage() + m.chatDbDeleted.value = true DatabaseUtils.removeDatabaseKey() m.controller.appPrefs.storeDBPassphrase.set(true) operationEnded(m, progressIndicator) { @@ -569,6 +575,7 @@ fun PreviewDatabaseLayout() { chatArchiveName = remember { mutableStateOf("dummy_archive") }, chatArchiveTime = remember { mutableStateOf(Clock.System.now()) }, chatLastStart = remember { mutableStateOf(Clock.System.now()) }, + chatDbDeleted = false, appFilesCountAndSize = remember { mutableStateOf(0 to 0L) }, startChat = {}, stopChatAlert = {}, diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/ExposedDropDownSettingRow.kt b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/ExposedDropDownSettingRow.kt new file mode 100644 index 000000000..89ba9669e --- /dev/null +++ b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/ExposedDropDownSettingRow.kt @@ -0,0 +1,95 @@ +package chat.simplex.app.views.helpers + +import androidx.compose.foundation.layout.* +import androidx.compose.material.* +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.ExpandLess +import androidx.compose.material.icons.outlined.ExpandMore +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import chat.simplex.app.R +import chat.simplex.app.ui.theme.HighOrLowlight + +@Composable +fun ExposedDropDownSettingRow( + title: String, + values: List>, + selection: State, + label: String? = null, + icon: ImageVector? = null, + iconTint: Color = HighOrLowlight, + enabled: State = mutableStateOf(true), + onSelected: (T) -> Unit +) { + Row( + Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + ) { + var expanded by remember { mutableStateOf(false) } + + if (icon != null) { + Icon( + icon, + "", + Modifier.padding(end = 8.dp), + tint = iconTint + ) + } + Text(title, color = if (enabled.value) Color.Unspecified else HighOrLowlight) + + Spacer(Modifier.fillMaxWidth().weight(1f)) + + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = { + expanded = !expanded && enabled.value + } + ) { + Row( + Modifier.padding(start = 10.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.End + ) { + Text( + values.first { it.first == selection.value }.second + (if (label != null) " $label" else ""), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + color = HighOrLowlight + ) + Spacer(Modifier.size(12.dp)) + Icon( + if (!expanded) Icons.Outlined.ExpandMore else Icons.Outlined.ExpandLess, + generalGetString(R.string.icon_descr_more_button), + tint = HighOrLowlight + ) + } + ExposedDropdownMenu( + modifier = Modifier.widthIn(min = 200.dp), + expanded = expanded, + onDismissRequest = { + expanded = false + } + ) { + values.forEach { selectionOption -> + DropdownMenuItem( + onClick = { + onSelected(selectionOption.first) + expanded = false + } + ) { + Text( + selectionOption.second + (if (label != null) " $label" else ""), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + } + } + } + } +} diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/Section.kt b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/Section.kt index bb03fa565..3d416a70e 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/helpers/Section.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/helpers/Section.kt @@ -58,11 +58,11 @@ fun SectionViewSelectable( } @Composable -fun SectionItemView(click: (() -> Unit)? = null, height: Dp = 46.dp, disabled: Boolean = false, content: (@Composable RowScope.() -> Unit)) { +fun SectionItemView(click: (() -> Unit)? = null, minHeight: Dp = 46.dp, disabled: Boolean = false, content: (@Composable RowScope.() -> Unit)) { val modifier = Modifier .padding(horizontal = 8.dp) .fillMaxWidth() - .height(height) + .sizeIn(minHeight = minHeight) Row( if (click == null || disabled) modifier else modifier.clickable(onClick = click), verticalAlignment = Alignment.CenterVertically @@ -74,7 +74,7 @@ fun SectionItemView(click: (() -> Unit)? = null, height: Dp = 46.dp, disabled: B @Composable fun SectionItemViewSpaceBetween( click: (() -> Unit)? = null, - height: Dp = 46.dp, + minHeight: Dp = 46.dp, padding: PaddingValues = PaddingValues(horizontal = 8.dp), disabled: Boolean = false, content: (@Composable () -> Unit) @@ -82,7 +82,7 @@ fun SectionItemViewSpaceBetween( val modifier = Modifier .padding(padding) .fillMaxWidth() - .height(height) + .sizeIn(minHeight = minHeight) Row( if (click == null || disabled) modifier else modifier.clickable(onClick = click), horizontalArrangement = Arrangement.SpaceBetween, diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/CallSettings.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/CallSettings.kt index 915229db6..aaf3190dc 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/CallSettings.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/CallSettings.kt @@ -15,6 +15,8 @@ import androidx.compose.ui.unit.dp import chat.simplex.app.R import chat.simplex.app.model.* import chat.simplex.app.ui.theme.HighOrLowlight +import chat.simplex.app.views.helpers.ExposedDropDownSettingRow +import chat.simplex.app.views.helpers.generalGetString @Composable fun CallSettingsView(m: ChatModel, @@ -50,22 +52,35 @@ fun CallSettingsLayout( } SectionDivider() - Column(Modifier.padding(start = 10.dp, top = 12.dp)) { - Text(stringResource(R.string.call_on_lock_screen)) - Row { - SharedPreferenceRadioButton(stringResource(R.string.no_call_on_lock_screen), lockCallState, callOnLockScreen, CallOnLockScreen.DISABLE) - Spacer(Modifier.fillMaxWidth().weight(1f)) - SharedPreferenceRadioButton(stringResource(R.string.show_call_on_lock_screen), lockCallState, callOnLockScreen, CallOnLockScreen.SHOW) - Spacer(Modifier.fillMaxWidth().weight(1f)) - SharedPreferenceRadioButton(stringResource(R.string.accept_call_on_lock_screen), lockCallState, callOnLockScreen, CallOnLockScreen.ACCEPT) - } - } + val enabled = remember { mutableStateOf(true) } + SectionItemView { LockscreenOpts(lockCallState, enabled, onSelected = { callOnLockScreen.set(it); lockCallState.value = it }) } SectionDivider() SectionItemView(editIceServers) { Text(stringResource(R.string.webrtc_ice_servers)) } } } } +@Composable +private fun LockscreenOpts(lockscreenOpts: State, enabled: State, onSelected: (CallOnLockScreen) -> Unit) { + val values = remember { + CallOnLockScreen.values().map { + when (it) { + CallOnLockScreen.DISABLE -> it to generalGetString(R.string.no_call_on_lock_screen) + CallOnLockScreen.SHOW -> it to generalGetString(R.string.show_call_on_lock_screen) + CallOnLockScreen.ACCEPT -> it to generalGetString(R.string.accept_call_on_lock_screen) + } + } + } + ExposedDropDownSettingRow( + generalGetString(R.string.call_on_lock_screen), + values, + lockscreenOpts, + icon = null, + enabled = enabled, + onSelected = onSelected + ) +} + @Composable fun SharedPreferenceToggle( text: String, diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/NetworkAndServers.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/NetworkAndServers.kt index 8c93a1313..35c55cbde 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/NetworkAndServers.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/NetworkAndServers.kt @@ -115,7 +115,7 @@ fun NetworkAndServersView( Modifier.padding(start = 16.dp, bottom = 24.dp), style = MaterialTheme.typography.h1 ) - SectionView(generalGetString(R.string.settings_section_title_calls)) { + SectionView(generalGetString(R.string.settings_section_title_messages)) { SettingsActionItem(Icons.Outlined.Dns, stringResource(R.string.smp_servers), showModal { SMPServersView(it) }) SectionDivider() SectionItemView { @@ -146,6 +146,7 @@ fun UseSocksProxySwitch( horizontalArrangement = Arrangement.SpaceBetween ) { Row( + Modifier.weight(1f), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp) ) { diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/RTCSettings.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/RTCServers.kt similarity index 98% rename from apps/android/app/src/main/java/chat/simplex/app/views/usersettings/RTCSettings.kt rename to apps/android/app/src/main/java/chat/simplex/app/views/usersettings/RTCServers.kt index f3042ba37..ff268f8a9 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/RTCSettings.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/RTCServers.kt @@ -1,5 +1,6 @@ package chat.simplex.app.views.usersettings +import SectionItemViewSpaceBetween import androidx.compose.runtime.Composable import androidx.compose.foundation.* import androidx.compose.foundation.layout.* @@ -106,9 +107,7 @@ fun RTCServersLayout( Modifier.padding(bottom = 24.dp), style = MaterialTheme.typography.h1 ) - Row( - verticalAlignment = Alignment.CenterVertically - ) { + SectionItemViewSpaceBetween(padding = PaddingValues()) { Text(stringResource(R.string.configure_ICE_servers), Modifier.padding(end = 24.dp)) Switch( checked = isUserRTCServers, diff --git a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SMPServers.kt b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SMPServers.kt index 0cba7c34c..24331b7eb 100644 --- a/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SMPServers.kt +++ b/apps/android/app/src/main/java/chat/simplex/app/views/usersettings/SMPServers.kt @@ -1,5 +1,6 @@ package chat.simplex.app.views.usersettings +import SectionItemViewSpaceBetween import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape @@ -107,9 +108,7 @@ fun SMPServersLayout( Modifier.padding(bottom = 24.dp), style = MaterialTheme.typography.h1 ) - Row( - verticalAlignment = Alignment.CenterVertically - ) { + SectionItemViewSpaceBetween(padding = PaddingValues()) { Text(stringResource(R.string.configure_SMP_servers), Modifier.padding(end = 24.dp)) Switch( checked = isUserSMPServers,