settings as modal

This commit is contained in:
Diogo
2024-08-31 15:12:46 +01:00
parent ed13bc9f27
commit 67ca556331
6 changed files with 37 additions and 59 deletions
@@ -46,7 +46,6 @@ import kotlin.math.sqrt
data class SettingsViewState(
val userPickerState: MutableStateFlow<AnimatedViewState>,
val scaffoldState: ScaffoldState
)
@Composable
@@ -145,8 +144,7 @@ fun MainScreen() {
userPickerState.value = AnimatedViewState.VISIBLE
}
}
val scaffoldState = rememberScaffoldState()
val settingsState = remember { SettingsViewState(userPickerState, scaffoldState) }
val settingsState = remember { SettingsViewState(userPickerState) }
SetupClipboardListener()
if (appPlatform.isAndroid) {
AndroidScreen(settingsState)
@@ -388,25 +386,21 @@ fun DesktopScreen(settingsState: SettingsViewState) {
EndPartOfScreen()
}
}
val (userPickerState, scaffoldState ) = settingsState
val (userPickerState ) = settingsState
val scope = rememberCoroutineScope()
if (scaffoldState.drawerState.isOpen || (ModalManager.start.hasModalsOpen && !ModalManager.center.hasModalsOpen)) {
if (ModalManager.start.hasModalsOpen && !ModalManager.center.hasModalsOpen) {
Box(
Modifier
.fillMaxSize()
.padding(start = DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier)
.clickable(interactionSource = remember { MutableInteractionSource() }, indication = null, onClick = {
ModalManager.start.closeModals()
scope.launch { settingsState.scaffoldState.drawerState.close() }
})
)
}
VerticalDivider(Modifier.padding(start = DEFAULT_START_MODAL_WIDTH * fontSizeSqrtMultiplier))
tryOrShowError("UserPicker", error = {}) {
UserPicker(chatModel, userPickerState, scaffoldState.drawerState) {
scope.launch { if (scaffoldState.drawerState.isOpen) scaffoldState.drawerState.close() else scaffoldState.drawerState.open() }
userPickerState.value = AnimatedViewState.GONE
}
UserPicker(chatModel, userPickerState, setPerformLA = AppLock::setPerformLA)
}
ModalManager.fullscreen.showInView()
}
@@ -23,6 +23,7 @@ import dev.icerock.moko.resources.compose.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.unit.*
import chat.simplex.common.AppLock
import chat.simplex.common.SettingsViewState
import chat.simplex.common.model.*
import chat.simplex.common.model.ChatController.appPrefs
@@ -155,16 +156,15 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf
}
val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp
val searchText = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) }
val scope = rememberCoroutineScope()
val (userPickerState, scaffoldState ) = settingsState
val (userPickerState) = settingsState
Scaffold(
topBar = {
if (!oneHandUI.value) {
Column(Modifier.padding(end = endPadding)) {
ChatListToolbar(
scaffoldState.drawerState,
userPickerState,
stopped,
setPerformLA,
)
Divider()
}
@@ -175,23 +175,10 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf
Column(Modifier.padding(end = endPadding)) {
Divider()
ChatListToolbar(
scaffoldState.drawerState,
userPickerState,
stopped,
)
}
}
},
scaffoldState = scaffoldState,
drawerContent = {
tryOrShowError("Settings", error = { ErrorSettingsView() }) {
val handler = remember { AppBarHandler() }
CompositionLocalProvider(
LocalAppBarHandler provides handler
) {
ModalView(showClose = appPlatform.isDesktop, close = { scope.launch { scaffoldState.drawerState.close() } }) {
SettingsView(chatModel, setPerformLA, scaffoldState.drawerState)
}
setPerformLA,
)
}
}
},
@@ -252,11 +239,8 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf
UserPicker(
chatModel = chatModel,
userPickerState = userPickerState,
drawerState = scaffoldState.drawerState
) {
scope.launch { if (scaffoldState.drawerState.isOpen) scaffoldState.drawerState.close() else scaffoldState.drawerState.open() }
userPickerState.value = AnimatedViewState.GONE
}
setPerformLA = AppLock::setPerformLA
)
}
}
}
@@ -278,7 +262,7 @@ private fun ConnectButton(text: String, onClick: () -> Unit) {
}
@Composable
private fun ChatListToolbar(drawerState: DrawerState, userPickerState: MutableStateFlow<AnimatedViewState>, stopped: Boolean) {
private fun ChatListToolbar(userPickerState: MutableStateFlow<AnimatedViewState>, stopped: Boolean, setPerformLA: (Boolean) -> Unit) {
val serversSummary: MutableState<PresentedServersSummary?> = remember { mutableStateOf(null) }
val barButtons = arrayListOf<@Composable RowScope.() -> Unit>()
val updatingProgress = remember { chatModel.updatingProgress }.value
@@ -349,7 +333,11 @@ private fun ChatListToolbar(drawerState: DrawerState, userPickerState: MutableSt
DefaultTopAppBar(
navigationButton = {
if (chatModel.users.isEmpty() && !chatModel.desktopNoUserNoRemote) {
NavigationButtonMenu { scope.launch { if (drawerState.isOpen) drawerState.close() else drawerState.open() } }
NavigationButtonMenu {
ModalManager.start.showModalCloseable { close ->
SettingsView(chatModel, setPerformLA, close)
}
}
} else {
val users by remember { derivedStateOf { chatModel.users.filter { u -> u.user.activeUser || !u.user.hidden } } }
val allRead = users
@@ -23,7 +23,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
@Composable
fun ShareListView(chatModel: ChatModel, settingsState: SettingsViewState, stopped: Boolean) {
var searchInList by rememberSaveable { mutableStateOf("") }
val (userPickerState, scaffoldState) = settingsState
val (userPickerState) = settingsState
val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp
val oneHandUI = remember { appPrefs.oneHandUI.state }
@@ -31,7 +31,6 @@ fun ShareListView(chatModel: ChatModel, settingsState: SettingsViewState, stoppe
Modifier.padding(end = endPadding),
contentColor = LocalContentColor.current,
drawerContentColor = LocalContentColor.current,
scaffoldState = scaffoldState,
topBar = {
if (!oneHandUI.value) {
Column {
@@ -209,7 +209,6 @@ private fun UsersLayout(
private fun UserPickerUserSectionLayout (
chatModel: ChatModel,
userPickerState: MutableStateFlow<AnimatedViewState>,
drawerState: DrawerState,
showCustomModal: (@Composable ModalData.(ChatModel, () -> Unit) -> Unit) -> (() -> Unit),
showModalWithSearch: (@Composable (ChatModel, MutableState<String>) -> Unit) -> Unit,
withAuth: (title: String, desc: String, block: () -> Unit) -> Unit,
@@ -236,7 +235,7 @@ private fun UserPickerUserSectionLayout (
generalGetString(MR.strings.auth_open_chat_profiles),
generalGetString(MR.strings.auth_log_in_using_credential)
) {
showModalWithSearch { it, search -> UserProfilesView(it, search, profileHidden, drawerState) }
showModalWithSearch { it, search -> UserProfilesView(it, search, profileHidden) }
}
}
)
@@ -300,8 +299,7 @@ private fun UserPickerUserSectionLayout (
fun UserPicker(
chatModel: ChatModel,
userPickerState: MutableStateFlow<AnimatedViewState>,
drawerState: DrawerState,
settingsClicked: () -> Unit = {},
setPerformLA: (Boolean) -> Unit,
) {
var newChat by remember { mutableStateOf(userPickerState.value) }
if (newChat.isVisible()) {
@@ -435,7 +433,6 @@ fun UserPicker(
UserPickerUserSectionLayout(
chatModel = chatModel,
userPickerState = userPickerState,
drawerState = drawerState,
showCustomModal = { modalView ->
{
if (appPlatform.isDesktop) {
@@ -464,7 +461,15 @@ fun UserPicker(
Divider(Modifier.padding(DEFAULT_PADDING))
val text = generalGetString(MR.strings.settings_section_title_settings).lowercase().capitalize(Locale.current)
SectionItemView(settingsClicked, padding = PaddingValues(start = DEFAULT_PADDING, end = DEFAULT_PADDING_HALF)) {
SectionItemView(
click = {
userPickerState.value = AnimatedViewState.GONE
ModalManager.start.showModalCloseable { close ->
SettingsView(chatModel, setPerformLA, close)
}
},
padding = PaddingValues(start = DEFAULT_PADDING, end = DEFAULT_PADDING_HALF)
) {
Icon(painterResource(MR.images.ic_settings), text, tint = MaterialTheme.colors.secondary)
TextIconSpaced()
Text(text, color = Color.Unspecified)
@@ -35,7 +35,7 @@ import chat.simplex.res.MR
import kotlinx.coroutines.*
@Composable
fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit, drawerState: DrawerState) {
fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit, close: () -> Unit) {
val user = chatModel.currentUser.value
val stopped = chatModel.chatRunning.value == false
SettingsLayout(
@@ -69,10 +69,9 @@ fun SettingsView(chatModel: ChatModel, setPerformLA: (Boolean) -> Unit, drawerSt
}
},
withAuth = ::doWithAuth,
drawerState = drawerState,
)
KeyChangeEffect(chatModel.updatingProgress.value != null) {
drawerState.close()
close.invoke()
}
}
@@ -94,18 +93,11 @@ fun SettingsLayout(
showCustomModal: (@Composable ModalData.(ChatModel, () -> Unit) -> Unit) -> (() -> Unit),
showVersion: () -> Unit,
withAuth: (title: String, desc: String, block: () -> Unit) -> Unit,
drawerState: DrawerState,
) {
val scope = rememberCoroutineScope()
val closeSettings: () -> Unit = { scope.launch { drawerState.close() } }
val view = LocalMultiplatformView()
if (drawerState.isOpen) {
BackHandler {
closeSettings()
}
LaunchedEffect(Unit) {
hideKeyboard(view)
}
LaunchedEffect(Unit) {
hideKeyboard(view)
}
val theme = CurrentColors.collectAsState()
val uriHandler = LocalUriHandler.current
@@ -509,7 +501,6 @@ fun PreviewSettingsLayout() {
showCustomModal = { {} },
showVersion = {},
withAuth = { _, _, _ -> },
drawerState = DrawerState(DrawerValue.Closed),
)
}
}
@@ -36,7 +36,7 @@ import dev.icerock.moko.resources.StringResource
import kotlinx.coroutines.*
@Composable
fun UserProfilesView(m: ChatModel, search: MutableState<String>, profileHidden: MutableState<Boolean>, drawerState: DrawerState) {
fun UserProfilesView(m: ChatModel, search: MutableState<String>, profileHidden: MutableState<Boolean>) {
val searchTextOrPassword = rememberSaveable { search }
val users by remember { derivedStateOf { m.users.map { it.user } } }
val filteredUsers by remember { derivedStateOf { filteredUsers(m, searchTextOrPassword.value) } }
@@ -53,9 +53,10 @@ fun UserProfilesView(m: ChatModel, search: MutableState<String>, profileHidden:
CreateProfile(m, close)
if (appPlatform.isDesktop) {
// Hide settings to allow clicks to pass through to CreateProfile view
DisposableEffectOnGone(always = { scope.launch { drawerState.close() } }) {
DisposableEffectOnGone(always = { scope.launch { close.invoke() } }) {
// Show settings again to allow intercept clicks to close modals after profile creation finishes
scope.launch(NonCancellable) { drawerState.open() } }
//scope.launch(NonCancellable) { drawerState.open() }
}
}
}
},