From 43381b5cf03f881874367fd21a1653c4ca79339d Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Tue, 19 Mar 2024 23:56:36 +0700 Subject: [PATCH 01/10] desktop: scroll bars (#3920) * desktop: scroll bar * more places with scrollbar * removed unused code * color --------- Co-authored-by: Evgeny Poberezkin --- .../platform/ScrollableColumn.android.kt | 35 +++++ .../views/usersettings/Appearance.android.kt | 4 +- .../chat/simplex/common/platform/Platform.kt | 11 +- .../common/platform/ScrollableColumn.kt | 34 +++++ .../chat/simplex/common/views/TerminalView.kt | 2 +- .../chat/simplex/common/views/WelcomeView.kt | 8 +- .../simplex/common/views/chat/ChatInfoView.kt | 3 +- .../common/views/chat/ChatItemInfoView.kt | 12 +- .../simplex/common/views/chat/ChatView.kt | 6 +- .../common/views/chat/ContactPreferences.kt | 6 +- .../common/views/chat/VerifyCodeView.kt | 6 +- .../views/chat/group/AddGroupMembersView.kt | 5 +- .../views/chat/group/GroupChatInfoView.kt | 3 +- .../common/views/chat/group/GroupLinkView.kt | 6 +- .../views/chat/group/GroupMemberInfoView.kt | 5 +- .../views/chat/group/GroupPreferences.kt | 5 +- .../views/chat/group/GroupProfileView.kt | 3 +- .../views/chat/group/WelcomeMessageView.kt | 5 +- .../views/chat/item/CIInvalidJSONView.kt | 18 +-- .../common/views/chatlist/ChatListView.kt | 2 +- .../common/views/chatlist/ShareListView.kt | 7 +- .../common/views/database/ChatArchiveView.kt | 2 +- .../views/database/DatabaseEncryptionView.kt | 11 +- .../views/database/DatabaseErrorView.kt | 4 +- .../common/views/database/DatabaseView.kt | 7 +- .../simplex/common/views/helpers/Section.kt | 5 +- .../views/migration/MigrateFromDevice.kt | 9 +- .../common/views/migration/MigrateToDevice.kt | 11 +- .../views/newchat/AddContactLearnMore.kt | 11 +- .../common/views/newchat/AddGroupView.kt | 3 +- .../newchat/ContactConnectionInfoView.kt | 14 +- .../common/views/newchat/NewChatView.kt | 15 +- .../views/onboarding/CreateSimpleXAddress.kt | 4 +- .../common/views/onboarding/HowItWorks.kt | 3 +- .../views/onboarding/SetNotificationsMode.kt | 4 +- .../onboarding/SetupDatabasePassphrase.kt | 4 +- .../common/views/onboarding/SimpleXInfo.kt | 4 +- .../common/views/onboarding/WhatsNewView.kt | 6 +- .../common/views/remote/ConnectDesktopView.kt | 8 +- .../common/views/remote/ConnectMobileView.kt | 8 +- .../usersettings/AdvancedNetworkSettings.kt | 6 +- .../common/views/usersettings/Appearance.kt | 4 +- .../common/views/usersettings/CallSettings.kt | 5 +- .../views/usersettings/DeveloperView.kt | 5 +- .../common/views/usersettings/HelpView.kt | 4 +- .../views/usersettings/HiddenProfileView.kt | 6 +- .../views/usersettings/IncognitoView.kt | 5 +- .../views/usersettings/NetworkAndServers.kt | 12 +- .../usersettings/NotificationsSettingsView.kt | 8 +- .../common/views/usersettings/Preferences.kt | 5 +- .../views/usersettings/PrivacySettings.kt | 15 +- .../views/usersettings/ProtocolServerView.kt | 6 +- .../views/usersettings/ProtocolServersView.kt | 4 +- .../common/views/usersettings/RTCServers.kt | 4 +- .../usersettings/SetDeliveryReceiptsView.kt | 9 +- .../common/views/usersettings/SettingsView.kt | 3 +- .../usersettings/UserAddressLearnMore.kt | 8 +- .../views/usersettings/UserAddressView.kt | 15 +- .../views/usersettings/UserProfileView.kt | 3 +- .../views/usersettings/UserProfilesView.kt | 6 +- .../platform/ScrollableColumn.desktop.kt | 129 ++++++++++++++++++ .../views/usersettings/Appearance.desktop.kt | 7 +- .../kotlin/chat/simplex/desktop/Main.kt | 47 +++++++ 63 files changed, 436 insertions(+), 199 deletions(-) create mode 100644 apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/ScrollableColumn.android.kt create mode 100644 apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/ScrollableColumn.kt create mode 100644 apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/ScrollableColumn.desktop.kt diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/ScrollableColumn.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/ScrollableColumn.android.kt new file mode 100644 index 0000000000..199e719703 --- /dev/null +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/platform/ScrollableColumn.android.kt @@ -0,0 +1,35 @@ +package chat.simplex.common.platform + +import androidx.compose.foundation.* +import androidx.compose.foundation.gestures.FlingBehavior +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier + +@Composable +actual fun LazyColumnWithScrollBar( + modifier: Modifier, + state: LazyListState, + contentPadding: PaddingValues, + reverseLayout: Boolean, + verticalArrangement: Arrangement.Vertical, + horizontalAlignment: Alignment.Horizontal, + flingBehavior: FlingBehavior, + userScrollEnabled: Boolean, + content: LazyListScope.() -> Unit +) { + LazyColumn(modifier, state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled, content) +} + +@Composable +actual fun ColumnWithScrollBar( + modifier: Modifier, + verticalArrangement: Arrangement.Vertical, + horizontalAlignment: Alignment.Horizontal, + state: ScrollState, + content: @Composable ColumnScope.() -> Unit +) { + Column(modifier.verticalScroll(rememberScrollState()), verticalArrangement, horizontalAlignment, content) +} diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt index e02c011fac..ccb85c3982 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/usersettings/Appearance.android.kt @@ -85,8 +85,8 @@ fun AppearanceScope.AppearanceLayout( showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), editColor: (ThemeColor, Color) -> Unit, ) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.appearance_settings)) SectionView(stringResource(MR.strings.settings_section_title_language), padding = PaddingValues()) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Platform.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Platform.kt index 03878a19d1..5ca6dbdeb3 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Platform.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Platform.kt @@ -1,8 +1,14 @@ package chat.simplex.common.platform -import androidx.compose.runtime.Composable +import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.AnimationVector1D +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier import chat.simplex.common.model.ChatId import chat.simplex.common.model.NotificationsMode +import kotlinx.coroutines.Job interface PlatformInterface { suspend fun androidServiceStart() {} @@ -19,6 +25,9 @@ interface PlatformInterface { fun androidCallEnded() {} @Composable fun androidLockPortraitOrientation() {} suspend fun androidAskToAllowBackgroundCalls(): Boolean = true + @Composable fun desktopScrollBarComponents(): Triple, Modifier, MutableState> = remember { Triple(Animatable(0f), Modifier, mutableStateOf(Job())) } + @Composable fun desktopScrollBar(state: LazyListState, modifier: Modifier, scrollBarAlpha: Animatable, scrollJob: MutableState, reversed: Boolean) {} + @Composable fun desktopScrollBar(state: ScrollState, modifier: Modifier, scrollBarAlpha: Animatable, scrollJob: MutableState, reversed: Boolean) {} } /** * Multiplatform project has separate directories per platform + common directory that contains directories per platform + common for all of them. diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/ScrollableColumn.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/ScrollableColumn.kt new file mode 100644 index 0000000000..d4fa2fe125 --- /dev/null +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/ScrollableColumn.kt @@ -0,0 +1,34 @@ +package chat.simplex.common.platform + +import androidx.compose.foundation.* +import androidx.compose.foundation.gestures.FlingBehavior +import androidx.compose.foundation.gestures.ScrollableDefaults +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@Composable +expect fun LazyColumnWithScrollBar( + modifier: Modifier = Modifier, + state: LazyListState = rememberLazyListState(), + contentPadding: PaddingValues = PaddingValues(0.dp), + reverseLayout: Boolean = false, + verticalArrangement: Arrangement.Vertical = + if (!reverseLayout) Arrangement.Top else Arrangement.Bottom, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), + userScrollEnabled: Boolean = true, + content: LazyListScope.() -> Unit +) + +@Composable +expect fun ColumnWithScrollBar( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + state: ScrollState = rememberScrollState(), + content: @Composable ColumnScope.() -> Unit +) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/TerminalView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/TerminalView.kt index bcdf2e8380..1cd85ae7f9 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/TerminalView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/TerminalView.kt @@ -130,7 +130,7 @@ fun TerminalLog() { derivedStateOf { chatModel.terminalItems.value.asReversed() } } val clipboard = LocalClipboardManager.current - LazyColumn(state = listState, reverseLayout = true) { + LazyColumnWithScrollBar(state = listState, reverseLayout = true) { items(reversedTerminalItems) { item -> val rhId = item.remoteHostId val rhIdStr = if (rhId == null) "" else "$rhId " diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt index c4cbe06831..aa6b22fcde 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt @@ -49,8 +49,8 @@ fun CreateProfile(chatModel: ChatModel, close: () -> Unit) { val displayName = rememberSaveable { mutableStateOf("") } val focusRequester = remember { FocusRequester() } - Column( - modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()) + ColumnWithScrollBar( + modifier = Modifier.fillMaxSize() ) { Column(Modifier.padding(horizontal = DEFAULT_PADDING)) { AppBarTitle(stringResource(MR.strings.create_profile), bottomPadding = DEFAULT_PADDING) @@ -120,8 +120,8 @@ fun CreateFirstProfile(chatModel: ChatModel, close: () -> Unit) { val displayName = rememberSaveable { mutableStateOf("") } val focusRequester = remember { FocusRequester() } - Column( - modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()) + ColumnWithScrollBar( + modifier = Modifier.fillMaxSize() ) { /*CloseSheetBar(close = { if (chatModel.users.isEmpty()) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt index bbd5d93018..9f526f3eb8 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt @@ -319,10 +319,9 @@ fun ChatInfoLayout( KeyChangeEffect(chat.id) { scope.launch { scrollState.scrollTo(0) } } - Column( + ColumnWithScrollBar( Modifier .fillMaxWidth() - .verticalScroll(scrollState) ) { Row( Modifier.fillMaxWidth(), diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt index 4347623bd1..14bb3543c3 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatItemInfoView.kt @@ -24,11 +24,10 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.* -import chat.simplex.common.platform.onRightClick +import chat.simplex.common.platform.* import chat.simplex.common.views.chat.item.ItemAction import chat.simplex.common.views.chat.item.MarkdownText import chat.simplex.common.views.helpers.* -import chat.simplex.common.platform.shareText import chat.simplex.common.ui.theme.* import chat.simplex.res.MR import dev.icerock.moko.resources.ImageResource @@ -186,7 +185,8 @@ fun ChatItemInfoView(chatModel: ChatModel, ci: ChatItem, ciInfo: ChatItemInfo, d @Composable fun HistoryTab() { - Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) { + // LALAL SCROLLBAR DOESN'T WORK + ColumnWithScrollBar(Modifier.fillMaxWidth()) { Details() SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false) val versions = ciInfo.itemVersions @@ -210,7 +210,8 @@ fun ChatItemInfoView(chatModel: ChatModel, ci: ChatItem, ciInfo: ChatItemInfo, d @Composable fun QuoteTab(qi: CIQuote) { - Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) { + // LALAL SCROLLBAR DOESN'T WORK + ColumnWithScrollBar(Modifier.fillMaxWidth()) { Details() SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false) SectionView(padding = PaddingValues(horizontal = DEFAULT_PADDING)) { @@ -267,7 +268,8 @@ fun ChatItemInfoView(chatModel: ChatModel, ci: ChatItem, ciInfo: ChatItemInfo, d @Composable fun DeliveryTab(memberDeliveryStatuses: List) { - Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) { + // LALAL SCROLLBAR DOESN'T WORK + ColumnWithScrollBar(Modifier.fillMaxWidth()) { Details() SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false) val mss = membersStatuses(chatModel, memberDeliveryStatuses) 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 6e30bd11ca..c70511f847 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 @@ -1,5 +1,6 @@ package chat.simplex.common.views.chat +import androidx.compose.animation.core.Animatable import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.foundation.* import androidx.compose.foundation.gestures.* @@ -21,6 +22,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.input.pointer.* import androidx.compose.ui.text.* import androidx.compose.ui.unit.* import chat.simplex.common.model.* @@ -473,7 +475,7 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: suspend (chatId: } is ChatInfo.InvalidJSON -> { val close = { chatModel.chatId.value = null } - ModalView(close, showClose = appPlatform.isAndroid, content = { + ModalView(close, showClose = appPlatform.isAndroid, endButtons = { ShareButton { clipboard.shareText(chat.chatInfo.json) } }, content = { InvalidJSONView(chat.chatInfo.json) }) LaunchedEffect(chat.id) { @@ -907,7 +909,7 @@ fun BoxWithConstraintsScope.ChatItemsList( VideoPlayerHolder.releaseAll() } ) - LazyColumn(Modifier.align(Alignment.BottomCenter), state = listState, reverseLayout = true) { + LazyColumnWithScrollBar(Modifier.align(Alignment.BottomCenter), state = listState, reverseLayout = true) { itemsIndexed(reversedChatItems, key = { _, item -> item.id }) { i, cItem -> CompositionLocalProvider( // Makes horizontal and vertical scrolling to coexist nicely. diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ContactPreferences.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ContactPreferences.kt index f412c02154..5ad98aa216 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ContactPreferences.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ContactPreferences.kt @@ -19,6 +19,7 @@ import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.views.usersettings.PreferenceToggle import chat.simplex.common.model.* +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.res.MR @Composable @@ -77,10 +78,9 @@ private fun ContactPreferencesLayout( reset: () -> Unit, savePrefs: () -> Unit, ) { - Column( + ColumnWithScrollBar( Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()), + .fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.contact_preferences)) val timedMessages: MutableState = remember(featuresAllowed) { mutableStateOf(featuresAllowed.timedMessagesAllowed) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/VerifyCodeView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/VerifyCodeView.kt index 57c469adf2..5bd707ab66 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/VerifyCodeView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/VerifyCodeView.kt @@ -16,8 +16,7 @@ import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import chat.simplex.common.platform.appPlatform -import chat.simplex.common.platform.shareText +import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.views.newchat.QRCode @@ -57,10 +56,9 @@ private fun VerifyCodeLayout( connectionVerified: Boolean, verifyCode: (String?, cb: (Boolean) -> Unit) -> Unit, ) { - Column( + ColumnWithScrollBar( Modifier .fillMaxSize() - .verticalScroll(rememberScrollState()) .padding(horizontal = DEFAULT_PADDING) ) { AppBarTitle(stringResource(MR.strings.security_code), withPadding = false) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/AddGroupMembersView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/AddGroupMembersView.kt index 3f283f704e..d546b51a93 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/AddGroupMembersView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/AddGroupMembersView.kt @@ -125,10 +125,9 @@ fun AddGroupMembersLayout( } } - Column( + ColumnWithScrollBar( Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()), + .fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.button_add_members)) profileText() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt index 98c0fb4679..bfd7b5d52f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupChatInfoView.kt @@ -205,7 +205,8 @@ fun GroupChatInfoLayout( } val searchText = rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue()) } val filteredMembers = remember(members) { derivedStateOf { members.filter { it.chatViewName.lowercase().contains(searchText.value.text.trim()) } } } - LazyColumn( + // LALAL strange scrolling + LazyColumnWithScrollBar( Modifier .fillMaxWidth(), state = listState diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupLinkView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupLinkView.kt index 7b198bc41a..5291520566 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupLinkView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupLinkView.kt @@ -16,6 +16,7 @@ import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.* +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.platform.shareText import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* @@ -118,9 +119,8 @@ fun GroupLinkLayout( ) } - Column( - Modifier - .verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier, ) { AppBarTitle(stringResource(MR.strings.group_link)) Text( diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt index b1034b914b..ebb35a4468 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupMemberInfoView.kt @@ -291,10 +291,9 @@ fun GroupMemberInfoLayout( } } - Column( + ColumnWithScrollBar( Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()), + .fillMaxWidth(), ) { Row( Modifier.fillMaxWidth(), diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupPreferences.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupPreferences.kt index 694dac8898..607efb9a3b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupPreferences.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupPreferences.kt @@ -18,6 +18,7 @@ import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.views.usersettings.PreferenceToggleWithIcon import chat.simplex.common.model.* +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.res.MR @Composable @@ -72,8 +73,8 @@ private fun GroupPreferencesLayout( reset: () -> Unit, savePrefs: () -> Unit, ) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.group_preferences)) val timedMessages = remember(preferences) { mutableStateOf(preferences.timedMessages.enable) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupProfileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupProfileView.kt index 35bec31d7b..7975a298d1 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupProfileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/GroupProfileView.kt @@ -95,9 +95,8 @@ fun GroupProfileLayout( sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp) ) { ModalView(close = closeWithAlert) { - Column( + ColumnWithScrollBar( Modifier - .verticalScroll(scrollState) ) { Column( Modifier.fillMaxWidth() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/WelcomeMessageView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/WelcomeMessageView.kt index 6c2c37503c..3bbeceb03c 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/WelcomeMessageView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/WelcomeMessageView.kt @@ -29,6 +29,7 @@ import chat.simplex.common.views.chat.item.MarkdownText import chat.simplex.common.views.helpers.* import chat.simplex.common.model.ChatModel import chat.simplex.common.model.GroupInfo +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.platform.chatJsonLength import chat.simplex.common.ui.theme.DEFAULT_PADDING_HALF import chat.simplex.res.MR @@ -91,8 +92,8 @@ private fun GroupWelcomeLayout( linkMode: SimplexLinkMode, save: () -> Unit, ) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { val editMode = remember { mutableStateOf(true) } AppBarTitle(stringResource(MR.strings.group_welcome_title)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIInvalidJSONView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIInvalidJSONView.kt index 21c27fa34e..d297d5ef76 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIInvalidJSONView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/item/CIInvalidJSONView.kt @@ -1,6 +1,5 @@ package chat.simplex.common.views.chat.item -import SectionView import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.material.* @@ -8,23 +7,23 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalClipboardManager -import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.unit.dp +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.platform.shareText import chat.simplex.common.ui.theme.DEFAULT_PADDING import chat.simplex.common.views.helpers.* -import chat.simplex.common.views.usersettings.SettingsActionItem import chat.simplex.res.MR @Composable fun CIInvalidJSONView(json: String) { + val clipboard = LocalClipboardManager.current Row(Modifier .clickable { ModalManager.center.closeModals() ModalManager.end.closeModals() - ModalManager.center.showModal(true) { InvalidJSONView(json) } + ModalManager.center.showModal(true, endButtons = { ShareButton { clipboard.shareText(json) } }) { InvalidJSONView(json) } } .padding(horizontal = 10.dp, vertical = 6.dp) ) { @@ -34,15 +33,8 @@ fun CIInvalidJSONView(json: String) { @Composable fun InvalidJSONView(json: String) { - Column { - Spacer(Modifier.height(DEFAULT_PADDING)) - SectionView { - val clipboard = LocalClipboardManager.current - SettingsActionItem(painterResource(MR.images.ic_share), generalGetString(MR.strings.share_verb), click = { - clipboard.shareText(json) - }) - } - Column(Modifier.padding(DEFAULT_PADDING).fillMaxWidth().verticalScroll(rememberScrollState())) { + ColumnWithScrollBar { + Column(Modifier.padding(DEFAULT_PADDING).fillMaxWidth()) { Text(json) } } 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 417050db35..d03b8a708d 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 @@ -460,7 +460,7 @@ private fun ChatList(chatModel: ChatModel, searchText: MutableState(null) } val chats = filteredChats(showUnreadAndFavorites, searchShowingSimplexLink, searchChatFilteredBySimplexLink, searchText.value.text, allChats.toList()) - LazyColumn( + LazyColumnWithScrollBar( Modifier.fillMaxWidth(), listState ) { 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 818f1c70a5..04fef25ac2 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 @@ -1,7 +1,6 @@ package chat.simplex.common.views.chatlist import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material.* import androidx.compose.runtime.* @@ -14,12 +13,10 @@ import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import chat.simplex.common.SettingsViewState -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 @@ -146,7 +143,7 @@ private fun ShareList(chatModel: ChatModel, search: String) { if (search.isEmpty()) chatModel.chats.toList().filter { it.chatInfo.ready } else chatModel.chats.toList().filter { it.chatInfo.ready }.filter(filter) } } - LazyColumn( + LazyColumnWithScrollBar( modifier = Modifier.fillMaxWidth() ) { items(chats) { chat -> diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/ChatArchiveView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/ChatArchiveView.kt index 1e2f8420fd..6846d1c735 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/ChatArchiveView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/ChatArchiveView.kt @@ -46,7 +46,7 @@ fun ChatArchiveLayout( saveArchive: () -> Unit, deleteArchiveAlert: () -> Unit ) { - Column( + ColumnWithScrollBar( Modifier.fillMaxWidth(), ) { AppBarTitle(title) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt index 7ee9442b11..ca14b19adf 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.kt @@ -27,7 +27,7 @@ import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.unit.* import chat.simplex.common.model.* -import chat.simplex.common.platform.appPreferences +import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.views.usersettings.SettingsActionItem @@ -100,8 +100,10 @@ fun DatabaseEncryptionLayout( migration: Boolean, onConfirmEncrypt: () -> Unit, ) { + val (scrollBarAlpha, scrollModifier, scrollJob) = platform.desktopScrollBarComponents() + val scrollState = rememberScrollState() Column( - if (!migration) Modifier.fillMaxWidth().verticalScroll(rememberScrollState()) else Modifier.fillMaxWidth(), + if (!migration) Modifier.fillMaxWidth().verticalScroll(scrollState).then(if (appPlatform.isDesktop) scrollModifier else Modifier) else Modifier.fillMaxWidth(), ) { if (!migration) { AppBarTitle(stringResource(MR.strings.database_passphrase)) @@ -190,6 +192,11 @@ fun DatabaseEncryptionLayout( } SectionBottomSpacer() } + if (appPlatform.isDesktop && !migration) { + Box(Modifier.fillMaxSize()) { + platform.desktopScrollBar(scrollState, Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, false) + } + } } expect fun encryptDatabaseSavedAlert(onConfirm: () -> Unit) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseErrorView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseErrorView.kt index a22e6399f7..5f0356bb2d 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseErrorView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseErrorView.kt @@ -76,8 +76,8 @@ fun DatabaseErrorView( Text(String.format(generalGetString(MR.strings.database_migrations), ms.joinToString(", "))) } - Column( - Modifier.fillMaxSize().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, ) { val buttonEnabled = validKey(dbKey.value) && !progressIndicator.value diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt index 8d7d9f8166..023d10c539 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt @@ -7,8 +7,6 @@ import SectionItemView import SectionView import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment @@ -27,7 +25,6 @@ import chat.simplex.common.views.helpers.* import chat.simplex.common.views.usersettings.* import chat.simplex.common.platform.* import chat.simplex.res.MR -import kotlinx.coroutines.delay import kotlinx.coroutines.sync.withLock import kotlinx.datetime.* import java.io.* @@ -158,8 +155,8 @@ fun DatabaseLayout( val stopped = !runChat val operationsDisabled = (!stopped || progressIndicator) && !chatModel.desktopNoUserNoRemote - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.your_chat_database)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Section.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Section.kt index 1c3540d7f2..d930a2841e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Section.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/Section.kt @@ -61,9 +61,8 @@ fun SectionViewSelectable( onSelected: (T) -> Unit, ) { SectionView(title) { - LazyColumn { - items(values.size) { index -> - val item = values[index] + Column { + values.forEach { item -> SectionItemViewSpaceBetween({ onSelected(item.value) }) { Text(item.title) if (currentValue.value == item.value) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt index da6e7181d1..10add37e54 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt @@ -145,13 +145,20 @@ private fun MigrateFromDeviceLayout( ) { val tempDatabaseFile = rememberSaveable { mutableStateOf(fileForTemporaryDatabase()) } + val (scrollBarAlpha, scrollModifier, scrollJob) = platform.desktopScrollBarComponents() + val scrollState = rememberScrollState() Column( - Modifier.fillMaxSize().verticalScroll(rememberScrollState()).height(IntrinsicSize.Max), + Modifier.fillMaxSize().verticalScroll(scrollState).then(if (appPlatform.isDesktop) scrollModifier else Modifier).height(IntrinsicSize.Max), ) { AppBarTitle(stringResource(MR.strings.migrate_from_device_title)) SectionByState(migrationState, tempDatabaseFile.value, chatReceiver) SectionBottomSpacer() } + if (appPlatform.isDesktop) { + Box(Modifier.fillMaxSize()) { + platform.desktopScrollBar(scrollState, Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, false) + } + } platform.androidLockPortraitOrientation() } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt index e24570ba8b..9d204ad42c 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateToDevice.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalClipboardManager import chat.simplex.common.model.* @@ -154,14 +155,20 @@ private fun ModalData.MigrateToDeviceLayout( close: () -> Unit, ) { val tempDatabaseFile = rememberSaveable { mutableStateOf(fileForTemporaryDatabase()) } - + val (scrollBarAlpha, scrollModifier, scrollJob) = platform.desktopScrollBarComponents() + val scrollState = rememberScrollState() Column( - Modifier.fillMaxSize().verticalScroll(rememberScrollState()).height(IntrinsicSize.Max), + Modifier.fillMaxSize().verticalScroll(scrollState).then(if (appPlatform.isDesktop) scrollModifier else Modifier).height(IntrinsicSize.Max), ) { AppBarTitle(stringResource(MR.strings.migrate_to_device_title)) SectionByState(migrationState, tempDatabaseFile.value, chatReceiver, close) SectionBottomSpacer() } + if (appPlatform.isDesktop) { + Box(Modifier.fillMaxSize()) { + platform.desktopScrollBar(scrollState, Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, false) + } + } platform.androidLockPortraitOrientation() } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddContactLearnMore.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddContactLearnMore.kt index c2523c9b2e..da59050a3a 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddContactLearnMore.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddContactLearnMore.kt @@ -1,10 +1,11 @@ package chat.simplex.common.views.newchat -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.platform.chatModel +import chat.simplex.common.ui.theme.DEFAULT_PADDING import dev.icerock.moko.resources.compose.stringResource import chat.simplex.common.views.helpers.AppBarTitle import chat.simplex.common.views.helpers.KeyChangeEffect @@ -14,10 +15,10 @@ import chat.simplex.res.MR @Composable fun AddContactLearnMore(close: () -> Unit) { - Column( - Modifier.verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.padding(horizontal = DEFAULT_PADDING), ) { - AppBarTitle(stringResource(MR.strings.one_time_link)) + AppBarTitle(stringResource(MR.strings.one_time_link), withPadding = false) ReadableText(MR.strings.scan_qr_to_connect_to_contact) ReadableText(MR.strings.if_you_cant_meet_in_person) ReadableTextWithLink(MR.strings.read_more_in_user_guide_with_link, "https://simplex.chat/docs/guide/readme.html#connect-to-friends") diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddGroupView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddGroupView.kt index ee03028909..a7bb026f1a 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddGroupView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddGroupView.kt @@ -94,10 +94,9 @@ fun AddGroupLayout( sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp) ) { ModalView(close = close) { - Column( + ColumnWithScrollBar( Modifier .fillMaxSize() - .verticalScroll(rememberScrollState()) .padding(horizontal = DEFAULT_PADDING) ) { AppBarTitle(stringResource(MR.strings.create_secret_group_title), hostDevice(rhId)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ContactConnectionInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ContactConnectionInfoView.kt index 6202d8263f..31623e4a61 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ContactConnectionInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/ContactConnectionInfoView.kt @@ -65,14 +65,7 @@ fun ContactConnectionInfoView( share = { if (connReqInvitation != null) clipboard.shareText(connReqInvitation) }, learnMore = { ModalManager.end.showModalCloseable { close -> - Column( - Modifier - .fillMaxHeight() - .padding(horizontal = DEFAULT_PADDING), - verticalArrangement = Arrangement.SpaceBetween - ) { - AddContactLearnMore(close) - } + AddContactLearnMore(close) } } ) @@ -111,9 +104,8 @@ private fun ContactConnectionInfoLayout( } } - Column( - Modifier - .verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier, ) { AppBarTitle( stringResource( 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 bf154acca8..f341d59305 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 @@ -141,10 +141,10 @@ fun ModalData.NewChatView(rh: RemoteHostInfo?, selection: NewChatOption, showQRC } HorizontalPager(state = pagerState, Modifier.fillMaxSize(), verticalAlignment = Alignment.Top) { index -> - Column( + // LALAL SCROLLBAR DOESN'T WORK + ColumnWithScrollBar( Modifier - .fillMaxSize() - .verticalScroll(rememberScrollState()), + .fillMaxSize(), verticalArrangement = if (index == NewChatOption.INVITE.ordinal && connReqInvitation.isEmpty()) Arrangement.Center else Arrangement.Top) { Spacer(Modifier.height(DEFAULT_PADDING)) when (index) { @@ -232,14 +232,7 @@ private fun AddContactLearnMoreButton() { { if (appPlatform.isDesktop) ModalManager.end.closeModals() ModalManager.end.showModalCloseable { close -> - Column( - Modifier - .fillMaxHeight() - .padding(horizontal = DEFAULT_PADDING), - verticalArrangement = Arrangement.SpaceBetween - ) { - AddContactLearnMore(close) - } + AddContactLearnMore(close) } } ) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/CreateSimpleXAddress.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/CreateSimpleXAddress.kt index 190b962eae..e8ba5d7b60 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/CreateSimpleXAddress.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/CreateSimpleXAddress.kt @@ -75,8 +75,8 @@ private fun CreateSimpleXAddressLayout( createAddress: () -> Unit, nextStep: () -> Unit, ) { - Column( - Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(top = DEFAULT_PADDING), + ColumnWithScrollBar( + Modifier.fillMaxSize().padding(top = DEFAULT_PADDING), horizontalAlignment = Alignment.CenterHorizontally, ) { AppBarTitle(stringResource(MR.strings.simplex_address)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/HowItWorks.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/HowItWorks.kt index 14b36d0718..28fa1d3a48 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/HowItWorks.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/HowItWorks.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.* +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.ui.theme.* import chat.simplex.common.views.chat.item.MarkdownText import chat.simplex.common.views.helpers.* @@ -22,7 +23,7 @@ import dev.icerock.moko.resources.StringResource @Composable fun HowItWorks(user: User?, onboardingStage: SharedPreference? = null) { - Column(Modifier + ColumnWithScrollBar(Modifier .fillMaxWidth() .padding(horizontal = DEFAULT_PADDING), ) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetNotificationsMode.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetNotificationsMode.kt index aa413016d1..9124808959 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetNotificationsMode.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetNotificationsMode.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.ChatModel import chat.simplex.common.model.NotificationsMode +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.views.usersettings.changeNotificationsMode @@ -23,10 +24,9 @@ import dev.icerock.moko.resources.StringResource @Composable fun SetNotificationsMode(m: ChatModel) { - Column( + ColumnWithScrollBar( modifier = Modifier .fillMaxSize() - .verticalScroll(rememberScrollState()) .padding(vertical = 14.dp) ) { //CloseSheetBar(null) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetupDatabasePassphrase.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetupDatabasePassphrase.kt index 905bf77989..65bd89b11b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetupDatabasePassphrase.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SetupDatabasePassphrase.kt @@ -98,8 +98,8 @@ private fun SetupDatabasePassphraseLayout( onConfirmEncrypt: () -> Unit, nextStep: () -> Unit, ) { - Column( - Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(top = DEFAULT_PADDING), + ColumnWithScrollBar( + Modifier.fillMaxSize().padding(top = DEFAULT_PADDING), horizontalAlignment = Alignment.CenterHorizontally, ) { AppBarTitle(stringResource(MR.strings.setup_database_passphrase)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SimpleXInfo.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SimpleXInfo.kt index b82852664b..84c48bbc1b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SimpleXInfo.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/SimpleXInfo.kt @@ -16,6 +16,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.* import chat.simplex.common.model.* +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.platform.chatModel import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* @@ -39,10 +40,9 @@ fun SimpleXInfoLayout( onboardingStage: SharedPreference?, showModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), ) { - Column( + ColumnWithScrollBar( Modifier .fillMaxSize() - .verticalScroll(rememberScrollState()) .padding(start = DEFAULT_PADDING , end = DEFAULT_PADDING, top = DEFAULT_PADDING), horizontalAlignment = Alignment.CenterHorizontally ) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/WhatsNewView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/WhatsNewView.kt index fa7058160a..3f63e72a69 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/WhatsNewView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/WhatsNewView.kt @@ -18,6 +18,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.ChatModel +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.res.MR @@ -105,11 +106,10 @@ fun WhatsNewView(viaSettings: Boolean = false, close: () -> Unit) { val v = versionDescriptions[currentVersion.value] ModalView(close = close) { - Column( + ColumnWithScrollBar( Modifier .fillMaxSize() - .padding(horizontal = DEFAULT_PADDING) - .verticalScroll(rememberScrollState()), + .padding(horizontal = DEFAULT_PADDING), verticalArrangement = Arrangement.spacedBy(DEFAULT_PADDING.times(0.75f)) ) { AppBarTitle(String.format(generalGetString(MR.strings.new_in_version), v.version), bottomPadding = DEFAULT_PADDING) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectDesktopView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectDesktopView.kt index 5acb240cb3..76f522c614 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectDesktopView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectDesktopView.kt @@ -75,8 +75,8 @@ private fun ConnectDesktopLayout(deviceName: String, close: () -> Unit) { val sessionAddress = remember { mutableStateOf("") } val remoteCtrls = remember { mutableStateListOf() } val session = remember { chatModel.remoteCtrlSession }.value - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { val discovery = if (session == null) null else session.sessionState is UIRemoteCtrlSessionState.Searching if (discovery == true || (discovery == null && !showConnectScreen.value)) { @@ -391,8 +391,8 @@ private fun DesktopAddressView(sessionAddress: MutableState) { @Composable private fun LinkedDesktopsView(remoteCtrls: SnapshotStateList) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.linked_desktops)) SectionView(stringResource(MR.strings.desktop_devices).uppercase()) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectMobileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectMobileView.kt index bf7884e9d8..bd1be525be 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectMobileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/remote/ConnectMobileView.kt @@ -91,8 +91,8 @@ fun ConnectMobileLayout( connectDesktop: () -> Unit, deleteHost: (RemoteHostInfo) -> Unit, ) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp) ) { AppBarTitle(stringResource(if (remember { chatModel.remoteHosts }.isEmpty()) MR.strings.link_a_mobile else MR.strings.linked_mobiles)) @@ -181,8 +181,8 @@ private fun ConnectMobileViewLayout( refreshQrCode: () -> Unit = {}, UnderQrLayout: @Composable () -> Unit = {}, ) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp) ) { if (title != null) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt index 7683f0ed18..a2ea5959c3 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/AdvancedNetworkSettings.kt @@ -23,6 +23,7 @@ import chat.simplex.common.model.* import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.model.ChatModel +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.res.MR import java.text.DecimalFormat @@ -141,10 +142,9 @@ fun AdvancedNetworkSettingsView(chatModel: ChatModel) { ) { val secondsLabel = stringResource(MR.strings.network_option_seconds_label) - Column( + ColumnWithScrollBar( Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()), + .fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.network_settings_title)) SectionView { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt index 62216761ed..67f9a02ca7 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Appearance.kt @@ -57,8 +57,8 @@ object AppearanceScope { @Composable fun CustomizeThemeView(editColor: (ThemeColor, Color) -> Unit) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { val currentTheme by CurrentColors.collectAsState() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/CallSettings.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/CallSettings.kt index d4219a51c5..94415b0ee0 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/CallSettings.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/CallSettings.kt @@ -16,6 +16,7 @@ import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import chat.simplex.common.views.helpers.* import chat.simplex.common.model.* +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.res.MR @Composable @@ -35,8 +36,8 @@ fun CallSettingsLayout( callOnLockScreen: SharedPreference, editIceServers: () -> Unit, ) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp) ) { AppBarTitle(stringResource(MR.strings.your_calls)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/DeveloperView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/DeveloperView.kt index 421d4feec3..a03a015207 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/DeveloperView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/DeveloperView.kt @@ -12,10 +12,9 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalUriHandler import chat.simplex.common.model.* +import chat.simplex.common.platform.* import dev.icerock.moko.resources.compose.painterResource import dev.icerock.moko.resources.compose.stringResource -import chat.simplex.common.platform.appPlatform -import chat.simplex.common.platform.appPreferences import chat.simplex.common.views.TerminalView import chat.simplex.common.views.helpers.* import chat.simplex.res.MR @@ -26,7 +25,7 @@ fun DeveloperView( showCustomModal: (@Composable ModalData.(ChatModel, () -> Unit) -> Unit) -> (() -> Unit), withAuth: (title: String, desc: String, block: () -> Unit) -> Unit ) { - Column(Modifier.fillMaxWidth().verticalScroll(rememberScrollState())) { + ColumnWithScrollBar(Modifier.fillMaxWidth()) { val uriHandler = LocalUriHandler.current AppBarTitle(stringResource(MR.strings.settings_developer_tools)) val developerTools = m.controller.appPrefs.developerTools diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HelpView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HelpView.kt index 33e183aaaf..c2bf69bc0e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HelpView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HelpView.kt @@ -7,6 +7,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import dev.icerock.moko.resources.compose.stringResource import androidx.compose.desktop.ui.tooling.preview.Preview +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.ui.theme.DEFAULT_PADDING import chat.simplex.common.ui.theme.SimpleXTheme import chat.simplex.common.views.chatlist.ChatHelpView @@ -20,10 +21,9 @@ fun HelpView(userDisplayName: String) { @Composable fun HelpLayout(userDisplayName: String) { - Column( + ColumnWithScrollBar( Modifier .fillMaxWidth() - .verticalScroll(rememberScrollState()) .padding(horizontal = DEFAULT_PADDING), ){ AppBarTitle(String.format(stringResource(MR.strings.personal_welcome), userDisplayName), withPadding = false) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HiddenProfileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HiddenProfileView.kt index f3496c850f..4dd406c398 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HiddenProfileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/HiddenProfileView.kt @@ -17,6 +17,7 @@ import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp import chat.simplex.common.model.ChatModel import chat.simplex.common.model.User +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.ui.theme.* import chat.simplex.common.views.chatlist.UserProfileRow import chat.simplex.common.views.database.PassphraseField @@ -53,10 +54,9 @@ private fun HiddenProfileLayout( user: User, saveProfilePassword: (String) -> Unit ) { - Column( + ColumnWithScrollBar( Modifier - .fillMaxWidth() - .verticalScroll(rememberScrollState()), + .fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.hide_profile)) SectionView(padding = PaddingValues(start = 8.dp, end = DEFAULT_PADDING)) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/IncognitoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/IncognitoView.kt index 6da0d34bd3..6098f66941 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/IncognitoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/IncognitoView.kt @@ -1,13 +1,13 @@ package chat.simplex.common.views.usersettings import SectionBottomSpacer -import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Modifier import dev.icerock.moko.resources.compose.stringResource import androidx.compose.ui.unit.dp +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.ui.theme.DEFAULT_PADDING import chat.simplex.common.views.helpers.AppBarTitle import chat.simplex.common.views.helpers.generalGetString @@ -21,11 +21,10 @@ fun IncognitoView() { @Composable fun IncognitoLayout() { - Column { + ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.settings_section_title_incognito)) Column( Modifier - .verticalScroll(rememberScrollState()) .padding(horizontal = DEFAULT_PADDING), verticalArrangement = Arrangement.spacedBy(20.dp) ) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt index 27e5c80cde..e1f050b0b6 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NetworkAndServers.kt @@ -25,6 +25,7 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.* +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.platform.chatModel import chat.simplex.common.ui.theme.* import chat.simplex.common.views.chat.item.ClickableText @@ -151,8 +152,8 @@ fun NetworkAndServersView() { updateSessionMode: (TransportSessionMode) -> Unit, ) { val m = chatModel - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp) ) { AppBarTitle(stringResource(MR.strings.network_and_servers)) @@ -276,10 +277,9 @@ fun SockProxySettings( networkProxyHostPort: SharedPreference = m.controller.appPrefs.networkProxyHostPort, migration: Boolean, ) { - Column( + ColumnWithScrollBar( Modifier .fillMaxWidth() - .verticalScroll(rememberScrollState()) ) { val defaultHostPort = remember { "localhost:9050" } AppBarTitle(generalGetString(MR.strings.network_socks_proxy_settings)) @@ -376,7 +376,7 @@ private fun UseOnionHosts( } val onSelected = { showModal { - Column( + ColumnWithScrollBar( Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.network_use_onion_hosts)) @@ -430,7 +430,7 @@ private fun SessionModePicker( icon = painterResource(MR.images.ic_safety_divider), onSelected = { showModal { - Column( + ColumnWithScrollBar( Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.network_session_mode_transport_isolation)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt index ddd1b4068e..515d73a426 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/NotificationsSettingsView.kt @@ -56,8 +56,8 @@ fun NotificationsSettingsLayout( val modes = remember { notificationModes() } val previewModes = remember { notificationPreviewModes() } - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.notifications)) SectionView(null) { @@ -90,7 +90,7 @@ fun NotificationsModeView( onNotificationsModeSelected: (NotificationsMode) -> Unit, ) { val modes = remember { notificationModes() } - Column( + ColumnWithScrollBar( Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.settings_notifications_mode_title).lowercase().capitalize(Locale.current)) @@ -104,7 +104,7 @@ fun NotificationPreviewView( onNotificationPreviewModeSelected: (NotificationPreviewMode) -> Unit, ) { val previewModes = remember { notificationPreviewModes() } - Column( + ColumnWithScrollBar( Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.settings_notification_preview_title)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Preferences.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Preferences.kt index 8b7ac68205..cd0e40f5d0 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Preferences.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/Preferences.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.Modifier import dev.icerock.moko.resources.compose.stringResource import chat.simplex.common.views.helpers.* import chat.simplex.common.model.* +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.res.MR @Composable @@ -62,8 +63,8 @@ private fun PreferencesLayout( reset: () -> Unit, savePrefs: () -> Unit, ) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.your_preferences)) val timedMessages = remember(preferences) { mutableStateOf(preferences.timedMessages.allow) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt index 5f4b6c01e3..b376285259 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/PrivacySettings.kt @@ -30,8 +30,7 @@ import chat.simplex.common.views.isValidDisplayName import chat.simplex.common.views.localauth.SetAppPasscodeView import chat.simplex.common.views.onboarding.ReadableText import chat.simplex.common.model.ChatModel -import chat.simplex.common.platform.AppPlatform -import chat.simplex.common.platform.appPlatform +import chat.simplex.common.platform.* enum class LAMode { SYSTEM, @@ -55,8 +54,8 @@ fun PrivacySettingsView( showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), setPerformLA: (Boolean) -> Unit ) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { val simplexLinkMode = chatModel.controller.appPrefs.simplexLinkMode AppBarTitle(stringResource(MR.strings.your_privacy)) @@ -473,8 +472,8 @@ fun SimplexLockView( } } - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.chat_lock)) SectionView { @@ -580,8 +579,8 @@ fun SimplexLockView( @Composable private fun SelfDestructInfoView() { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()).padding(horizontal = DEFAULT_PADDING), + ColumnWithScrollBar( + Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING), ) { AppBarTitle(stringResource(MR.strings.self_destruct), withPadding = false) ReadableText(stringResource(MR.strings.if_you_enter_self_destruct_code)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServerView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServerView.kt index cb3b16b227..399895870f 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServerView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServerView.kt @@ -5,7 +5,6 @@ import SectionDividerSpaced import SectionItemView import SectionItemViewSpaceBetween import SectionView -import chat.simplex.common.platform.Log import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.selection.SelectionContainer @@ -20,13 +19,13 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import chat.simplex.common.platform.TAG import chat.simplex.common.model.* import chat.simplex.common.model.ServerAddress.Companion.parseServerAddress import chat.simplex.common.ui.theme.* import chat.simplex.common.views.helpers.* import chat.simplex.common.views.newchat.QRCode import chat.simplex.common.model.ChatModel +import chat.simplex.common.platform.* import chat.simplex.res.MR import kotlinx.coroutines.* import kotlinx.coroutines.flow.distinctUntilChanged @@ -76,10 +75,9 @@ private fun ProtocolServerLayout( onUpdate: (ServerCfg) -> Unit, onDelete: () -> Unit, ) { - Column( + ColumnWithScrollBar( Modifier .fillMaxWidth() - .verticalScroll(rememberScrollState()) ) { AppBarTitle(stringResource(if (server.preset) MR.strings.smp_servers_preset_server else MR.strings.smp_servers_your_server)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServersView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServersView.kt index ad1648f1ea..fe847432fb 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServersView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/ProtocolServersView.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.unit.dp import chat.simplex.common.model.ServerAddress.Companion.parseServerAddress import chat.simplex.common.views.helpers.* import chat.simplex.common.model.* +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.platform.appPlatform import chat.simplex.res.MR @@ -191,10 +192,9 @@ private fun ProtocolServersLayout( saveSMPServers: () -> Unit, showServer: (ServerCfg) -> Unit, ) { - Column( + ColumnWithScrollBar( Modifier .fillMaxWidth() - .verticalScroll(rememberScrollState()) ) { AppBarTitle(stringResource(if (serverProtocol == ServerProtocol.SMP) MR.strings.your_SMP_servers else MR.strings.your_XFTP_servers)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/RTCServers.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/RTCServers.kt index 50bed458cc..761a74d6e4 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/RTCServers.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/RTCServers.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.ChatModel +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.ui.theme.* import chat.simplex.common.views.call.parseRTCIceServers import chat.simplex.common.views.helpers.* @@ -98,12 +99,11 @@ fun RTCServersLayout( saveRTCServers: () -> Unit, editOn: () -> Unit, ) { - Column { + ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.your_ICE_servers)) Column( Modifier .fillMaxWidth() - .verticalScroll(rememberScrollState()) .padding(horizontal = DEFAULT_PADDING), verticalArrangement = Arrangement.spacedBy(8.dp) ) { 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 c18fd3f6f6..f0960c1511 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 @@ -74,8 +74,10 @@ private fun SetDeliveryReceiptsLayout( userCount: Int, ) { val endPadding = if (appPlatform.isDesktop) 56.dp else 0.dp + val (scrollBarAlpha, scrollModifier, scrollJob) = platform.desktopScrollBarComponents() + val scrollState = rememberScrollState() Column( - Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(top = DEFAULT_PADDING, end = endPadding), + Modifier.fillMaxSize().verticalScroll(scrollState).then(if (appPlatform.isDesktop) scrollModifier else Modifier).padding(top = DEFAULT_PADDING, end = endPadding), horizontalAlignment = Alignment.CenterHorizontally, ) { AppBarTitle(stringResource(MR.strings.delivery_receipts_title)) @@ -95,6 +97,11 @@ private fun SetDeliveryReceiptsLayout( SectionBottomSpacer() } + if (appPlatform.isDesktop) { + Box(Modifier.fillMaxSize().padding(end = endPadding)) { + platform.desktopScrollBar(scrollState, Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, false) + } + } } @Composable diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt index 3ef02f536a..298eb39737 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/SettingsView.kt @@ -105,10 +105,9 @@ fun SettingsLayout( val theme = CurrentColors.collectAsState() val uriHandler = LocalUriHandler.current Box(Modifier.fillMaxSize()) { - Column( + ColumnWithScrollBar( Modifier .fillMaxSize() - .verticalScroll(rememberScrollState()) .themedBackground(theme.value.base) .padding(top = if (appPlatform.isAndroid) DEFAULT_PADDING else DEFAULT_PADDING * 3) ) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressLearnMore.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressLearnMore.kt index 276c595435..63baece5cf 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressLearnMore.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressLearnMore.kt @@ -1,9 +1,10 @@ package chat.simplex.common.views.usersettings -import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import chat.simplex.common.platform.ColumnWithScrollBar +import chat.simplex.common.ui.theme.DEFAULT_PADDING import dev.icerock.moko.resources.compose.stringResource import chat.simplex.common.views.helpers.* import chat.simplex.common.views.onboarding.ReadableText @@ -12,8 +13,9 @@ import chat.simplex.res.MR @Composable fun UserAddressLearnMore() { - Column( - Modifier.verticalScroll(rememberScrollState()), + ColumnWithScrollBar(Modifier + .fillMaxHeight() + .padding(horizontal = DEFAULT_PADDING) ) { AppBarTitle(stringResource(MR.strings.simplex_address)) ReadableText(MR.strings.you_can_share_your_address) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressView.kt index ffaec8eb04..b595bd4e0e 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserAddressView.kt @@ -7,9 +7,7 @@ import SectionTextFooter import SectionView import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.verticalScroll import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable @@ -91,14 +89,7 @@ fun UserAddressView( }, learnMore = { ModalManager.start.showModal { - Column( - Modifier - .fillMaxHeight() - .padding(horizontal = DEFAULT_PADDING), - verticalArrangement = Arrangement.SpaceBetween - ) { - UserAddressLearnMore() - } + UserAddressLearnMore() } }, share = { userAddress: String -> clipboard.shareText(userAddress) }, @@ -182,9 +173,7 @@ private fun UserAddressLayout( deleteAddress: () -> Unit, saveAas: (AutoAcceptState, MutableState) -> Unit, ) { - Column( - Modifier.verticalScroll(rememberScrollState()), - ) { + ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.simplex_address), hostDevice(user?.remoteHostId), withPadding = false) Column( Modifier.fillMaxWidth().padding(bottom = DEFAULT_PADDING_HALF), diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfileView.kt index 1f5177d08b..e3636ec9c5 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfileView.kt @@ -98,9 +98,8 @@ fun UserProfileLayout( } } ModalView(close = closeWithAlert) { - Column( + ColumnWithScrollBar( Modifier - .verticalScroll(scrollState) .padding(horizontal = DEFAULT_PADDING), ) { AppBarTitle(stringResource(MR.strings.your_current_profile)) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt index 1beccd516c..a7e57662b5 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt @@ -158,10 +158,9 @@ private fun UserProfilesLayout( unmuteUser: (User) -> Unit, showHiddenProfile: (User) -> Unit, ) { - Column( + ColumnWithScrollBar( Modifier .fillMaxWidth() - .verticalScroll(rememberScrollState()) ) { if (profileHidden.value) { SectionView { @@ -260,10 +259,9 @@ enum class UserProfileAction { @Composable private fun ProfileActionView(action: UserProfileAction, user: User, doAction: (String) -> Unit) { - Column( + ColumnWithScrollBar( Modifier .fillMaxWidth() - .verticalScroll(rememberScrollState()) ) { val actionPassword = rememberSaveable { mutableStateOf("") } val passwordValid by remember { derivedStateOf { actionPassword.value == actionPassword.value.trim() } } diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/ScrollableColumn.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/ScrollableColumn.desktop.kt new file mode 100644 index 0000000000..1caf96902d --- /dev/null +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/platform/ScrollableColumn.desktop.kt @@ -0,0 +1,129 @@ +package chat.simplex.common.platform + +import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.AnimationVector1D +import androidx.compose.foundation.* +import androidx.compose.foundation.gestures.FlingBehavior +import androidx.compose.foundation.interaction.* +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.MaterialTheme +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.input.pointer.* +import androidx.compose.ui.unit.dp +import chat.simplex.common.views.helpers.detectCursorMove +import chat.simplex.common.views.helpers.mixWith +import kotlinx.coroutines.* + +@Composable +actual fun LazyColumnWithScrollBar( + modifier: Modifier, + state: LazyListState, + contentPadding: PaddingValues, + reverseLayout: Boolean, + verticalArrangement: Arrangement.Vertical, + horizontalAlignment: Alignment.Horizontal, + flingBehavior: FlingBehavior, + userScrollEnabled: Boolean, + content: LazyListScope.() -> Unit +) { + if (appPlatform.isAndroid) { + LazyColumn(modifier, state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled, content) + } else { + val scope = rememberCoroutineScope() + val scrollBarAlpha = remember { Animatable(0f) } + val scrollJob: MutableState = remember { mutableStateOf(Job()) } + val scrollModifier = remember { + Modifier + .pointerInput(Unit) { + detectCursorMove { + scope.launch { + scrollBarAlpha.animateTo(1f) + } + scrollJob.value.cancel() + scrollJob.value = scope.launch { + delay(1000L) + scrollBarAlpha.animateTo(0f) + } + } + } + } + LazyColumn(modifier.then(if (appPlatform.isDesktop) scrollModifier else Modifier), state, contentPadding, reverseLayout, verticalArrangement, horizontalAlignment, flingBehavior, userScrollEnabled, content) + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.CenterEnd) { + DesktopScrollBar(rememberScrollbarAdapter(state), Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, reverseLayout) + } + } +} + +@Composable +actual fun ColumnWithScrollBar( + modifier: Modifier, + verticalArrangement: Arrangement.Vertical, + horizontalAlignment: Alignment.Horizontal, + state: ScrollState, + content: @Composable ColumnScope.() -> Unit +) { + val scope = rememberCoroutineScope() + val scrollBarAlpha = remember { Animatable(0f) } + val scrollJob: MutableState = remember { mutableStateOf(Job()) } + val scrollModifier = remember { + Modifier + .pointerInput(Unit) { + detectCursorMove { + scope.launch { + scrollBarAlpha.animateTo(1f) + } + scrollJob.value.cancel() + scrollJob.value = scope.launch { + delay(1000L) + scrollBarAlpha.animateTo(0f) + } + } + } + } + Column(modifier.verticalScroll(state).then(scrollModifier), verticalArrangement, horizontalAlignment, content) + Box(Modifier.fillMaxSize(), contentAlignment = Alignment.CenterEnd) { + DesktopScrollBar(rememberScrollbarAdapter(state), Modifier.align(Alignment.CenterEnd).fillMaxHeight(), scrollBarAlpha, scrollJob, false) + } +} + +@Composable +fun DesktopScrollBar(adapter: androidx.compose.foundation.v2.ScrollbarAdapter, modifier: Modifier, scrollBarAlpha: Animatable, scrollJob: MutableState, reversed: Boolean) { + val scope = rememberCoroutineScope() + val interactionSource = remember { MutableInteractionSource() } + val isHovered by interactionSource.collectIsHoveredAsState() + val isDragged by interactionSource.collectIsDraggedAsState() + LaunchedEffect(isHovered, isDragged) { + scrollJob.value.cancel() + if (isHovered || isDragged) { + scrollBarAlpha.animateTo(1f) + } else { + scrollJob.value = scope.launch { + delay(1000L) + scrollBarAlpha.animateTo(0f) + } + } + } + VerticalScrollbar( + modifier = modifier.graphicsLayer { alpha = scrollBarAlpha.value } + .onPointerEvent(PointerEventType.Enter) { + scrollJob.value.cancel() + scope.launch { + scrollBarAlpha.animateTo(1f) + } + }, + reverseLayout = reversed, + style = LocalScrollbarStyle.current.copy( + thickness = if (isHovered || isDragged) 10.dp else 6.dp, + shape = RoundedCornerShape(if (isHovered || isDragged) 5.dp else 3.dp), + unhoverColor = if (MaterialTheme.colors.isLight) MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 0.7f) else MaterialTheme.colors.onBackground.mixWith(MaterialTheme.colors.background, 0.3f), + hoverColor = if (MaterialTheme.colors.isLight) MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 0.6f) else MaterialTheme.colors.onBackground.mixWith(MaterialTheme.colors.background, 0.4f) + ), + adapter = adapter, + interactionSource = interactionSource + ) +} diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt index 1a8ad010e3..5ffc68be79 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/usersettings/Appearance.desktop.kt @@ -4,8 +4,6 @@ import SectionBottomSpacer import SectionDividerSpaced import SectionView import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable @@ -13,6 +11,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import chat.simplex.common.model.ChatModel import chat.simplex.common.model.SharedPreference +import chat.simplex.common.platform.ColumnWithScrollBar import chat.simplex.common.platform.defaultLocale import chat.simplex.common.ui.theme.ThemeColor import chat.simplex.common.views.helpers.* @@ -43,8 +42,8 @@ fun AppearanceScope.AppearanceLayout( showSettingsModal: (@Composable (ChatModel) -> Unit) -> (() -> Unit), editColor: (ThemeColor, Color) -> Unit, ) { - Column( - Modifier.fillMaxWidth().verticalScroll(rememberScrollState()), + ColumnWithScrollBar( + Modifier.fillMaxWidth(), ) { AppBarTitle(stringResource(MR.strings.appearance_settings)) SectionView(stringResource(MR.strings.settings_section_title_language), padding = PaddingValues()) { diff --git a/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt b/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt index e32b0ae79a..7171f17991 100644 --- a/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt +++ b/apps/multiplatform/desktop/src/jvmMain/kotlin/chat/simplex/desktop/Main.kt @@ -1,7 +1,19 @@ package chat.simplex.desktop +import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.AnimationVector1D +import androidx.compose.foundation.* +import androidx.compose.foundation.interaction.* +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.runtime.* +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.* import chat.simplex.common.platform.* +import chat.simplex.common.platform.DesktopPlatform import chat.simplex.common.showApp +import chat.simplex.common.views.helpers.* +import kotlinx.coroutines.* import java.io.File fun main() { @@ -12,6 +24,7 @@ fun main() { return showApp() } +@OptIn(ExperimentalComposeUiApi::class) @Suppress("UnsafeDynamicallyLoadedCode") private fun initHaskell() { val resourcesDir = File(System.getProperty("compose.application.resources.dir")) @@ -27,6 +40,40 @@ private fun initHaskell() { System.setProperty("jna.library.path", vlcDir.absolutePath) //discoverVlcLibs(File(File(vlcDir, "vlc"), "plugins").absolutePath) initHS() + + platform = object: PlatformInterface { + @Composable + override fun desktopScrollBarComponents(): Triple, Modifier, MutableState> { + val scope = rememberCoroutineScope() + val scrollBarAlpha = remember { Animatable(0f) } + val scrollJob: MutableState = remember { mutableStateOf(Job()) } + val modifier = remember { + Modifier.pointerInput(Unit) { + detectCursorMove { + scope.launch { + scrollBarAlpha.animateTo(1f) + } + scrollJob.value.cancel() + scrollJob.value = scope.launch { + delay(1000L) + scrollBarAlpha.animateTo(0f) + } + } + } + } + return Triple(scrollBarAlpha, modifier, scrollJob) + } + + @Composable + override fun desktopScrollBar(state: LazyListState, modifier: Modifier, scrollBarAlpha: Animatable, scrollJob: MutableState, reversed: Boolean) { + DesktopScrollBar(rememberScrollbarAdapter(scrollState = state), modifier, scrollBarAlpha, scrollJob, reversed) + } + + @Composable + override fun desktopScrollBar(state: ScrollState, modifier: Modifier, scrollBarAlpha: Animatable, scrollJob: MutableState, reversed: Boolean) { + DesktopScrollBar(rememberScrollbarAdapter(scrollState = state), modifier, scrollBarAlpha, scrollJob, reversed) + } + } } private fun windowsLoadRequiredLibs(libsTmpDir: File, vlcDir: File) { From c2707d3c2b52e40761479390379831337b5572fd Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Tue, 19 Mar 2024 17:58:29 +0000 Subject: [PATCH 02/10] 5.6-beta.1: ios 203, android 190, desktop 34 --- apps/ios/SimpleX.xcodeproj/project.pbxproj | 52 +++++++++++----------- apps/multiplatform/gradle.properties | 8 ++-- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/apps/ios/SimpleX.xcodeproj/project.pbxproj b/apps/ios/SimpleX.xcodeproj/project.pbxproj index 93767f4b30..b2be41c947 100644 --- a/apps/ios/SimpleX.xcodeproj/project.pbxproj +++ b/apps/ios/SimpleX.xcodeproj/project.pbxproj @@ -36,6 +36,11 @@ 5C35CFC827B2782E00FB6C6D /* BGManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C35CFC727B2782E00FB6C6D /* BGManager.swift */; }; 5C35CFCB27B2E91D00FB6C6D /* NtfManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C35CFCA27B2E91D00FB6C6D /* NtfManager.swift */; }; 5C36027327F47AD5009F19D9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C36027227F47AD5009F19D9 /* AppDelegate.swift */; }; + 5C371E6A2BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C371E652BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a */; }; + 5C371E6B2BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C371E662BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a */; }; + 5C371E6C2BA9FDFA00100AD3 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C371E672BA9FDFA00100AD3 /* libgmpxx.a */; }; + 5C371E6D2BA9FDFA00100AD3 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C371E682BA9FDFA00100AD3 /* libffi.a */; }; + 5C371E6E2BA9FDFA00100AD3 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C371E692BA9FDFA00100AD3 /* libgmp.a */; }; 5C3A88CE27DF50170060F1C2 /* DetermineWidth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3A88CD27DF50170060F1C2 /* DetermineWidth.swift */; }; 5C3A88D127DF57800060F1C2 /* FramedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3A88D027DF57800060F1C2 /* FramedItemView.swift */; }; 5C3CCFCC2AE6BD3100C3F0C3 /* ConnectDesktopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C3CCFCB2AE6BD3100C3F0C3 /* ConnectDesktopView.swift */; }; @@ -57,11 +62,6 @@ 5C65F343297D45E100B67AF3 /* VersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C65F341297D3F3600B67AF3 /* VersionView.swift */; }; 5C6BA667289BD954009B8ECC /* DismissSheets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6BA666289BD954009B8ECC /* DismissSheets.swift */; }; 5C7031162953C97F00150A12 /* CIFeaturePreferenceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7031152953C97F00150A12 /* CIFeaturePreferenceView.swift */; }; - 5C746DB82BA0DA920049D734 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C746DB32BA0DA920049D734 /* libffi.a */; }; - 5C746DB92BA0DA920049D734 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C746DB42BA0DA920049D734 /* libgmpxx.a */; }; - 5C746DBA2BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C746DB52BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a */; }; - 5C746DBB2BA0DA920049D734 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C746DB62BA0DA920049D734 /* libgmp.a */; }; - 5C746DBC2BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C746DB72BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a */; }; 5C7505A227B65FDB00BE3227 /* CIMetaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A127B65FDB00BE3227 /* CIMetaView.swift */; }; 5C7505A527B679EE00BE3227 /* NavLinkPlain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */; }; 5C7505A827B6D34800BE3227 /* ChatInfoToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */; }; @@ -291,6 +291,11 @@ 5C371E4E2BA9AAA200100AD3 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = ""; }; 5C371E4F2BA9AB6400100AD3 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = "hu.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = ""; }; 5C371E502BA9AB6400100AD3 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/InfoPlist.strings; sourceTree = ""; }; + 5C371E652BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a"; sourceTree = ""; }; + 5C371E662BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a"; sourceTree = ""; }; + 5C371E672BA9FDFA00100AD3 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; + 5C371E682BA9FDFA00100AD3 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; + 5C371E692BA9FDFA00100AD3 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; 5C3A88CD27DF50170060F1C2 /* DetermineWidth.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetermineWidth.swift; sourceTree = ""; }; 5C3A88D027DF57800060F1C2 /* FramedItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FramedItemView.swift; sourceTree = ""; }; 5C3CCFCB2AE6BD3100C3F0C3 /* ConnectDesktopView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectDesktopView.swift; sourceTree = ""; }; @@ -327,11 +332,6 @@ 5C6D183229E93FBA00D430B3 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = "pl.lproj/SimpleX--iOS--InfoPlist.strings"; sourceTree = ""; }; 5C6D183329E93FBA00D430B3 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; 5C7031152953C97F00150A12 /* CIFeaturePreferenceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIFeaturePreferenceView.swift; sourceTree = ""; }; - 5C746DB32BA0DA920049D734 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = ""; }; - 5C746DB42BA0DA920049D734 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = ""; }; - 5C746DB52BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a"; sourceTree = ""; }; - 5C746DB62BA0DA920049D734 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = ""; }; - 5C746DB72BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a"; sourceTree = ""; }; 5C7505A127B65FDB00BE3227 /* CIMetaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIMetaView.swift; sourceTree = ""; }; 5C7505A427B679EE00BE3227 /* NavLinkPlain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavLinkPlain.swift; sourceTree = ""; }; 5C7505A727B6D34800BE3227 /* ChatInfoToolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInfoToolbar.swift; sourceTree = ""; }; @@ -523,12 +523,12 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5C746DB92BA0DA920049D734 /* libgmpxx.a in Frameworks */, - 5C746DBA2BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a in Frameworks */, + 5C371E6A2BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a in Frameworks */, + 5C371E6E2BA9FDFA00100AD3 /* libgmp.a in Frameworks */, + 5C371E6D2BA9FDFA00100AD3 /* libffi.a in Frameworks */, + 5C371E6C2BA9FDFA00100AD3 /* libgmpxx.a in Frameworks */, + 5C371E6B2BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a in Frameworks */, 5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */, - 5C746DB82BA0DA920049D734 /* libffi.a in Frameworks */, - 5C746DBC2BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a in Frameworks */, - 5C746DBB2BA0DA920049D734 /* libgmp.a in Frameworks */, 5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -592,11 +592,11 @@ 5C764E5C279C70B7000C6508 /* Libraries */ = { isa = PBXGroup; children = ( - 5C746DB32BA0DA920049D734 /* libffi.a */, - 5C746DB62BA0DA920049D734 /* libgmp.a */, - 5C746DB42BA0DA920049D734 /* libgmpxx.a */, - 5C746DB72BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo-ghc9.6.3.a */, - 5C746DB52BA0DA920049D734 /* libHSsimplex-chat-5.6.0.2-CrEKCx0J5BfIirfPSOWUVo.a */, + 5C371E682BA9FDFA00100AD3 /* libffi.a */, + 5C371E692BA9FDFA00100AD3 /* libgmp.a */, + 5C371E672BA9FDFA00100AD3 /* libgmpxx.a */, + 5C371E662BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH-ghc9.6.3.a */, + 5C371E652BA9FDFA00100AD3 /* libHSsimplex-chat-5.6.0.3-4nskXXUBgQ3Bvo5v4RfruH.a */, ); path = Libraries; sourceTree = ""; @@ -1536,7 +1536,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 202; + CURRENT_PROJECT_VERSION = 203; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_PREVIEWS = YES; @@ -1579,7 +1579,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "SimpleX (iOS).entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 202; + CURRENT_PROJECT_VERSION = 203; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; ENABLE_PREVIEWS = YES; @@ -1660,7 +1660,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 202; + CURRENT_PROJECT_VERSION = 203; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; GENERATE_INFOPLIST_FILE = YES; @@ -1692,7 +1692,7 @@ CODE_SIGN_ENTITLEMENTS = "SimpleX NSE/SimpleX NSE.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 202; + CURRENT_PROJECT_VERSION = 203; DEVELOPMENT_TEAM = 5NN7GUYB6T; ENABLE_BITCODE = NO; GENERATE_INFOPLIST_FILE = YES; @@ -1724,7 +1724,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 202; + CURRENT_PROJECT_VERSION = 203; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; @@ -1770,7 +1770,7 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 202; + CURRENT_PROJECT_VERSION = 203; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5NN7GUYB6T; DYLIB_COMPATIBILITY_VERSION = 1; diff --git a/apps/multiplatform/gradle.properties b/apps/multiplatform/gradle.properties index 5d3863f10a..62f1ad21bc 100644 --- a/apps/multiplatform/gradle.properties +++ b/apps/multiplatform/gradle.properties @@ -25,11 +25,11 @@ android.nonTransitiveRClass=true android.enableJetifier=true kotlin.mpp.androidSourceSetLayoutVersion=2 -android.version_name=5.6-beta.0 -android.version_code=189 +android.version_name=5.6-beta.1 +android.version_code=190 -desktop.version_name=5.6-beta.0 -desktop.version_code=33 +desktop.version_name=5.6-beta.1 +desktop.version_code=34 kotlin.version=1.8.20 gradle.plugin.version=7.4.2 From d2e6313ce305069469e7b4630818f58dda200144 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 20 Mar 2024 20:20:10 +0400 Subject: [PATCH 03/10] ui: swap finalize migration buttons (make destructive harder to reach, consistent order of primary and destructive with previous page) (#3931) --- .../Views/Migration/MigrateFromDevice.swift | 10 +++--- .../views/migration/MigrateFromDevice.kt | 32 +++++++++---------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift b/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift index b3b7269d22..aa02ebb12a 100644 --- a/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift +++ b/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift @@ -333,16 +333,16 @@ struct MigrateFromDevice: View { ZStack { List { Section { - Button(action: { alert = .deleteChat() }) { - settingsRow("trash.fill") { - Text("Delete database from this device").foregroundColor(.accentColor) - } - } Button(action: { alert = .startChat() }) { settingsRow("play.fill") { Text("Start chat").foregroundColor(.red) } } + Button(action: { alert = .deleteChat() }) { + settingsRow("trash.fill") { + Text("Delete database from this device").foregroundColor(.accentColor) + } + } } header: { Text("Migration complete") } footer: { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt index 10add37e54..d51bb17e40 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt @@ -375,22 +375,6 @@ private fun MutableState.LinkShownView(fileId: Long, link: S private fun MutableState.FinishedView(chatDeletion: Boolean) { Box { SectionView(stringResource(MR.strings.migrate_from_device_migration_complete).uppercase()) { - SettingsActionItemWithContent( - icon = painterResource(MR.images.ic_delete_forever), - text = stringResource(MR.strings.migrate_from_device_delete_database_from_device), - textColor = MaterialTheme.colors.primary, - click = { - AlertManager.shared.showAlertDialog( - title = generalGetString(MR.strings.delete_chat_profile_question), - text = generalGetString(MR.strings.delete_chat_profile_action_cannot_be_undone_warning), - confirmText = generalGetString(MR.strings.delete_verb), - onConfirm = { - deleteChatAndDismiss() - } - ) - } - ) {} - SettingsActionItemWithContent( icon = painterResource(MR.images.ic_play_arrow_filled), text = stringResource(MR.strings.migrate_from_device_start_chat), @@ -406,6 +390,22 @@ private fun MutableState.FinishedView(chatDeletion: Boolean) ) } ) {} + + SettingsActionItemWithContent( + icon = painterResource(MR.images.ic_delete_forever), + text = stringResource(MR.strings.migrate_from_device_delete_database_from_device), + textColor = MaterialTheme.colors.primary, + click = { + AlertManager.shared.showAlertDialog( + title = generalGetString(MR.strings.delete_chat_profile_question), + text = generalGetString(MR.strings.delete_chat_profile_action_cannot_be_undone_warning), + confirmText = generalGetString(MR.strings.delete_verb), + onConfirm = { + deleteChatAndDismiss() + } + ) + } + ) {} SectionTextFooter(annotatedStringResource(MR.strings.migrate_from_device_you_must_not_start_database_on_two_device)) SectionTextFooter(annotatedStringResource(MR.strings.migrate_from_device_using_on_two_device_breaks_encryption)) } From 6d54c21774284f777d14b1fde6a3920f4b6bb0c1 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Thu, 21 Mar 2024 00:49:53 +0700 Subject: [PATCH 04/10] ios: chatitem height with menu workaround (#3930) * ios: chatitem height with menu workaround * turned on animation * disabled animation in some places again --- apps/ios/Shared/Views/Chat/ChatView.swift | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index 3ada57ef5d..36d3e318ed 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -557,7 +557,12 @@ struct ChatView: View { chatItemView(ci, nil, prev) } } else { - chatItemView(chatItem, range, prevItem) + // Switch branches just to work around context menu problem when 'revealed' changes but size of item isn't + if revealed { + chatItemView(chatItem, range, prevItem) + } else { + chatItemView(chatItem, range, prevItem) + } } } } @@ -974,9 +979,8 @@ struct ChatView: View { title: NSLocalizedString("Hide", comment: "chat item action"), image: UIImage(systemName: "eye.slash") ) { _ in - withAnimation { - revealed = false - } + // With animation it looks bad because of UIKit context menu involved + revealed = false } } @@ -1045,9 +1049,8 @@ struct ChatView: View { title: NSLocalizedString("Reveal", comment: "chat item action"), image: UIImage(systemName: "eye") ) { _ in - withAnimation { - revealed = true - } + // With animation it looks bad because of UIKit context menu involved + revealed = true } } From a16e3eebd10dbaf2acce1bb39979cd295f620083 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Thu, 21 Mar 2024 13:13:18 +0400 Subject: [PATCH 05/10] ui: improve "allow PQ" button (#3932) * ios: improve "allow PQ" button * android --- apps/ios/Shared/Views/Chat/ChatInfoView.swift | 2 +- .../kotlin/chat/simplex/common/views/chat/ChatInfoView.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/ios/Shared/Views/Chat/ChatInfoView.swift b/apps/ios/Shared/Views/Chat/ChatInfoView.swift index 86532605db..8b60fc7649 100644 --- a/apps/ios/Shared/Views/Chat/ChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/ChatInfoView.swift @@ -579,7 +579,7 @@ struct ChatInfoView: View { let ct = try await apiSetContactPQ(contact.apiId, true) contact = ct await MainActor.run { - chatModel.updateContact(contact) + chatModel.updateContact(ct) dismiss() } } catch let error { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt index 9f526f3eb8..42257cf723 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ChatInfoView.kt @@ -145,7 +145,7 @@ fun ChatInfoView( withBGApi { val ct = chatModel.controller.apiSetContactPQ(chatRh, contact.contactId, true) if (ct != null) { - chatModel.updateContact(chatRh, contact) + chatModel.updateContact(chatRh, ct) } close.invoke() } From b220ea23e2a49793919a12e90d04a4972f59975a Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Thu, 21 Mar 2024 20:58:04 +0700 Subject: [PATCH 06/10] ios: stop chat after deleting the last profile (#3935) --- apps/ios/Shared/Views/UserSettings/UserProfilesView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift b/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift index f2cac59dae..af3d60c9c0 100644 --- a/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift +++ b/apps/ios/Shared/Views/UserSettings/UserProfilesView.swift @@ -276,6 +276,7 @@ struct UserProfilesView: View { // Deleting the last visible user while having hidden one(s) try await deleteUser() try await changeActiveUserAsync_(nil, viewPwd: nil) + try? await stopChatAsync() await MainActor.run { onboardingStageDefault.set(.step1_SimpleXInfo) m.onboardingStage = .step1_SimpleXInfo From c2adf40b5a99ed2990c6196b9d25fd6f995bdb56 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Thu, 21 Mar 2024 18:00:27 +0400 Subject: [PATCH 07/10] ui: align finalize migration destructive/default button colors (#3938) * ios: align finalize migration destructive/default button colors * android --- apps/ios/Shared/Views/Migration/MigrateFromDevice.swift | 2 +- .../chat/simplex/common/views/migration/MigrateFromDevice.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift b/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift index aa02ebb12a..645de4c3f8 100644 --- a/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift +++ b/apps/ios/Shared/Views/Migration/MigrateFromDevice.swift @@ -150,7 +150,7 @@ struct MigrateFromDevice: View { return Alert( title: Text(title), message: Text(text), - primaryButton: .destructive(Text("Delete")) { + primaryButton: .default(Text("Delete")) { deleteChatAndDismiss() }, secondaryButton: .cancel() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt index d51bb17e40..f8e3d48625 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/migration/MigrateFromDevice.kt @@ -386,7 +386,8 @@ private fun MutableState.FinishedView(chatDeletion: Boolean) confirmText = generalGetString(MR.strings.migrate_from_device_start_chat), onConfirm = { withLongRunningApi { startChatAndDismiss() } - } + }, + destructive = true ) } ) {} From 0706e6e4640602547ddf1f14ef2ba8dbca01d0c0 Mon Sep 17 00:00:00 2001 From: Stanislav Dmitrenko <7953703+avently@users.noreply.github.com> Date: Thu, 21 Mar 2024 21:02:38 +0700 Subject: [PATCH 08/10] android: stopping chat after deleting the last user (#3937) * android: stopping chat after deleting the last user * fix for hidden users + onboarding --- .../common/views/call/CallView.android.kt | 2 +- .../chat/simplex/common/model/SimpleXAPI.kt | 30 +++++++++---------- .../chat/simplex/common/platform/Files.kt | 4 +-- .../chat/simplex/common/views/WelcomeView.kt | 3 +- .../common/views/database/DatabaseView.kt | 2 +- .../views/onboarding/CreateSimpleXAddress.kt | 3 +- .../views/usersettings/UserProfilesView.kt | 1 + .../common/views/call/CallView.desktop.kt | 2 +- 8 files changed, 25 insertions(+), 22 deletions(-) diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt index f8f9fe14ed..8a958327d8 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/call/CallView.android.kt @@ -154,7 +154,7 @@ actual fun ActiveCallView() { setCallSound(call.soundSpeaker, audioViaBluetooth) } withBGApi { chatModel.controller.apiCallStatus(callRh, call.contact, callStatus) } - } catch (e: Error) { + } catch (e: Throwable) { Log.d(TAG,"call status ${r.state.connectionState} not used") } is WCallResponse.Connected -> { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 85ce8dc00b..0d6420dad2 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -75,7 +75,7 @@ class AppPreferences { val value = _callOnLockScreen.get() ?: return CallOnLockScreen.default return try { CallOnLockScreen.valueOf(value) - } catch (e: Error) { + } catch (e: Throwable) { CallOnLockScreen.default } }, @@ -95,7 +95,7 @@ class AppPreferences { val value = _simplexLinkMode.get() ?: return SimplexLinkMode.default return try { SimplexLinkMode.valueOf(value) - } catch (e: Error) { + } catch (e: Throwable) { SimplexLinkMode.default } }, @@ -123,7 +123,7 @@ class AppPreferences { val value = _networkSessionMode.get() ?: return TransportSessionMode.default return try { TransportSessionMode.valueOf(value) - } catch (e: Error) { + } catch (e: Throwable) { TransportSessionMode.default } }, @@ -393,7 +393,7 @@ object ChatController { } Log.d(TAG, "startChat: running") } - } catch (e: Error) { + } catch (e: Throwable) { Log.e(TAG, "failed starting chat $e") throw e } @@ -411,7 +411,7 @@ object ChatController { startReceiver() setLocalDeviceName(appPrefs.deviceNameForRemoteAccess.get()!!) Log.d(TAG, "startChat: started without user") - } catch (e: Error) { + } catch (e: Throwable) { Log.e(TAG, "failed starting chat without user $e") throw e } @@ -628,7 +628,7 @@ object ChatController { when (r) { is CR.ChatStarted -> return true is CR.ChatRunning -> return false - else -> throw Error("failed starting chat: ${r.responseType} ${r.details}") + else -> throw Exception("failed starting chat: ${r.responseType} ${r.details}") } } @@ -636,26 +636,26 @@ object ChatController { val r = sendCmd(null, CC.ApiStopChat()) when (r) { is CR.ChatStopped -> return true - else -> throw Error("failed stopping chat: ${r.responseType} ${r.details}") + else -> throw Exception("failed stopping chat: ${r.responseType} ${r.details}") } } suspend fun apiSetTempFolder(tempFolder: String, ctrl: ChatCtrl? = null) { val r = sendCmd(null, CC.SetTempFolder(tempFolder), ctrl) if (r is CR.CmdOk) return - throw Error("failed to set temp folder: ${r.responseType} ${r.details}") + throw Exception("failed to set temp folder: ${r.responseType} ${r.details}") } suspend fun apiSetFilesFolder(filesFolder: String, ctrl: ChatCtrl? = null) { val r = sendCmd(null, CC.SetFilesFolder(filesFolder), ctrl) if (r is CR.CmdOk) return - throw Error("failed to set files folder: ${r.responseType} ${r.details}") + throw Exception("failed to set files folder: ${r.responseType} ${r.details}") } suspend fun apiSetRemoteHostsFolder(remoteHostsFolder: String) { val r = sendCmd(null, CC.SetRemoteHostsFolder(remoteHostsFolder)) if (r is CR.CmdOk) return - throw Error("failed to set remote hosts folder: ${r.responseType} ${r.details}") + throw Exception("failed to set remote hosts folder: ${r.responseType} ${r.details}") } suspend fun apiSetEncryptLocalFiles(enable: Boolean) = sendCommandOkResp(null, CC.ApiSetEncryptLocalFiles(enable)) @@ -663,13 +663,13 @@ object ChatController { suspend fun apiSaveAppSettings(settings: AppSettings) { val r = sendCmd(null, CC.ApiSaveSettings(settings)) if (r is CR.CmdOk) return - throw Error("failed to set app settings: ${r.responseType} ${r.details}") + throw Exception("failed to set app settings: ${r.responseType} ${r.details}") } suspend fun apiGetAppSettings(settings: AppSettings): AppSettings { val r = sendCmd(null, CC.ApiGetSettings(settings)) if (r is CR.AppSettingsR) return r.appSettings - throw Error("failed to get app settings: ${r.responseType} ${r.details}") + throw Exception("failed to get app settings: ${r.responseType} ${r.details}") } suspend fun apiSetPQEncryption(enable: Boolean) = sendCommandOkResp(null, CC.ApiSetPQEncryption(enable)) @@ -684,19 +684,19 @@ object ChatController { suspend fun apiExportArchive(config: ArchiveConfig) { val r = sendCmd(null, CC.ApiExportArchive(config)) if (r is CR.CmdOk) return - throw Error("failed to export archive: ${r.responseType} ${r.details}") + throw Exception("failed to export archive: ${r.responseType} ${r.details}") } suspend fun apiImportArchive(config: ArchiveConfig): List { val r = sendCmd(null, CC.ApiImportArchive(config)) if (r is CR.ArchiveImported) return r.archiveErrors - throw Error("failed to import archive: ${r.responseType} ${r.details}") + throw Exception("failed to import archive: ${r.responseType} ${r.details}") } suspend fun apiDeleteStorage() { val r = sendCmd(null, CC.ApiDeleteStorage()) if (r is CR.CmdOk) return - throw Error("failed to delete storage: ${r.responseType} ${r.details}") + throw Exception("failed to delete storage: ${r.responseType} ${r.details}") } suspend fun apiStorageEncryption(currentKey: String = "", newKey: String = ""): CR.ChatCmdError? { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt index 7ae2ab23dd..f804f2079c 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/platform/Files.kt @@ -42,7 +42,7 @@ fun copyFileToFile(from: File, to: URI, finally: () -> Unit) { } } showToast(generalGetString(MR.strings.file_saved)) - } catch (e: Error) { + } catch (e: Throwable) { showToast(generalGetString(MR.strings.error_saving_file)) Log.e(TAG, "copyFileToFile error saving file $e") } finally { @@ -58,7 +58,7 @@ fun copyBytesToFile(bytes: ByteArrayInputStream, to: URI, finally: () -> Unit) { } } showToast(generalGetString(MR.strings.file_saved)) - } catch (e: Error) { + } catch (e: Throwable) { showToast(generalGetString(MR.strings.error_saving_file)) Log.e(TAG, "copyBytesToFile error saving file $e") } finally { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt index aa6b22fcde..41b30be640 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/WelcomeView.kt @@ -214,7 +214,8 @@ fun createProfileOnboarding(chatModel: ChatModel, displayName: String, close: () ) ?: return@withBGApi chatModel.localUserCreated.value = true val onboardingStage = chatModel.controller.appPrefs.onboardingStage - if (chatModel.users.isEmpty()) { + // No users or no visible users + if (chatModel.users.none { u -> !u.user.hidden }) { onboardingStage.set(if (appPlatform.isDesktop && chatModel.controller.appPrefs.initialRandomDBPassphrase.get() && !chatModel.desktopOnboardingRandomPassword.value) { OnboardingStage.Step2_5_SetupDatabasePassphrase } else { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt index 023d10c539..814ff9969a 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/database/DatabaseView.kt @@ -388,7 +388,7 @@ fun startChat(m: ChatModel, chatLastStart: MutableState, chatDbChanged m.controller.appPrefs.chatLastStart.set(ts) chatLastStart.value = ts platform.androidChatStartedAfterBeingOff() - } catch (e: Error) { + } catch (e: Throwable) { m.chatRunning.value = false AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_starting_chat), e.toString()) } finally { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/CreateSimpleXAddress.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/CreateSimpleXAddress.kt index e8ba5d7b60..5e50475951 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/CreateSimpleXAddress.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/CreateSimpleXAddress.kt @@ -169,7 +169,8 @@ private fun ProgressIndicator() { } private fun prepareChatBeforeAddressCreation(rhId: Long?) { - if (chatModel.users.isNotEmpty()) return + // No visible users but may have hidden. In this case chat should be started anyway because it's stopped on this stage with hidden users + if (chatModel.users.any { u -> !u.user.hidden }) return withBGApi { val user = chatModel.controller.apiGetActiveUser(rhId) ?: return@withBGApi chatModel.currentUser.value = user diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt index a7e57662b5..b40cc7db92 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/UserProfilesView.kt @@ -356,6 +356,7 @@ private suspend fun doRemoveUser(m: ChatModel, user: User, users: List, de m.controller.apiDeleteUser(user, delSMPQueues, viewPwd) m.controller.changeActiveUser_(user.remoteHostId, null, null) if (appPlatform.isAndroid) { + m.controller.apiStopChat() controller.appPrefs.onboardingStage.set(OnboardingStage.Step1_SimpleXInfo) ModalManager.closeAllModalsEverywhere() } diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/call/CallView.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/call/CallView.desktop.kt index f35b114740..87c2d3e8f2 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/call/CallView.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/call/CallView.desktop.kt @@ -75,7 +75,7 @@ actual fun ActiveCallView() { chatModel.activeCall.value = call.copy(callState = CallState.Connected, connectedAt = Clock.System.now()) } withBGApi { chatModel.controller.apiCallStatus(callRh, call.contact, callStatus) } - } catch (e: Error) { + } catch (e: Throwable) { Log.d(TAG, "call status ${r.state.connectionState} not used") } is WCallResponse.Connected -> { From 2546ad535118fbe67d7074ea3411db25cd954743 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Thu, 21 Mar 2024 17:37:56 +0000 Subject: [PATCH 09/10] Translated using Weblate (Czech) (#3941) Currently translated at 99.2% (252 of 254 strings) Translation: SimpleX Chat/SimpleX Chat website Translate-URL: https://hosted.weblate.org/projects/simplex-chat/website/cs/ Co-authored-by: zenobit --- website/langs/cs.json | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/website/langs/cs.json b/website/langs/cs.json index d087fd5bec..6e2416e4a2 100644 --- a/website/langs/cs.json +++ b/website/langs/cs.json @@ -37,10 +37,10 @@ "hero-overlay-1-title": "Jak funguje SimpleX?", "hero-overlay-2-title": "Proč jsou uživatelská ID špatná pro soukromí?", "feature-1-title": "E2E šifrované zprávy s Markdown a editací", - "feature-3-title": "Decentralizované tajné skupiny —
pouze uživatelé vědí, že existují", + "feature-3-title": "E2E-šifrované decentralizované skupiny — pouze uživatelé vědí, že existují", "feature-4-title": "Hlasové zprávy šifrované E2E", "feature-6-title": "E2E šifrované
hlasové a videohovory", - "feature-7-title": "Přenosná šifrovaná databáze— přeneste svůj profil do jiného zařízení", + "feature-7-title": "Přenosné šifrované ůložiště aplikace — přeneste profil do jiného zařízení", "feature-8-title": "režim Inkognito —
Unikátní pro SimpleX Chat", "simplex-network-overlay-1-title": "Srovnání s protokoly zpráv P2P", "simplex-private-2-title": "Další vrstva
šifrování serveru", @@ -170,8 +170,8 @@ "comparison-section-list-point-1": "Založeném obvykle na telefonním čísle a v některých případech uživatelském jménu", "comparison-section-list-point-2": "Adresy založené na DNS", "comparison-section-list-point-3": "Veřejný klíč nebo jiné globálně jedinečné ID", - "comparison-section-list-point-4": "Pokud jsou servery operátora ohroženy", - "comparison-section-list-point-5": "Nechrání metadata uživatelů", + "comparison-section-list-point-4": "Pokud jsou servery operátora kompromitovány. Ověřte bezpečnostní kód v Signálu a nějaké jiné aplikaci ke zmírnění", + "comparison-section-list-point-5": "Nechrání soukromí metadat uživatelů", "comparison-section-list-point-6": "Zatímco P2P jsou distribuovány, nejsou federované – fungují jako jediná síť", "comparison-section-list-point-7": "P2P sítě mají buď centrální autoritu, nebo může být ohrožena celá síť", "see-here": "viz zde", @@ -195,7 +195,7 @@ "simplex-explained-tab-3-p-2": "Uživatelé mohou dále zlepšit soukromí metadat pomocí Tor pro přístup k serverům, což zabraňuje korelaci podle IP adresy.", "hero-p-1": "Jiné aplikace mají uživatelská ID: Signal, Matrix, Session, Briar, Jami, Cwtch atd.
SimpleX ne, ani náhodná čísla.
To radikálně zlepšuje vaše soukromí.", "hero-2-header-desc": "Video ukazuje, jak se spojit se svým přítelem prostřednictvím jeho jednorázového QR kódu, osobně nebo prostřednictvím QR kódu ve videu. Můžete se také připojit sdílením pozvánky.", - "feature-2-title": "Obrázky a soubory šifrované E2E
", + "feature-2-title": "E2E šifrované
obrázky, videa a soubory", "feature-5-title": "Mizící tajné konverzace", "simplex-private-1-title": "2-vrstvé
end-to-end šifrování", "simplex-private-8-title": "Smíchání zpráv
ke snížení korelace", @@ -232,5 +232,25 @@ "on-this-page": "Na této stránce", "back-to-top": "Zpět nahoru", "newer-version-of-eng-msg": "V angličtině je novější verze této stránky.", - "glossary": "Rejstřík" + "glossary": "Rejstřík", + "hero-overlay-3-title": "Posouzení bezpečnosti", + "hero-overlay-3-textlink": "Posouzení bezpečnosti", + "hero-overlay-card-3-p-1": "Trail of Bits je přední bezpečnostní a technologické poradenství, jejichž klienti zahrnují velké technologické firmy, vládní agentury a významné blockchainové projekty.", + "f-droid-page-simplex-chat-repo-section-text": "Chcete-li jej přidat do vašeho F-Droid clienta, naskenujte QR kód nebo použijte tuto adresu URL:", + "f-droid-page-f-droid-org-repo-section-text": "SimpleX Chat a F-Droid.org repozitáře jsou podepsané různými klíči. Chcete-li přepnout, prosím exportujte chat databázi a přeinstalujte aplikaci.", + "comparison-section-list-point-4a": "SimpleX relé nemůže ohrozit šifrování e2e. Ověřte bezpečnostní kód, který zmírňuje mimo pásmový útok na kanál", + "docs-dropdown-8": "Služba SimpleX Directory", + "please-enable-javascript": "Prosím, povolte JavaScript k zobrazení QR kódu.", + "please-use-link-in-mobile-app": "Prosím použijte odkaz v mobilní aplikaci", + "simplex-chat-via-f-droid": "SimpleX Chat přes F-Droid", + "simplex-chat-repo": "SimpleX Chat repozitář", + "stable-and-beta-versions-built-by-developers": "Stabilní a beta verze vytvořené vývojáři", + "signing-key-fingerprint": "Otisk podpisového klíče (SHA-256)", + "f-droid-org-repo": "F-Droid.org repozitář", + "stable-versions-built-by-f-droid-org": "Stabilní verze vytvořené F-Droid.org", + "releases-to-this-repo-are-done-1-2-days-later": "Vydání v tomto repozitáři se provádí o 1-2 dny později", + "jobs": "Připojit k týmu", + "hero-overlay-card-3-p-2": "Trail of Bits přezkoumala kryptografii a síťové komponenty SimpleX platformy v listopadu 2022.", + "hero-overlay-card-3-p-3": "Přečtěte si více v ohlášení.", + "docs-dropdown-9": "Ke stažení" } From e0566599a45d005c6b517699963b953c23b3e7d7 Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Thu, 21 Mar 2024 19:00:19 +0000 Subject: [PATCH 10/10] core: 5.6.0.4 (#3939) --- cabal.project | 2 +- package.yaml | 2 +- scripts/nix/sha256map.nix | 2 +- simplex-chat.cabal | 2 +- tests/ChatClient.hs | 7 +++++-- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cabal.project b/cabal.project index 547ec861e0..be58b64283 100644 --- a/cabal.project +++ b/cabal.project @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd source-repository-package type: git location: https://github.com/simplex-chat/simplexmq.git - tag: 7b6b80cea21c7fbafffa118f1ed268411fcb79ca + tag: 8496884b42d76bd0d934e5ae481846d9c324d3c7 source-repository-package type: git diff --git a/package.yaml b/package.yaml index ed6bc96cb1..7d8af47401 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: simplex-chat -version: 5.6.0.3 +version: 5.6.0.4 #synopsis: #description: homepage: https://github.com/simplex-chat/simplex-chat#readme diff --git a/scripts/nix/sha256map.nix b/scripts/nix/sha256map.nix index b898978fcc..1fd783a1d3 100644 --- a/scripts/nix/sha256map.nix +++ b/scripts/nix/sha256map.nix @@ -1,5 +1,5 @@ { - "https://github.com/simplex-chat/simplexmq.git"."7b6b80cea21c7fbafffa118f1ed268411fcb79ca" = "0a665v4v1ilm2j9cxkiwqq2xlp2732h95mqaywf7qrlk03qkasfi"; + "https://github.com/simplex-chat/simplexmq.git"."8496884b42d76bd0d934e5ae481846d9c324d3c7" = "0c040s00zc1qg0ilsvpv54f01xz7flh8rsar2nplcs4a4gnp78qs"; "https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38"; "https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d"; "https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl"; diff --git a/simplex-chat.cabal b/simplex-chat.cabal index 8361d3f55d..9caa46da55 100644 --- a/simplex-chat.cabal +++ b/simplex-chat.cabal @@ -5,7 +5,7 @@ cabal-version: 1.12 -- see: https://github.com/sol/hpack name: simplex-chat -version: 5.6.0.3 +version: 5.6.0.4 category: Web, System, Services, Cryptography homepage: https://github.com/simplex-chat/simplex-chat#readme author: simplex.chat diff --git a/tests/ChatClient.hs b/tests/ChatClient.hs index 409dd2bb3e..8e9d11d91f 100644 --- a/tests/ChatClient.hs +++ b/tests/ChatClient.hs @@ -37,10 +37,11 @@ import Simplex.Chat.Types import Simplex.FileTransfer.Description (kb, mb) import Simplex.FileTransfer.Server (runXFTPServerBlocking) import Simplex.FileTransfer.Server.Env (XFTPServerConfig (..), defaultFileExpiration) +import Simplex.Messaging.Agent (disposeAgentClient) import Simplex.Messaging.Agent.Env.SQLite import Simplex.Messaging.Agent.Protocol (currentSMPAgentVersion, duplexHandshakeSMPAgentVersion, pqdrSMPAgentVersion, supportedSMPAgentVRange) import Simplex.Messaging.Agent.RetryInterval -import Simplex.Messaging.Agent.Store.SQLite (MigrationConfirmation (..)) +import Simplex.Messaging.Agent.Store.SQLite (MigrationConfirmation (..), closeSQLiteStore) import qualified Simplex.Messaging.Agent.Store.SQLite.DB as DB import Simplex.Messaging.Client (ProtocolClientConfig (..), defaultNetworkConfig) import Simplex.Messaging.Crypto.Ratchet (supportedE2EEncryptVRange, pattern PQSupportOff) @@ -250,10 +251,12 @@ startTestChat_ db cfg opts user = do pure TestCC {chatController = cc, virtualTerminal = t, chatAsync, termAsync, termQ, printOutput = False} stopTestChat :: TestCC -> IO () -stopTestChat TestCC {chatController = cc, chatAsync, termAsync} = do +stopTestChat TestCC {chatController = cc@ChatController {smpAgent, chatStore}, chatAsync, termAsync} = do stopChatController cc uninterruptibleCancel termAsync uninterruptibleCancel chatAsync + liftIO $ disposeAgentClient smpAgent + closeSQLiteStore chatStore threadDelay 200000 withNewTestChat :: HasCallStack => FilePath -> String -> Profile -> (HasCallStack => TestCC -> IO a) -> IO a