mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-11 11:04:56 +00:00
settings as modal
This commit is contained in:
@@ -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()
|
||||
}
|
||||
|
||||
+13
-25
@@ -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
|
||||
|
||||
+1
-2
@@ -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 {
|
||||
|
||||
+11
-6
@@ -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)
|
||||
|
||||
+4
-13
@@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -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() }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user