diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.kt index 1f8155d3dd..39c8866747 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.kt @@ -27,6 +27,7 @@ import chat.simplex.common.views.chat.* import chat.simplex.common.views.chat.group.deleteGroupDialog import chat.simplex.common.views.chat.group.leaveGroupDialog import chat.simplex.common.views.chat.item.ItemAction +import chat.simplex.common.views.contacts.onRequestAccepted import chat.simplex.common.views.helpers.* import chat.simplex.common.views.newchat.* import chat.simplex.res.MR @@ -129,7 +130,7 @@ fun ChatListNavLinkView(chat: Chat, nextChatSelected: State, oneHandUI: ContactRequestView(chat.chatInfo) } }, - click = { contactRequestAlertDialog(chat.remoteHostId, chat.chatInfo, chatModel) }, + click = { contactRequestAlertDialog(chat.remoteHostId, chat.chatInfo, chatModel) { onRequestAccepted(it) } }, dropdownMenuItems = { tryOrShowError("${chat.id}ChatListNavLinkDropdown", error = {}) { ContactRequestMenuItems(chat.remoteHostId, chat.chatInfo, chatModel, showMenu) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt index 32f8a2f481..9bb82ede98 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ChatListView.kt @@ -43,14 +43,12 @@ import kotlinx.serialization.json.Json import java.net.URI import kotlin.time.Duration.Companion.seconds -private fun showNewChatSheet(oneHandUI: State, barTitle: String) { +private fun showNewChatSheet(oneHandUI: State) { ModalManager.start.closeModals() ModalManager.end.closeModals() chatModel.newChatSheetVisible.value = true ModalManager.start.showModalCloseable( closeOnTop = !oneHandUI.value, - closeBarTitle = if (oneHandUI.value) barTitle else null, - endButtons = { Spacer(Modifier.minimumInteractiveComponentSize()) } ) { close -> NewChatSheet(rh = chatModel.currentRemoteHost.value, close) DisposableEffect(Unit) { @@ -88,19 +86,21 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf Scaffold( topBar = { if (!oneHandUI.state.value) { - Box(Modifier.padding(end = endPadding)) { + Column(Modifier.padding(end = endPadding)) { ChatListToolbar( scaffoldState.drawerState, userPickerState, stopped, oneHandUI ) + Divider() } } }, bottomBar = { if (oneHandUI.state.value) { - Box(Modifier.padding(end = endPadding)) { + Column(Modifier.padding(end = endPadding)) { + Divider() ChatListToolbar( scaffoldState.drawerState, userPickerState, @@ -125,7 +125,7 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf FloatingActionButton( onClick = { if (!stopped) { - showNewChatSheet(oneHandUI.state, generalGetString(MR.strings.new_chat)) + showNewChatSheet(oneHandUI.state) } }, Modifier @@ -222,14 +222,15 @@ private fun ChatListToolbar(drawerState: DrawerState, userPickerState: MutableSt IconButton( onClick = { if (!stopped) { - showNewChatSheet(oneHandUI.state, generalGetString(MR.strings.new_chat)) + showNewChatSheet(oneHandUI.state) } }, ) { Box( + contentAlignment = Alignment.Center, modifier = Modifier .background(if (!stopped) MaterialTheme.colors.primary else MaterialTheme.colors.secondary, shape = CircleShape) - .padding(DEFAULT_PADDING_HALF) + .size(33.dp * fontSizeSqrtMultiplier) ){ Icon( painterResource(MR.images.ic_edit_filled), @@ -327,7 +328,6 @@ private fun ChatListToolbar(drawerState: DrawerState, userPickerState: MutableSt onSearchValueChanged = {}, buttons = barButtons ) - Divider(Modifier.padding(top = AppBarHeight * fontSizeSqrtMultiplier)) } @Composable @@ -551,6 +551,7 @@ private fun ChatList(chatModel: ChatModel, searchText: MutableState, oneHandUI: State) { +fun ContactListNavLinkView(chat: Chat, nextChatSelected: State) { + val oneHandUI = remember { appPrefs.oneHandUI.state } val showMenu = remember { mutableStateOf(false) } val rhId = chat.remoteHostId val disabled = chatModel.chatRunning.value == false || chatModel.deletedChats.value.contains(rhId to chat.chatInfo.id) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt index 8cdac67bf4..da1e59fa70 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/CloseSheetBar.kt @@ -20,7 +20,7 @@ import chat.simplex.res.MR import dev.icerock.moko.resources.compose.painterResource @Composable -fun CloseSheetBar(close: (() -> Unit)?, showClose: Boolean = true, tintColor: Color = if (close != null) MaterialTheme.colors.primary else MaterialTheme.colors.secondary, arrangement: Arrangement.Vertical = Arrangement.Top, closeBarTitle: String? = null, endButtons: @Composable RowScope.() -> Unit = {}) { +fun CloseSheetBar(close: (() -> Unit)?, showClose: Boolean = true, tintColor: Color = if (close != null) MaterialTheme.colors.primary else MaterialTheme.colors.secondary, arrangement: Arrangement.Vertical = Arrangement.Top, closeBarTitle: String? = null, barPaddingValues: PaddingValues = PaddingValues(horizontal = AppBarHorizontalPadding), endButtons: @Composable RowScope.() -> Unit = {}) { var rowModifier = Modifier .fillMaxWidth() .height(AppBarHeight * fontSizeSqrtMultiplier) @@ -36,7 +36,7 @@ fun CloseSheetBar(close: (() -> Unit)?, showClose: Boolean = true, tintColor: Co .heightIn(min = AppBarHeight * fontSizeSqrtMultiplier) ) { Row( - modifier = Modifier.padding(horizontal = AppBarHorizontalPadding), + modifier = Modifier.padding(barPaddingValues), content = { Row( rowModifier, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt index a1d8574d9f..d20d573bd2 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ModalView.kt @@ -26,7 +26,6 @@ fun ModalView( background: Color = MaterialTheme.colors.background, modifier: Modifier = Modifier, closeOnTop: Boolean = true, - closeBarTitle: String? = null, endButtons: @Composable RowScope.() -> Unit = {}, content: @Composable () -> Unit, ) { @@ -38,14 +37,10 @@ fun ModalView( if (closeOnTop) { CloseSheetBar(if (enableClose) close else null, showClose, endButtons = endButtons) } - Box(if (closeOnTop) modifier else modifier.padding(bottom = AppBarHeight * fontSizeSqrtMultiplier)) { + Box(modifier = modifier) { content() } } - - if (!closeOnTop) { - CloseSheetBar(if (enableClose) close else null, showClose, endButtons = endButtons, arrangement = Arrangement.Bottom, closeBarTitle = closeBarTitle) - } } } @@ -72,17 +67,17 @@ class ModalManager(private val placement: ModalPlacement? = null) { // java.lang.IllegalStateException: Reading a state that was created after the snapshot was taken or in a snapshot that has not yet been applied private var passcodeView: MutableStateFlow<(@Composable (close: () -> Unit) -> Unit)?> = MutableStateFlow(null) - fun showModal(settings: Boolean = false, showClose: Boolean = true, closeOnTop: Boolean = true, closeBarTitle: String? = null,endButtons: @Composable RowScope.() -> Unit = {}, content: @Composable ModalData.() -> Unit) { + fun showModal(settings: Boolean = false, showClose: Boolean = true, closeOnTop: Boolean = true, endButtons: @Composable RowScope.() -> Unit = {}, content: @Composable ModalData.() -> Unit) { val data = ModalData() showCustomModal { close -> - ModalView(close, showClose = showClose, closeOnTop = closeOnTop, closeBarTitle = closeBarTitle, endButtons = endButtons, content = { data.content() }) + ModalView(close, showClose = showClose, closeOnTop = closeOnTop, endButtons = endButtons, content = { data.content() }) } } - fun showModalCloseable(settings: Boolean = false, showClose: Boolean = true, closeOnTop: Boolean = true, closeBarTitle: String? = null, endButtons: @Composable RowScope.() -> Unit = {}, content: @Composable ModalData.(close: () -> Unit) -> Unit) { + fun showModalCloseable(settings: Boolean = false, showClose: Boolean = true, closeOnTop: Boolean = true, endButtons: @Composable RowScope.() -> Unit = {}, content: @Composable ModalData.(close: () -> Unit) -> Unit) { val data = ModalData() showCustomModal { close -> - ModalView(close, showClose = showClose, endButtons = endButtons, closeOnTop = closeOnTop, closeBarTitle = closeBarTitle, content = { data.content(close) }) + ModalView(close, showClose = showClose, endButtons = endButtons, closeOnTop = closeOnTop, content = { data.content(close) }) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt index 6714e3aff6..6ebe0ae9d2 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.* import chat.simplex.common.model.* +import chat.simplex.common.model.ChatController.appPrefs import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.chatlist.ScrollDirection @@ -39,45 +40,47 @@ import java.net.URI @Composable fun NewChatSheet(rh: RemoteHostInfo?, close: () -> Unit) { - val oneHandUI = remember { chatModel.controller.appPrefs.oneHandUI } + val oneHandUI = remember { appPrefs.oneHandUI.state } + val keyboardState by getKeyboardState() + val showToolbarInOneHandUI = remember { derivedStateOf { keyboardState == KeyboardState.Closed && oneHandUI.value } } - Column( - modifier = Modifier.fillMaxSize() - ) { - if (!oneHandUI.state.value) { - Box(contentAlignment = Alignment.Center) { - val bottomPadding = DEFAULT_PADDING - AppBarTitle( - stringResource(MR.strings.new_chat), - hostDevice(rh?.remoteHostId), - bottomPadding = bottomPadding - ) + Scaffold( + bottomBar = { + if (showToolbarInOneHandUI.value) { + Column { + Divider() + CloseSheetBar( + close = close, + showClose = true, + endButtons = { Spacer(Modifier.minimumInteractiveComponentSize()) }, + arrangement = Arrangement.Bottom, + closeBarTitle = generalGetString(MR.strings.new_chat), + barPaddingValues = PaddingValues(horizontal = 0.dp) + ) + } } } + ) { + Column( + modifier = Modifier.fillMaxSize().padding(it) + ) { + val closeAll = { ModalManager.start.closeModals() } - val closeAll = { ModalManager.start.closeModals() } - - var modifier = Modifier.fillMaxSize() - - if (oneHandUI.state.value) { - modifier = modifier.scale(scaleX = 1f, scaleY = -1f) - } - - Column(modifier = modifier) { - NewChatSheetLayout( - addContact = { - ModalManager.start.showModalCloseable { _ -> NewChatView(chatModel.currentRemoteHost.value, NewChatOption.INVITE, close = closeAll ) } - }, - scanPaste = { - ModalManager.start.showModalCloseable { _ -> NewChatView(chatModel.currentRemoteHost.value, NewChatOption.CONNECT, showQRCodeScanner = appPlatform.isAndroid, close = closeAll) } - }, - createGroup = { - ModalManager.start.showCustomModal { close -> AddGroupView(chatModel, chatModel.currentRemoteHost.value, close, closeAll) } - }, - rh = rh, - close = close, - oneHandUI = oneHandUI - ) + Column(modifier = Modifier.fillMaxSize().then(if (oneHandUI.value) Modifier.scale(scaleX = 1f, scaleY = -1f) else Modifier)) { + NewChatSheetLayout( + addContact = { + ModalManager.start.showModalCloseable { _ -> NewChatView(chatModel.currentRemoteHost.value, NewChatOption.INVITE, close = closeAll ) } + }, + scanPaste = { + ModalManager.start.showModalCloseable { _ -> NewChatView(chatModel.currentRemoteHost.value, NewChatOption.CONNECT, showQRCodeScanner = appPlatform.isAndroid, close = closeAll) } + }, + createGroup = { + ModalManager.start.showCustomModal { close -> AddGroupView(chatModel, chatModel.currentRemoteHost.value, close, closeAll) } + }, + rh = rh, + close = close + ) + } } } } @@ -90,7 +93,7 @@ fun chatContactType(chat: Chat): ContactType { return when (val cInfo = chat.chatInfo) { is ChatInfo.ContactRequest -> ContactType.REQUEST is ChatInfo.Direct -> { - val contact = cInfo.contact; + val contact = cInfo.contact when { contact.activeConn == null && contact.profile.contactLink != null -> ContactType.CARD @@ -116,15 +119,15 @@ private fun NewChatSheetLayout( scanPaste: () -> Unit, createGroup: () -> Unit, close: () -> Unit, - oneHandUI: SharedPreference ) { + val oneHandUI = remember { appPrefs.oneHandUI.state } val listState = rememberLazyListState(lazyListState.first, lazyListState.second) val searchText = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) } val searchShowingSimplexLink = remember { mutableStateOf(false) } val searchChatFilteredBySimplexLink = remember { mutableStateOf(null) } val showUnreadAndFavorites = remember { ChatController.appPrefs.showUnreadAndFavorites.state }.value - val baseContactTypes = listOf(ContactType.CARD, ContactType.RECENT, ContactType.REQUEST) - val contactTypes by remember(baseContactTypes, searchText.value.text.isEmpty()) { + val baseContactTypes = remember { listOf(ContactType.CARD, ContactType.RECENT, ContactType.REQUEST) } + val contactTypes by remember(searchText.value.text.isEmpty()) { derivedStateOf { contactTypesSearchTargets(baseContactTypes, searchText.value.text.isEmpty()) } } val allChats by remember(chatModel.chats.value, contactTypes) { @@ -133,6 +136,7 @@ private fun NewChatSheetLayout( var scrollDirection by remember { mutableStateOf(ScrollDirection.Idle) } var previousIndex by remember { mutableStateOf(0) } var previousScrollOffset by remember { mutableStateOf(0) } + val keyboardState by getKeyboardState() LaunchedEffect(listState.firstVisibleItemIndex, listState.firstVisibleItemScrollOffset) { val currentIndex = listState.firstVisibleItemIndex @@ -160,22 +164,32 @@ private fun NewChatSheetLayout( contactChats = allChats ) - var sectionModifier = Modifier.fillMaxWidth() - - if (oneHandUI.state.value) { - sectionModifier = sectionModifier.scale(scaleX = 1f, scaleY = -1f) - } - + val sectionModifier = if (oneHandUI.value) Modifier.fillMaxWidth().scale(scaleX = 1f, scaleY = -1f) else Modifier.fillMaxWidth() LazyColumnWithScrollBar( Modifier.fillMaxWidth(), listState ) { + if (!oneHandUI.value) { + item { + Box(contentAlignment = Alignment.Center) { + val bottomPadding = DEFAULT_PADDING + AppBarTitle( + stringResource(MR.strings.new_chat), + hostDevice(rh?.remoteHostId), + bottomPadding = bottomPadding + ) + } + } + } stickyHeader { Column( Modifier .offset { val y = if (searchText.value.text.isEmpty()) { - if (oneHandUI.state.value && scrollDirection == ScrollDirection.Up) { + if ( + (oneHandUI.value && scrollDirection == ScrollDirection.Up) || + (appPlatform.isAndroid && keyboardState == KeyboardState.Opened) + ) { 0 } else if (listState.firstVisibleItemIndex == 0) -listState.firstVisibleItemScrollOffset else -1000 } else { @@ -185,7 +199,7 @@ private fun NewChatSheetLayout( } .background(MaterialTheme.colors.background) ) { - if (!oneHandUI.state.value) { + if (!oneHandUI.value) { Divider() } ContactsSearchBar( @@ -194,13 +208,12 @@ private fun NewChatSheetLayout( searchShowingSimplexLink = searchShowingSimplexLink, searchChatFilteredBySimplexLink = searchChatFilteredBySimplexLink, close = close, - oneHandUI = oneHandUI ) Divider() } } item { - Spacer(Modifier.padding(bottom = DEFAULT_PADDING)) + Spacer(Modifier.padding(bottom = 27.dp)) if (searchText.value.text.isEmpty()) { Row { @@ -210,21 +223,18 @@ private fun NewChatSheetLayout( text = stringResource(MR.strings.add_contact_tab), click = addContact, extraPadding = true, - oneHandUI = oneHandUI.state ) NewChatButton( icon = painterResource(MR.images.ic_qr_code), text = if (appPlatform.isAndroid) stringResource(MR.strings.scan_paste_link) else stringResource(MR.strings.paste_link), click = scanPaste, extraPadding = true, - oneHandUI = oneHandUI.state ) NewChatButton( icon = painterResource(MR.images.ic_group), text = stringResource(MR.strings.create_group_button), click = createGroup, extraPadding = true, - oneHandUI = oneHandUI.state ) } } @@ -242,11 +252,9 @@ private fun NewChatSheetLayout( ModalManager.start.showCustomModal { closeDeletedChats -> ModalView( close = closeDeletedChats, - closeOnTop = !oneHandUI.state.value, - closeBarTitle = if (oneHandUI.state.value) generalGetString(MR.strings.deleted_chats) else null, - endButtons = { Spacer(Modifier.minimumInteractiveComponentSize()) } + closeOnTop = !oneHandUI.value, ) { - DeletedContactsView(rh = rh, close = { + DeletedContactsView(rh = rh, closeDeletedChats = closeDeletedChats, close = { ModalManager.start.closeModals() }) } @@ -263,16 +271,16 @@ private fun NewChatSheetLayout( } } } - SectionDividerSpaced() + SectionDividerSpaced(maxBottomPadding = false) } } } item { - if (filteredContactChats.isNotEmpty() && !oneHandUI.state.value) { + if (filteredContactChats.isNotEmpty() && !oneHandUI.value) { Text( stringResource(MR.strings.contact_list_header_title).uppercase(), color = MaterialTheme.colors.secondary, style = MaterialTheme.typography.body2, - modifier = sectionModifier.padding(start = DEFAULT_PADDING, bottom = 5.dp), fontSize = 12.sp + modifier = sectionModifier.padding(start = DEFAULT_PADDING, top = DEFAULT_PADDING_HALF, bottom = DEFAULT_PADDING_HALF), fontSize = 12.sp ) } } @@ -283,7 +291,7 @@ private fun NewChatSheetLayout( chatModel.chatId.value != null && filteredContactChats.getOrNull(index + 1)?.id == chatModel.chatId.value } } - ContactListNavLinkView(chat, nextChatSelected, oneHandUI.state) + ContactListNavLinkView(chat, nextChatSelected) } } @@ -308,8 +316,9 @@ private fun NewChatButton( iconColor: Color = MaterialTheme.colors.secondary, disabled: Boolean = false, extraPadding: Boolean = false, - oneHandUI: State ) { + val oneHandUI = remember { appPrefs.oneHandUI.state } + SectionItemView(click, disabled = disabled) { Row(modifier = if (oneHandUI.value) Modifier.scale(scaleX = 1f, scaleY = -1f) else Modifier) { Icon(icon, text, tint = if (disabled) MaterialTheme.colors.secondary else iconColor) @@ -326,14 +335,10 @@ private fun ContactsSearchBar( searchShowingSimplexLink: MutableState, searchChatFilteredBySimplexLink: MutableState, close: () -> Unit, - oneHandUI: SharedPreference ) { - var modifier = Modifier.fillMaxWidth(); - - if (oneHandUI.state.value) { - modifier = modifier.scale(scaleX = 1f, scaleY = -1f) - } + val oneHandUI = remember { appPrefs.oneHandUI.state } + val modifier = if (oneHandUI.value) Modifier.fillMaxWidth().scale(scaleX = 1f, scaleY = -1f) else Modifier.fillMaxWidth() var focused by remember { mutableStateOf(false) } Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) { @@ -416,7 +421,7 @@ private fun ContactsSearchBar( @Composable private fun ToggleFilterButton() { - val pref = remember { ChatController.appPrefs.showUnreadAndFavorites } + val pref = remember { appPrefs.showUnreadAndFavorites } IconButton(onClick = { pref.set(!pref.get()) }) { val sp16 = with(LocalDensity.current) { 16.sp.toDp() } Icon( @@ -471,7 +476,7 @@ private fun filteredContactChats( } private fun filterChat(chat: Chat, searchText: String, showUnreadAndFavorites: Boolean): Boolean { - var meetsPredicate = true; + var meetsPredicate = true val s = searchText.trim().lowercase() val cInfo = chat.chatInfo @@ -485,7 +490,7 @@ private fun filterChat(chat: Chat, searchText: String, showUnreadAndFavorites: B meetsPredicate = meetsPredicate && (cInfo.chatSettings?.favorite ?: false) } - return meetsPredicate; + return meetsPredicate } private fun viewNameContains(cInfo: ChatInfo, s: String): Boolean = @@ -512,84 +517,99 @@ private fun contactTypesSearchTargets(baseContactTypes: List, searc } @Composable -private fun DeletedContactsView(rh: RemoteHostInfo?, close: () -> Unit) { - val oneHandUI = remember { chatModel.controller.appPrefs.oneHandUI } +private fun DeletedContactsView(rh: RemoteHostInfo?, closeDeletedChats: () -> Unit, close: () -> Unit) { + val oneHandUI = remember { appPrefs.oneHandUI.state } + val keyboardState by getKeyboardState() + val showToolbarInOneHandUI = remember { derivedStateOf { keyboardState == KeyboardState.Closed && oneHandUI.value } } - var modifier = Modifier.fillMaxSize() - - if (oneHandUI.state.value) { - modifier = modifier.scale(scaleX = 1f, scaleY = -1f) - } - - Column( - modifier, + Scaffold( + bottomBar = { + if (showToolbarInOneHandUI.value) { + CloseSheetBar( + close = closeDeletedChats, + showClose = true, + endButtons = { Spacer(Modifier.minimumInteractiveComponentSize()) }, + arrangement = Arrangement.Bottom, + closeBarTitle = generalGetString(MR.strings.deleted_chats), + barPaddingValues = PaddingValues(horizontal = 0.dp) + ) + Divider() + } + } ) { - if (!oneHandUI.state.value) { - Box(contentAlignment = Alignment.Center) { - val bottomPadding = DEFAULT_PADDING - AppBarTitle( - stringResource(MR.strings.deleted_chats), - hostDevice(rh?.remoteHostId), - bottomPadding = bottomPadding - ) - } - } - - val listState = rememberLazyListState(lazyListState.first, lazyListState.second) - val searchText = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) } - val searchShowingSimplexLink = remember { mutableStateOf(false) } - val searchChatFilteredBySimplexLink = remember { mutableStateOf(null) } - val showUnreadAndFavorites = remember { ChatController.appPrefs.showUnreadAndFavorites.state }.value - val contactTypes = listOf(ContactType.CHAT_DELETED) - val allChats by remember(chatModel.chats.value, contactTypes) { - derivedStateOf { filterContactTypes(chatModel.chats.value, contactTypes) } - } - val filteredContactChats = filteredContactChats( - showUnreadAndFavorites = showUnreadAndFavorites, - searchChatFilteredBySimplexLink = searchChatFilteredBySimplexLink, - searchShowingSimplexLink = searchShowingSimplexLink, - searchText = searchText.value.text, - contactChats = allChats - ) - - LazyColumnWithScrollBar( - Modifier.fillMaxWidth(), - listState + Column( + Modifier + .fillMaxSize() + .padding(it) + .then(if (oneHandUI.value) Modifier.scale(scaleX = 1f, scaleY = -1f) else Modifier), ) { - item { - Divider() - ContactsSearchBar( - listState = listState, - searchText = searchText, - searchShowingSimplexLink = searchShowingSimplexLink, - searchChatFilteredBySimplexLink = searchChatFilteredBySimplexLink, - close = close, - oneHandUI = oneHandUI - ) - Divider() - - Spacer(Modifier.padding(bottom = DEFAULT_PADDING)) - } - - itemsIndexed(filteredContactChats) { index, chat -> - val nextChatSelected = remember(chat.id, filteredContactChats) { - derivedStateOf { - chatModel.chatId.value != null && filteredContactChats.getOrNull(index + 1)?.id == chatModel.chatId.value - } - } - ContactListNavLinkView(chat, nextChatSelected, oneHandUI.state) - } - } - if (filteredContactChats.isEmpty() && allChats.isNotEmpty()) { - Column(Modifier.fillMaxSize().padding(DEFAULT_PADDING)) { - Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { - Text( - generalGetString(MR.strings.no_filtered_contacts), - color = MaterialTheme.colors.secondary, - modifier = if (oneHandUI.state.value) Modifier.scale(scaleX = 1f, scaleY = -1f) else Modifier + if (!oneHandUI.value) { + Box(contentAlignment = Alignment.Center) { + val bottomPadding = DEFAULT_PADDING + AppBarTitle( + stringResource(MR.strings.deleted_chats), + hostDevice(rh?.remoteHostId), + bottomPadding = bottomPadding ) } } + + val listState = rememberLazyListState(lazyListState.first, lazyListState.second) + val searchText = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) } + val searchShowingSimplexLink = remember { mutableStateOf(false) } + val searchChatFilteredBySimplexLink = remember { mutableStateOf(null) } + val showUnreadAndFavorites = remember { appPrefs.showUnreadAndFavorites.state }.value + val allChats by remember(chatModel.chats.value) { + derivedStateOf { filterContactTypes(chatModel.chats.value, listOf(ContactType.CHAT_DELETED)) } + } + val filteredContactChats = filteredContactChats( + showUnreadAndFavorites = showUnreadAndFavorites, + searchChatFilteredBySimplexLink = searchChatFilteredBySimplexLink, + searchShowingSimplexLink = searchShowingSimplexLink, + searchText = searchText.value.text, + contactChats = allChats + ) + + LazyColumnWithScrollBar( + Modifier.fillMaxWidth(), + listState + ) { + item { + if (!oneHandUI.value) { + Divider() + } + ContactsSearchBar( + listState = listState, + searchText = searchText, + searchShowingSimplexLink = searchShowingSimplexLink, + searchChatFilteredBySimplexLink = searchChatFilteredBySimplexLink, + close = close, + ) + Divider() + + Spacer(Modifier.padding(bottom = DEFAULT_PADDING)) + } + + itemsIndexed(filteredContactChats) { index, chat -> + val nextChatSelected = remember(chat.id, filteredContactChats) { + derivedStateOf { + chatModel.chatId.value != null && filteredContactChats.getOrNull(index + 1)?.id == chatModel.chatId.value + } + } + ContactListNavLinkView(chat, nextChatSelected) + } + } + if (filteredContactChats.isEmpty() && allChats.isNotEmpty()) { + Column(Modifier.fillMaxSize().padding(DEFAULT_PADDING)) { + Box(Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) { + Text( + generalGetString(MR.strings.no_filtered_contacts), + color = MaterialTheme.colors.secondary, + modifier = if (oneHandUI.value) Modifier.scale(scaleX = 1f, scaleY = -1f) else Modifier + ) + } + } + } } } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt index 77e5662b21..007f474265 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatView.kt @@ -61,9 +61,8 @@ fun ModalData.NewChatView(rh: RemoteHostInfo?, selection: NewChatOption, showQRC /** When [AddContactLearnMore] is open, we don't need to drop [ChatModel.showingInvitation]. * Otherwise, it will be called here AFTER [AddContactLearnMore] is launched and will clear the value too soon. * It will be dropped automatically when connection established or when user goes away from this screen. - * It applies only to Android because on Desktop center space will not be overlapped by [AddContactLearnMore] **/ - if (chatModel.showingInvitation.value != null && (ModalManager.start.openModalCount() == 1 || appPlatform.isDesktop)) { + if (chatModel.showingInvitation.value != null && ModalManager.start.openModalCount() == 1) { val conn = contactConnection.value if (chatModel.showingInvitation.value?.connChatUsed == false && conn != null) { AlertManager.shared.showAlertDialog( @@ -78,7 +77,7 @@ fun ModalData.NewChatView(rh: RemoteHostInfo?, selection: NewChatOption, showQRC controller.deleteChat(Chat(remoteHostId = rh?.remoteHostId, chatInfo = chatInfo, chatItems = listOf())) if (chatModel.chatId.value == chatInfo.id) { chatModel.chatId.value = null - ModalManager.end.closeModals() + ModalManager.start.closeModals() } } } @@ -212,8 +211,7 @@ private fun InviteView(rhId: Long?, connReqInvitation: String, contactConnection Spacer(Modifier.height(10.dp)) val incognito = remember { mutableStateOf(controller.appPrefs.incognito.get()) } IncognitoToggle(controller.appPrefs.incognito, incognito) { - if (appPlatform.isDesktop) ModalManager.end.closeModals() - ModalManager.end.showModal { IncognitoView() } + ModalManager.start.showModal { IncognitoView() } } KeyChangeEffect(incognito.value) { withBGApi { @@ -233,8 +231,7 @@ private fun InviteView(rhId: Long?, connReqInvitation: String, contactConnection private fun AddContactLearnMoreButton() { IconButton( { - if (appPlatform.isDesktop) ModalManager.end.closeModals() - ModalManager.end.showModalCloseable { close -> + ModalManager.start.showModalCloseable { close -> AddContactLearnMore(close) } },