diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Resources.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Resources.android.kt index 226e97d4dc..db3a9666c3 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Resources.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/Resources.android.kt @@ -50,4 +50,7 @@ actual fun screenWidth(): Dp = LocalConfiguration.current.screenWidthDp.dp actual fun desktopExpandWindowToWidth(width: Dp) {} +@Composable +actual fun allowToShowBackButtonInCenter(): Boolean = true + actual fun isRtl(text: CharSequence): Boolean = BidiFormatter.getInstance().isRtl(text) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt index dda00fc43c..74395edb91 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/App.kt @@ -274,26 +274,44 @@ fun EndPartOfScreen() { @Composable fun DesktopScreen(settingsState: SettingsViewState) { - Box { - // 56.dp is a size of unused space of settings drawer - Box(Modifier.width(DEFAULT_START_MODAL_WIDTH + 56.dp)) { - StartPartOfScreen(settingsState) - } - Box(Modifier.widthIn(max = DEFAULT_START_MODAL_WIDTH)) { - ModalManager.start.showInView() - } - Row(Modifier.padding(start = DEFAULT_START_MODAL_WIDTH).clipToBounds()) { - Box(Modifier.widthIn(min = DEFAULT_MIN_CENTER_MODAL_WIDTH).weight(1f)) { - CenterPartOfScreen() + BoxWithConstraints { + Box { + val maxWidth = this@BoxWithConstraints.maxWidth + // 56.dp is a size of unused space of settings drawer + val startMaxWidth = when { + maxWidth >= DEFAULT_START_MODAL_WIDTH + DEFAULT_MIN_CENTER_MODAL_WIDTH -> DEFAULT_START_MODAL_WIDTH + 56.dp + ChatModel.chatId.value == null && !ModalManager.center.hasModalsOpen() -> maxWidth + else -> DEFAULT_START_MODAL_WIDTH } - if (ModalManager.end.hasModalsOpen()) { - VerticalDivider() + val startModalMaxWidth = when { + maxWidth >= DEFAULT_START_MODAL_WIDTH + DEFAULT_MIN_CENTER_MODAL_WIDTH -> DEFAULT_START_MODAL_WIDTH + ChatModel.chatId.value == null && !ModalManager.center.hasModalsOpen() -> maxWidth + else -> DEFAULT_START_MODAL_WIDTH } - Box(Modifier.widthIn(max = DEFAULT_END_MODAL_WIDTH).clipToBounds()) { - EndPartOfScreen() + Box(Modifier.widthIn(max = startMaxWidth)) { + StartPartOfScreen(settingsState) + Box(Modifier.widthIn(max = startModalMaxWidth)) { + ModalManager.start.showInView() + } + } + val centerMaxWidth = when { + maxWidth >= DEFAULT_START_MODAL_WIDTH + DEFAULT_MIN_CENTER_MODAL_WIDTH -> maxWidth - DEFAULT_START_MODAL_WIDTH + ChatModel.chatId.value != null || ModalManager.center.hasModalsOpen() -> maxOf(DEFAULT_START_MODAL_WIDTH, maxWidth) - 1.dp + else -> 0.dp + } + Row(Modifier.padding(start = maxOf(maxWidth - centerMaxWidth, 0.dp))) { + Box(Modifier.widthIn(min = DEFAULT_MIN_CENTER_MODAL_WIDTH).weight(1f)) { + CenterPartOfScreen() + } + if (ModalManager.end.hasModalsOpen() && maxWidth >= DEFAULT_START_MODAL_WIDTH + DEFAULT_MIN_CENTER_MODAL_WIDTH + DEFAULT_END_MODAL_WIDTH) { + VerticalDivider() + } + Box(Modifier.widthIn(max = if (centerMaxWidth < DEFAULT_MIN_CENTER_MODAL_WIDTH + DEFAULT_END_MODAL_WIDTH) centerMaxWidth else DEFAULT_END_MODAL_WIDTH).clipToBounds()) { + EndPartOfScreen() + } } } - val (userPickerState, scaffoldState, switchingUsers ) = settingsState + val (userPickerState, scaffoldState, switchingUsers) = settingsState val scope = rememberCoroutineScope() if (scaffoldState.drawerState.isOpen) { Box( @@ -306,7 +324,9 @@ fun DesktopScreen(settingsState: SettingsViewState) { }) ) } - VerticalDivider(Modifier.padding(start = DEFAULT_START_MODAL_WIDTH)) + if (maxWidth >= DEFAULT_START_MODAL_WIDTH + DEFAULT_MIN_CENTER_MODAL_WIDTH) { + VerticalDivider(Modifier.padding(start = DEFAULT_START_MODAL_WIDTH)) + } UserPicker(chatModel, userPickerState, switchingUsers) { scope.launch { if (scaffoldState.drawerState.isOpen) scaffoldState.drawerState.close() else scaffoldState.drawerState.open() } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Resources.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Resources.kt index c7799e592b..723fc0fe7b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Resources.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Resources.kt @@ -5,6 +5,7 @@ import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.Dp +import chat.simplex.common.ui.theme.DEFAULT_MIN_CENTER_MODAL_WIDTH import com.russhwolf.settings.Settings import dev.icerock.moko.resources.StringResource @@ -30,4 +31,7 @@ expect fun screenWidth(): Dp expect fun desktopExpandWindowToWidth(width: Dp) +@Composable +expect fun allowToShowBackButtonInCenter(): Boolean + expect fun isRtl(text: CharSequence): Boolean diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt index 0f7dd1a081..e149d49693 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatView.kt @@ -474,7 +474,7 @@ fun ChatInfoToolbar( showSearch = false } } - if (appPlatform.isAndroid) { + if (allowToShowBackButtonInCenter()) { BackHandler(onBack = onBackClicked) } val barButtons = arrayListOf<@Composable RowScope.() -> Unit>() @@ -534,7 +534,7 @@ fun ChatInfoToolbar( } DefaultTopAppBar( - navigationButton = { if (appPlatform.isAndroid || showSearch) { NavigationButtonBack(onBackClicked) } }, + navigationButton = { if (allowToShowBackButtonInCenter() || showSearch) { Box(Modifier.offset(y = 4.dp)) { NavigationButtonBack(onBackClicked) } } }, title = { ChatInfoToolbarTitle(chat.chatInfo) }, onTitleClick = info, showSearch = showSearch, 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 0be9ef12d8..460bced62b 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 @@ -16,6 +16,7 @@ import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.* +import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.chat.* import chat.simplex.common.views.chat.group.deleteGroupDialog @@ -24,8 +25,6 @@ import chat.simplex.common.views.chat.item.InvalidJSONView import chat.simplex.common.views.chat.item.ItemAction import chat.simplex.common.views.helpers.* import chat.simplex.common.views.newchat.ContactConnectionInfoView -import chat.simplex.common.platform.appPlatform -import chat.simplex.common.platform.ntfManager import chat.simplex.res.MR import kotlinx.coroutines.delay import kotlinx.datetime.Clock @@ -42,6 +41,7 @@ fun ChatListNavLinkView(chat: Chat, chatModel: ChatModel) { showMenu.value = false delay(500L) } + val showClose = allowToShowBackButtonInCenter() when (chat.chatInfo) { is ChatInfo.Direct -> { val contactNetworkStatus = chatModel.contactNetworkStatus(chat.chatInfo.contact) @@ -75,7 +75,7 @@ fun ChatListNavLinkView(chat: Chat, chatModel: ChatModel) { click = { ModalManager.center.closeModals() ModalManager.end.closeModals() - ModalManager.center.showModalCloseable(true, showClose = appPlatform.isAndroid) { close -> + ModalManager.center.showModalCloseable(true, showClose = showClose) { close -> ContactConnectionInfoView(chatModel, chat.chatInfo.contactConnection.connReqInv, chat.chatInfo.contactConnection, false, close) } }, @@ -341,13 +341,14 @@ fun ContactRequestMenuItems(chatInfo: ChatInfo.ContactRequest, chatModel: ChatMo @Composable fun ContactConnectionMenuItems(chatInfo: ChatInfo.ContactConnection, chatModel: ChatModel, showMenu: MutableState) { + val showClose = allowToShowBackButtonInCenter() ItemAction( stringResource(MR.strings.set_contact_name), painterResource(MR.images.ic_edit), onClick = { ModalManager.center.closeModals() ModalManager.end.closeModals() - ModalManager.center.showModalCloseable(true, showClose = appPlatform.isAndroid) { close -> + ModalManager.center.showModalCloseable(true, showClose = showClose) { close -> ContactConnectionInfoView(chatModel, chatInfo.contactConnection.connReqInv, chatInfo.contactConnection, true, close) } showMenu.value = false 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 43b06a2159..9af382060a 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 @@ -58,7 +58,7 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf connectIfOpenedViaUri(url, chatModel) } } - val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp + val endPadding = if (appPlatform.isDesktop && !allowToShowBackButtonInCenter()) 56.dp else 0.dp var searchInList by rememberSaveable { mutableStateOf("") } val scope = rememberCoroutineScope() val (userPickerState, scaffoldState, switchingUsers ) = settingsState diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ShareListView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ShareListView.kt index 2d0ed7eb53..d2bd239009 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ShareListView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ShareListView.kt @@ -18,8 +18,7 @@ import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.model.Chat import chat.simplex.common.model.ChatModel -import chat.simplex.common.platform.BackHandler -import chat.simplex.common.platform.appPlatform +import chat.simplex.common.platform.* import chat.simplex.res.MR import kotlinx.coroutines.flow.MutableStateFlow @@ -27,7 +26,7 @@ import kotlinx.coroutines.flow.MutableStateFlow fun ShareListView(chatModel: ChatModel, settingsState: SettingsViewState, stopped: Boolean) { var searchInList by rememberSaveable { mutableStateOf("") } val (userPickerState, scaffoldState, switchingUsers) = settingsState - val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp + val endPadding = if (appPlatform.isDesktop && !allowToShowBackButtonInCenter()) 56.dp else 0.dp Scaffold( Modifier.padding(end = endPadding), scaffoldState = scaffoldState, 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 171465d86d..7751018197 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 @@ -96,7 +96,7 @@ private fun NewChatSheetLayout( } } } - val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp + val endPadding = if (appPlatform.isDesktop && !allowToShowBackButtonInCenter()) 56.dp else 0.dp val maxWidth = with(LocalDensity.current) { screenWidth() * density } Column( Modifier diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SetDeliveryReceiptsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SetDeliveryReceiptsView.kt index 089ec7713f..30b8687527 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SetDeliveryReceiptsView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SetDeliveryReceiptsView.kt @@ -73,7 +73,7 @@ private fun SetDeliveryReceiptsLayout( skip: () -> Unit, userCount: Int, ) { - val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp + val endPadding = if (appPlatform.isDesktop && !allowToShowBackButtonInCenter()) 56.dp else 0.dp Column( Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(top = DEFAULT_PADDING, end = endPadding), horizontalAlignment = Alignment.CenterHorizontally, diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Resources.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Resources.desktop.kt index 3a76808b0c..3df276fd2f 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Resources.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/Resources.desktop.kt @@ -6,6 +6,8 @@ import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.* import chat.simplex.common.simplexWindowState +import chat.simplex.common.ui.theme.DEFAULT_MIN_CENTER_MODAL_WIDTH +import chat.simplex.common.ui.theme.DEFAULT_START_MODAL_WIDTH import com.russhwolf.settings.* import dev.icerock.moko.resources.StringResource import dev.icerock.moko.resources.desc.desc @@ -54,6 +56,9 @@ actual fun desktopExpandWindowToWidth(width: Dp) { simplexWindowState.windowState.size = simplexWindowState.windowState.size.copy(width = width) } +@Composable +actual fun allowToShowBackButtonInCenter(): Boolean = simplexWindowState.windowState.size.width < DEFAULT_START_MODAL_WIDTH + DEFAULT_MIN_CENTER_MODAL_WIDTH + actual fun isRtl(text: CharSequence): Boolean { if (text.isEmpty()) return false return text.any { char ->