diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.android.kt index 9e96429b59..9a3d9e5e4f 100644 --- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.android.kt +++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.android.kt @@ -1,6 +1,5 @@ package chat.simplex.common.views.chatlist -import SectionDivider import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.material.Divider @@ -9,7 +8,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import chat.simplex.common.platform.onRightClick -import LocalInSectionCard import chat.simplex.common.views.helpers.* @Composable @@ -40,9 +38,5 @@ actual fun ChatListNavLinkLayout( DefaultDropdownMenu(showMenu, dropdownMenuItems = dropdownMenuItems) } } - if (LocalInSectionCard.current) { - SectionDivider() - } else { - Divider(Modifier.padding(horizontal = 8.dp)) - } + Divider(Modifier.padding(horizontal = 8.dp)) } 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 e360e6e3a7..47506d9532 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 @@ -126,7 +126,7 @@ fun AppearanceScope.AppearanceLayout( SectionDividerSpaced() ProfileImageSection() - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) SectionView(stringResource(MR.strings.settings_section_title_icon), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING_HALF)) { LazyRow { @@ -152,7 +152,7 @@ fun AppearanceScope.AppearanceLayout( } } - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) FontScaleSection() SectionBottomSpacer() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt index 4004184b2c..5601001b34 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/ui/theme/Theme.kt @@ -603,13 +603,6 @@ data class ThemeModeOverride ( // cards above. DARK/BLACK: palette bg (cards already raised via founder's // formula in Section.kt). SIMPLEX: gradient bottom stop (darker), since the // canvas itself is a gradient drawn by themedBackgroundBrush. -// -// Reads CurrentColors.value directly rather than via MaterialTheme/CompositionLocal -// because this helper is called from two scopes: @Composable bodies (SectionView, -// SectionDivider) and DrawScope (sectionItemDivider's drawWithContent). DrawScope -// can't call @Composable getters, so a snapshot read keeps one helper usable in -// both places. State invalidation still works — CurrentColors is a MutableStateFlow, -// reads are tracked by Compose snapshot system. fun canvasColorForCurrentTheme(): Color { val theme = CurrentColors.value val c = theme.colors 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 3b9907eacc..3e4b8ce1db 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 @@ -85,7 +85,7 @@ fun CreateProfile(chatModel: ChatModel, close: () -> Unit) { sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp) ) { Box( - modifier = Modifier.fillMaxSize().background(MaterialTheme.colors.surface) + modifier = Modifier.fillMaxSize() ) { ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.create_profile), bottomPadding = DEFAULT_PADDING_HALF) @@ -239,7 +239,6 @@ private fun CreateFirstProfileMobile(chatModel: ChatModel, close: () -> Unit) { val refocusTrigger = remember { mutableStateOf(0) } ModalView( close = { onboardingBackAction(chatModel, close) }, - background = MaterialTheme.colors.surface, endButtons = { MigrateButton(refocusTrigger) } ) { val displayName = rememberSaveable { mutableStateOf("") } @@ -318,7 +317,6 @@ private fun CreateFirstProfileDesktop(chatModel: ChatModel, close: () -> Unit) { CompositionLocalProvider(LocalAppBarHandler provides rememberAppBarHandler()) { ModalView( close = { onboardingBackAction(chatModel, close) }, - background = MaterialTheme.colors.surface, endButtons = { MigrateButton(refocusTrigger) } ) { ColumnWithScrollBar(horizontalAlignment = Alignment.CenterHorizontally) { 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 0bf4857c10..5c2b79fe0b 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 @@ -576,7 +576,7 @@ fun ChatInfoLayout( SectionSpacer() if (customUserProfile != null) { - SectionView(generalGetString(MR.strings.incognito)) { + SectionView(generalGetString(MR.strings.incognito), card = true) { SectionItemViewSpaceBetween { Text(generalGetString(MR.strings.incognito_random_profile)) Text(customUserProfile.chatViewName, color = Indigo) @@ -585,7 +585,7 @@ fun ChatInfoLayout( SectionDividerSpaced() } - SectionView { + SectionView(card = true) { if (contact.ready && contact.active) { if (connectionCode != null) { VerifyCodeButton(contact.verified, verifyClicked) @@ -610,35 +610,35 @@ fun ChatInfoLayout( } } } - SectionDividerSpaced() + SectionDividerSpaced(maxBottomPadding = false) - SectionView { + SectionView(card = true) { ChatTTLOption(chatItemTTL, setChatItemTTL, deletingItems) + SectionTextFooter(stringResource(MR.strings.chat_ttl_options_footer)) } - SectionTextFooter(stringResource(MR.strings.chat_ttl_options_footer)) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false) val conn = contact.activeConn if (conn != null) { - SectionView { + SectionView(card = true) { InfoRow("E2E encryption", if (conn.connPQEnabled) "Quantum resistant" else "Standard") + SectionDividerSpaced() } - SectionDividerSpaced() } if (contact.contactLink != null) { - SectionView(stringResource(MR.strings.address_section_title)) { + SectionView(stringResource(MR.strings.address_section_title), card = true) { SimpleXLinkQRCode(contact.contactLink) val clipboard = LocalClipboardManager.current ShareAddressButton { clipboard.shareText(simplexChatLink(contact.contactLink)) } + SectionTextFooter(stringResource(MR.strings.you_can_share_this_address_with_your_contacts).format(contact.displayName)) } - SectionTextFooter(stringResource(MR.strings.you_can_share_this_address_with_your_contacts).format(contact.displayName)) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) } - val chatSubStatus = chatModel.chatSubStatus.value - if (contact.ready && contact.active && (chatSubStatus != null || cStats != null)) { - SectionView(title = stringResource(MR.strings.conn_stats_section_title_servers)) { + if (contact.ready && contact.active) { + SectionView(title = stringResource(MR.strings.conn_stats_section_title_servers), card = true) { + val chatSubStatus = chatModel.chatSubStatus.value if (chatSubStatus != null) { SectionItemView({ AlertManager.shared.showAlertMsg( @@ -673,14 +673,14 @@ fun ChatInfoLayout( SectionDividerSpaced(maxBottomPadding = false) } - SectionView { + SectionView(card = true) { ClearChatButton(clearChat) DeleteContactButton(deleteContact) } if (developerTools) { SectionDividerSpaced() - SectionView(title = stringResource(MR.strings.section_title_for_console)) { + SectionView(title = stringResource(MR.strings.section_title_for_console), card = true) { InfoRow(stringResource(MR.strings.info_row_local_name), chat.chatInfo.localDisplayName) InfoRow(stringResource(MR.strings.info_row_database_id), chat.chatInfo.apiId.toString()) SectionItemView({ 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 d67a2730d8..9c36f4896b 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 @@ -4,6 +4,7 @@ import InfoRow import SectionBottomSpacer import SectionDividerSpaced import SectionItemView +import SectionView import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape @@ -248,7 +249,7 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools @Composable fun Details() { AppBarTitle(stringResource(if (ci.localNote) MR.strings.saved_message_title else if (sent) MR.strings.sent_message else MR.strings.received_message)) - Column { + SectionView { InfoRow(stringResource(if (!ci.localNote) MR.strings.info_row_sent_at else MR.strings.info_row_created_at), localTimestamp(ci.meta.itemTs)) if (!sent) { InfoRow(stringResource(MR.strings.info_row_received_at), localTimestamp(ci.meta.createdAt)) @@ -285,17 +286,17 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools fun HistoryTab() { ColumnWithScrollBar { Details() - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = true) val versions = ciInfo.itemVersions if (versions.isNotEmpty()) { - Column(Modifier.padding(horizontal = DEFAULT_PADDING)) { + SectionView(contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { Text(stringResource(MR.strings.edit_history), style = MaterialTheme.typography.h2, modifier = Modifier.padding(bottom = DEFAULT_PADDING)) versions.forEachIndexed { i, ciVersion -> ItemVersionView(ciVersion, current = i == 0) } } } else { - Column(Modifier.padding(horizontal = DEFAULT_PADDING)) { + SectionView(contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Text(stringResource(MR.strings.no_history), color = MaterialTheme.colors.secondary) } @@ -310,8 +311,8 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools fun QuoteTab(qi: CIQuote) { ColumnWithScrollBar { Details() - SectionDividerSpaced() - Column(Modifier.padding(horizontal = DEFAULT_PADDING)) { + SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = true) + SectionView(contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { Text(stringResource(MR.strings.in_reply_to), style = MaterialTheme.typography.h2, modifier = Modifier.padding(bottom = DEFAULT_PADDING)) QuotedMsgView(qi) } @@ -324,8 +325,8 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools fun ForwardedFromTab(forwardedFromItem: AChatItem) { ColumnWithScrollBar { Details() - SectionDividerSpaced() - Column { + SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = true) + SectionView { Text(stringResource(if (local) MR.strings.saved_from_chat_item_info_title else MR.strings.forwarded_from_chat_item_info_title), style = MaterialTheme.typography.h2, modifier = Modifier.padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, bottom = DEFAULT_PADDING)) @@ -387,17 +388,17 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools fun DeliveryTab(memberDeliveryStatuses: List) { ColumnWithScrollBar { Details() - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = true) val mss = membersStatuses(chatModel, memberDeliveryStatuses) if (mss.isNotEmpty()) { - Column(Modifier.padding(horizontal = DEFAULT_PADDING)) { + SectionView(contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { Text(stringResource(MR.strings.delivery), style = MaterialTheme.typography.h2, modifier = Modifier.padding(bottom = DEFAULT_PADDING)) mss.forEach { (member, status, sentViaProxy) -> MemberDeliveryStatusView(member, status, sentViaProxy) } } } else { - Column(Modifier.padding(horizontal = DEFAULT_PADDING)) { + SectionView(contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { Text(stringResource(MR.strings.no_info_on_delivery), color = MaterialTheme.colors.secondary) } @@ -441,7 +442,7 @@ fun ChatItemInfoView(chatRh: Long?, ci: ChatItem, ciInfo: ChatItemInfo, devTools return numTabs } - Column(Modifier.fillMaxSize().background(MaterialTheme.colors.surface)) { + Column { if (numTabs() > 1) { Box( Modifier 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 48f8359a5f..7c6658ed00 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 @@ -90,27 +90,27 @@ private fun ContactPreferencesLayout( TimedMessagesFeatureSection(featuresAllowed, contact.mergedPreferences.timedMessages, timedMessages, onTTLUpdated) { allowed, ttl -> applyPrefs(featuresAllowed.copy(timedMessagesAllowed = allowed, timedMessagesTTL = ttl ?: currentFeaturesAllowed.timedMessagesTTL)) } - SectionDividerSpaced() + SectionDividerSpaced(true) val allowFullDeletion: MutableState = remember(featuresAllowed) { mutableStateOf(featuresAllowed.fullDelete) } FeatureSection(ChatFeature.FullDelete, user.fullPreferences.fullDelete.allow, contact.mergedPreferences.fullDelete, allowFullDeletion) { applyPrefs(featuresAllowed.copy(fullDelete = it)) } - SectionDividerSpaced() + SectionDividerSpaced(true) val allowReactions: MutableState = remember(featuresAllowed) { mutableStateOf(featuresAllowed.reactions) } FeatureSection(ChatFeature.Reactions, user.fullPreferences.reactions.allow, contact.mergedPreferences.reactions, allowReactions) { applyPrefs(featuresAllowed.copy(reactions = it)) } - SectionDividerSpaced() + SectionDividerSpaced(true) val allowVoice: MutableState = remember(featuresAllowed) { mutableStateOf(featuresAllowed.voice) } FeatureSection(ChatFeature.Voice, user.fullPreferences.voice.allow, contact.mergedPreferences.voice, allowVoice) { applyPrefs(featuresAllowed.copy(voice = it)) } - SectionDividerSpaced() + SectionDividerSpaced(true) val allowCalls: MutableState = remember(featuresAllowed) { mutableStateOf(featuresAllowed.calls) } FeatureSection(ChatFeature.Calls, user.fullPreferences.calls.allow, contact.mergedPreferences.calls, allowCalls) { applyPrefs(featuresAllowed.copy(calls = it)) } - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false) ResetSaveButtons( reset = reset, save = savePrefs, @@ -139,6 +139,7 @@ private fun FeatureSection( icon = feature.iconFilled(), iconTint = if (enabled.forUser) SimplexGreen else if (enabled.forContact) WarningYellow else Color.Red, leadingIcon = true, + card = true, ) { ExposedDropDownSettingRow( generalGetString(MR.strings.chat_preferences_you_allow), @@ -174,6 +175,7 @@ private fun TimedMessagesFeatureSection( icon = ChatFeature.TimedMessages.iconFilled(), iconTint = if (enabled.forUser) SimplexGreen else if (enabled.forContact) WarningYellow else Color.Red, leadingIcon = true, + card = true, ) { PreferenceToggle( generalGetString(MR.strings.chat_preferences_you_allow), @@ -205,7 +207,7 @@ private fun TimedMessagesFeatureSection( @Composable private fun ResetSaveButtons(reset: () -> Unit, save: () -> Unit, disabled: Boolean) { - SectionView { + SectionView(card = true) { SectionItemView(reset, disabled = disabled) { Text(stringResource(MR.strings.reset_verb), color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary) } 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 b14b397728..b0ce2d2d24 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 @@ -175,7 +175,7 @@ fun AddGroupMembersLayout( ) } } else { - SectionView { + SectionView(card = true) { if (creatingGroup) { SectionItemView(openMemberAdmission) { Text(stringResource(MR.strings.set_member_admission)) @@ -195,8 +195,8 @@ fun AddGroupMembersLayout( SectionCustomFooter { InviteSectionFooter(selectedContactsCount = selectedContacts.size, allowModifyMembers, clearSelection) } - SectionDividerSpaced() - SectionView(stringResource(MR.strings.select_contacts)) { + SectionDividerSpaced(maxTopPadding = true) + SectionView(stringResource(MR.strings.select_contacts), card = true) { SectionItemView(padding = PaddingValues(start = DEFAULT_PADDING, end = DEFAULT_PADDING_HALF)) { SearchRowView(searchText) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/AddGroupRelayView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/AddGroupRelayView.kt index f26567e1e3..5fb2363713 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/AddGroupRelayView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/AddGroupRelayView.kt @@ -106,7 +106,7 @@ private fun AddGroupRelayLayout( CircularProgressIndicator() } } else if (availableRelays.isEmpty()) { - SectionView { + SectionView(card = true) { SectionItemView(padding = PaddingValues(horizontal = DEFAULT_PADDING)) { Text( generalGetString(MR.strings.no_available_relays), @@ -115,7 +115,7 @@ private fun AddGroupRelayLayout( } } } else { - SectionView { + SectionView(card = true) { AddRelaysButton( onClick = onAddRelays, disabled = selectedRelayIds.isEmpty() || isAdding @@ -131,8 +131,8 @@ private fun AddGroupRelayLayout( fontSize = 14.sp ) } - SectionDividerSpaced() - SectionView(generalGetString(MR.strings.select_relays)) { + SectionDividerSpaced(maxTopPadding = true) + SectionView(generalGetString(MR.strings.select_relays), card = true) { availableRelays.forEach { item -> val selected = item.relayId in selectedRelayIds SectionItemView( diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/ChannelMembersView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/ChannelMembersView.kt index bcf8048971..a761c3ce41 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/ChannelMembersView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/ChannelMembersView.kt @@ -44,7 +44,7 @@ fun ChannelMembersView( if (groupInfo.isOwner) { val subscriberCount = groupInfo.groupSummary.publicMemberCount ?: (members.size + 1).toLong() - SectionView(title = subscriberCountStr(subscriberCount)) { + SectionView(title = subscriberCountStr(subscriberCount), card = true) { SectionItemView(minHeight = 54.dp, padding = PaddingValues(horizontal = DEFAULT_PADDING)) { ChannelMemberRow(groupInfo.membership, user = true, showRole = true) } @@ -61,7 +61,7 @@ fun ChannelMembersView( } } else { val owners = members.filter { it.memberRole >= GroupMemberRole.Owner } - SectionView(title = generalGetString(MR.strings.channel_members_section_owners)) { + SectionView(title = generalGetString(MR.strings.channel_members_section_owners), card = true) { owners.forEachIndexed { index, member -> if (index > 0) { Divider() 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 87ecd7d31e..0910c5fd27 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 @@ -584,7 +584,7 @@ fun ModalData.GroupChatInfoLayout( SectionSpacer() if (groupInfo.useRelays && groupInfo.membership.memberIncognito) { - SectionView(generalGetString(MR.strings.incognito)) { + SectionView(generalGetString(MR.strings.incognito), card = true) { SectionItemViewSpaceBetween { Text(generalGetString(MR.strings.incognito_random_profile)) Text(groupInfo.membership.chatViewName, color = Indigo) @@ -600,7 +600,7 @@ fun ModalData.GroupChatInfoLayout( || groupInfo.membership.supportChat != null) if (groupInfo.useRelays) { - SectionView { + SectionView(card = true) { if (groupInfo.isOwner && groupLink != null) { anyTopSectionRowShow = true ChannelLinkButton(manageGroupLink) @@ -630,7 +630,7 @@ fun ModalData.GroupChatInfoLayout( SectionTextFooter(stringResource(MR.strings.you_can_share_channel_link_anybody_will_be_able_to_connect)) } } else { - SectionView { + SectionView(card = true) { if (groupInfo.canAddMembers && groupInfo.businessChat == null) { anyTopSectionRowShow = true if (groupLink == null) { @@ -658,9 +658,9 @@ fun ModalData.GroupChatInfoLayout( } } if (anyTopSectionRowShow) { - SectionDividerSpaced() + SectionDividerSpaced(maxBottomPadding = false) } - SectionView { + SectionView(card = true) { if (groupInfo.isOwner && groupInfo.businessChat?.chatType == null) { val editProfileTitleId = if (groupInfo.useRelays) MR.strings.button_edit_channel_profile else MR.strings.button_edit_group_profile EditGroupProfileButton(editProfileTitleId, editGroupProfile) @@ -677,9 +677,9 @@ fun ModalData.GroupChatInfoLayout( else if (groupInfo.businessChat == null) MR.strings.only_group_owners_can_change_prefs else MR.strings.only_chat_owners_can_change_prefs SectionTextFooter(stringResource(footerId)) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false) - SectionView { + SectionView(card = true) { if (!groupInfo.useRelays) { if (activeSortedMembers.filter { it.memberCurrent }.size <= SMALL_GROUPS_RCPS_MEM_LIMIT) { SendReceiptsOption(currentUser, sendReceipts, setSendReceipts) @@ -697,12 +697,12 @@ fun ModalData.GroupChatInfoLayout( } } ChatTTLOption(chatItemTTL, setChatItemTTL, deletingItems) + SectionTextFooter(stringResource(MR.strings.chat_ttl_options_footer)) } - SectionTextFooter(stringResource(MR.strings.chat_ttl_options_footer)) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = true) if (!groupInfo.nextConnectPrepared && !groupInfo.useRelays) { - SectionView(title = String.format(generalGetString(MR.strings.group_info_section_title_num_members), activeSortedMembers.count() + 1)) { + SectionView(title = String.format(generalGetString(MR.strings.group_info_section_title_num_members), activeSortedMembers.count() + 1), card = true) { if (groupInfo.canAddMembers) { val onAddMembersClick = if (chat.chatInfo.incognito) ::cantInviteIncognitoAlert else addMembers val tint = if (chat.chatInfo.incognito) MaterialTheme.colors.secondary else MaterialTheme.colors.primary @@ -718,18 +718,16 @@ fun ModalData.GroupChatInfoLayout( MemberListSearchRowView(searchText) } } + SectionItemView(minHeight = 54.dp, padding = PaddingValues(horizontal = DEFAULT_PADDING)) { + MemberRow(groupInfo.membership, user = true) + } } } } if (!groupInfo.nextConnectPrepared && !groupInfo.useRelays) { - item { - SectionItemView(minHeight = 54.dp, padding = PaddingValues(horizontal = DEFAULT_PADDING)) { - MemberRow(groupInfo.membership, user = true) - } - } items(filteredMembers.value, key = { it.groupMemberId }) { member -> Divider() - val showMenu = remember(member.groupMemberId) { mutableStateOf(false) } + val showMenu = remember { mutableStateOf(false) } val canBeSelected = groupInfo.membership.memberRole >= member.memberRole && member.memberRole < GroupMemberRole.Moderator SectionItemViewLongClickable( click = { @@ -760,9 +758,9 @@ fun ModalData.GroupChatInfoLayout( } item { if (!groupInfo.nextConnectPrepared && !groupInfo.useRelays) { - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false) } - SectionView { + SectionView(card = true) { if (groupInfo.useRelays && (groupInfo.isOwner || activeSortedMembers.any { it.memberRole == GroupMemberRole.Relay })) { ChannelRelaysButton(chat.remoteHostId, groupInfo, showMemberInfo) } @@ -788,7 +786,7 @@ fun ModalData.GroupChatInfoLayout( if (developerTools) { SectionDividerSpaced() - SectionView(title = stringResource(MR.strings.section_title_for_console)) { + SectionView(title = stringResource(MR.strings.section_title_for_console), card = true) { InfoRow(stringResource(MR.strings.info_row_local_name), groupInfo.localDisplayName) InfoRow(stringResource(MR.strings.info_row_database_id), groupInfo.apiId.toString()) } 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 686c6dcc75..673f72bb4e 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 @@ -3,7 +3,6 @@ package chat.simplex.common.views.chat.group import SectionBottomSpacer import SectionItemView import SectionViewWithButton -import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.runtime.* @@ -191,110 +190,108 @@ fun GroupLinkLayout( ) } - Box(Modifier.fillMaxSize().background(MaterialTheme.colors.surface)) { - ColumnWithScrollBar { - AppBarTitle(stringResource(if (isChannel) MR.strings.channel_link else MR.strings.group_link)) - Text( - stringResource(if (isChannel) MR.strings.you_can_share_channel_link_anybody_will_be_able_to_connect else MR.strings.you_can_share_group_link_anybody_will_be_able_to_connect), - Modifier.padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, bottom = 12.dp), - lineHeight = 22.sp - ) - Column( - Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.SpaceEvenly - ) { - if (groupLink == null) { - Row( - horizontalArrangement = Arrangement.spacedBy(10.dp), - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(horizontal = DEFAULT_PADDING, vertical = 10.dp) - ) { - SimpleButton(stringResource(MR.strings.button_create_group_link), icon = painterResource(MR.images.ic_add_link), disabled = creatingLink, click = createLink) - if (creatingGroup && close != null) { - ContinueButton(close) - } + ColumnWithScrollBar { + AppBarTitle(stringResource(if (isChannel) MR.strings.channel_link else MR.strings.group_link)) + Text( + stringResource(if (isChannel) MR.strings.you_can_share_channel_link_anybody_will_be_able_to_connect else MR.strings.you_can_share_group_link_anybody_will_be_able_to_connect), + Modifier.padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, bottom = 12.dp), + lineHeight = 22.sp + ) + Column( + Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceEvenly + ) { + if (groupLink == null) { + Row( + horizontalArrangement = Arrangement.spacedBy(10.dp), + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(horizontal = DEFAULT_PADDING, vertical = 10.dp) + ) { + SimpleButton(stringResource(MR.strings.button_create_group_link), icon = painterResource(MR.images.ic_add_link), disabled = creatingLink, click = createLink) + if (creatingGroup && close != null) { + ContinueButton(close) } - } else { - if (!isChannel) { - RoleSelectionRow(groupInfo, groupLinkMemberRole) + } + } else { + if (!isChannel) { + RoleSelectionRow(groupInfo, groupLinkMemberRole) + } + var initialLaunch by remember { mutableStateOf(true) } + LaunchedEffect(groupLinkMemberRole.value) { + if (!initialLaunch) { + updateLink() } - var initialLaunch by remember { mutableStateOf(true) } - LaunchedEffect(groupLinkMemberRole.value) { - if (!initialLaunch) { - updateLink() - } - initialLaunch = false - } - val showShortLink = remember { mutableStateOf(true) } - Spacer(Modifier.height(DEFAULT_PADDING_HALF)) - SectionViewWithButton( - titleButton = - if (!isChannel && groupLink.connLinkContact.connShortLink != null) { - { ToggleShortLinkButton(showShortLink) } - } else null) { - SimpleXCreatedLinkQRCode(groupLink.connLinkContact, short = showShortLink.value) - } - if (!isChannel && groupLink.shouldBeUpgraded) { - SettingsActionItem( - painterResource(MR.images.ic_add), - stringResource(MR.strings.upgrade_group_link), - click = { showAddShortLinkAlert(null) }, - iconColor = MaterialTheme.colors.primary, - textColor = MaterialTheme.colors.primary, - ) - } - val clipboard = LocalClipboardManager.current + initialLaunch = false + } + val showShortLink = remember { mutableStateOf(true) } + Spacer(Modifier.height(DEFAULT_PADDING_HALF)) + SectionViewWithButton( + titleButton = + if (!isChannel && groupLink.connLinkContact.connShortLink != null) { + { ToggleShortLinkButton(showShortLink) } + } else null) { + SimpleXCreatedLinkQRCode(groupLink.connLinkContact, short = showShortLink.value) + } + if (!isChannel && groupLink.shouldBeUpgraded) { SettingsActionItem( - painterResource(MR.images.ic_share), - stringResource(MR.strings.share_link), - click = { - if (!isChannel && groupLink.shouldBeUpgraded) { - showAddShortLinkAlert { - clipboard.shareText(groupLink.connLinkContact.simplexChatUri(short = showShortLink.value)) - } - } else { + painterResource(MR.images.ic_add), + stringResource(MR.strings.upgrade_group_link), + click = { showAddShortLinkAlert(null) }, + iconColor = MaterialTheme.colors.primary, + textColor = MaterialTheme.colors.primary, + ) + } + val clipboard = LocalClipboardManager.current + SettingsActionItem( + painterResource(MR.images.ic_share), + stringResource(MR.strings.share_link), + click = { + if (!isChannel && groupLink.shouldBeUpgraded) { + showAddShortLinkAlert { clipboard.shareText(groupLink.connLinkContact.simplexChatUri(short = showShortLink.value)) } + } else { + clipboard.shareText(groupLink.connLinkContact.simplexChatUri(short = showShortLink.value)) + } + }, + iconColor = MaterialTheme.colors.primary, + textColor = MaterialTheme.colors.primary, + ) + if (shareGroupInfo != null && isChannel) { + SettingsActionItem( + painterResource(MR.images.ic_forward), + stringResource(MR.strings.share_via_chat), + click = { + chatModel.sharedContent.value = SharedContent.ChatLink(shareGroupInfo) + chatModel.chatId.value = null + ModalManager.closeAllModalsEverywhere() }, iconColor = MaterialTheme.colors.primary, textColor = MaterialTheme.colors.primary, ) - if (shareGroupInfo != null && isChannel) { - SettingsActionItem( - painterResource(MR.images.ic_forward), - stringResource(MR.strings.share_via_chat), - click = { - chatModel.sharedContent.value = SharedContent.ChatLink(shareGroupInfo) - chatModel.chatId.value = null - ModalManager.closeAllModalsEverywhere() - }, - iconColor = MaterialTheme.colors.primary, - textColor = MaterialTheme.colors.primary, - ) - } - if (!creatingGroup && !isChannel) { - SettingsActionItem( - painterResource(MR.images.ic_delete), - stringResource(MR.strings.delete_link), - click = deleteLink, - iconColor = Color.Red, - textColor = Color.Red, - ) - } - if (creatingGroup && close != null) { - SettingsActionItem( - painterResource(MR.images.ic_check), - stringResource(MR.strings.continue_to_next_step), - click = close, - iconColor = MaterialTheme.colors.primary, - textColor = MaterialTheme.colors.primary, - ) - } + } + if (!creatingGroup && !isChannel) { + SettingsActionItem( + painterResource(MR.images.ic_delete), + stringResource(MR.strings.delete_link), + click = deleteLink, + iconColor = Color.Red, + textColor = Color.Red, + ) + } + if (creatingGroup && close != null) { + SettingsActionItem( + painterResource(MR.images.ic_check), + stringResource(MR.strings.continue_to_next_step), + click = close, + iconColor = MaterialTheme.colors.primary, + textColor = MaterialTheme.colors.primary, + ) } } - SectionBottomSpacer() } + SectionBottomSpacer() } } 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 53d626fb95..7f98949f21 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 @@ -424,7 +424,7 @@ fun GroupMemberInfoLayout( val canRemove = member.canBeRemoved(groupInfo) && member.memberRole != GroupMemberRole.Relay if (canBlockForAll || canRemove) { SectionDividerSpaced(maxBottomPadding = false) - SectionView { + SectionView(card = true) { if (canBlockForAll) { if (member.blockedByAdmin) { UnblockForAllButton(unblockForAll) @@ -446,7 +446,7 @@ fun GroupMemberInfoLayout( @Composable fun NonAdminBlockSection() { SectionDividerSpaced(maxBottomPadding = false) - SectionView { + SectionView(card = true) { if (member.blockedByAdmin) { SettingsActionItem( painterResource(MR.images.ic_back_hand), @@ -543,7 +543,7 @@ fun GroupMemberInfoLayout( || member.supportChat != null) if (member.memberActive) { - SectionView { + SectionView(card = true) { if (showMemberSupportChat) { SupportChatButton() } @@ -559,14 +559,14 @@ fun GroupMemberInfoLayout( } SectionDividerSpaced() } else if (groupInfo.useRelays && member.memberCurrent && showMemberSupportChat) { - SectionView { + SectionView(card = true) { SupportChatButton() } SectionDividerSpaced() } if (member.contactLink != null) { - SectionView(stringResource(MR.strings.address_section_title)) { + SectionView(stringResource(MR.strings.address_section_title), card = true) { SimpleXLinkQRCode(member.contactLink) val clipboard = LocalClipboardManager.current ShareAddressButton { clipboard.shareText(simplexChatLink(member.contactLink)) } @@ -577,8 +577,8 @@ fun GroupMemberInfoLayout( } else { ConnectViaAddressButton(onClick = { connectViaAddress(member.contactLink) }) } + SectionTextFooter(stringResource(MR.strings.you_can_share_this_address_with_your_contacts).format(member.displayName)) } - SectionTextFooter(stringResource(MR.strings.you_can_share_this_address_with_your_contacts).format(member.displayName)) SectionDividerSpaced() } @@ -591,7 +591,7 @@ fun GroupMemberInfoLayout( } else { stringResource(MR.strings.member_info_section_title_member) } - SectionView(title = memberSectionTitle) { + SectionView(title = memberSectionTitle, card = true) { val titleId = if (groupInfo.useRelays) MR.strings.info_row_channel else if (groupInfo.businessChat == null) MR.strings.info_row_group else MR.strings.info_row_chat @@ -628,7 +628,7 @@ fun GroupMemberInfoLayout( } if (cStats != null) { SectionDividerSpaced() - SectionView(title = stringResource(MR.strings.conn_stats_section_title_servers)) { + SectionView(title = stringResource(MR.strings.conn_stats_section_title_servers), card = true) { val subStatus = cStats.subStatus if (subStatus != null) { SectionItemView({ @@ -664,7 +664,7 @@ fun GroupMemberInfoLayout( val connFailedErr = member.activeConn?.connFailedErr if (connFailedErr != null) { SectionDividerSpaced() - SectionView(title = stringResource(MR.strings.info_row_connection_failed), icon = painterResource(MR.images.ic_warning), iconTint = Color.Red, leadingIcon = true) { + SectionView(title = stringResource(MR.strings.info_row_connection_failed), icon = painterResource(MR.images.ic_warning), iconTint = Color.Red, leadingIcon = true, card = true) { SectionItemView { Text( connFailedErr, @@ -682,7 +682,7 @@ fun GroupMemberInfoLayout( if (developerTools) { SectionDividerSpaced() - SectionView(title = stringResource(MR.strings.section_title_for_console)) { + SectionView(title = stringResource(MR.strings.section_title_for_console), card = true) { InfoRow(stringResource(MR.strings.info_row_local_name), member.localDisplayName) InfoRow(stringResource(MR.strings.info_row_database_id), member.groupMemberId.toString()) val conn = member.activeConn 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 cb17e46f0a..4e3e46065b 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 @@ -186,33 +186,33 @@ private fun GroupPreferencesLayout( SectionDividerSpaced(maxBottomPadding = false) } TimedMessagesPreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) DirectMessagesPreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) FullDeletePreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) ReactionsPreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) VoicePreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) FilesPreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) SimplexLinksPreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) ReportsPreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) HistoryPreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) SupportPreference(disabled = true) } else { TimedMessagesPreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) FullDeletePreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) ReactionsPreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) HistoryPreference() - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) SupportPreference(notice = generalGetString(MR.strings.chat_with_admins_relay_note), onEnable = { revert -> AlertManager.shared.showAlertDialog( title = generalGetString(MR.strings.enable_chats_with_admins_question), @@ -225,7 +225,7 @@ private fun GroupPreferencesLayout( }) } if (groupInfo.isOwner) { - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false) val saveTextId = if (groupInfo.useRelays) MR.strings.save_and_notify_channel_subscribers else MR.strings.save_and_notify_group_members ResetSaveButtons( @@ -260,7 +260,7 @@ private fun FeatureSection( notice: String? = null, onSelected: (GroupFeatureEnabled, GroupMemberRole?) -> Unit ) { - SectionView { + SectionView(card = true) { val on = enableFeature.value == GroupFeatureEnabled.ON val icon = if (on) feature.iconFilled() else feature.icon val iconTint = if (on) SimplexGreen else MaterialTheme.colors.secondary @@ -325,7 +325,7 @@ private fun FeatureSection( @Composable private fun ResetSaveButtons(reset: () -> Unit, save: () -> Unit, disabled: Boolean, saveTextId: StringResource) { - SectionView { + SectionView(card = true) { SectionItemView(reset, disabled = disabled) { Text(stringResource(MR.strings.reset_verb), color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary) } 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 8c4e4a5339..6e91ad92d6 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 @@ -100,7 +100,7 @@ fun GroupProfileLayout( sheetState = bottomSheetModalState, sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp) ) { - ModalView(close = closeWithAlert, background = MaterialTheme.colors.surface) { + ModalView(close = closeWithAlert) { ColumnWithScrollBar { Column( Modifier.fillMaxWidth() diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/MemberAdmission.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/MemberAdmission.kt index d89280e62f..0338cb9985 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/MemberAdmission.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/group/MemberAdmission.kt @@ -85,7 +85,7 @@ private fun MemberAdmissionLayout( } } if (groupInfo.isOwner) { - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false) ResetSaveButtons( reset = reset, save = saveAdmission, @@ -109,7 +109,7 @@ private fun AdmissionSection( groupInfo: GroupInfo, onSelected: (MemberCriteria?) -> Unit ) { - SectionView { + SectionView(card = true) { if (groupInfo.isOwner) { ExposedDropDownSettingRow( generalGetString(admissionStageStrId), @@ -131,7 +131,7 @@ private fun AdmissionSection( @Composable private fun ResetSaveButtons(reset: () -> Unit, save: () -> Unit, disabled: Boolean) { - SectionView { + SectionView(card = true) { SectionItemView(reset, disabled = disabled) { Text(stringResource(MR.strings.reset_verb), color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary) } 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 7851f72297..927e9940b5 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 @@ -4,6 +4,7 @@ import SectionBottomSpacer import SectionDividerSpaced import SectionItemView import SectionTextFooter +import SectionView import TextIconSpaced import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.selection.SelectionContainer @@ -64,7 +65,6 @@ fun GroupWelcomeView(m: ChatModel, rhId: Long?, groupInfo: GroupInfo, close: () else -> showUnsavedChangesAlert({ save(close) }, close) } }, - background = MaterialTheme.colors.surface, ) { GroupWelcomeLayout( welcomeText, @@ -160,8 +160,10 @@ private fun TextPreview(text: String, linkMode: SimplexLinkMode, markdown: Boole @Composable private fun SaveButton(save: () -> Unit, disabled: Boolean) { - SectionItemView(save, disabled = disabled) { - Text(stringResource(MR.strings.save_and_update_group_profile), color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary) + SectionView { + SectionItemView(save, disabled = disabled) { + Text(stringResource(MR.strings.save_and_update_group_profile), color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary) + } } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt index fa787cd764..80914d83a3 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/ServersSummaryView.kt @@ -1,6 +1,5 @@ package chat.simplex.common.views.chatlist -import CARD_ITEM_PADDING import InfoRow import InfoRowTwoValues import SectionBottomSpacer @@ -30,7 +29,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import chat.simplex.common.model.AgentSMPServerStatsData @@ -153,7 +151,7 @@ enum class PresentedServerType { @Composable private fun ServerSessionsView(sess: ServerSessions) { - SectionView(generalGetString(MR.strings.servers_info_transport_sessions_section_header)) { + SectionView(generalGetString(MR.strings.servers_info_transport_sessions_section_header), card = true) { InfoRow( generalGetString(MR.strings.servers_info_sessions_connected), numOrDash(sess.ssConnected) @@ -220,7 +218,7 @@ private fun SMPServersListView(servers: List, statsStartedAt: val sortedServers = servers.sortedWith(compareBy { !it.hasSubs } .thenBy { serverAddress(it.smpServer) }) - SectionView(header) { + SectionView(header, card = true) { sortedServers.map { svr -> SMPServerView(srvSumm = svr, statsStartedAt = statsStartedAt, rh = rh) } } if (footer != null) { @@ -288,14 +286,14 @@ private fun XFTPServerInProgressIcon(srvSumm: XFTPServerSummary) { private fun XFTPServersListView(servers: List, statsStartedAt: Instant, header: String? = null, rh: RemoteHostInfo?) { val sortedServers = servers.sortedBy { serverAddress(it.xftpServer) } - SectionView(header) { + SectionView(header, card = true) { sortedServers.map { svr -> XFTPServerView(svr, statsStartedAt, rh) } } } @Composable private fun SMPStatsView(stats: AgentSMPServerStatsData, statsStartedAt: Instant, remoteHostInfo: RemoteHostInfo?) { - SectionView(generalGetString(MR.strings.servers_info_statistics_section_header)) { + SectionView(generalGetString(MR.strings.servers_info_statistics_section_header), card = true) { InfoRow( generalGetString(MR.strings.servers_info_messages_sent), numOrDash(stats._sentDirect + stats._sentViaProxy) @@ -326,20 +324,19 @@ private fun SMPStatsView(stats: AgentSMPServerStatsData, statsStartedAt: Instant private fun SMPSubscriptionsSection(totals: SMPTotals) { Column { Row( - Modifier.padding(start = DEFAULT_PADDING + DEFAULT_PADDING_HALF, bottom = 8.dp), + Modifier.padding(start = DEFAULT_PADDING, bottom = 5.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(DEFAULT_SPACE_AFTER_ICON * 2) ) { Text( - generalGetString(MR.strings.servers_info_subscriptions_section_header), + generalGetString(MR.strings.servers_info_subscriptions_section_header).uppercase(), color = MaterialTheme.colors.secondary, style = MaterialTheme.typography.body2, - fontSize = 14.sp, - fontWeight = FontWeight.Medium + fontSize = 12.sp ) SubscriptionStatusIndicatorView(totals.subs, totals.sessions.hasSess) } - SectionView { + Column(Modifier.padding(PaddingValues()).fillMaxWidth()) { InfoRow( generalGetString(MR.strings.servers_info_subscriptions_connections_subscribed), numOrDash(totals.subs.ssActive) @@ -357,20 +354,19 @@ private fun SMPSubscriptionsSection(totals: SMPTotals) { private fun SMPSubscriptionsSection(subs: SMPServerSubs, summary: SMPServerSummary, rh: RemoteHostInfo?) { Column { Row( - Modifier.padding(start = DEFAULT_PADDING + DEFAULT_PADDING_HALF, bottom = 8.dp), + Modifier.padding(start = DEFAULT_PADDING, bottom = 5.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(DEFAULT_SPACE_AFTER_ICON * 2) ) { Text( - generalGetString(MR.strings.servers_info_subscriptions_section_header), + generalGetString(MR.strings.servers_info_subscriptions_section_header).uppercase(), color = MaterialTheme.colors.secondary, style = MaterialTheme.typography.body2, - fontSize = 14.sp, - fontWeight = FontWeight.Medium + fontSize = 12.sp ) SubscriptionStatusIndicatorView(subs, summary.sessionsOrNew.hasSess) } - SectionView { + Column(Modifier.padding(PaddingValues()).fillMaxWidth()) { InfoRow( generalGetString(MR.strings.servers_info_subscriptions_connections_subscribed), numOrDash(subs.ssActive) @@ -419,7 +415,7 @@ private fun reconnectServerAlert(rh: RemoteHostInfo?, server: String) { @Composable fun XFTPStatsView(stats: AgentXFTPServerStatsData, statsStartedAt: Instant, rh: RemoteHostInfo?) { - SectionView(generalGetString(MR.strings.servers_info_statistics_section_header)) { + SectionView(generalGetString(MR.strings.servers_info_statistics_section_header), card = true) { InfoRow( generalGetString(MR.strings.servers_info_uploaded), prettySize(stats._uploadsSize) @@ -448,12 +444,12 @@ fun XFTPStatsView(stats: AgentXFTPServerStatsData, statsStartedAt: Instant, rh: @Composable private fun IndentedInfoRow(title: String, desc: String) { - InfoRow(title, desc, padding = PaddingValues(start = 24.dp + CARD_ITEM_PADDING, end = CARD_ITEM_PADDING)) + InfoRow(title, desc, padding = PaddingValues(start = 24.dp + DEFAULT_PADDING, end = DEFAULT_PADDING)) } @Composable fun DetailedSMPStatsLayout(stats: AgentSMPServerStatsData, statsStartedAt: Instant) { - SectionView(generalGetString(MR.strings.servers_info_detailed_statistics_sent_messages_header)) { + SectionView(generalGetString(MR.strings.servers_info_detailed_statistics_sent_messages_header), card = true) { InfoRow(generalGetString(MR.strings.servers_info_detailed_statistics_sent_messages_total), numOrDash(stats._sentDirect + stats._sentViaProxy)) InfoRowTwoValues(generalGetString(MR.strings.sent_directly), generalGetString(MR.strings.attempts_label), stats._sentDirect, stats._sentDirectAttempts) InfoRowTwoValues(generalGetString(MR.strings.sent_via_proxy), generalGetString(MR.strings.attempts_label), stats._sentViaProxy, stats._sentViaProxyAttempts) @@ -469,7 +465,7 @@ fun DetailedSMPStatsLayout(stats: AgentSMPServerStatsData, statsStartedAt: Insta SectionDividerSpaced() - SectionView(generalGetString(MR.strings.servers_info_detailed_statistics_received_messages_header)) { + SectionView(generalGetString(MR.strings.servers_info_detailed_statistics_received_messages_header), card = true) { InfoRow(generalGetString(MR.strings.servers_info_detailed_statistics_received_total), numOrDash(stats._recvMsgs)) SectionItemView { Text(generalGetString(MR.strings.servers_info_detailed_statistics_receive_errors), color = MaterialTheme.colors.onBackground) @@ -487,7 +483,7 @@ fun DetailedSMPStatsLayout(stats: AgentSMPServerStatsData, statsStartedAt: Insta SectionDividerSpaced() - SectionView(generalGetString(MR.strings.connections)) { + SectionView(generalGetString(MR.strings.connections), card = true) { InfoRow(generalGetString(MR.strings.created), numOrDash(stats._connCreated)) InfoRow(generalGetString(MR.strings.secured), numOrDash(stats._connSecured)) InfoRow(generalGetString(MR.strings.completed), numOrDash(stats._connCompleted)) @@ -506,7 +502,7 @@ fun DetailedSMPStatsLayout(stats: AgentSMPServerStatsData, statsStartedAt: Insta @Composable fun DetailedXFTPStatsLayout(stats: AgentXFTPServerStatsData, statsStartedAt: Instant) { - SectionView(generalGetString(MR.strings.uploaded_files)) { + SectionView(generalGetString(MR.strings.uploaded_files), card = true) { InfoRow(generalGetString(MR.strings.size), prettySize(stats._uploadsSize)) InfoRowTwoValues(generalGetString(MR.strings.chunks_uploaded), generalGetString(MR.strings.attempts_label), stats._uploads, stats._uploadAttempts) InfoRow(generalGetString(MR.strings.upload_errors), numOrDash(stats._uploadErrs)) @@ -514,7 +510,7 @@ fun DetailedXFTPStatsLayout(stats: AgentXFTPServerStatsData, statsStartedAt: Ins InfoRow(generalGetString(MR.strings.deletion_errors), numOrDash(stats._deleteErrs)) } SectionDividerSpaced() - SectionView(generalGetString(MR.strings.downloaded_files)) { + SectionView(generalGetString(MR.strings.downloaded_files), card = true) { InfoRow(generalGetString(MR.strings.size), prettySize(stats._downloadsSize)) InfoRowTwoValues(generalGetString(MR.strings.chunks_downloaded), generalGetString(MR.strings.attempts_label), stats._downloads, stats._downloadAttempts) SectionItemView { @@ -532,27 +528,31 @@ fun DetailedXFTPStatsLayout(stats: AgentXFTPServerStatsData, statsStartedAt: Ins @Composable fun XFTPServerSummaryLayout(summary: XFTPServerSummary, statsStartedAt: Instant, rh: RemoteHostInfo?) { - SectionView(generalGetString(MR.strings.server_address)) { + SectionView(generalGetString(MR.strings.server_address), card = true) { SelectionContainer { Text( summary.xftpServer, - Modifier.padding(start = CARD_ITEM_PADDING, top = 5.dp, end = CARD_ITEM_PADDING, bottom = 10.dp), + Modifier.padding(start = DEFAULT_PADDING, top = 5.dp, end = DEFAULT_PADDING, bottom = 10.dp), style = TextStyle( fontFamily = FontFamily.Monospace, fontSize = 16.sp, color = MaterialTheme.colors.secondary ) ) } - } + if (summary.stats != null || summary.sessions != null) { + SectionDividerSpaced() + } - if (summary.stats != null) { - SectionDividerSpaced() - XFTPStatsView(stats = summary.stats, rh = rh, statsStartedAt = statsStartedAt) - } + if (summary.stats != null) { + XFTPStatsView(stats = summary.stats, rh = rh, statsStartedAt = statsStartedAt) + if (summary.sessions != null) { + SectionDividerSpaced(maxTopPadding = true) + } + } - if (summary.sessions != null) { - SectionDividerSpaced() - ServerSessionsView(summary.sessions) + if (summary.sessions != null) { + ServerSessionsView(summary.sessions) + } } SectionBottomSpacer() @@ -560,32 +560,38 @@ fun XFTPServerSummaryLayout(summary: XFTPServerSummary, statsStartedAt: Instant, @Composable fun SMPServerSummaryLayout(summary: SMPServerSummary, statsStartedAt: Instant, rh: RemoteHostInfo?) { - SectionView(generalGetString(MR.strings.server_address)) { + SectionView(generalGetString(MR.strings.server_address), card = true) { SelectionContainer { Text( summary.smpServer, - Modifier.padding(start = CARD_ITEM_PADDING, top = 5.dp, end = CARD_ITEM_PADDING, bottom = 10.dp), + Modifier.padding(start = DEFAULT_PADDING, top = 5.dp, end = DEFAULT_PADDING, bottom = 10.dp), style = TextStyle( fontFamily = FontFamily.Monospace, fontSize = 16.sp, color = MaterialTheme.colors.secondary ) ) } - } + if (summary.stats != null || summary.subs != null || summary.sessions != null) { + SectionDividerSpaced() + } - if (summary.stats != null) { - SectionDividerSpaced() - SMPStatsView(stats = summary.stats, remoteHostInfo = rh, statsStartedAt = statsStartedAt) - } + if (summary.stats != null) { + SMPStatsView(stats = summary.stats, remoteHostInfo = rh, statsStartedAt = statsStartedAt) + if (summary.subs != null || summary.sessions != null) { + SectionDividerSpaced(maxTopPadding = true) + } + } - if (summary.subs != null) { - SectionDividerSpaced() - SMPSubscriptionsSection(subs = summary.subs, summary = summary, rh = rh) - } + if (summary.subs != null) { + SMPSubscriptionsSection(subs = summary.subs, summary = summary, rh = rh) + if (summary.sessions != null) { + SectionDividerSpaced() + } + } - if (summary.sessions != null) { - SectionDividerSpaced() - ServerSessionsView(summary.sessions) + if (summary.sessions != null) { + ServerSessionsView(summary.sessions) + } } SectionBottomSpacer() @@ -809,18 +815,16 @@ fun ModalData.ServersSummaryView(rh: RemoteHostInfo?, serversSummary: MutableSta ) { Spacer(Modifier.height(DEFAULT_PADDING)) if (showUserSelection) { - SectionView { - ExposedDropDownSettingRow( - generalGetString(MR.strings.servers_info_target), - userOptions, - selectedUserCategory, - icon = null, - enabled = remember { mutableStateOf(true) }, - onSelected = { - selectedUserCategory.value = it - } - ) - } + ExposedDropDownSettingRow( + generalGetString(MR.strings.servers_info_target), + userOptions, + selectedUserCategory, + icon = null, + enabled = remember { mutableStateOf(true) }, + onSelected = { + selectedUserCategory.value = it + } + ) SectionDividerSpaced() } when (index) { @@ -835,7 +839,7 @@ fun ModalData.ServersSummaryView(rh: RemoteHostInfo?, serversSummary: MutableSta val statsStartedAt = it.statsStartedAt SMPStatsView(totals.stats, statsStartedAt, rh) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) SMPSubscriptionsSection(totals) SectionDividerSpaced() @@ -843,7 +847,7 @@ fun ModalData.ServersSummaryView(rh: RemoteHostInfo?, serversSummary: MutableSta SMPServersListView( servers = currentlyUsedSMPServers, statsStartedAt = statsStartedAt, - header = generalGetString(MR.strings.servers_info_connected_servers_section_header), + header = generalGetString(MR.strings.servers_info_connected_servers_section_header).uppercase(), rh = rh ) SectionDividerSpaced() @@ -853,7 +857,7 @@ fun ModalData.ServersSummaryView(rh: RemoteHostInfo?, serversSummary: MutableSta SMPServersListView( servers = previouslyUsedSMPServers, statsStartedAt = statsStartedAt, - header = generalGetString(MR.strings.servers_info_previously_connected_servers_section_header), + header = generalGetString(MR.strings.servers_info_previously_connected_servers_section_header).uppercase(), rh = rh ) SectionDividerSpaced() @@ -863,11 +867,11 @@ fun ModalData.ServersSummaryView(rh: RemoteHostInfo?, serversSummary: MutableSta SMPServersListView( servers = proxySMPServers, statsStartedAt = statsStartedAt, - header = generalGetString(MR.strings.servers_info_proxied_servers_section_header), + header = generalGetString(MR.strings.servers_info_proxied_servers_section_header).uppercase(), footer = generalGetString(MR.strings.servers_info_proxied_servers_section_footer), rh = rh ) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) } ServerSessionsView(totals.sessions) @@ -884,13 +888,13 @@ fun ModalData.ServersSummaryView(rh: RemoteHostInfo?, serversSummary: MutableSta val previouslyUsedXFTPServers = xftpSummary.previouslyUsedXFTPServers XFTPStatsView(totals.stats, statsStartedAt, rh) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) if (currentlyUsedXFTPServers.isNotEmpty()) { XFTPServersListView( currentlyUsedXFTPServers, statsStartedAt, - generalGetString(MR.strings.servers_info_connected_servers_section_header), + generalGetString(MR.strings.servers_info_connected_servers_section_header).uppercase(), rh ) SectionDividerSpaced() @@ -900,7 +904,7 @@ fun ModalData.ServersSummaryView(rh: RemoteHostInfo?, serversSummary: MutableSta XFTPServersListView( previouslyUsedXFTPServers, statsStartedAt, - generalGetString(MR.strings.servers_info_previously_connected_servers_section_header), + generalGetString(MR.strings.servers_info_previously_connected_servers_section_header).uppercase(), rh ) SectionDividerSpaced() @@ -913,7 +917,7 @@ fun ModalData.ServersSummaryView(rh: RemoteHostInfo?, serversSummary: MutableSta SectionDividerSpaced(maxBottomPadding = false) - SectionView { + SectionView(card = true) { ReconnectAllServersButton(rh) ResetStatisticsButton(rh, resetStats = { resetStats() }) } 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 4997936dc5..96af5337d0 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,6 +1,5 @@ package chat.simplex.common.views.chatlist -import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.items import androidx.compose.material.* @@ -26,7 +25,7 @@ import chat.simplex.res.MR fun ShareListView(chatModel: ChatModel, stopped: Boolean) { var searchInList by rememberSaveable { mutableStateOf("") } val oneHandUI = remember { appPrefs.oneHandUI.state } - Box(Modifier.fillMaxSize().background(MaterialTheme.colors.surface)) { + Box(Modifier.fillMaxSize().themedBackground(bgLayerSize = LocalAppBarHandler.current?.backgroundGraphicsLayerSize, bgLayer = LocalAppBarHandler.current?.backgroundGraphicsLayer)) { val sharedContent = chatModel.sharedContent.value var isMediaOrFileAttachment = false var isVoice = false diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/TagListView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/TagListView.kt index 6d2f7e255e..fe61859937 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/TagListView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chatlist/TagListView.kt @@ -1,7 +1,6 @@ package chat.simplex.common.views.chatlist import SectionCustomFooter -import SectionDivider import SectionItemView import TextIconSpaced import androidx.compose.animation.core.animateDpAsState @@ -72,101 +71,99 @@ fun TagListView(rhId: Long?, chat: Chat? = null, close: () -> Unit, reorderMode: } val topPaddingToContent = topPaddingToContent(false) - Box(Modifier.fillMaxSize().background(MaterialTheme.colors.surface)) { - LazyColumnWithScrollBar( - modifier = if (reorderMode) Modifier.dragContainer(dragDropState) else Modifier, - state = listState, - contentPadding = PaddingValues( - top = if (oneHandUI.value) WindowInsets.statusBars.asPaddingValues().calculateTopPadding() else topPaddingToContent, - bottom = if (oneHandUI.value) WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + AppBarHeight * fontSizeSqrtMultiplier else 0.dp - ), - verticalArrangement = if (oneHandUI.value) Arrangement.Bottom else Arrangement.Top, - ) { - @Composable fun CreateList() { - SectionItemView({ - ModalManager.start.showModalCloseable { close -> - TagListEditor(rhId = rhId, close = close, chat = chat) - } - }) { - Icon(painterResource(MR.images.ic_add), stringResource(MR.strings.create_list), tint = MaterialTheme.colors.primary) - Spacer(Modifier.padding(horizontal = 4.dp)) - Text(stringResource(MR.strings.create_list), color = MaterialTheme.colors.primary) + LazyColumnWithScrollBar( + modifier = if (reorderMode) Modifier.dragContainer(dragDropState) else Modifier, + state = listState, + contentPadding = PaddingValues( + top = if (oneHandUI.value) WindowInsets.statusBars.asPaddingValues().calculateTopPadding() else topPaddingToContent, + bottom = if (oneHandUI.value) WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + AppBarHeight * fontSizeSqrtMultiplier else 0.dp + ), + verticalArrangement = if (oneHandUI.value) Arrangement.Bottom else Arrangement.Top, + ) { + @Composable fun CreateList() { + SectionItemView({ + ModalManager.start.showModalCloseable { close -> + TagListEditor(rhId = rhId, close = close, chat = chat) } + }) { + Icon(painterResource(MR.images.ic_add), stringResource(MR.strings.create_list), tint = MaterialTheme.colors.primary) + Spacer(Modifier.padding(horizontal = 4.dp)) + Text(stringResource(MR.strings.create_list), color = MaterialTheme.colors.primary) } + } - if (oneHandUI.value && !reorderMode) { - item { - CreateList() - } + if (oneHandUI.value && !reorderMode) { + item { + CreateList() } - itemsIndexed(userTags.value, key = { _, item -> item.chatTagId }) { index, tag -> - DraggableItem(dragDropState, index) { isDragging -> - val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp) + } + itemsIndexed(userTags.value, key = { _, item -> item.chatTagId }) { index, tag -> + DraggableItem(dragDropState, index) { isDragging -> + val elevation by animateDpAsState(if (isDragging) 4.dp else 0.dp) - Card( - elevation = elevation, - backgroundColor = if (isDragging) colors.surface else Color.Unspecified - ) { - Column { - val selected = chatTagIds.value.contains(tag.chatTagId) + Card( + elevation = elevation, + backgroundColor = if (isDragging) colors.surface else Color.Unspecified + ) { + Column { + val selected = chatTagIds.value.contains(tag.chatTagId) - Row( - Modifier - .fillMaxWidth() - .sizeIn(minHeight = DEFAULT_MIN_SECTION_ITEM_HEIGHT) - .clickable( - enabled = !saving.value && !reorderMode, - onClick = { - if (chat == null) { - ModalManager.start.showModalCloseable { close -> - TagListEditor( - rhId = rhId, - tagId = tag.chatTagId, - close = close, - emoji = tag.chatTagEmoji, - name = tag.chatTagText, - ) - } - } else { - saving.value = true - setTag(rhId = rhId, tagId = if (selected) null else tag.chatTagId, chat = chat, close = { - saving.value = false - close() - }) + Row( + Modifier + .fillMaxWidth() + .sizeIn(minHeight = DEFAULT_MIN_SECTION_ITEM_HEIGHT) + .clickable( + enabled = !saving.value && !reorderMode, + onClick = { + if (chat == null) { + ModalManager.start.showModalCloseable { close -> + TagListEditor( + rhId = rhId, + tagId = tag.chatTagId, + close = close, + emoji = tag.chatTagEmoji, + name = tag.chatTagText, + ) } - }, - ) - .padding(PaddingValues(horizontal = DEFAULT_PADDING, vertical = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL)), - verticalAlignment = Alignment.CenterVertically - ) { - if (tag.chatTagEmoji != null) { - ReactionIcon(tag.chatTagEmoji, fontSize = 14.sp) - } else { - Icon(painterResource(MR.images.ic_label), null, Modifier.size(18.sp.toDp()), tint = MaterialTheme.colors.onBackground) - } - Spacer(Modifier.padding(horizontal = 4.dp)) - Text( - tag.chatTagText, - color = MenuTextColor, - fontWeight = if (selected) FontWeight.Medium else FontWeight.Normal + } else { + saving.value = true + setTag(rhId = rhId, tagId = if (selected) null else tag.chatTagId, chat = chat, close = { + saving.value = false + close() + }) + } + }, ) - if (selected) { - Spacer(Modifier.weight(1f)) - Icon(painterResource(MR.images.ic_done_filled), null, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) - } else if (reorderMode) { - Spacer(Modifier.weight(1f)) - Icon(painterResource(MR.images.ic_drag_handle), null, Modifier.size(20.dp), tint = MaterialTheme.colors.secondary) - } + .padding(PaddingValues(horizontal = DEFAULT_PADDING, vertical = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL)), + verticalAlignment = Alignment.CenterVertically + ) { + if (tag.chatTagEmoji != null) { + ReactionIcon(tag.chatTagEmoji, fontSize = 14.sp) + } else { + Icon(painterResource(MR.images.ic_label), null, Modifier.size(18.sp.toDp()), tint = MaterialTheme.colors.onBackground) + } + Spacer(Modifier.padding(horizontal = 4.dp)) + Text( + tag.chatTagText, + color = MenuTextColor, + fontWeight = if (selected) FontWeight.Medium else FontWeight.Normal + ) + if (selected) { + Spacer(Modifier.weight(1f)) + Icon(painterResource(MR.images.ic_done_filled), null, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground) + } else if (reorderMode) { + Spacer(Modifier.weight(1f)) + Icon(painterResource(MR.images.ic_drag_handle), null, Modifier.size(20.dp), tint = MaterialTheme.colors.secondary) } - SectionDivider() } + Divider(Modifier.padding(horizontal = 8.dp)) } } } - if (!oneHandUI.value && !reorderMode) { - item { - CreateList() - } + } + if (!oneHandUI.value && !reorderMode) { + item { + CreateList() } } } 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 b656b8b8da..2d67ec58b6 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 @@ -119,7 +119,7 @@ fun DatabaseEncryptionLayout( ChatStoppedView() SectionSpacer() } - SectionView(if (migration) generalGetString(MR.strings.database_passphrase) else null) { + SectionView(if (migration) generalGetString(MR.strings.database_passphrase) else null, card = true) { SavePassphraseSetting( useKeychain.value, initialRandomDBPassphrase.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 e3d661c9df..0f6dc7e7e8 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 @@ -170,7 +170,7 @@ fun DatabaseLayout( AppBarTitle(stringResource(MR.strings.your_chat_database)) if (!chatModel.desktopNoUserNoRemote) { - SectionView(stringResource(MR.strings.messages_section_title)) { + SectionView(stringResource(MR.strings.messages_section_title), card = true) { TtlOptions(chatItemTTL, enabled = rememberUpdatedState(!stopped && !progressIndicator), onChatItemTTLSelected) } SectionTextFooter( @@ -184,14 +184,14 @@ fun DatabaseLayout( } } ) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) } val toggleEnabled = remember { chatModel.remoteHosts }.none { it.sessionState is RemoteHostSessionState.Connected } if (chatModel.localUserCreated.value == true) { // still show the toggle in case database was stopped when the user opened this screen because it can be in the following situations: // - database was stopped after migration and the app relaunched // - something wrong happened with database operations and the database couldn't be launched when it should - SectionView(stringResource(MR.strings.run_chat_section)) { + SectionView(stringResource(MR.strings.run_chat_section), card = true) { if (!toggleEnabled) { SectionItemView(disconnectAllHosts) { Text(generalGetString(MR.strings.disconnect_remote_hosts), Modifier.fillMaxWidth(), color = WarningOrange) @@ -200,10 +200,10 @@ fun DatabaseLayout( RunChatSetting(stopped, toggleEnabled && !progressIndicator, startChat, stopChatAlert) } if (stopped) SectionTextFooter(stringResource(MR.strings.you_must_use_the_most_recent_version_of_database)) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) } - SectionView(stringResource(MR.strings.chat_database_section)) { + SectionView(stringResource(MR.strings.chat_database_section), card = true) { if (chatModel.localUserCreated.value != true && !toggleEnabled) { SectionItemView(disconnectAllHosts) { Text(generalGetString(MR.strings.disconnect_remote_hosts), Modifier.fillMaxWidth(), color = WarningOrange) @@ -262,7 +262,7 @@ fun DatabaseLayout( } SectionDividerSpaced() - SectionView(stringResource(MR.strings.files_and_media_section)) { + SectionView(stringResource(MR.strings.files_and_media_section), card = true) { val deleteFilesDisabled = operationsDisabled || appFilesCountAndSize.value.first == 0 SectionItemView( deleteAppFilesAndMedia, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatInfoImage.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatInfoImage.kt index e33a59243d..5f3a73e7ea 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatInfoImage.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ChatInfoImage.kt @@ -25,14 +25,7 @@ import dev.icerock.moko.resources.ImageResource import kotlin.math.max @Composable -private fun defaultProfileIconColor(): Color = - if (CurrentColors.value.base == DefaultTheme.LIGHT) - MaterialTheme.colors.background.mixWith(MaterialTheme.colors.onBackground, 0.91f) - else - MaterialTheme.colors.secondaryVariant - -@Composable -fun ChatInfoImage(chatInfo: ChatInfo, size: Dp, iconColor: Color = defaultProfileIconColor(), shadow: Boolean = false) { +fun ChatInfoImage(chatInfo: ChatInfo, size: Dp, iconColor: Color = MaterialTheme.colors.secondaryVariant, shadow: Boolean = false) { val icon = when (chatInfo) { is ChatInfo.Group -> chatInfo.groupInfo.chatIconName @@ -59,7 +52,7 @@ fun ProfileImage( size: Dp, image: String? = null, icon: ImageResource = MR.images.ic_account_circle_filled, - color: Color = defaultProfileIconColor(), + color: Color = MaterialTheme.colors.secondaryVariant, backgroundColor: Color? = null, blurred: Boolean = false, async: Boolean = false 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 5c2369c8c4..6791b91b45 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 @@ -6,8 +6,9 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.layout.Layout import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.platform.LocalDensity @@ -30,41 +31,71 @@ val CARD_PADDING = 16.dp val ICON_TEXT_SPACING = 5.dp val CARD_ITEM_PADDING = CARD_PADDING - 1.dp -// Set to true by SectionView around its inner Column. SectionItemView reads it -// to decide whether to draw the 2dp bottom divider. False default keeps -// standalone usage (alerts, pickers, custom contexts) unaffected. -internal val LocalInSectionCard = staticCompositionLocalOf { false } - - @Composable -private fun Modifier.sectionItemDivider(): Modifier { - if (!LocalInSectionCard.current) return this - return this.drawWithContent { - drawContent() - drawLine(canvasColorForCurrentTheme(), Offset(0f, size.height), Offset(size.width, size.height), strokeWidth = 2.dp.toPx()) +private fun CardColumnLayout( + contentPadding: PaddingValues = PaddingValues(), + content: @Composable () -> Unit +) { + val dividerColor = canvasColorForCurrentTheme() + val dividerPx = with(LocalDensity.current) { 2.dp.toPx() } + val childBottoms = remember { mutableListOf() } + Layout( + content = content, + modifier = Modifier + .padding(horizontal = CARD_PADDING) + .fillMaxWidth() + .clip(SectionCardShape) + .background(sectionCardColor()) + .padding(contentPadding) + .drawBehind { + for (i in 0 until childBottoms.size - 1) { + val y = childBottoms[i] + drawLine(dividerColor, Offset(0f, y), Offset(size.width, y), strokeWidth = dividerPx) + } + } + ) { measurables, constraints -> + val placeables = measurables.map { it.measure(constraints) } + childBottoms.clear() + var y = 0f + placeables.forEach { p -> + y += p.height + childBottoms.add(y) + } + layout(constraints.maxWidth, y.toInt()) { + var yPos = 0 + placeables.forEach { p -> + p.placeRelative(0, yPos) + yPos += p.height + } + } } } @Composable -fun SectionView(title: String? = null, contentPadding: PaddingValues = PaddingValues(), headerBottomPadding: Dp = 8.dp, content: (@Composable ColumnScope.() -> Unit)) { - val cardColor = sectionCardColor() +private fun CardColumn( + card: Boolean, + contentPadding: PaddingValues = PaddingValues(), + content: @Composable () -> Unit +) { + if (card) { + CardColumnLayout(contentPadding, content) + } else { + Column(Modifier.padding(contentPadding).fillMaxWidth()) { content() } + } +} + +@Composable +fun SectionView(title: String? = null, contentPadding: PaddingValues = PaddingValues(), headerBottomPadding: Dp = DEFAULT_PADDING, card: Boolean = false, content: (@Composable ColumnScope.() -> Unit)) { Column { if (title != null) { Text( title, color = MaterialTheme.colors.secondary, style = MaterialTheme.typography.body2, - modifier = Modifier.padding(start = DEFAULT_PADDING + DEFAULT_PADDING_HALF, bottom = headerBottomPadding), fontSize = 14.sp, fontWeight = FontWeight.Medium + modifier = Modifier.padding(start = if (card) DEFAULT_PADDING + DEFAULT_PADDING_HALF else DEFAULT_PADDING, bottom = if (card) 8.dp else headerBottomPadding), + fontSize = if (card) 14.sp else 12.sp, + fontWeight = if (card) FontWeight.Medium else FontWeight.Normal ) } - CompositionLocalProvider(LocalInSectionCard provides true) { - Column( - Modifier - .padding(horizontal = CARD_PADDING) - .fillMaxWidth() - .clip(SectionCardShape) - .background(cardColor) - .padding(contentPadding) - ) { content() } - } + CardColumn(card, contentPadding) { content() } } } @@ -75,37 +106,28 @@ fun SectionView( iconTint: Color = MaterialTheme.colors.secondary, leadingIcon: Boolean = false, padding: PaddingValues = PaddingValues(), + card: Boolean = false, content: (@Composable ColumnScope.() -> Unit) ) { - val cardColor = sectionCardColor() Column { val iconSize = with(LocalDensity.current) { 21.sp.toDp() } - Row(Modifier.padding(start = DEFAULT_PADDING + DEFAULT_PADDING_HALF, bottom = 5.dp), verticalAlignment = Alignment.CenterVertically) { + Row(Modifier.padding(start = if (card) DEFAULT_PADDING + DEFAULT_PADDING_HALF else DEFAULT_PADDING, bottom = 5.dp), verticalAlignment = Alignment.CenterVertically) { if (leadingIcon) Icon(icon, null, Modifier.padding(end = DEFAULT_PADDING_HALF).size(iconSize), tint = iconTint) - Text(title, color = MaterialTheme.colors.secondary, style = MaterialTheme.typography.body2, fontSize = 14.sp, fontWeight = FontWeight.Medium) + Text(title, color = MaterialTheme.colors.secondary, style = MaterialTheme.typography.body2, fontSize = if (card) 14.sp else 12.sp, fontWeight = if (card) FontWeight.Medium else FontWeight.Normal) if (!leadingIcon) Icon(icon, null, Modifier.padding(start = DEFAULT_PADDING_HALF).size(iconSize), tint = iconTint) } - CompositionLocalProvider(LocalInSectionCard provides true) { - Column( - Modifier - .padding(horizontal = CARD_PADDING) - .fillMaxWidth() - .clip(SectionCardShape) - .background(cardColor) - .padding(padding) - ) { content() } - } + CardColumn(card, padding) { content() } } } @Composable -fun SectionViewWithButton(title: String? = null, titleButton: (@Composable () -> Unit)?, contentPadding: PaddingValues = PaddingValues(), headerBottomPadding: Dp = 8.dp, content: (@Composable ColumnScope.() -> Unit)) { - val cardColor = sectionCardColor() +fun SectionViewWithButton(title: String? = null, titleButton: (@Composable () -> Unit)?, contentPadding: PaddingValues = PaddingValues(), headerBottomPadding: Dp = DEFAULT_PADDING, card: Boolean = false, content: (@Composable ColumnScope.() -> Unit)) { Column { if (title != null || titleButton != null) { - Row(modifier = Modifier.padding(start = DEFAULT_PADDING + DEFAULT_PADDING_HALF, end = DEFAULT_PADDING + DEFAULT_PADDING_HALF, bottom = headerBottomPadding).fillMaxWidth()) { + val hPadding = if (card) DEFAULT_PADDING + DEFAULT_PADDING_HALF else DEFAULT_PADDING + Row(modifier = Modifier.padding(start = hPadding, end = hPadding, bottom = if (card) 8.dp else headerBottomPadding).fillMaxWidth()) { if (title != null) { - Text(title, color = MaterialTheme.colors.secondary, style = MaterialTheme.typography.body2, fontSize = 14.sp, fontWeight = FontWeight.Medium) + Text(title, color = MaterialTheme.colors.secondary, style = MaterialTheme.typography.body2, fontSize = if (card) 14.sp else 12.sp, fontWeight = if (card) FontWeight.Medium else FontWeight.Normal) } if (titleButton != null) { Spacer(modifier = Modifier.weight(1f)) @@ -113,16 +135,7 @@ fun SectionViewWithButton(title: String? = null, titleButton: (@Composable () -> } } } - CompositionLocalProvider(LocalInSectionCard provides true) { - Column( - Modifier - .padding(horizontal = CARD_PADDING) - .fillMaxWidth() - .clip(SectionCardShape) - .background(cardColor) - .padding(contentPadding) - ) { content() } - } + CardColumn(card, contentPadding) { content() } } } @@ -172,19 +185,18 @@ fun SectionViewSelectableCards( @Composable fun SectionItemView( click: (() -> Unit)? = null, - minHeight: Dp = DEFAULT_MIN_SECTION_ITEM_HEIGHT + 8.dp, + minHeight: Dp = DEFAULT_MIN_SECTION_ITEM_HEIGHT, disabled: Boolean = false, extraPadding: Boolean = false, padding: PaddingValues = if (extraPadding) - PaddingValues(start = DEFAULT_PADDING * 1.7f, end = CARD_ITEM_PADDING, top = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL, bottom = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL) + PaddingValues(start = DEFAULT_PADDING * 1.7f, end = DEFAULT_PADDING, top = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL, bottom = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL) else - PaddingValues(horizontal = CARD_ITEM_PADDING, vertical = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL), + PaddingValues(horizontal = DEFAULT_PADDING, vertical = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL), content: (@Composable RowScope.() -> Unit) ) { val modifier = Modifier .fillMaxWidth() .sizeIn(minHeight = minHeight) - .sectionItemDivider() Row( if (click == null || disabled) modifier.padding(padding) else modifier.clickable(onClick = click).padding(padding), verticalAlignment = Alignment.CenterVertically @@ -196,13 +208,13 @@ fun SectionItemView( @Composable fun SectionItemViewWithoutMinPadding( click: (() -> Unit)? = null, - minHeight: Dp = DEFAULT_MIN_SECTION_ITEM_HEIGHT + 8.dp, + minHeight: Dp = DEFAULT_MIN_SECTION_ITEM_HEIGHT, disabled: Boolean = false, extraPadding: Boolean = false, padding: PaddingValues = if (extraPadding) - PaddingValues(start = DEFAULT_PADDING * 1.7f, end = CARD_ITEM_PADDING) + PaddingValues(start = DEFAULT_PADDING * 1.7f, end = DEFAULT_PADDING) else - PaddingValues(horizontal = CARD_ITEM_PADDING), + PaddingValues(horizontal = DEFAULT_PADDING), content: (@Composable RowScope.() -> Unit) ) { SectionItemView(click, minHeight, disabled, extraPadding, padding, content) @@ -212,19 +224,18 @@ fun SectionItemViewWithoutMinPadding( fun SectionItemViewLongClickable( click: () -> Unit, longClick: () -> Unit, - minHeight: Dp = DEFAULT_MIN_SECTION_ITEM_HEIGHT + 8.dp, + minHeight: Dp = DEFAULT_MIN_SECTION_ITEM_HEIGHT, disabled: Boolean = false, extraPadding: Boolean = false, padding: PaddingValues = if (extraPadding) - PaddingValues(start = DEFAULT_PADDING * 1.7f, end = CARD_ITEM_PADDING, top = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL, bottom = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL) + PaddingValues(start = DEFAULT_PADDING * 1.7f, end = DEFAULT_PADDING, top = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL, bottom = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL) else - PaddingValues(horizontal = CARD_ITEM_PADDING, vertical = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL), + PaddingValues(horizontal = DEFAULT_PADDING, vertical = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL), content: (@Composable RowScope.() -> Unit) ) { val modifier = Modifier .fillMaxWidth() .sizeIn(minHeight = minHeight) - .sectionItemDivider() Row( if (disabled) { modifier.padding(padding) @@ -241,15 +252,14 @@ fun SectionItemViewLongClickable( fun SectionItemViewSpaceBetween( click: (() -> Unit)? = null, onLongClick: (() -> Unit)? = null, - minHeight: Dp = DEFAULT_MIN_SECTION_ITEM_HEIGHT + 8.dp, - padding: PaddingValues = PaddingValues(horizontal = CARD_ITEM_PADDING), + minHeight: Dp = DEFAULT_MIN_SECTION_ITEM_HEIGHT, + padding: PaddingValues = PaddingValues(horizontal = DEFAULT_PADDING), disabled: Boolean = false, content: (@Composable RowScope.() -> Unit) ) { val modifier = Modifier .fillMaxWidth() .sizeIn(minHeight = minHeight) - .sectionItemDivider() Row( if (click == null || disabled) modifier.padding(padding).padding(vertical = DEFAULT_MIN_SECTION_ITEM_PADDING_VERTICAL) else modifier .combinedClickable(onClick = click, onLongClick = onLongClick).padding(padding) @@ -297,7 +307,7 @@ fun SectionTextFooter(text: String, color: Color = MaterialTheme.colors.secondar fun SectionTextFooter(text: AnnotatedString, textAlign: TextAlign = TextAlign.Start, color: Color = MaterialTheme.colors.secondary) { Text( text, - Modifier.padding(start = DEFAULT_PADDING + DEFAULT_PADDING_HALF, end = DEFAULT_PADDING + DEFAULT_PADDING_HALF, top = DEFAULT_PADDING_HALF).fillMaxWidth(0.9F), + Modifier.padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, top = DEFAULT_PADDING_HALF).fillMaxWidth(0.9F), color = color, lineHeight = 18.sp, fontSize = 14.sp, @@ -306,7 +316,7 @@ fun SectionTextFooter(text: AnnotatedString, textAlign: TextAlign = TextAlign.St } @Composable -fun SectionCustomFooter(padding: PaddingValues = PaddingValues(start = DEFAULT_PADDING + DEFAULT_PADDING_HALF, end = DEFAULT_PADDING + DEFAULT_PADDING_HALF, top = 5.dp), content: (@Composable () -> Unit)) { +fun SectionCustomFooter(padding: PaddingValues = PaddingValues(start = DEFAULT_PADDING, end = DEFAULT_PADDING, top = 5.dp), content: (@Composable () -> Unit)) { Row( Modifier.padding(padding) ) { @@ -314,20 +324,15 @@ fun SectionCustomFooter(padding: PaddingValues = PaddingValues(start = DEFAULT_P } } -// Explicit 2dp canvas-color divider for inserting between non-SectionItemView -// composables inside a SectionView card (e.g., between a custom block and a -// SectionItemView). Auto-divider on SectionItemView handles the row-to-row -// case; this one covers manual placement around mixed content. No-op outside -// a SectionView card. -@Composable -fun SectionDivider() { - if (!LocalInSectionCard.current) return - Box(Modifier.fillMaxWidth().height(2.dp).background(canvasColorForCurrentTheme())) -} - @Composable fun SectionDividerSpaced(maxTopPadding: Boolean = false, maxBottomPadding: Boolean = true) { - Spacer(Modifier.height(if (maxTopPadding || maxBottomPadding) DEFAULT_PADDING else DEFAULT_PADDING_HALF)) + Divider( + Modifier.padding( + start = DEFAULT_PADDING_HALF, + top = if (maxTopPadding) DEFAULT_PADDING + 18.dp else DEFAULT_PADDING + 2.dp, + end = DEFAULT_PADDING_HALF, + bottom = if (maxBottomPadding) DEFAULT_PADDING + 18.dp else DEFAULT_PADDING + 2.dp) + ) } @Composable @@ -342,11 +347,11 @@ fun SectionBottomSpacer() { @Composable fun TextIconSpaced(extraPadding: Boolean = false) { - Spacer(Modifier.padding(horizontal = if (extraPadding) 17.dp else ICON_TEXT_SPACING)) + Spacer(Modifier.padding(horizontal = if (extraPadding) 17.dp else DEFAULT_PADDING_HALF)) } @Composable -fun InfoRow(title: String, value: String, icon: Painter? = null, iconTint: Color? = null, textColor: Color = MaterialTheme.colors.onBackground, padding: PaddingValues = PaddingValues(horizontal = CARD_ITEM_PADDING)) { +fun InfoRow(title: String, value: String, icon: Painter? = null, iconTint: Color? = null, textColor: Color = MaterialTheme.colors.onBackground, padding: PaddingValues = PaddingValues(horizontal = DEFAULT_PADDING)) { SectionItemViewSpaceBetween(padding = padding) { Row { val iconSize = with(LocalDensity.current) { 21.sp.toDp() } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ThemeModeEditor.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ThemeModeEditor.kt index 38b1737243..5522e3988c 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ThemeModeEditor.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/helpers/ThemeModeEditor.kt @@ -329,7 +329,6 @@ fun ModalData.ChatWallpaperEditor( ThemeManager.currentColors(type, if (type?.sameType(themeModeOverride.value.type) == true) themeModeOverride.value else null, chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) } - SectionView { WallpaperPresetSelector( selectedWallpaper = currentTheme.wallpaper.type, activeBackgroundColor = currentTheme.wallpaper.background, @@ -368,11 +367,9 @@ fun ModalData.ChatWallpaperEditor( editColor = editColor, onTypeChange = onTypeChange, ) - } SectionSpacer() - SectionView { if (!globalThemeUsed.value) { ResetToGlobalThemeButton(remember { chatModel.currentUser }.value?.uiThemes?.preferredMode(isInDarkTheme()) == null) { themeModeOverride.value = ThemeManager.defaultActiveTheme(chatModel.currentUser.value?.uiThemes, appPrefs.themeOverrides.get()) @@ -396,7 +393,6 @@ fun ModalData.ChatWallpaperEditor( save(themeModeOverride.value.mode, themeModeOverride.value) } } - } KeyChangeEffect(theme.mode) { themeModeOverride.value = theme @@ -424,7 +420,6 @@ fun ModalData.ChatWallpaperEditor( ) ) } - SectionView { ExposedDropDownSettingRow( generalGetString(MR.strings.chat_theme_apply_to_mode), values, @@ -440,7 +435,6 @@ fun ModalData.ChatWallpaperEditor( } } ) - } SectionDividerSpaced() @@ -454,9 +448,7 @@ fun ModalData.ChatWallpaperEditor( } } } else { - SectionView { - AdvancedSettingsButton { showMore = true } - } + AdvancedSettingsButton { showMore = true } } SectionBottomSpacer() @@ -465,7 +457,7 @@ fun ModalData.ChatWallpaperEditor( @Composable private fun ImportExportThemeSection(perChat: ThemeModeOverride?, perUser: ThemeModeOverrides?, save: (ThemeModeOverride) -> Unit) { - SectionView { + SectionView(card = true) { val theme = remember { mutableStateOf(null as String?) } val exportThemeLauncher = rememberFileChooserLauncher(false) { to: URI? -> val themeValue = theme.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 982bedfb83..e78056b8e2 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 @@ -182,7 +182,7 @@ private fun SectionByState( @Composable private fun MutableState.ChatStopInProgressView() { Box { - SectionView(stringResource(MR.strings.migrate_from_device_stopping_chat)) {} + SectionView(stringResource(MR.strings.migrate_from_device_stopping_chat), card = true) {} ProgressView() } LaunchedEffect(Unit) { @@ -192,7 +192,7 @@ private fun MutableState.ChatStopInProgressView() { @Composable private fun MutableState.ChatStopFailedView(reason: String) { - SectionView(stringResource(MR.strings.error_stopping_chat)) { + SectionView(stringResource(MR.strings.error_stopping_chat), card = true) { Text(reason) SectionSpacer() SettingsActionItemWithContent( @@ -201,8 +201,8 @@ private fun MutableState.ChatStopFailedView(reason: String) textColor = MaterialTheme.colors.error, click = ::stopChat ){} + SectionTextFooter(stringResource(MR.strings.migrate_from_device_chat_should_be_stopped)) } - SectionTextFooter(stringResource(MR.strings.migrate_from_device_chat_should_be_stopped)) } @Composable @@ -226,7 +226,7 @@ private fun MutableState.PassphraseConfirmationView() { ChatStoppedView() SectionSpacer() - SectionView(stringResource(MR.strings.migrate_from_device_verify_database_passphrase)) { + SectionView(stringResource(MR.strings.migrate_from_device_verify_database_passphrase), card = true) { PassphraseField(currentKey, placeholder = stringResource(MR.strings.current_passphrase), Modifier.padding(horizontal = DEFAULT_PADDING), isValid = ::validKey, requestFocus = true) SettingsActionItemWithContent( @@ -243,8 +243,8 @@ private fun MutableState.PassphraseConfirmationView() { } } ) {} + SectionTextFooter(stringResource(MR.strings.migrate_from_device_confirm_you_remember_passphrase)) } - SectionTextFooter(stringResource(MR.strings.migrate_from_device_confirm_you_remember_passphrase)) } if (verifyingPassphrase.value) { ProgressView() @@ -254,21 +254,21 @@ private fun MutableState.PassphraseConfirmationView() { @Composable private fun MutableState.UploadConfirmationView() { - SectionView(stringResource(MR.strings.migrate_from_device_confirm_upload)) { + SectionView(stringResource(MR.strings.migrate_from_device_confirm_upload), card = true) { SettingsActionItemWithContent( icon = painterResource(MR.images.ic_ios_share), text = stringResource(MR.strings.migrate_from_device_archive_and_upload), textColor = MaterialTheme.colors.primary, click = { state = MigrationFromState.Archiving } ){} + SectionTextFooter(stringResource(MR.strings.migrate_from_device_all_data_will_be_uploaded)) } - SectionTextFooter(stringResource(MR.strings.migrate_from_device_all_data_will_be_uploaded)) } @Composable private fun MutableState.ArchivingView() { Box { - SectionView(stringResource(MR.strings.migrate_from_device_archiving_database)) {} + SectionView(stringResource(MR.strings.migrate_from_device_archiving_database), card = true) {} ProgressView() } LaunchedEffect(Unit) { @@ -279,7 +279,7 @@ private fun MutableState.ArchivingView() { @Composable private fun MutableState.DatabaseInitView(tempDatabaseFile: File, totalBytes: Long, archivePath: String) { Box { - SectionView(stringResource(MR.strings.migrate_from_device_database_init)) {} + SectionView(stringResource(MR.strings.migrate_from_device_database_init), card = true) {} ProgressView() } LaunchedEffect(Unit) { @@ -298,7 +298,7 @@ private fun MutableState.UploadProgressView( archivePath: String, ) { Box { - SectionView(stringResource(MR.strings.migrate_from_device_uploading_archive)) { + SectionView(stringResource(MR.strings.migrate_from_device_uploading_archive), card = true) { val ratio = uploadedBytes.toFloat() / max(totalBytes, 1) LargeProgressView(ratio, "${(ratio * 100).toInt()}%", stringResource(MR.strings.migrate_from_device_bytes_uploaded).format(formatBytes(uploadedBytes))) } @@ -310,7 +310,7 @@ private fun MutableState.UploadProgressView( @Composable private fun MutableState.UploadFailedView(totalBytes: Long, archivePath: String, chatReceiver: MigrationFromChatReceiver?) { - SectionView(stringResource(MR.strings.migrate_from_device_upload_failed)) { + SectionView(stringResource(MR.strings.migrate_from_device_upload_failed), card = true) { SettingsActionItemWithContent( icon = painterResource(MR.images.ic_ios_share), text = stringResource(MR.strings.migrate_from_device_repeat_upload), @@ -319,8 +319,8 @@ private fun MutableState.UploadFailedView(totalBytes: Long, state = MigrationFromState.DatabaseInit(totalBytes, archivePath) } ) {} + SectionTextFooter(stringResource(MR.strings.migrate_from_device_try_again)) } - SectionTextFooter(stringResource(MR.strings.migrate_from_device_try_again)) LaunchedEffect(Unit) { chatReceiver?.stopAndCleanUp() } @@ -329,14 +329,14 @@ private fun MutableState.UploadFailedView(totalBytes: Long, @Composable private fun LinkCreationView() { Box { - SectionView(stringResource(MR.strings.migrate_from_device_creating_archive_link)) {} + SectionView(stringResource(MR.strings.migrate_from_device_creating_archive_link), card = true) {} ProgressView() } } @Composable private fun MutableState.LinkShownView(fileId: Long, link: String, ctrl: ChatCtrl, chatReceiver: MigrationFromChatReceiver?) { - SectionView { + SectionView(card = true) { SettingsActionItemWithContent( icon = painterResource(MR.images.ic_close), text = stringResource(MR.strings.migrate_from_device_cancel_migration), @@ -361,15 +361,15 @@ private fun MutableState.LinkShownView(fileId: Long, link: S ) } ) {} + SectionTextFooter(annotatedStringResource(MR.strings.migrate_from_device_archive_will_be_deleted)) + SectionTextFooter(annotatedStringResource(MR.strings.migrate_from_device_choose_migrate_from_another_device)) } - SectionTextFooter(annotatedStringResource(MR.strings.migrate_from_device_archive_will_be_deleted)) - SectionTextFooter(annotatedStringResource(MR.strings.migrate_from_device_choose_migrate_from_another_device)) SectionSpacer() - SectionView(stringResource(MR.strings.show_QR_code)) { + SectionView(stringResource(MR.strings.show_QR_code), card = true) { SimpleXLinkQRCode(link, onShare = {}) } SectionSpacer() - SectionView(stringResource(MR.strings.migrate_from_device_or_share_this_file_link)) { + SectionView(stringResource(MR.strings.migrate_from_device_or_share_this_file_link), card = true) { LinkTextView(link, true) } } @@ -377,7 +377,7 @@ private fun MutableState.LinkShownView(fileId: Long, link: S @Composable private fun MutableState.FinishedView(chatDeletion: Boolean) { Box { - SectionView(stringResource(MR.strings.migrate_from_device_migration_complete)) { + SectionView(stringResource(MR.strings.migrate_from_device_migration_complete), card = true) { SettingsActionItemWithContent( icon = painterResource(MR.images.ic_play_arrow_filled), text = stringResource(MR.strings.migrate_from_device_start_chat), @@ -410,9 +410,9 @@ private fun MutableState.FinishedView(chatDeletion: Boolean) ) } ) {} + 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)) } - 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)) if (chatDeletion) { ProgressView() } 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 09d2d60e99..26f06d8997 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 @@ -201,7 +201,7 @@ private fun MutableState.PasteOrScanLinkView(close: () -> Uni val progressIndicator = remember { mutableStateOf(false) } Column { if (appPlatform.isAndroid) { - SectionView(stringResource(MR.strings.scan_QR_code).replace('\n', ' ')) { + SectionView(stringResource(MR.strings.scan_QR_code).replace('\n', ' '), card = true) { QRCodeScanner(showQRCodeScanner = remember { mutableStateOf(true) }) { text -> checkUserLink(text) } @@ -209,12 +209,12 @@ private fun MutableState.PasteOrScanLinkView(close: () -> Uni SectionSpacer() } - SectionView(stringResource(if (appPlatform.isAndroid) MR.strings.or_paste_archive_link else MR.strings.paste_archive_link)) { + SectionView(stringResource(if (appPlatform.isAndroid) MR.strings.or_paste_archive_link else MR.strings.paste_archive_link), card = true) { PasteLinkView() } SectionSpacer() - SectionView(stringResource(MR.strings.chat_archive)) { + SectionView(stringResource(MR.strings.chat_archive), card = true) { ArchiveImportView(progressIndicator, close) } } @@ -280,7 +280,7 @@ private fun ModalData.OnionView(link: String, legacyLinkSocksProxy: String?, lin mutableStateOf(getNetCfg().withOnionHosts(onionHosts.value).copy(socksProxy = linkNetworkProxy?.toProxyString() ?: legacyLinkSocksProxy, sessionMode = sessionMode.value)) } - SectionView(stringResource(MR.strings.migrate_to_device_confirm_network_settings)) { + SectionView(stringResource(MR.strings.migrate_to_device_confirm_network_settings), card = true) { SettingsActionItemWithContent( icon = painterResource(MR.images.ic_check), text = stringResource(MR.strings.migrate_to_device_apply_onion), @@ -297,15 +297,15 @@ private fun ModalData.OnionView(link: String, legacyLinkSocksProxy: String?, lin } } ){} + SectionTextFooter(stringResource(MR.strings.migrate_to_device_confirm_network_settings_footer)) } - SectionTextFooter(stringResource(MR.strings.migrate_to_device_confirm_network_settings_footer)) SectionSpacer() val networkProxyPref = SharedPreference(get = { networkProxy.value }, set = { networkProxy.value = it }) - SectionView(stringResource(MR.strings.network_settings_title)) { + SectionView(stringResource(MR.strings.network_settings_title), card = true) { OnionRelatedLayout( appPreferences.developerTools.get(), networkUseSocksProxy, @@ -325,7 +325,7 @@ private fun ModalData.OnionView(link: String, legacyLinkSocksProxy: String?, lin @Composable private fun MutableState.DatabaseInitView(link: String, tempDatabaseFile: File, netCfg: NetCfg, networkProxy: NetworkProxy?) { Box { - SectionView(stringResource(MR.strings.migrate_to_device_database_init)) {} + SectionView(stringResource(MR.strings.migrate_to_device_database_init), card = true) {} ProgressView() } LaunchedEffect(Unit) { @@ -345,7 +345,7 @@ private fun MutableState.LinkDownloadingView( networkProxy: NetworkProxy? ) { Box { - SectionView(stringResource(MR.strings.migrate_to_device_downloading_details)) {} + SectionView(stringResource(MR.strings.migrate_to_device_downloading_details), card = true) {} ProgressView() } LaunchedEffect(Unit) { @@ -356,7 +356,7 @@ private fun MutableState.LinkDownloadingView( @Composable private fun DownloadProgressView(downloadedBytes: Long, totalBytes: Long) { Box { - SectionView(stringResource(MR.strings.migrate_to_device_downloading_archive)) { + SectionView(stringResource(MR.strings.migrate_to_device_downloading_archive), card = true) { val ratio = downloadedBytes.toFloat() / max(totalBytes, 1) LargeProgressView(ratio, "${(ratio * 100).toInt()}%", stringResource(MR.strings.migrate_to_device_bytes_downloaded).format(formatBytes(downloadedBytes))) } @@ -365,7 +365,7 @@ private fun DownloadProgressView(downloadedBytes: Long, totalBytes: Long) { @Composable private fun MutableState.DownloadFailedView(link: String, chatReceiver: MigrationToChatReceiver?, archivePath: String, netCfg: NetCfg, networkProxy: NetworkProxy?) { - SectionView(stringResource(MR.strings.migrate_to_device_download_failed)) { + SectionView(stringResource(MR.strings.migrate_to_device_download_failed), card = true) { SettingsActionItemWithContent( icon = painterResource(MR.images.ic_download), text = stringResource(MR.strings.migrate_to_device_repeat_download), @@ -374,8 +374,8 @@ private fun MutableState.DownloadFailedView(link: String, cha state = MigrationToState.DatabaseInit(link, netCfg, networkProxy) } ) {} + SectionTextFooter(stringResource(MR.strings.migrate_to_device_try_again)) } - SectionTextFooter(stringResource(MR.strings.migrate_to_device_try_again)) LaunchedEffect(Unit) { chatReceiver?.stopAndCleanUp() File(archivePath).delete() @@ -386,7 +386,7 @@ private fun MutableState.DownloadFailedView(link: String, cha @Composable private fun MutableState.ArchiveImportView(archivePath: String, netCfg: NetCfg, networkProxy: NetworkProxy?) { Box { - SectionView(stringResource(MR.strings.migrate_to_device_importing_archive)) {} + SectionView(stringResource(MR.strings.migrate_to_device_importing_archive).uppercase()) {} ProgressView() } LaunchedEffect(Unit) { @@ -396,7 +396,7 @@ private fun MutableState.ArchiveImportView(archivePath: Strin @Composable private fun MutableState.ArchiveImportFailedView(archivePath: String, netCfg: NetCfg, networkProxy: NetworkProxy?) { - SectionView(stringResource(MR.strings.migrate_to_device_import_failed)) { + SectionView(stringResource(MR.strings.migrate_to_device_import_failed).uppercase()) { SettingsActionItemWithContent( icon = painterResource(MR.images.ic_download), text = stringResource(MR.strings.migrate_to_device_repeat_import), @@ -405,8 +405,8 @@ private fun MutableState.ArchiveImportFailedView(archivePath: state = MigrationToState.ArchiveImport(archivePath, netCfg, networkProxy) } ) {} + SectionTextFooter(stringResource(MR.strings.migrate_to_device_try_again)) } - SectionTextFooter(stringResource(MR.strings.migrate_to_device_try_again)) } @Composable @@ -417,7 +417,7 @@ private fun MutableState.PassphraseEnteringView(currentKey: S Box { val view = LocalMultiplatformView() - SectionView(stringResource(MR.strings.migrate_to_device_enter_passphrase)) { + SectionView(stringResource(MR.strings.migrate_to_device_enter_passphrase), card = true) { SavePassphraseSetting( useKeychain.value, false, @@ -489,7 +489,7 @@ private fun MutableState.MigrationConfirmationView(status: DB } else -> Tuple4(generalGetString(MR.strings.error), null, generalGetString(MR.strings.unknown_error), null) } - SectionView(header) { + SectionView(header, card = true) { if (button != null && confirmation != null) { SettingsActionItemWithContent( icon = painterResource(MR.images.ic_download), @@ -500,14 +500,14 @@ private fun MutableState.MigrationConfirmationView(status: DB } ) {} } + SectionTextFooter(footer) } - SectionTextFooter(footer) } @Composable private fun MigrationView(passphrase: String, confirmation: MigrationConfirmation, useKeychain: Boolean, netCfg: NetCfg, networkProxy: NetworkProxy?, close: () -> Unit) { Box { - SectionView(stringResource(MR.strings.migrate_to_device_migrating)) {} + SectionView(stringResource(MR.strings.migrate_to_device_migrating), card = true) {} ProgressView() } LaunchedEffect(Unit) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddChannelView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddChannelView.kt index fdde41d7e2..93bb4f49db 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddChannelView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/AddChannelView.kt @@ -257,7 +257,7 @@ private fun ProfileStepView( sheetState = bottomSheetModalState, sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp) ) { - ModalView(close = close, background = MaterialTheme.colors.surface) { + ModalView(close = close) { ColumnWithScrollBar { AppBarTitle(generalGetString(MR.strings.create_channel_title), bottomPadding = DEFAULT_PADDING_HALF) Row( @@ -403,7 +403,6 @@ private fun ProgressStepView( ModalView( close = { showCancelAlert() }, - background = MaterialTheme.colors.surface, showClose = false, ) { ColumnWithScrollBar { @@ -568,7 +567,7 @@ private fun LinkStepView( } } } - ModalView(close = close, background = MaterialTheme.colors.surface, showClose = false) { + ModalView(close = close, showClose = false) { GroupLinkView( chatModel = chatModel, rhId = null, 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 b1529a7dfa..a54d2e42e7 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 @@ -99,7 +99,7 @@ fun AddGroupLayout( sheetState = bottomSheetModalState, sheetShape = RoundedCornerShape(topStart = 18.dp, topEnd = 18.dp) ) { - ModalView(close = close, background = MaterialTheme.colors.surface) { + ModalView(close = close) { ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.create_secret_group_title), hostDevice(rhId), bottomPadding = DEFAULT_PADDING_HALF) Row( 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 8685796c5d..dd07dfb6e1 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 @@ -131,7 +131,8 @@ private fun ContactConnectionInfoLayout( Spacer(Modifier.height(DEFAULT_PADDING)) SectionViewWithButton( stringResource(MR.strings.one_time_link), - titleButton = if (connLink.connShortLink == null) null else {{ ToggleShortLinkButton(showShortLink) }} + titleButton = if (connLink.connShortLink == null) null else {{ ToggleShortLinkButton(showShortLink) }}, + card = true ) { SimpleXCreatedLinkQRCode(connLink, short = showShortLink.value) incognitoEnabled() @@ -139,14 +140,14 @@ private fun ContactConnectionInfoLayout( OneTimeLinkLearnMoreButton(learnMore) } } else { - SectionView { + SectionView(card = true) { incognitoEnabled() OneTimeLinkLearnMoreButton(learnMore) } } SectionTextFooter(sharedProfileInfo(chatModel, contactConnection.incognito)) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false) DeleteButton(deleteConnection) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt index 5ad7b1eef3..1eceaf4158 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/newchat/NewChatSheet.kt @@ -224,7 +224,7 @@ private fun ModalData.NewChatSheetLayout( } } if (deletedChats.isNotEmpty()) { - SectionDividerSpaced() + SectionDividerSpaced(maxBottomPadding = false) SectionView { SectionItemView( click = { @@ -322,26 +322,23 @@ private fun ModalData.NewChatSheetLayout( item { DeletedChatsItem(actionButtonsOriginal.asReversed()) } - if (filteredContactChats.isNotEmpty()) { - if (searchText.value.text.isEmpty()) { - item { - SectionDividerSpaced() - SectionView(stringResource(MR.strings.contact_list_header_title), headerBottomPadding = DEFAULT_PADDING_HALF) {} + item { + if (filteredContactChats.isNotEmpty() && searchText.value.text.isEmpty()) { + SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false) + SectionView(stringResource(MR.strings.contact_list_header_title).uppercase(), headerBottomPadding = DEFAULT_PADDING_HALF) {} + Spacer(Modifier.height(DEFAULT_PADDING_HALF)) + } + } + item { + NoFilteredContactsItem() + } + itemsIndexed(filteredContactChats) { index, chat -> + val nextChatSelected = remember(chat.id, filteredContactChats) { + derivedStateOf { + chatModel.chatId.value != null && filteredContactChats.getOrNull(index + 1)?.id == chatModel.chatId.value } } - itemsIndexed(filteredContactChats) { index, chat -> - val nextChatSelected = remember(chat.id, filteredContactChats) { - derivedStateOf { - chatModel.chatId.value != null && filteredContactChats.getOrNull(index + 1)?.id == chatModel.chatId.value - } - } - ContactListNavLinkView(chat, nextChatSelected, showDeletedChatIcon = true) - } - if (searchText.value.text.isEmpty()) { - item { Spacer(Modifier.height(DEFAULT_PADDING_HALF)) } - } - } else { - item { NoFilteredContactsItem() } + ContactListNavLinkView(chat, nextChatSelected, showDeletedChatIcon = true) } if (appPlatform.isAndroid) { item { @@ -410,23 +407,22 @@ private fun ModalData.NewChatSheetLayout( item { DeletedChatsItem(actionButtonsOriginal) } - if (filteredContactChats.isNotEmpty()) { - if (searchText.value.text.isEmpty()) { - item { - SectionDividerSpaced() - SectionView(stringResource(MR.strings.contact_list_header_title), headerBottomPadding = DEFAULT_PADDING_HALF) {} + item { + if (filteredContactChats.isNotEmpty() && searchText.value.text.isEmpty()) { + SectionDividerSpaced() + SectionView(stringResource(MR.strings.contact_list_header_title).uppercase(), headerBottomPadding = DEFAULT_PADDING_HALF) {} + } + } + item { + NoFilteredContactsItem() + } + itemsIndexed(filteredContactChats) { index, chat -> + val nextChatSelected = remember(chat.id, filteredContactChats) { + derivedStateOf { + chatModel.chatId.value != null && filteredContactChats.getOrNull(index + 1)?.id == chatModel.chatId.value } } - itemsIndexed(filteredContactChats) { index, chat -> - val nextChatSelected = remember(chat.id, filteredContactChats) { - derivedStateOf { - chatModel.chatId.value != null && filteredContactChats.getOrNull(index + 1)?.id == chatModel.chatId.value - } - } - ContactListNavLinkView(chat, nextChatSelected, showDeletedChatIcon = true) - } - } else { - item { NoFilteredContactsItem() } + ContactListNavLinkView(chat, nextChatSelected, showDeletedChatIcon = true) } if (appPlatform.isAndroid) { item { 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 ee6d888e78..72311cd7fe 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 @@ -495,14 +495,14 @@ private fun InviteView(rhId: Long?, connLinkInvitation: CreatedConnLink, contact ) SimpleXCreatedLinkQRCode(connLinkInvitation, short = showShortLink.value, onShare = { chatModel.markShowingInvitationUsed() }) } else { - SectionView(stringResource(MR.strings.share_this_1_time_link), headerBottomPadding = 5.dp) { + SectionView(stringResource(MR.strings.share_this_1_time_link).uppercase(), headerBottomPadding = 5.dp) { LinkTextView(connLinkInvitation.simplexChatUri(short = showShortLink.value), true) } Spacer(Modifier.height(DEFAULT_PADDING)) SectionViewWithButton( - stringResource(MR.strings.or_show_this_qr_code), + stringResource(MR.strings.or_show_this_qr_code).uppercase(), titleButton = if (connLinkInvitation.connShortLink != null) {{ ToggleShortLinkButton(showShortLink) }} else null ) { SimpleXCreatedLinkQRCode(connLinkInvitation, short = showShortLink.value, onShare = { chatModel.markShowingInvitationUsed() }) @@ -519,7 +519,7 @@ private fun InviteView(rhId: Long?, connLinkInvitation: CreatedConnLink, contact val currentUser = remember { chatModel.currentUser }.value if (currentUser != null) { - SectionView(stringResource(MR.strings.new_chat_share_profile), headerBottomPadding = 5.dp) { + SectionView(stringResource(MR.strings.new_chat_share_profile).uppercase(), headerBottomPadding = 5.dp) { SectionItemView( padding = PaddingValues( top = 0.dp, @@ -643,14 +643,14 @@ private fun ConnectView(rhId: Long?, showQRCodeScanner: MutableState, p ) } - SectionView(stringResource(MR.strings.paste_the_link_you_received), headerBottomPadding = 5.dp) { + SectionView(stringResource(MR.strings.paste_the_link_you_received).uppercase(), headerBottomPadding = 5.dp) { PasteLinkView(rhId, pastedLink, showQRCodeScanner, close) } if (appPlatform.isAndroid) { Spacer(Modifier.height(10.dp)) - SectionView(stringResource(MR.strings.or_scan_qr_code), headerBottomPadding = 5.dp) { + SectionView(stringResource(MR.strings.or_scan_qr_code).uppercase(), headerBottomPadding = 5.dp) { QRCodeScanner(showQRCodeScanner) { text -> val linkVerified = verifyOnly(text) if (!linkVerified) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/ChooseServerOperators.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/ChooseServerOperators.kt index 78ae518b18..bd778b7760 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/ChooseServerOperators.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/ChooseServerOperators.kt @@ -373,7 +373,7 @@ private fun ChooseServerOperatorsInfoView() { SectionDividerSpaced() - SectionView(title = stringResource(MR.strings.onboarding_network_about_operators)) { + SectionView(title = stringResource(MR.strings.onboarding_network_about_operators), card = true) { chatModel.conditions.value.serverOperators.forEach { op -> ServerOperatorRow(op) } 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 008e8c82aa..703d295523 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 @@ -23,7 +23,7 @@ import dev.icerock.moko.resources.StringResource @Composable fun HowItWorks(user: User?, onboardingStage: SharedPreference? = null) { - Column(Modifier.fillMaxSize().background(MaterialTheme.colors.surface).padding(horizontal = if (appPlatform.isDesktop) DEFAULT_PADDING * 2 else DEFAULT_PADDING)) { + Column(Modifier.fillMaxSize().padding(horizontal = if (appPlatform.isDesktop) DEFAULT_PADDING * 2 else DEFAULT_PADDING)) { Spacer(Modifier.statusBarsPadding().padding(top = AppBarHeight * fontSizeSqrtMultiplier)) val paraPadding = PaddingValues(bottom = if (appPlatform.isDesktop) 10.dp else 12.dp) Column(Modifier.weight(1f).padding(bottom = DEFAULT_PADDING).verticalScroll(rememberScrollState())) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/LinkAMobileView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/LinkAMobileView.kt index 97dfcd34b9..061a924a63 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/LinkAMobileView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/onboarding/LinkAMobileView.kt @@ -65,7 +65,7 @@ private fun LinkAMobileLayout( Modifier.weight(0.3f), verticalArrangement = Arrangement.spacedBy(8.dp) ) { - SectionView(generalGetString(MR.strings.this_device_name)) { + SectionView(generalGetString(MR.strings.this_device_name), card = true) { DeviceNameField(deviceName.value ?: "") { updateDeviceName(it) } SectionTextFooter(generalGetString(MR.strings.this_device_name_shared_with_mobile)) PreferenceToggle(stringResource(MR.strings.multicast_discoverable_via_local_network), checked = remember { ChatModel.controller.appPrefs.offerRemoteMulticast.state }.value) { 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 22476ceba1..74dadcd671 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 @@ -106,8 +106,7 @@ fun SimpleXInfoLayout( onboardingStage: SharedPreference? ) { val topBar = onboardingStage == null && !appPrefs.oneHandUI.state.value - val baseModifier = Modifier.fillMaxSize().systemBarsPadding().padding(horizontal = DEFAULT_ONBOARDING_HORIZONTAL_PADDING) - val modifier = if (onboardingStage == null) baseModifier.background(MaterialTheme.colors.surface) else baseModifier + val modifier = Modifier.fillMaxSize().systemBarsPadding().padding(horizontal = DEFAULT_ONBOARDING_HORIZONTAL_PADDING) Column(if (topBar) modifier.padding(top = AppBarHeight * fontSizeSqrtMultiplier) else modifier, horizontalAlignment = Alignment.CenterHorizontally) { Box(Modifier.padding(top = DEFAULT_PADDING * 2).widthIn(max = if (appPlatform.isAndroid) 185.dp else 160.dp), contentAlignment = Alignment.Center) { SimpleXLogo() 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 6eaf00958e..e1415d071d 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 @@ -138,7 +138,7 @@ fun ModalData.WhatsNewView(updatedConditions: Boolean = false, viaSettings: Bool val v = versionDescriptions[currentVersion.value] - ModalView(close = close, background = MaterialTheme.colors.surface) { + ModalView(close = close) { ColumnWithScrollBar( Modifier .padding(horizontal = 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 39d126b23f..05ca68d02f 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 @@ -128,7 +128,7 @@ private fun ConnectDesktopLayout(deviceName: String, close: () -> Unit) { @Composable private fun ConnectDesktop(deviceName: String, remoteCtrls: SnapshotStateList, sessionAddress: MutableState) { AppBarTitle(stringResource(MR.strings.connect_to_desktop)) - SectionView(stringResource(MR.strings.this_device_name)) { + SectionView(stringResource(MR.strings.this_device_name), card = true) { DevicesView(deviceName, remoteCtrls) { if (it != "") { setDeviceName(it) @@ -147,7 +147,7 @@ private fun ConnectDesktop(deviceName: String, remoteCtrls: SnapshotStateList) { AppBarTitle(stringResource(MR.strings.connecting_to_desktop)) - SectionView(stringResource(MR.strings.this_device_name)) { + SectionView(stringResource(MR.strings.this_device_name), card = true) { DevicesView(deviceName, remoteCtrls) { if (it != "") { setDeviceName(it) @@ -197,7 +197,7 @@ private fun SearchingDesktop(deviceName: String, remoteCtrls: SnapshotStateList< } } SectionDividerSpaced() - SectionView(stringResource(MR.strings.found_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { + SectionView(stringResource(MR.strings.found_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING), card = true) { Text(stringResource(MR.strings.waiting_for_desktop), fontStyle = FontStyle.Italic) } SectionSpacer() @@ -215,7 +215,7 @@ private fun FoundDesktop( sessionAddress: MutableState, ) { AppBarTitle(stringResource(MR.strings.found_desktop)) - SectionView(stringResource(MR.strings.this_device_name)) { + SectionView(stringResource(MR.strings.this_device_name), card = true) { DevicesView(deviceName, remoteCtrls) { if (it != "") { setDeviceName(it) @@ -224,7 +224,7 @@ private fun FoundDesktop( } } SectionDividerSpaced() - SectionView(stringResource(MR.strings.found_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { + SectionView(stringResource(MR.strings.found_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING), card = true) { CtrlDeviceNameText(session, rc) CtrlDeviceVersionText(session) if (!compatible) { @@ -256,7 +256,7 @@ private fun FoundDesktop( @Composable private fun VerifySession(session: RemoteCtrlSession, rc: RemoteCtrlInfo?, sessCode: String, remoteCtrls: SnapshotStateList) { AppBarTitle(stringResource(MR.strings.verify_connection)) - SectionView(stringResource(MR.strings.connected_to_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { + SectionView(stringResource(MR.strings.connected_to_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING), card = true) { CtrlDeviceNameText(session, rc) Spacer(Modifier.height(DEFAULT_PADDING_HALF)) CtrlDeviceVersionText(session) @@ -264,7 +264,7 @@ private fun VerifySession(session: RemoteCtrlSession, rc: RemoteCtrlInfo?, sessC SectionSpacer() - SectionView(stringResource(MR.strings.verify_code_with_desktop)) { + SectionView(stringResource(MR.strings.verify_code_with_desktop), card = true) { SessionCodeText(sessCode) } @@ -276,7 +276,7 @@ private fun VerifySession(session: RemoteCtrlSession, rc: RemoteCtrlInfo?, sessC Text(generalGetString(MR.strings.confirm_verb)) } - SectionView { + SectionView(card = true) { DisconnectButton(onClick = ::disconnectDesktop) } } @@ -311,7 +311,7 @@ private fun CtrlDeviceVersionText(session: RemoteCtrlSession) { @Composable private fun ActiveSession(session: RemoteCtrlSession, rc: RemoteCtrlInfo, close: () -> Unit) { AppBarTitle(stringResource(MR.strings.connected_to_desktop)) - SectionView(stringResource(MR.strings.connected_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { + SectionView(stringResource(MR.strings.connected_desktop), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING), card = true) { Text(rc.deviceViewName) Spacer(Modifier.height(DEFAULT_PADDING_HALF)) CtrlDeviceVersionText(session) @@ -319,14 +319,14 @@ private fun ActiveSession(session: RemoteCtrlSession, rc: RemoteCtrlInfo, close: if (session.sessionCode != null) { SectionSpacer() - SectionView(stringResource(MR.strings.session_code)) { + SectionView(stringResource(MR.strings.session_code), card = true) { SessionCodeText(session.sessionCode!!) } } SectionSpacer() - SectionView { + SectionView(card = true) { DisconnectButton { disconnectDesktop(close) } } } @@ -355,7 +355,7 @@ private fun DevicesView(deviceName: String, remoteCtrls: SnapshotStateList) { - SectionView(stringResource(MR.strings.scan_qr_code_from_desktop)) { + SectionView(stringResource(MR.strings.scan_qr_code_from_desktop), card = true) { QRCodeScanner { text -> sessionAddress.value = text connectDesktopAddress(sessionAddress, text) @@ -366,7 +366,7 @@ private fun ScanDesktopAddressView(sessionAddress: MutableState) { @Composable private fun DesktopAddressView(sessionAddress: MutableState) { val clipboard = LocalClipboardManager.current - SectionView(stringResource(MR.strings.desktop_address)) { + SectionView(stringResource(MR.strings.desktop_address), card = true) { if (sessionAddress.value.isEmpty()) { SettingsActionItem( painterResource(MR.images.ic_content_paste), @@ -410,7 +410,7 @@ private fun DesktopAddressView(sessionAddress: MutableState) { private fun LinkedDesktopsView(remoteCtrls: SnapshotStateList) { ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.linked_desktops)) - SectionView(stringResource(MR.strings.desktop_devices)) { + SectionView(stringResource(MR.strings.desktop_devices), card = true) { remoteCtrls.forEach { rc -> val showMenu = rememberSaveable { mutableStateOf(false) } SectionItemViewLongClickable(click = {}, longClick = { showMenu.value = true }) { @@ -427,7 +427,7 @@ private fun LinkedDesktopsView(remoteCtrls: SnapshotStateList) { } SectionDividerSpaced() - SectionView(stringResource(MR.strings.linked_desktop_options)) { + SectionView(stringResource(MR.strings.linked_desktop_options), card = true) { PreferenceToggle(stringResource(MR.strings.verify_connections), checked = remember { controller.appPrefs.confirmRemoteSessions.state }.value) { controller.appPrefs.confirmRemoteSessions.set(it) } 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 21a6b344f7..e1db3f5202 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 @@ -92,15 +92,15 @@ fun ConnectMobileLayout( ) { ColumnWithScrollBar { AppBarTitle(stringResource(if (remember { chatModel.remoteHosts }.isEmpty()) MR.strings.link_a_mobile else MR.strings.linked_mobiles)) - SectionView(generalGetString(MR.strings.this_device_name)) { + SectionView(generalGetString(MR.strings.this_device_name), card = true) { DeviceNameField(deviceName.value ?: "") { updateDeviceName(it) } + SectionTextFooter(generalGetString(MR.strings.this_device_name_shared_with_mobile)) PreferenceToggle(stringResource(MR.strings.multicast_discoverable_via_local_network), checked = remember { controller.appPrefs.offerRemoteMulticast.state }.value) { controller.appPrefs.offerRemoteMulticast.set(it) } + SectionDividerSpaced() } - SectionTextFooter(generalGetString(MR.strings.this_device_name_shared_with_mobile)) - SectionDividerSpaced() - SectionView(stringResource(MR.strings.devices)) { + SectionView(stringResource(MR.strings.devices), card = true) { if (chatModel.localUserCreated.value == true) { SettingsActionItemWithContent(text = stringResource(MR.strings.this_device), icon = painterResource(MR.images.ic_desktop), click = connectDesktop) { if (connectedHost.value == null) { @@ -189,7 +189,7 @@ private fun ConnectMobileViewLayout( if (title != null) { AppBarTitle(title) } - SectionView { + SectionView(card = true) { if (invitation != null && sessionCode == null && port != null) { Box { QRCode(invitation) @@ -211,10 +211,11 @@ private fun ConnectMobileViewLayout( Text(generalGetString(MR.strings.share_link), color = MaterialTheme.colors.primary) } } - } + Spacer(Modifier.height(DEFAULT_PADDING)) + } if (deviceName != null || sessionCode != null) { - SectionView(stringResource(MR.strings.connected_mobile)) { + SectionView(stringResource(MR.strings.connected_mobile), card = true) { SelectionContainer { Text( deviceName ?: stringResource(MR.strings.new_mobile_device), @@ -227,7 +228,7 @@ private fun ConnectMobileViewLayout( } if (sessionCode != null) { - SectionView(stringResource(MR.strings.verify_code_on_mobile)) { + SectionView(stringResource(MR.strings.verify_code_on_mobile), card = true) { SelectionContainer { Text( sessionCode.substring(0, 23), 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 0d8abf25f3..81f4fe0e7b 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 @@ -1,9 +1,6 @@ package chat.simplex.common.views.usersettings -import CARD_ITEM_PADDING -import CARD_PADDING import SectionBottomSpacer -import SectionDivider import SectionDividerSpaced import SectionItemView import SectionItemViewSpaceBetween @@ -61,9 +58,9 @@ expect fun AppearanceView(m: ChatModel) object AppearanceScope { @Composable fun ProfileImageSection() { - SectionView(stringResource(MR.strings.settings_section_title_profile_images), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { + SectionView(stringResource(MR.strings.settings_section_title_profile_images), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING), card = true) { val image = remember { chatModel.currentUser }.value?.image - Row(Modifier.padding(vertical = 10.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) { + Row(Modifier.padding(top = 10.dp), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) { val size = 60 Box(Modifier.offset(x = -(size / 12).dp)) { if (!image.isNullOrEmpty()) { @@ -94,7 +91,7 @@ object AppearanceScope { @Composable fun AppToolbarsSection() { BoxWithConstraints { - SectionView(stringResource(MR.strings.appearance_app_toolbars)) { + SectionView(stringResource(MR.strings.appearance_app_toolbars), card = true) { SectionItemViewWithoutMinPadding { Box(Modifier.weight(1f)) { Text( @@ -115,7 +112,7 @@ object AppearanceScope { val diff = it % 0.025f appPrefs.inAppBarsAlpha.set(1f - (String.format(Locale.US, "%.3f", it + (if (diff >= 0.0125f) -diff + 0.025f else -diff)).toFloatOrNull() ?: 1f)) }, - Modifier.widthIn(max = (this@BoxWithConstraints.maxWidth - (CARD_PADDING + CARD_ITEM_PADDING) * 2) * 0.618f), + Modifier.widthIn(max = (this@BoxWithConstraints.maxWidth - DEFAULT_PADDING * 2) * 0.618f), valueRange = 0f..0.5f, steps = 21, colors = SliderDefaults.colors( @@ -161,7 +158,7 @@ object AppearanceScope { val diff = it % 0.05f saveBlur(((String.format(Locale.US, "%.2f", it + (if (diff >= 0.025f) -diff + 0.05f else -diff)).toFloatOrNull() ?: 1f) * 100).toInt()) }, - Modifier.widthIn(max = (this@BoxWithConstraints.maxWidth - (CARD_PADDING + CARD_ITEM_PADDING) * 2) * 0.618f), + Modifier.widthIn(max = (this@BoxWithConstraints.maxWidth - DEFAULT_PADDING * 2) * 0.618f), valueRange = 0f..1f, steps = 21, colors = SliderDefaults.colors( @@ -178,7 +175,7 @@ object AppearanceScope { @Composable fun MessageShapeSection() { BoxWithConstraints { - SectionView(stringResource(MR.strings.settings_section_title_message_shape)) { + SectionView(stringResource(MR.strings.settings_section_title_message_shape), card = true) { SectionItemViewWithoutMinPadding { Text(stringResource(MR.strings.settings_message_shape_corner), Modifier.weight(1f)) Spacer(Modifier.width(10.dp)) @@ -189,7 +186,7 @@ object AppearanceScope { appPreferences.chatItemRoundness.set(it + (if (diff >= 0.025f) -diff + 0.05f else -diff)) saveThemeToDatabase(null) }, - Modifier.widthIn(max = (this@BoxWithConstraints.maxWidth - (CARD_PADDING + CARD_ITEM_PADDING) * 2) * 0.618f), + Modifier.widthIn(max = (this@BoxWithConstraints.maxWidth - DEFAULT_PADDING * 2) * 0.618f), valueRange = 0f..1f, steps = 20, colors = SliderDefaults.colors( @@ -208,8 +205,8 @@ object AppearanceScope { @Composable fun FontScaleSection() { val localFontScale = remember { mutableStateOf(appPrefs.fontScale.get()) } - SectionView(stringResource(MR.strings.appearance_font_size), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { - Row(Modifier.padding(vertical = 10.dp), verticalAlignment = Alignment.CenterVertically) { + SectionView(stringResource(MR.strings.appearance_font_size), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING), card = true) { + Row(Modifier.padding(top = 10.dp), verticalAlignment = Alignment.CenterVertically) { Box(Modifier.size(50.dp) .background(MaterialTheme.colors.surface, RoundedCornerShape(percent = 22)) .clip(RoundedCornerShape(percent = 22)) @@ -523,9 +520,10 @@ object AppearanceScope { } } - SectionView(stringResource(MR.strings.settings_section_title_themes)) { + SectionView(stringResource(MR.strings.settings_section_title_themes), card = true) { Spacer(Modifier.height(DEFAULT_PADDING_HALF)) ThemeDestinationPicker(themeUserDestination) + Spacer(Modifier.height(DEFAULT_PADDING_HALF)) val importWallpaperLauncher = rememberFileChooserLauncher(true) { to: URI? -> if (to != null) onImport(to) @@ -539,7 +537,6 @@ object AppearanceScope { }, onChooseType = { onChooseType(it, importWallpaperLauncher) }, ) - SectionDivider() val type = MaterialTheme.wallpaper.type if (type is WallpaperType.Image && (themeUserDestination.value == null || perUserTheme.value.wallpaper?.imageFile != null)) { SectionItemView(disabled = chatModel.remoteHostId != null && themeUserDestination.value != null, click = { @@ -558,6 +555,7 @@ object AppearanceScope { color = if (chatModel.remoteHostId != null && themeUserDestination.value != null) MaterialTheme.colors.secondary else MaterialTheme.colors.primary ) } + SectionSpacer() } val state: State = remember(appPrefs.currentTheme.get()) { @@ -586,23 +584,23 @@ object AppearanceScope { } saveThemeToDatabase(null) } - SectionItemView(click = { - val user = themeUserDestination.value - if (user == null) { - ModalManager.start.showModal { - val importWallpaperLauncher = rememberFileChooserLauncher(true) { to: URI? -> - if (to != null) onImport(to) - } - CustomizeThemeView { onChooseType(it, importWallpaperLauncher) } - } - } else { - ModalManager.start.showModalCloseable { close -> - UserWallpaperEditorModal(chatModel.remoteHostId(), user.first, close) + } + SectionItemView(click = { + val user = themeUserDestination.value + if (user == null) { + ModalManager.start.showModal { + val importWallpaperLauncher = rememberFileChooserLauncher(true) { to: URI? -> + if (to != null) onImport(to) } + CustomizeThemeView { onChooseType(it, importWallpaperLauncher) } + } + } else { + ModalManager.start.showModalCloseable { close -> + UserWallpaperEditorModal(chatModel.remoteHostId(), user.first, close) } - }) { - Text(stringResource(MR.strings.customize_theme_title)) } + }) { + Text(stringResource(MR.strings.customize_theme_title)) } } @@ -628,35 +626,33 @@ object AppearanceScope { ) } - SectionView { - WallpaperPresetSelector( - selectedWallpaper = wallpaperType, - baseTheme = currentTheme.base, - currentColors = { type -> - ThemeManager.currentColors(type, null, null, appPrefs.themeOverrides.get()) - }, - onChooseType = onChooseType - ) + WallpaperPresetSelector( + selectedWallpaper = wallpaperType, + baseTheme = currentTheme.base, + currentColors = { type -> + ThemeManager.currentColors(type, null, null, appPrefs.themeOverrides.get()) + }, + onChooseType = onChooseType + ) - val type = MaterialTheme.wallpaper.type - if (type is WallpaperType.Image) { - SectionItemView(disabled = chatModel.remoteHostId != null, click = { - val defaultActiveTheme = ThemeManager.defaultActiveTheme(appPrefs.themeOverrides.get()) - ThemeManager.saveAndApplyWallpaper(baseTheme, null) - ThemeManager.removeTheme(defaultActiveTheme?.themeId) - removeWallpaperFile(type.filename) - saveThemeToDatabase(null) - }) { - Text( - stringResource(MR.strings.theme_remove_image), - color = if (chatModel.remoteHostId == null) MaterialTheme.colors.primary else MaterialTheme.colors.secondary - ) - } + val type = MaterialTheme.wallpaper.type + if (type is WallpaperType.Image) { + SectionItemView(disabled = chatModel.remoteHostId != null, click = { + val defaultActiveTheme = ThemeManager.defaultActiveTheme(appPrefs.themeOverrides.get()) + ThemeManager.saveAndApplyWallpaper(baseTheme, null) + ThemeManager.removeTheme(defaultActiveTheme?.themeId) + removeWallpaperFile(type.filename) + saveThemeToDatabase(null) + }) { + Text( + stringResource(MR.strings.theme_remove_image), + color = if (chatModel.remoteHostId == null) MaterialTheme.colors.primary else MaterialTheme.colors.secondary + ) } + SectionSpacer() } - SectionDividerSpaced() - SectionView(stringResource(MR.strings.settings_section_title_chat_colors)) { + SectionView(stringResource(MR.strings.settings_section_title_chat_colors), card = true) { WallpaperSetupView( wallpaperType, baseTheme, @@ -685,18 +681,16 @@ object AppearanceScope { val currentOverrides = remember(currentTheme) { ThemeManager.defaultActiveTheme(appPrefs.themeOverrides.get()) } val canResetColors = currentTheme.base.hasChangedAnyColor(currentOverrides) if (canResetColors) { - SectionView { - SectionItemView({ - ThemeManager.resetAllThemeColors() - saveThemeToDatabase(null) - }) { - Text(generalGetString(MR.strings.reset_color), color = colors.primary) - } + SectionItemView({ + ThemeManager.resetAllThemeColors() + saveThemeToDatabase(null) + }) { + Text(generalGetString(MR.strings.reset_color), color = colors.primary) } SectionSpacer() } - SectionView { + SectionView(card = true) { val theme = remember { mutableStateOf(null as String?) } val exportThemeLauncher = rememberFileChooserLauncher(false) { to: URI? -> val themeValue = theme.value @@ -759,7 +753,7 @@ object AppearanceScope { onLongClick = onLongClick ) .onRightClick(onLongClick) - .size(28.dp), + .size(44.dp), contentAlignment = Alignment.Center ) { Icon(painterResource(if (themeMode == DefaultThemeMode.LIGHT) MR.images.ic_light_mode else MR.images.ic_bedtime_moon), stringResource(MR.strings.color_mode_light), tint = MaterialTheme.colors.secondary) @@ -949,7 +943,7 @@ object AppearanceScope { @Composable fun CustomizeThemeColorsSection(currentTheme: ThemeManager.ActiveTheme, editColor: (ThemeColor) -> Unit) { - SectionView(stringResource(MR.strings.theme_colors_section_title)) { + SectionView(stringResource(MR.strings.theme_colors_section_title), card = true) { SectionItemViewSpaceBetween({ editColor(ThemeColor.PRIMARY) }) { val title = generalGetString(MR.strings.color_primary) Text(title) @@ -1241,6 +1235,7 @@ fun WallpaperSetupView( Text(title) Icon(painterResource(MR.images.ic_circle_filled), title, tint = wallpaperTintColor) } + SectionSpacer() } SectionItemViewSpaceBetween({ editColor(ThemeColor.SENT_MESSAGE) }) { 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 9c083682c8..c35a8e9413 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 @@ -24,19 +24,19 @@ fun DeveloperView(withAuth: (title: String, desc: String, block: () -> Unit) -> val developerTools = m.controller.appPrefs.developerTools val devTools = remember { developerTools.state } val unchangedHints = mutableStateOf(unchangedHintPreferences()) - SectionView { + SectionView(card = true) { InstallTerminalAppItem(uriHandler) ChatConsoleItem { withAuth(generalGetString(MR.strings.auth_open_chat_console), generalGetString(MR.strings.auth_log_in_using_credential)) { ModalManager.start.showModalCloseable { TerminalView(false) } } } ResetHintsItem(unchangedHints) SettingsPreferenceItem(painterResource(MR.images.ic_code), stringResource(MR.strings.show_developer_options), developerTools) + SectionTextFooter( + generalGetString(if (devTools.value) MR.strings.show_dev_options else MR.strings.hide_dev_options) + " " + + generalGetString(MR.strings.developer_options) + ) } - SectionTextFooter( - generalGetString(if (devTools.value) MR.strings.show_dev_options else MR.strings.hide_dev_options) + " " + - generalGetString(MR.strings.developer_options) - ) if (devTools.value) { - SectionDividerSpaced() - SectionView(stringResource(MR.strings.developer_options_section)) { + SectionDividerSpaced(maxTopPadding = true) + SectionView(stringResource(MR.strings.developer_options_section), card = true) { SettingsActionItemWithContent(painterResource(MR.images.ic_breaking_news), stringResource(MR.strings.debug_logs)) { DefaultSwitch( checked = remember { appPrefs.logLevel.state }.value <= LogLevel.DEBUG, @@ -59,15 +59,15 @@ fun DeveloperView(withAuth: (title: String, desc: String, block: () -> Unit) -> SettingsPreferenceItem(painterResource(MR.images.ic_avg_pace), stringResource(MR.strings.show_slow_api_calls), appPreferences.showSlowApiCalls) } } - SectionDividerSpaced() - SectionView(stringResource(MR.strings.deprecated_options_section)) { + SectionDividerSpaced(maxTopPadding = true) + SectionView(stringResource(MR.strings.deprecated_options_section), card = true) { val simplexLinkMode = chatModel.controller.appPrefs.simplexLinkMode SimpleXLinkOptions(chatModel.simplexLinkMode, onSelected = { simplexLinkMode.set(it) chatModel.simplexLinkMode.value = it }) + SectionBottomSpacer() } - SectionBottomSpacer() } } 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 3dc038b8dc..55bd796a3b 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 @@ -6,7 +6,6 @@ import SectionItemViewWithoutMinPadding import SectionSpacer import SectionTextFooter import SectionView -import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.runtime.* @@ -57,32 +56,30 @@ private fun HiddenProfileLayout( user: User, saveProfilePassword: (String) -> Unit ) { - Box(Modifier.fillMaxSize().background(MaterialTheme.colors.surface)) { - ColumnWithScrollBar { - AppBarTitle(stringResource(MR.strings.hide_profile)) - SectionView(contentPadding = PaddingValues(start = 8.dp, end = DEFAULT_PADDING)) { - UserProfileRow(user) - } - SectionSpacer() - - val hidePassword = rememberSaveable { mutableStateOf("") } - val confirmHidePassword = rememberSaveable { mutableStateOf("") } - val passwordValid by remember { derivedStateOf { hidePassword.value == hidePassword.value.trim() } } - val confirmValid by remember { derivedStateOf { confirmHidePassword.value == "" || hidePassword.value == confirmHidePassword.value } } - val saveDisabled by remember { derivedStateOf { hidePassword.value == "" || !passwordValid || confirmHidePassword.value == "" || !confirmValid } } - SectionView(stringResource(MR.strings.hidden_profile_password)) { - SectionItemViewWithoutMinPadding { - PassphraseField(hidePassword, generalGetString(MR.strings.password_to_show), isValid = { passwordValid }, showStrength = true) - } - SectionItemViewWithoutMinPadding { - PassphraseField(confirmHidePassword, stringResource(MR.strings.confirm_password), isValid = { confirmValid }, dependsOn = hidePassword) - } - SectionItemViewSpaceBetween({ saveProfilePassword(hidePassword.value) }, disabled = saveDisabled, minHeight = TextFieldDefaults.MinHeight) { - Text(generalGetString(MR.strings.save_profile_password), color = if (saveDisabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary) - } - } - SectionTextFooter(stringResource(MR.strings.to_reveal_profile_enter_password)) - SectionBottomSpacer() + ColumnWithScrollBar { + AppBarTitle(stringResource(MR.strings.hide_profile)) + SectionView(contentPadding = PaddingValues(start = 8.dp, end = DEFAULT_PADDING)) { + UserProfileRow(user) } + SectionSpacer() + + val hidePassword = rememberSaveable { mutableStateOf("") } + val confirmHidePassword = rememberSaveable { mutableStateOf("") } + val passwordValid by remember { derivedStateOf { hidePassword.value == hidePassword.value.trim() } } + val confirmValid by remember { derivedStateOf { confirmHidePassword.value == "" || hidePassword.value == confirmHidePassword.value } } + val saveDisabled by remember { derivedStateOf { hidePassword.value == "" || !passwordValid || confirmHidePassword.value == "" || !confirmValid } } + SectionView(stringResource(MR.strings.hidden_profile_password).uppercase()) { + SectionItemViewWithoutMinPadding { + PassphraseField(hidePassword, generalGetString(MR.strings.password_to_show), isValid = { passwordValid }, showStrength = true) + } + SectionItemViewWithoutMinPadding { + PassphraseField(confirmHidePassword, stringResource(MR.strings.confirm_password), isValid = { confirmValid }, dependsOn = hidePassword) + } + SectionItemViewSpaceBetween({ saveProfilePassword(hidePassword.value) }, disabled = saveDisabled, minHeight = TextFieldDefaults.MinHeight) { + Text(generalGetString(MR.strings.save_profile_password), color = if (saveDisabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary) + } + } + SectionTextFooter(stringResource(MR.strings.to_reveal_profile_enter_password)) + SectionBottomSpacer() } } 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 e51ab0bddf..32e20cd8a8 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 @@ -55,7 +55,7 @@ fun NotificationsSettingsLayout( ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.notifications)) - SectionView(null) { + SectionView(null, card = true) { if (appPlatform == AppPlatform.ANDROID) { SettingsActionItemWithContent(null, stringResource(MR.strings.settings_notifications_mode_title), { showPage(CurrentPage.NOTIFICATIONS_MODE) }) { Text( @@ -74,9 +74,9 @@ fun NotificationsSettingsLayout( color = MaterialTheme.colors.secondary ) } - } - if (platform.androidIsXiaomiDevice() && (notificationsMode.value == NotificationsMode.PERIODIC || notificationsMode.value == NotificationsMode.SERVICE)) { - SectionTextFooter(annotatedStringResource(MR.strings.xiaomi_ignore_battery_optimization)) + if (platform.androidIsXiaomiDevice() && (notificationsMode.value == NotificationsMode.PERIODIC || notificationsMode.value == NotificationsMode.SERVICE)) { + SectionTextFooter(annotatedStringResource(MR.strings.xiaomi_ignore_battery_optimization)) + } } SectionBottomSpacer() } 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 e3170c808b..732e68fc32 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 @@ -81,27 +81,27 @@ private fun PreferencesLayout( onTTLUpdated = onTTLUpdated ) - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) val allowFullDeletion = remember(preferences) { mutableStateOf(preferences.fullDelete.allow) } FeatureSection(ChatFeature.FullDelete, allowFullDeletion) { applyPrefs(preferences.copy(fullDelete = SimpleChatPreference(allow = it))) } - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) val allowReactions = remember(preferences) { mutableStateOf(preferences.reactions.allow) } FeatureSection(ChatFeature.Reactions, allowReactions) { applyPrefs(preferences.copy(reactions = SimpleChatPreference(allow = it))) } - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) val allowVoice = remember(preferences) { mutableStateOf(preferences.voice.allow) } FeatureSection(ChatFeature.Voice, allowVoice) { applyPrefs(preferences.copy(voice = SimpleChatPreference(allow = it))) } - SectionDividerSpaced() + SectionDividerSpaced(true, maxBottomPadding = false) val allowCalls = remember(preferences) { mutableStateOf(preferences.calls.allow) } FeatureSection(ChatFeature.Calls, allowCalls) { applyPrefs(preferences.copy(calls = SimpleChatPreference(allow = it))) } - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false) ResetSaveButtons( reset = reset, save = savePrefs, @@ -113,7 +113,7 @@ private fun PreferencesLayout( @Composable private fun FeatureSection(feature: ChatFeature, allowFeature: State, onSelected: (FeatureAllowed) -> Unit) { - SectionView { + SectionView(card = true) { ExposedDropDownSettingRow( feature.text, FeatureAllowed.values().map { it to it.text }, @@ -133,7 +133,7 @@ private fun TimedMessagesFeatureSection( onTTLUpdated: (Int?) -> Unit ) { val ttl = rememberSaveable(preferences) { mutableStateOf(preferences.timedMessages.ttl) } - SectionView { + SectionView(card = true) { PreferenceToggleWithIcon( ChatFeature.TimedMessages.text, ChatFeature.TimedMessages.icon, @@ -163,7 +163,7 @@ private fun TimedMessagesFeatureSection( @Composable private fun ResetSaveButtons(reset: () -> Unit, save: () -> Unit, disabled: Boolean) { - SectionView { + SectionView(card = true) { SectionItemView(reset, disabled = disabled) { Text(stringResource(MR.strings.reset_verb), color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary) } 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 454072a0d7..b1b0786956 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 @@ -60,7 +60,7 @@ fun PrivacySettingsView( PrivacyDeviceSection(showSettingsModal, setPerformLA) SectionDividerSpaced() - SectionView(stringResource(MR.strings.settings_section_title_chats)) { + SectionView(stringResource(MR.strings.settings_section_title_chats), card = true) { SettingsPreferenceItem( painterResource(MR.images.ic_travel_explore), stringResource(MR.strings.send_link_previews), @@ -93,7 +93,7 @@ fun PrivacySettingsView( } SectionDividerSpaced() - SectionView(stringResource(MR.strings.settings_section_title_files)) { + SectionView(stringResource(MR.strings.settings_section_title_files), card = true) { SettingsPreferenceItem(painterResource(MR.images.ic_lock), stringResource(MR.strings.encrypt_local_files), chatModel.controller.appPrefs.privacyEncryptLocalFiles, onChange = { enable -> withBGApi { chatModel.controller.apiSetEncryptLocalFiles(enable) } }) @@ -171,7 +171,7 @@ fun PrivacySettingsView( } if (!chatModel.desktopNoUserNoRemote) { - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) ContacRequestsFromGroupsSection( currentUser = currentUser, setAutoAcceptGrpDirectInvs = { enable -> @@ -179,7 +179,7 @@ fun PrivacySettingsView( } ) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) DeliveryReceiptsSection( currentUser = currentUser, setOrAskSendReceiptsContacts = { enable -> @@ -277,7 +277,7 @@ private fun ContacRequestsFromGroupsSection( currentUser: User, setAutoAcceptGrpDirectInvs: (Boolean) -> Unit ) { - SectionView(stringResource(MR.strings.settings_section_title_contact_requests_from_groups)) { + SectionView(stringResource(MR.strings.settings_section_title_contact_requests_from_groups), card = true) { SettingsActionItemWithContent(painterResource(MR.images.ic_check), stringResource(MR.strings.auto_accept_contact)) { DefaultSwitch( checked = currentUser.autoAcceptMemberContacts, @@ -306,7 +306,7 @@ private fun DeliveryReceiptsSection( setOrAskSendReceiptsContacts: (Boolean) -> Unit, setOrAskSendReceiptsGroups: (Boolean) -> Unit, ) { - SectionView(stringResource(MR.strings.settings_section_title_delivery_receipts)) { + SectionView(stringResource(MR.strings.settings_section_title_delivery_receipts), card = true) { SettingsActionItemWithContent(painterResource(MR.images.ic_person), stringResource(MR.strings.receipts_section_contacts)) { DefaultSwitch( checked = currentUser.sendRcptsContacts, @@ -562,7 +562,7 @@ fun SimplexLockView( ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.chat_lock)) - SectionView { + SectionView(card = true) { EnableLock(remember { appPrefs.performLA.state }) { performLAToggle -> showAuthScreen.value = performLAToggle chatModel.controller.appPrefs.laNoticeShown.set(true) @@ -619,7 +619,7 @@ fun SimplexLockView( } if (performLA.value && laMode.value == LAMode.PASSCODE) { SectionDividerSpaced() - SectionView(stringResource(MR.strings.self_destruct_passcode)) { + SectionView(stringResource(MR.strings.self_destruct_passcode), card = true) { val openInfo = { ModalManager.start.showModal { SelfDestructInfoView() 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 4e93d4422a..0c31b062dd 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 @@ -2,7 +2,6 @@ package chat.simplex.common.views.usersettings import SectionBottomSpacer import SectionItemViewSpaceBetween -import SectionView import androidx.compose.runtime.Composable import androidx.compose.foundation.* import androidx.compose.foundation.layout.* @@ -102,21 +101,20 @@ fun RTCServersLayout( ) { ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.your_ICE_servers)) - SectionView { - SectionItemViewSpaceBetween { - Text(stringResource(MR.strings.configure_ICE_servers), Modifier.padding(end = 24.dp)) - DefaultSwitch( - checked = isUserRTCServers, - onCheckedChange = isUserRTCServersOnOff, - ) - } - } Column( Modifier .fillMaxWidth() .padding(horizontal = DEFAULT_PADDING), verticalArrangement = Arrangement.spacedBy(8.dp) ) { + SectionItemViewSpaceBetween(padding = PaddingValues()) { + Text(stringResource(MR.strings.configure_ICE_servers), Modifier.padding(end = 24.dp)) + DefaultSwitch( + checked = isUserRTCServers, + onCheckedChange = isUserRTCServersOnOff, + ) + } + if (!isUserRTCServers) { Text(stringResource(MR.strings.using_simplex_chat_servers), lineHeight = 22.sp) } else { 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 a27f607e6a..bd9996382b 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 @@ -1,6 +1,5 @@ package chat.simplex.common.views.usersettings -import CARD_ITEM_PADDING import SectionBottomSpacer import SectionDividerSpaced import SectionItemView @@ -101,7 +100,7 @@ fun SettingsLayout( ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.your_settings)) - SectionView(stringResource(MR.strings.settings_section_title_settings)) { + SectionView(stringResource(MR.strings.settings_section_title_settings), card = true) { SettingsActionItem(painterResource(if (notificationsMode.value == NotificationsMode.OFF) MR.images.ic_bolt_off else MR.images.ic_bolt), stringResource(MR.strings.notifications), showSettingsModal { NotificationsSettingsView(it) }, disabled = stopped) SettingsActionItem(painterResource(MR.images.ic_wifi_tethering), stringResource(MR.strings.network_and_servers), showCustomModal { _, close -> NetworkAndServersView(close) }, disabled = stopped) SettingsActionItem(painterResource(MR.images.ic_videocam), stringResource(MR.strings.settings_audio_video_calls), showSettingsModal { CallSettingsView(it, showModal) }, disabled = stopped) @@ -110,14 +109,14 @@ fun SettingsLayout( } SectionDividerSpaced() - SectionView(stringResource(MR.strings.settings_section_title_chat_database)) { + SectionView(stringResource(MR.strings.settings_section_title_chat_database), card = true) { DatabaseItem(encrypted, passphraseSaved, showSettingsModal { DatabaseView() }, stopped) SettingsActionItem(painterResource(MR.images.ic_ios_share), stringResource(MR.strings.migrate_from_device_to_another_device), { withAuth(generalGetString(MR.strings.auth_open_migration_to_another_device), generalGetString(MR.strings.auth_log_in_using_credential)) { ModalManager.fullscreen.showCustomModal { close -> MigrateFromDeviceView(close) } } }, disabled = stopped) } SectionDividerSpaced() - SectionView(stringResource(MR.strings.settings_section_title_help)) { + SectionView(stringResource(MR.strings.settings_section_title_help), card = true) { SettingsActionItem(painterResource(MR.images.ic_help), stringResource(MR.strings.how_to_use_simplex_chat), showModal { HelpView(userDisplayName ?: "") }, disabled = stopped) SettingsActionItem(painterResource(MR.images.ic_add), stringResource(MR.strings.whats_new), showCustomModal { _, close -> WhatsNewView(viaSettings = true, close = close) }, disabled = stopped) SettingsActionItem(painterResource(MR.images.ic_info), stringResource(MR.strings.about_simplex_chat), showModal { SimpleXInfo(it, onboarding = false) }) @@ -128,7 +127,7 @@ fun SettingsLayout( } SectionDividerSpaced() - SectionView(stringResource(MR.strings.settings_section_title_support)) { + SectionView(stringResource(MR.strings.settings_section_title_support), card = true) { if (!BuildConfigCommon.ANDROID_BUNDLE) { ContributeItem(uriHandler) } @@ -349,9 +348,9 @@ fun SettingsActionItemWithContent(icon: Painter?, text: String? = null, click: ( click, extraPadding = extraPadding, padding = if (extraPadding && icon != null) - PaddingValues(start = DEFAULT_PADDING * 1.7f, end = CARD_ITEM_PADDING) + PaddingValues(start = DEFAULT_PADDING * 1.7f, end = DEFAULT_PADDING) else - PaddingValues(horizontal = CARD_ITEM_PADDING), + PaddingValues(horizontal = DEFAULT_PADDING), disabled = disabled ) { if (icon != null) { 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 1e87864c0c..e3b72d6f33 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 @@ -301,17 +301,17 @@ private fun UserAddressLayout( ) { if (userAddress == null) { if (!onboarding) { - SectionView(generalGetString(MR.strings.for_social_media)) { + SectionView(generalGetString(MR.strings.for_social_media), card = true) { CreateAddressButton(createAddress) } SectionDividerSpaced() - SectionView(generalGetString(MR.strings.or_to_share_privately)) { + SectionView(generalGetString(MR.strings.or_to_share_privately), card = true) { CreateOneTimeLinkButton() } - SectionDividerSpaced() - SectionView { + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false) + SectionView(card = true) { LearnMoreButton(learnMore) } } @@ -336,7 +336,7 @@ private fun UserAddressLayout( val savedAddressSettingsState = remember { mutableStateOf(addressSettingsState.value) } SectionViewWithButton( - stringResource(MR.strings.for_social_media), + stringResource(MR.strings.for_social_media).uppercase(), titleButton = if (userAddress.connLinkContact.connShortLink != null) {{ ToggleShortLinkButton(showShortLink) }} else null ) { SimpleXCreatedLinkQRCode(userAddress.connLinkContact, short = showShortLink.value) @@ -359,20 +359,20 @@ private fun UserAddressLayout( } } - SectionDividerSpaced() - SectionView(generalGetString(MR.strings.or_to_share_privately)) { + SectionDividerSpaced(maxTopPadding = addressSettingsState.value.businessAddress) + SectionView(generalGetString(MR.strings.or_to_share_privately), card = true) { CreateOneTimeLinkButton() } SectionDividerSpaced(maxBottomPadding = false) - SectionView { + SectionView(card = true) { LearnMoreButton(learnMore) } SectionDividerSpaced(maxBottomPadding = false) - SectionView { + SectionView(card = true) { DeleteAddressButton(deleteAddress) + SectionTextFooter(stringResource(MR.strings.your_contacts_will_remain_connected)) } - SectionTextFooter(stringResource(MR.strings.your_contacts_will_remain_connected)) } } } @@ -503,7 +503,7 @@ private fun ModalData.UserAddressSettings( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.SpaceEvenly ) { - SectionView { + SectionView(card = true) { ShareWithContactsButton(shareViaProfile, setProfileAddress) AutoAcceptToggle(addressSettingsState) { saveAddressSettings(addressSettingsState.value, savedAddressSettingsState) } if (addressSettingsState.value.autoAccept && !chatModel.addressShortLinkDataSet() && !addressSettingsState.value.businessAddress) { @@ -512,18 +512,13 @@ private fun ModalData.UserAddressSettings( } SectionDividerSpaced() - SectionView( - stringResource(MR.strings.address_welcome_message), - contentPadding = PaddingValues(vertical = DEFAULT_PADDING_HALF), - ) { + SectionView(stringResource(MR.strings.address_welcome_message), card = true) { AutoReplyEditor(addressSettingsState) } - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false) - SectionView { - saveAddressSettingsButton(addressSettingsState.value == savedAddressSettingsState.value) { - saveAddressSettings(addressSettingsState.value, savedAddressSettingsState) - } + saveAddressSettingsButton(addressSettingsState.value == savedAddressSettingsState.value) { + saveAddressSettings(addressSettingsState.value, savedAddressSettingsState) } } } 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 0a8c55ffd0..45cdee6108 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,7 +98,7 @@ fun UserProfileLayout( showUnsavedChangesAlert({ saveProfile(displayName.value, fullName.value, shortDescr.value, profileImage.value) }, close) } } - ModalView(close = closeWithAlert, background = MaterialTheme.colors.surface) { + ModalView(close = closeWithAlert) { ColumnWithScrollBar( Modifier .padding(horizontal = DEFAULT_PADDING), 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 28cabb6a22..ac21fb6b23 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 @@ -1,14 +1,12 @@ package chat.simplex.common.views.usersettings import SectionBottomSpacer -import SectionDivider import SectionItemView import SectionItemViewSpaceBetween import SectionItemViewWithoutMinPadding import SectionSpacer import SectionTextFooter import SectionView -import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.material.* import androidx.compose.runtime.* @@ -164,16 +162,18 @@ private fun UserProfilesLayout( unmuteUser: (User) -> Unit, showHiddenProfile: (User) -> Unit, ) { - Box(Modifier.fillMaxSize().background(MaterialTheme.colors.surface)) { - ColumnWithScrollBar { - if (profileHidden.value) { + ColumnWithScrollBar { + if (profileHidden.value) { + SectionView { SettingsActionItem(painterResource(MR.images.ic_lock_open_right), stringResource(MR.strings.enter_password_to_show), click = { profileHidden.value = false }) - SectionSpacer() } - AppBarTitle(stringResource(MR.strings.your_chat_profiles), hostDevice(remember { chatModel.remoteHostId() })) + SectionSpacer() + } + AppBarTitle(stringResource(MR.strings.your_chat_profiles), hostDevice(remember { chatModel.remoteHostId() })) + SectionView { for (user in filteredUsers) { UserView(user, visibleUsersCount, activateUser, removeUser, unhideUser, muteUser, unmuteUser, showHiddenProfile) Divider(Modifier.padding(horizontal = 8.dp)) @@ -185,22 +185,22 @@ private fun UserProfilesLayout( Text(stringResource(MR.strings.users_add), color = MaterialTheme.colors.primary) } } - SectionTextFooter(stringResource(MR.strings.tap_to_activate_profile)) - LaunchedEffect(Unit) { - if (showHiddenProfilesNotice.state.value && users.size > 1) { - AlertManager.shared.showAlertDialog( - title = generalGetString(MR.strings.make_profile_private), - text = generalGetString(MR.strings.you_can_hide_or_mute_user_profile), - confirmText = generalGetString(MR.strings.ok), - dismissText = generalGetString(MR.strings.dont_show_again), - onDismiss = { - showHiddenProfilesNotice.set(false) - }, - ) - } - } - SectionBottomSpacer() } + SectionTextFooter(stringResource(MR.strings.tap_to_activate_profile)) + LaunchedEffect(Unit) { + if (showHiddenProfilesNotice.state.value && users.size > 1) { + AlertManager.shared.showAlertDialog( + title = generalGetString(MR.strings.make_profile_private), + text = generalGetString(MR.strings.you_can_hide_or_mute_user_profile), + confirmText = generalGetString(MR.strings.ok), + dismissText = generalGetString(MR.strings.dont_show_again), + onDismiss = { + showHiddenProfilesNotice.set(false) + }, + ) + } + } + SectionBottomSpacer() } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/VersionInfoView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/VersionInfoView.kt index c70c49ce67..52addd146b 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/VersionInfoView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/VersionInfoView.kt @@ -1,9 +1,6 @@ package chat.simplex.common.views.usersettings -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -19,7 +16,7 @@ import chat.simplex.res.MR @Composable fun VersionInfoView(info: CoreVersionInfo) { ColumnWithScrollBar( - Modifier.fillMaxSize().background(MaterialTheme.colors.surface).padding(horizontal = DEFAULT_PADDING), + Modifier.padding(horizontal = DEFAULT_PADDING), ) { AppBarTitle(stringResource(MR.strings.app_version_title), withPadding = false) if (appPlatform.isAndroid) { diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/AdvancedNetworkSettings.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/AdvancedNetworkSettings.kt index 43a15d79ea..a92a32bc81 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/AdvancedNetworkSettings.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/AdvancedNetworkSettings.kt @@ -228,19 +228,19 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (@Composable ModalData.() - AppBarTitle(stringResource(MR.strings.network_settings_title)) if (currentRemoteHost == null) { - SectionView(generalGetString(MR.strings.settings_section_title_private_message_routing)) { + SectionView(generalGetString(MR.strings.settings_section_title_private_message_routing), card = true) { SMPProxyModePicker(smpProxyMode, showModal, updateSMPProxyMode) SMPProxyFallbackPicker(smpProxyFallback, showModal, updateSMPProxyFallback, enabled = remember { derivedStateOf { smpProxyMode.value != SMPProxyMode.Never } }) SettingsPreferenceItem(painterResource(MR.images.ic_arrow_forward), stringResource(MR.strings.private_routing_show_message_status), chatModel.controller.appPrefs.showSentViaProxy) } SectionTextFooter(stringResource(MR.strings.private_routing_explanation)) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) - SectionView(stringResource(MR.strings.network_session_mode_transport_isolation)) { + SectionView(stringResource(MR.strings.network_session_mode_transport_isolation), card = true) { SessionModePicker(sessionMode, showModal, updateSessionMode) } SectionDividerSpaced() - SectionView(stringResource(MR.strings.network_smp_web_port_section_title)) { + SectionView(stringResource(MR.strings.network_smp_web_port_section_title), card = true) { ExposedDropDownSettingRow( stringResource(MR.strings.network_smp_web_port_toggle), SMPWebPortServers.entries.map { it to stringResource(it.text) }, @@ -251,9 +251,9 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (@Composable ModalData.() - if (smpWebPortServers.value == SMPWebPortServers.Preset) stringResource(MR.strings.network_smp_web_port_preset_footer) else String.format(stringResource(MR.strings.network_smp_web_port_footer), if (smpWebPortServers.value == SMPWebPortServers.All) "443" else "5223") ) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) - SectionView(stringResource(MR.strings.network_option_tcp_connection)) { + SectionView(stringResource(MR.strings.network_option_tcp_connection), card = true) { SectionItemView { TimeoutSettingRow( stringResource(MR.strings.network_option_tcp_connection_timeout), networkTCPConnectTimeoutInteractive, @@ -332,7 +332,7 @@ fun ModalData.AdvancedNetworkSettingsView(showModal: (@Composable ModalData.() - SectionDividerSpaced(maxBottomPadding = false) - SectionView { + SectionView(card = true) { SectionItemView(reset, disabled = resetDisabled) { Text(stringResource(MR.strings.network_options_reset_to_defaults), color = if (resetDisabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary) } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ChatRelayView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ChatRelayView.kt index 32faf21bef..1c68e780dc 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ChatRelayView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ChatRelayView.kt @@ -182,7 +182,7 @@ private fun ChatRelayLayout( @Composable private fun PresetRelay(relay: MutableState, testing: MutableState) { - SectionView(stringResource(MR.strings.preset_relay_address)) { + SectionView(stringResource(MR.strings.preset_relay_address).uppercase()) { SelectionContainer { Text( relay.value.address, @@ -192,7 +192,7 @@ private fun PresetRelay(relay: MutableState, testing: MutableStat } } SectionDividerSpaced() - SectionView(stringResource(MR.strings.preset_relay_name)) { + SectionView(stringResource(MR.strings.preset_relay_name).uppercase()) { SectionItemView { Text(relay.value.displayName) } @@ -229,7 +229,7 @@ private fun CustomRelay( } SectionView( - stringResource(MR.strings.your_relay_address), + stringResource(MR.strings.your_relay_address).uppercase(), icon = painterResource(MR.images.ic_error), iconTint = if (!validAddress.value) MaterialTheme.colors.error else Color.Transparent, ) { @@ -238,13 +238,13 @@ private fun CustomRelay( Modifier.height(144.dp) ) } - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) Column { val iconSize = with(LocalDensity.current) { 21.sp.toDp() } Row(Modifier.padding(start = DEFAULT_PADDING, bottom = 5.dp), verticalAlignment = Alignment.CenterVertically) { Text( - stringResource(MR.strings.your_relay_name), + stringResource(MR.strings.your_relay_name).uppercase(), color = MaterialTheme.colors.secondary, style = MaterialTheme.typography.body2, fontSize = 12.sp ) IconButton( @@ -270,7 +270,7 @@ private fun CustomRelay( if (relay.value.tested != true) { SectionTextFooter(annotatedStringResource(MR.strings.test_relay_to_retrieve_name)) } - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) UseRelaySection(relay, validAddress.value, testing) @@ -291,7 +291,7 @@ private fun UseRelaySection( testing: MutableState ) { val scope = rememberCoroutineScope() - SectionView(stringResource(MR.strings.use_relay)) { + SectionView(stringResource(MR.strings.use_relay).uppercase()) { SectionItemViewSpaceBetween( click = { testing.value = true @@ -377,7 +377,7 @@ fun ModalData.NewChatRelayView( ModalView(close = { addChatRelay(relayToEdit.value, userServers, serverErrors, serverWarnings, rhId, close) - }, background = MaterialTheme.colors.surface) { + }) { NewChatRelayLayout(relayToEdit) } } diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NetworkAndServers.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NetworkAndServers.kt index b5adf74d6a..954183de99 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NetworkAndServers.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NetworkAndServers.kt @@ -22,7 +22,6 @@ import androidx.compose.ui.text.* import androidx.compose.ui.text.input.* import androidx.compose.desktop.ui.tooling.preview.Preview import androidx.compose.foundation.Image -import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.shape.CircleShape import androidx.compose.ui.draw.clip @@ -211,13 +210,13 @@ fun ModalData.NetworkAndServersView(closeNetworkAndServers: () -> Unit) { AppBarTitle(stringResource(MR.strings.network_and_servers)) // TODO: Review this and socks. if (!chatModel.desktopNoUserNoRemote) { - SectionView(generalGetString(MR.strings.network_preset_servers_title)) { + SectionView(generalGetString(MR.strings.network_preset_servers_title), card = true) { userServers.value.forEachIndexed { index, srv -> srv.operator?.let { ServerOperatorRow(index, it, currUserServers, userServers, serverErrors, serverWarnings, currentRemoteHost?.remoteHostId) } } - if (conditionsAction != null && anyOperatorEnabled.value) { - ConditionsButton(conditionsAction, rhId = currentRemoteHost?.remoteHostId) - } + } + if (conditionsAction != null && anyOperatorEnabled.value) { + ConditionsButton(conditionsAction, rhId = currentRemoteHost?.remoteHostId) } val footerText = if (conditionsAction is UsageConditionsAction.Review && conditionsAction.deadline != null && anyOperatorEnabled.value) { String.format(generalGetString(MR.strings.operator_conditions_will_be_accepted_on), localDate(conditionsAction.deadline)) @@ -229,7 +228,7 @@ fun ModalData.NetworkAndServersView(closeNetworkAndServers: () -> Unit) { SectionDividerSpaced() } - SectionView(generalGetString(MR.strings.settings_section_title_messages)) { + SectionView(generalGetString(MR.strings.settings_section_title_messages), card = true) { val nullOperatorIndex = userServers.value.indexOfFirst { it.operator == null } if (nullOperatorIndex != -1) { @@ -263,25 +262,21 @@ fun ModalData.NetworkAndServersView(closeNetworkAndServers: () -> Unit) { UseSocksProxySwitch(networkUseSocksProxy, toggleSocksProxy) SettingsActionItem(painterResource(MR.images.ic_settings_ethernet), stringResource(MR.strings.network_socks_proxy_settings), { showCustomModal { SocksProxySettings(networkUseSocksProxy.value, appPrefs.networkProxy, onionHosts, sessionMode = appPrefs.networkSessionMode.get(), false, it) } }) SettingsActionItem(painterResource(MR.images.ic_cable), stringResource(MR.strings.network_settings), { ModalManager.start.showCustomModal { AdvancedNetworkSettingsView(showModal, it) } }) - } - } - if (currentRemoteHost == null) { - if (networkUseSocksProxy.value) { - SectionTextFooter(annotatedStringResource(MR.strings.socks_proxy_setting_limitations)) - SectionDividerSpaced() - } else { - SectionDividerSpaced(maxBottomPadding = false) + if (networkUseSocksProxy.value) { + SectionTextFooter(annotatedStringResource(MR.strings.socks_proxy_setting_limitations)) + SectionDividerSpaced(maxTopPadding = true) + } else { + SectionDividerSpaced(maxBottomPadding = false) + } } } val saveDisabled = !serversCanBeSaved(currUserServers.value, userServers.value, serverErrors.value) - SectionView { - SectionItemView( - { scope.launch { saveServers(rhId = currentRemoteHost?.remoteHostId, currUserServers, userServers) } }, - disabled = saveDisabled, - ) { - Text(stringResource(MR.strings.smp_servers_save), color = if (!saveDisabled) MaterialTheme.colors.onBackground else MaterialTheme.colors.secondary) - } + SectionItemView( + { scope.launch { saveServers(rhId = currentRemoteHost?.remoteHostId, currUserServers, userServers) } }, + disabled = saveDisabled, + ) { + Text(stringResource(MR.strings.smp_servers_save), color = if (!saveDisabled) MaterialTheme.colors.onBackground else MaterialTheme.colors.secondary) } val serversErr = globalServersError(serverErrors.value) if (serversErr != null) { @@ -302,13 +297,13 @@ fun ModalData.NetworkAndServersView(closeNetworkAndServers: () -> Unit) { SectionDividerSpaced() - SectionView(generalGetString(MR.strings.settings_section_title_calls)) { + SectionView(generalGetString(MR.strings.settings_section_title_calls), card = true) { SettingsActionItem(painterResource(MR.images.ic_electrical_services), stringResource(MR.strings.webrtc_ice_servers), { ModalManager.start.showModal { RTCServersView(m) } }) } if (appPlatform.isAndroid) { SectionDividerSpaced() - SectionView(generalGetString(MR.strings.settings_section_title_network_connection)) { + SectionView(generalGetString(MR.strings.settings_section_title_network_connection), card = true) { val info = remember { chatModel.networkInfo }.value SettingsActionItemWithContent(icon = null, info.networkType.text) { Icon(painterResource(MR.images.ic_circle_filled), stringResource(MR.strings.icon_descr_server_status_connected), tint = if (info.online) Color.Green else MaterialTheme.colors.error) @@ -340,10 +335,23 @@ fun UseSocksProxySwitch( networkUseSocksProxy: MutableState, toggleSocksProxy: (Boolean) -> Unit, ) { - SettingsActionItemWithContent( - icon = painterResource(MR.images.ic_settings_ethernet), - text = stringResource(MR.strings.network_socks_toggle_use_socks_proxy), + Row( + Modifier.fillMaxWidth().padding(end = DEFAULT_PADDING), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween ) { + Row( + Modifier.weight(1f).padding(horizontal = DEFAULT_PADDING), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + painterResource(MR.images.ic_settings_ethernet), + stringResource(MR.strings.network_socks_toggle_use_socks_proxy), + tint = MaterialTheme.colors.secondary + ) + TextIconSpaced(false) + Text(generalGetString(MR.strings.network_socks_toggle_use_socks_proxy)) + } DefaultSwitch( checked = networkUseSocksProxy.value, onCheckedChange = toggleSocksProxy, @@ -461,7 +469,7 @@ fun SocksProxySettings( ) { ColumnWithScrollBar { AppBarTitle(generalGetString(MR.strings.network_socks_proxy_settings)) - SectionView(stringResource(MR.strings.network_socks_proxy)) { + SectionView(stringResource(MR.strings.network_socks_proxy), card = true) { Column(Modifier.padding(horizontal = DEFAULT_PADDING)) { DefaultConfigurableTextField( hostUnsaved, @@ -484,13 +492,12 @@ fun SocksProxySettings( UseOnionHosts(onionHosts, rememberUpdatedState(networkUseSocksProxy && proxyAuthRandomUnsaved.value)) { onionHosts.value = it } + SectionTextFooter(annotatedStringResource(MR.strings.disable_onion_hosts_when_not_supported)) } - UseOnionHostsDescription(onionHosts) - SectionTextFooter(annotatedStringResource(MR.strings.disable_onion_hosts_when_not_supported)) - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) - SectionView(stringResource(MR.strings.network_proxy_auth)) { + SectionView(stringResource(MR.strings.network_proxy_auth), card = true) { PreferenceToggle( stringResource(MR.strings.network_proxy_random_credentials), checked = proxyAuthRandomUnsaved.value, @@ -516,12 +523,12 @@ fun SocksProxySettings( ) } } + SectionTextFooter(proxyAuthFooter(usernameUnsaved.value.text, passwordUnsaved.value.text, proxyAuthModeUnsaved.value, sessionMode)) } - SectionTextFooter(proxyAuthFooter(usernameUnsaved.value.text, passwordUnsaved.value.text, proxyAuthModeUnsaved.value, sessionMode)) - SectionDividerSpaced() + SectionDividerSpaced(maxBottomPadding = false, maxTopPadding = true) - SectionView { + SectionView(card = true) { SectionItemView({ hostUnsaved.value = hostUnsaved.value.copy("localhost", TextRange(9)) portUnsaved.value = portUnsaved.value.copy("9050", TextRange(4)) @@ -560,8 +567,13 @@ private fun showUnsavedSocksHostPortAlert(confirmText: String, save: () -> Unit, ) } -private val onionHostsValues: List> - @Composable get() = remember { +@Composable +fun UseOnionHosts( + onionHosts: MutableState, + enabled: State, + useOnion: (OnionHosts) -> Unit, +) { + val values = remember { OnionHosts.values().map { when (it) { OnionHosts.NEVER -> ValueTitleDesc(OnionHosts.NEVER, generalGetString(MR.strings.network_use_onion_hosts_no), AnnotatedString(generalGetString(MR.strings.network_use_onion_hosts_no_desc))) @@ -571,39 +583,31 @@ private val onionHostsValues: List> } } -@Composable -fun UseOnionHosts( - onionHosts: MutableState, - enabled: State, - useOnion: (OnionHosts) -> Unit, -) { - if (enabled.value) { - ExposedDropDownSettingRow( - generalGetString(MR.strings.network_use_onion_hosts), - onionHostsValues.map { it.value to it.title }, - onionHosts, - icon = painterResource(MR.images.ic_security), - enabled = enabled, - onSelected = useOnion - ) - } else { - // In reality, when socks proxy is disabled, this option acts like NEVER regardless of what was chosen before - ExposedDropDownSettingRow( - generalGetString(MR.strings.network_use_onion_hosts), - listOf(OnionHosts.NEVER to generalGetString(MR.strings.network_use_onion_hosts_no)), - remember { mutableStateOf(OnionHosts.NEVER) }, - icon = painterResource(MR.images.ic_security), - enabled = enabled, - onSelected = {} - ) + Column { + if (enabled.value) { + ExposedDropDownSettingRow( + generalGetString(MR.strings.network_use_onion_hosts), + values.map { it.value to it.title }, + onionHosts, + icon = painterResource(MR.images.ic_security), + enabled = enabled, + onSelected = useOnion + ) + } else { + // In reality, when socks proxy is disabled, this option acts like NEVER regardless of what was chosen before + ExposedDropDownSettingRow( + generalGetString(MR.strings.network_use_onion_hosts), + listOf(OnionHosts.NEVER to generalGetString(MR.strings.network_use_onion_hosts_no)), + remember { mutableStateOf(OnionHosts.NEVER) }, + icon = painterResource(MR.images.ic_security), + enabled = enabled, + onSelected = {} + ) + } + SectionTextFooter(values.firstOrNull { it.value == onionHosts.value }?.description ?: AnnotatedString("")) } } -@Composable -fun UseOnionHostsDescription(onionHosts: MutableState) { - SectionTextFooter(onionHostsValues.firstOrNull { it.value == onionHosts.value }?.description ?: AnnotatedString("")) -} - @Composable fun SessionModePicker( sessionMode: MutableState, @@ -778,7 +782,7 @@ fun UsageConditionsView( } } - ColumnWithScrollBar(modifier = Modifier.fillMaxSize().background(MaterialTheme.colors.surface).padding(horizontal = DEFAULT_PADDING)) { + ColumnWithScrollBar(modifier = Modifier.fillMaxSize().padding(horizontal = DEFAULT_PADDING)) { when (val conditionsAction = chatModel.conditions.value.conditionsAction) { is UsageConditionsAction.Review -> { AppBarTitle(stringResource(MR.strings.operator_updated_conditions), enableAlphaChanges = false, withPadding = false, bottomPadding = DEFAULT_PADDING) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NewServerView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NewServerView.kt index 582d2e0169..a3a843d034 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NewServerView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/NewServerView.kt @@ -2,7 +2,6 @@ package chat.simplex.common.views.usersettings.networkAndServers import SectionBottomSpacer import androidx.compose.foundation.layout.* -import androidx.compose.material.MaterialTheme import androidx.compose.runtime.* import dev.icerock.moko.resources.compose.stringResource import chat.simplex.common.model.* @@ -34,7 +33,7 @@ fun ModalData.NewServerView( rhId, close = close ) - }, background = MaterialTheme.colors.surface) { + }) { Box { NewServerLayout( newServer, diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/OperatorView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/OperatorView.kt index e349b2e7da..aae8b0f431 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/OperatorView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/OperatorView.kt @@ -181,7 +181,7 @@ fun OperatorViewLayout( val duplicateHosts = findDuplicateHosts(serverErrors.value) Column { - SectionView(generalGetString(MR.strings.operator)) { + SectionView(generalGetString(MR.strings.operator), card = true) { SectionItemView({ ModalManager.start.showModalCloseable { _ -> OperatorInfoView(operator) } }) { Row( Modifier.fillMaxWidth(), @@ -238,7 +238,7 @@ fun OperatorViewLayout( if (userServers.value[operatorIndex].chatRelays.any { !it.deleted }) { val duplicateRelayAddresses = findDuplicateRelayAddresses(serverErrors.value) SectionDividerSpaced() - SectionView(generalGetString(MR.strings.chat_relays)) { + SectionView(generalGetString(MR.strings.chat_relays), card = true) { userServers.value[operatorIndex].chatRelays.forEachIndexed { index, relay -> if (!relay.deleted) { ChatRelayViewLink(relay, duplicateRelayAddresses) { @@ -252,7 +252,7 @@ fun OperatorViewLayout( if (userServers.value[operatorIndex].smpServers.any { !it.deleted }) { SectionDividerSpaced() - SectionView(generalGetString(MR.strings.operator_use_for_messages)) { + SectionView(generalGetString(MR.strings.operator_use_for_messages), card = true) { SectionItemView(padding = PaddingValues(horizontal = DEFAULT_PADDING)) { Text( stringResource(MR.strings.operator_use_for_messages_receiving), @@ -306,7 +306,7 @@ fun OperatorViewLayout( // Preset servers can't be deleted if (userServers.value[operatorIndex].smpServers.any { it.preset }) { SectionDividerSpaced() - SectionView(generalGetString(MR.strings.message_servers)) { + SectionView(generalGetString(MR.strings.message_servers), card = true) { userServers.value[operatorIndex].smpServers.forEachIndexed { i, server -> if (!server.preset) return@forEachIndexed SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.SMP) }) { @@ -340,7 +340,7 @@ fun OperatorViewLayout( if (userServers.value[operatorIndex].smpServers.any { !it.preset && !it.deleted }) { SectionDividerSpaced() - SectionView(generalGetString(MR.strings.operator_added_message_servers)) { + SectionView(generalGetString(MR.strings.operator_added_message_servers), card = true) { userServers.value[operatorIndex].smpServers.forEachIndexed { i, server -> if (server.deleted || server.preset) return@forEachIndexed SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.SMP) }) { @@ -356,7 +356,7 @@ fun OperatorViewLayout( if (userServers.value[operatorIndex].xftpServers.any { !it.deleted }) { SectionDividerSpaced() - SectionView(generalGetString(MR.strings.operator_use_for_files)) { + SectionView(generalGetString(MR.strings.operator_use_for_files), card = true) { SectionItemView(padding = PaddingValues(horizontal = DEFAULT_PADDING)) { Text( stringResource(MR.strings.operator_use_for_sending), @@ -389,7 +389,7 @@ fun OperatorViewLayout( // Preset servers can't be deleted if (userServers.value[operatorIndex].xftpServers.any { it.preset }) { SectionDividerSpaced() - SectionView(generalGetString(MR.strings.media_and_file_servers)) { + SectionView(generalGetString(MR.strings.media_and_file_servers), card = true) { userServers.value[operatorIndex].xftpServers.forEachIndexed { i, server -> if (!server.preset) return@forEachIndexed SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.XFTP) }) { @@ -423,7 +423,7 @@ fun OperatorViewLayout( if (userServers.value[operatorIndex].xftpServers.any { !it.preset && !it.deleted}) { SectionDividerSpaced() - SectionView(generalGetString(MR.strings.operator_added_xftp_servers)) { + SectionView(generalGetString(MR.strings.operator_added_xftp_servers), card = true) { userServers.value[operatorIndex].xftpServers.forEachIndexed { i, server -> if (server.deleted || server.preset) return@forEachIndexed SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.XFTP) }) { @@ -438,7 +438,7 @@ fun OperatorViewLayout( } SectionDividerSpaced() - SectionView { + SectionView(card = true) { TestServersButton( testing = testing, smpServers = userServers.value[operatorIndex].smpServers, @@ -479,7 +479,7 @@ fun OperatorInfoView(serverOperator: ServerOperator) { ColumnWithScrollBar { AppBarTitle(stringResource(MR.strings.operator_info_title)) - SectionView { + SectionView(card = true) { SectionItemView { Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { Image(painterResource(serverOperator.largeLogo), null, Modifier.height(48.dp)) @@ -493,7 +493,7 @@ fun OperatorInfoView(serverOperator: ServerOperator) { SectionDividerSpaced(maxBottomPadding = false) val uriHandler = LocalUriHandler.current - SectionView { + SectionView(card = true) { SectionItemView { Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { serverOperator.info.description.forEach { d -> @@ -508,7 +508,7 @@ fun OperatorInfoView(serverOperator: ServerOperator) { val selfhost = serverOperator.info.selfhost if (selfhost != null) { SectionDividerSpaced(maxBottomPadding = false) - SectionView { + SectionView(card = true) { SectionItemView { val (text, link) = selfhost Text(text, color = MaterialTheme.colors.primary, modifier = Modifier.clickable { uriHandler.openExternalLink(link) }) @@ -645,7 +645,7 @@ private fun SingleOperatorUsageConditionsView( ) } - ColumnWithScrollBar(modifier = Modifier.fillMaxSize().background(MaterialTheme.colors.surface).padding(horizontal = DEFAULT_PADDING)) { + ColumnWithScrollBar(modifier = Modifier.fillMaxSize().padding(horizontal = DEFAULT_PADDING)) { AppBarTitle(String.format(stringResource(MR.strings.use_servers_of_operator_x), operator.tradeName), enableAlphaChanges = false, withPadding = false) if (operator.conditionsAcceptance is ConditionsAcceptance.Accepted) { // In current UI implementation this branch doesn't get shown - as conditions can't be opened from inside operator once accepted diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ProtocolServerView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ProtocolServerView.kt index 9cce9cce62..bf804c60f0 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ProtocolServerView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ProtocolServerView.kt @@ -140,7 +140,7 @@ private fun PresetServer( testing: Boolean, testServer: () -> Unit ) { - SectionView(stringResource(MR.strings.smp_servers_preset_address)) { + SectionView(stringResource(MR.strings.smp_servers_preset_address), card = true) { SelectionContainer { Text( server.value.server, @@ -175,7 +175,7 @@ fun CustomServer( stringResource(MR.strings.smp_servers_your_server_address), icon = painterResource(MR.images.ic_error), iconTint = if (!valid.value) MaterialTheme.colors.error else Color.Transparent, - padding = PaddingValues(vertical = DEFAULT_PADDING_HALF), + card = true, ) { val testedPreviously = remember { mutableMapOf() } TextEditor( @@ -191,13 +191,13 @@ fun CustomServer( } } } - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) UseServerSection(server, valid.value, testing, testServer, onDelete) if (valid.value) { SectionDividerSpaced() - SectionView(stringResource(MR.strings.smp_servers_add_to_another_device)) { + SectionView(stringResource(MR.strings.smp_servers_add_to_another_device), card = true) { QRCode(serverAddress.value, small = true) } } @@ -211,7 +211,7 @@ private fun UseServerSection( testServer: () -> Unit, onDelete: (() -> Unit)? = null, ) { - SectionView(stringResource(MR.strings.smp_servers_use_server)) { + SectionView(stringResource(MR.strings.smp_servers_use_server), card = true) { SectionItemViewSpaceBetween(testServer, disabled = !valid || testing) { Text(stringResource(MR.strings.smp_servers_test_server), color = if (valid && !testing) MaterialTheme.colors.onBackground else MaterialTheme.colors.secondary) ShowTestStatus(server.value) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ProtocolServersView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ProtocolServersView.kt index d3ea8a6726..7bbcaeff72 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ProtocolServersView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/usersettings/networkAndServers/ProtocolServersView.kt @@ -86,7 +86,7 @@ fun YourServersViewLayout( Column { if (userServers.value[operatorIndex].chatRelays.any { !it.deleted }) { val duplicateRelayAddresses = findDuplicateRelayAddresses(serverErrors.value) - SectionView(generalGetString(MR.strings.chat_relays)) { + SectionView(generalGetString(MR.strings.chat_relays), card = true) { userServers.value[operatorIndex].chatRelays.forEachIndexed { i, relay -> if (relay.deleted) return@forEachIndexed ChatRelayViewLink(relay, duplicateRelayAddresses) { @@ -99,7 +99,7 @@ fun YourServersViewLayout( if (userServers.value[operatorIndex].smpServers.any { !it.deleted }) { SectionDividerSpaced() - SectionView(generalGetString(MR.strings.message_servers)) { + SectionView(generalGetString(MR.strings.message_servers), card = true) { userServers.value[operatorIndex].smpServers.forEachIndexed { i, server -> if (server.deleted) return@forEachIndexed SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.SMP) }) { @@ -133,7 +133,7 @@ fun YourServersViewLayout( if (userServers.value[operatorIndex].xftpServers.any { !it.deleted }) { SectionDividerSpaced() - SectionView(generalGetString(MR.strings.media_and_file_servers)) { + SectionView(generalGetString(MR.strings.media_and_file_servers), card = true) { userServers.value[operatorIndex].xftpServers.forEachIndexed { i, server -> if (server.deleted) return@forEachIndexed SectionItemView({ navigateToProtocolView(i, server, ServerProtocol.XFTP) }) { @@ -170,10 +170,10 @@ fun YourServersViewLayout( userServers.value[operatorIndex].xftpServers.any { !it.deleted } || userServers.value[operatorIndex].chatRelays.any { !it.deleted } ) { - SectionDividerSpaced(maxBottomPadding = false) + SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false) } - SectionView { + SectionView(card = true) { SettingsActionItem( painterResource(MR.images.ic_add), stringResource(MR.strings.smp_servers_add), @@ -195,9 +195,9 @@ fun YourServersViewLayout( ServersWarningFooter(serversWarn) } } - SectionDividerSpaced(maxBottomPadding = false) + SectionDividerSpaced(maxTopPadding = false, maxBottomPadding = false) - SectionView { + SectionView(card = true) { TestServersButton( testing = testing, smpServers = userServers.value[operatorIndex].smpServers, diff --git a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.desktop.kt b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.desktop.kt index 2cc154cd61..c875c0c9da 100644 --- a/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.desktop.kt +++ b/apps/multiplatform/common/src/desktopMain/kotlin/chat/simplex/common/views/chatlist/ChatListNavLinkView.desktop.kt @@ -1,7 +1,5 @@ package chat.simplex.common.views.chatlist -import LocalInSectionCard -import SectionDivider import androidx.compose.foundation.* import androidx.compose.foundation.interaction.InteractionSource import androidx.compose.foundation.layout.* @@ -62,8 +60,6 @@ actual fun ChatListNavLinkLayout( } if (selectedChat.value || nextChatSelected.value) { Divider() - } else if (LocalInSectionCard.current) { - SectionDivider() } else { Divider(Modifier.padding(horizontal = 8.dp)) } 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 289e8bf57d..66be736fca 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 @@ -82,10 +82,10 @@ fun AppearanceScope.AppearanceLayout( SectionDividerSpaced() ProfileImageSection() - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) FontScaleSection() - SectionDividerSpaced() + SectionDividerSpaced(maxTopPadding = true) DensityScaleSection() SectionBottomSpacer() @@ -110,8 +110,8 @@ private fun MinimizeToTraySection() { @Composable fun DensityScaleSection() { val localDensityScale = remember { mutableStateOf(appPrefs.densityScale.get()) } - SectionView(stringResource(MR.strings.appearance_zoom), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { - Row(Modifier.padding(vertical = 10.dp), verticalAlignment = Alignment.CenterVertically) { + SectionView(stringResource(MR.strings.appearance_zoom).uppercase(), contentPadding = PaddingValues(horizontal = DEFAULT_PADDING)) { + Row(Modifier.padding(top = 10.dp), verticalAlignment = Alignment.CenterVertically) { Box(Modifier.size(50.dp) .background(MaterialTheme.colors.surface, RoundedCornerShape(percent = 22)) .clip(RoundedCornerShape(percent = 22))