android, desktop: gallery tabs changes (#6570)

* Done:
Tabs layout now looks like link/scan tabs
Changed tab texts with icons and removed text resources
Changed tabs order to match with Telegram: [ Members, Photos, Vides, Files, Links, Voices]
Moved “For console” section to settings
Differentiated Settings to Edit (for owners)  and Info (others), including icons

* conditionally show label text, paddings

---------

Co-authored-by: hayk-space <hayk.nahapetian@space.ge>
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
hayk888997
2026-01-15 16:34:54 +04:00
committed by GitHub
parent 1902fb5da9
commit f58c23eab8
4 changed files with 70 additions and 60 deletions
@@ -41,6 +41,7 @@ import chat.simplex.common.views.helpers.*
import chat.simplex.common.views.usersettings.SettingsActionItem
import chat.simplex.common.views.usersettings.SettingsActionItemWithContent
import chat.simplex.res.MR
import dev.icerock.moko.resources.ImageResource
import dev.icerock.moko.resources.StringResource
import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
@@ -50,9 +51,9 @@ enum class GroupInfoTab {
Members,
Images,
Videos,
Links,
Files,
Voices
Links,
Voice
}
fun LazyListScope.GroupChatInfoTabs(
@@ -73,37 +74,40 @@ fun LazyListScope.GroupChatInfoTabs(
) {
item {
SectionSpacer()
val scrollState = rememberScrollState()
Column {
Row(
Modifier
.fillMaxWidth()
.horizontalScroll(scrollState),
horizontalArrangement = Arrangement.Start
) {
GroupInfoTab.values().forEach { tab ->
Tab(
selected = selectedTab.value == tab,
onClick = { selectedTab.value = tab },
text = { Text(tabTitle(tab), fontSize = 13.sp) },
selectedContentColor = MaterialTheme.colors.primary,
unselectedContentColor = MaterialTheme.colors.secondary,
)
}
TabRow(
modifier = Modifier.padding(top = DEFAULT_PADDING_HALF, bottom = DEFAULT_PADDING),
selectedTabIndex = GroupInfoTab.entries.indexOf(selectedTab.value),
backgroundColor = Color.Transparent,
contentColor = MaterialTheme.colors.primary,
) {
GroupInfoTab.entries.forEachIndexed { index, tab ->
val isSelected = selectedTab.value == tab
LeadingIconTab(
selected = isSelected,
onClick = { selectedTab.value = tab },
text = { Text("") },
icon = {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
painterResource(tabLabel(tab).first),
contentDescription = tab.name,
modifier = Modifier.size(24.dp),
tint = if (isSelected) MaterialTheme.colors.primary else MaterialTheme.colors.secondary
)
// TODO make it conditional on the actual tab count
if (GroupInfoTab.entries.size <= 4) {
Text(generalGetString(tabLabel(tab).second), modifier = Modifier.padding(top = 2.dp, bottom = 6.dp), fontSize = 10.sp, softWrap = false, overflow = TextOverflow.Ellipsis)
}
}
},
selectedContentColor = MaterialTheme.colors.primary,
unselectedContentColor = MaterialTheme.colors.secondary,
)
}
// Simple indicator line
Box(
Modifier
.fillMaxWidth()
.height(2.dp)
.background(MaterialTheme.colors.surface)
)
}
Divider()
SectionSpacer()
}
when (selectedTab.value) {
@@ -125,9 +129,9 @@ fun LazyListScope.GroupChatInfoTabs(
}
GroupInfoTab.Images,
GroupInfoTab.Videos,
GroupInfoTab.Links,
GroupInfoTab.Files,
GroupInfoTab.Voices -> {
GroupInfoTab.Links,
GroupInfoTab.Voice -> {
ContentItemsTab(
filteredChatItems = filteredChatItems,
scrollToItemId = scrollToItemId
@@ -281,14 +285,14 @@ private fun LazyListScope.ContentItemsTab(
@Composable
private fun tabTitle(tab: GroupInfoTab): String {
private fun tabLabel(tab: GroupInfoTab): Pair<ImageResource, StringResource> {
return when (tab) {
GroupInfoTab.Members -> stringResource(MR.strings.group_info_tab_members)
GroupInfoTab.Images -> stringResource(MR.strings.group_info_tab_images)
GroupInfoTab.Videos -> stringResource(MR.strings.group_info_tab_videos)
GroupInfoTab.Links -> stringResource(MR.strings.group_info_tab_links)
GroupInfoTab.Files -> stringResource(MR.strings.group_info_tab_files)
GroupInfoTab.Voices -> stringResource(MR.strings.group_info_tab_voices)
GroupInfoTab.Members -> MR.images.ic_group to MR.strings.group_info_tab_members
GroupInfoTab.Images -> MR.images.ic_image to MR.strings.group_info_tab_images
GroupInfoTab.Videos -> MR.images.ic_videocam to MR.strings.group_info_tab_videos
GroupInfoTab.Voice -> MR.images.ic_mic_filled to MR.strings.group_info_tab_voice
GroupInfoTab.Files -> MR.images.ic_draft to MR.strings.group_info_tab_files
GroupInfoTab.Links -> MR.images.ic_link to MR.strings.group_info_tab_links
}
}
@@ -353,10 +353,11 @@ fun SettingsButton(
groupInfo: GroupInfo,
onClick: () -> Unit
) {
val isOwner = groupInfo.isOwner && groupInfo.businessChat?.chatType == null
InfoViewActionButton(
modifier = modifier,
icon = painterResource(MR.images.ic_settings),
title = generalGetString(MR.strings.icon_descr_settings),
icon = if (isOwner) painterResource(MR.images.ic_edit) else painterResource(MR.images.ic_info),
title = if (isOwner) generalGetString(MR.strings.edit_verb) else generalGetString(MR.strings.info_menu),
disabled = !groupInfo.ready,
disabledLook = !groupInfo.ready,
onClick = onClick
@@ -473,13 +474,13 @@ fun ModalData.GroupChatInfoLayout(
GroupInfoTab.Videos -> chat.chatItems.filter {
it.content.msgContent is MsgContent.MCVideo && it.meta.itemDeleted == null
}
GroupInfoTab.Links -> chat.chatItems.filter {
it.content.msgContent is MsgContent.MCLink && it.meta.itemDeleted == null
}
GroupInfoTab.Files -> chat.chatItems.filter {
it.content.msgContent is MsgContent.MCFile && it.meta.itemDeleted == null
}
GroupInfoTab.Voices -> chat.chatItems.filter {
GroupInfoTab.Links -> chat.chatItems.filter {
it.content.msgContent is MsgContent.MCLink && it.meta.itemDeleted == null
}
GroupInfoTab.Voice -> chat.chatItems.filter {
it.content.msgContent is MsgContent.MCVoice && it.meta.itemDeleted == null
}
}
@@ -570,13 +571,6 @@ fun ModalData.GroupChatInfoLayout(
)
item {
if (developerTools) {
SectionDividerSpaced()
SectionView(title = stringResource(MR.strings.section_title_for_console)) {
InfoRow(stringResource(MR.strings.info_row_local_name), groupInfo.localDisplayName)
InfoRow(stringResource(MR.strings.info_row_database_id), groupInfo.apiId.toString())
}
}
SectionBottomSpacer()
}
}
@@ -1,5 +1,6 @@
package chat.simplex.common.views.chat.group
import InfoRow
import SectionBottomSpacer
import SectionDividerSpaced
import SectionTextFooter
@@ -35,6 +36,7 @@ fun GroupSettingsView(
val groupInfo = c.chatInfo.groupInfo
val currentUser = m.currentUser.value ?: return
val developerTools = m.controller.appPrefs.developerTools.get()
val sendReceipts = remember { mutableStateOf(SendReceipts.fromBool(groupInfo.chatSettings.sendRcpts, currentUser.sendRcptsSmallGroups)) }
val chatItemTTL = rememberSaveable(groupInfo.id) { mutableStateOf(if (groupInfo.chatItemTTL != null) ChatItemTTL.fromSeconds(groupInfo.chatItemTTL) else null) }
@@ -63,6 +65,7 @@ fun GroupSettingsView(
chatItemTTL = chatItemTTL,
setChatItemTTL = ::setChatItemTTL,
deletingItems = deletingItems,
developerTools = developerTools,
editGroupProfile = {
ModalManager.end.showCustomModal { closeModal ->
GroupProfileView(rhId, groupInfo, m, closeModal)
@@ -96,6 +99,7 @@ private fun GroupSettingsLayout(
chatItemTTL: MutableState<ChatItemTTL?>,
setChatItemTTL: (ChatItemTTL?) -> Unit,
deletingItems: MutableState<Boolean>,
developerTools: Boolean,
editGroupProfile: () -> Unit,
addOrEditWelcomeMessage: () -> Unit,
openPreferences: () -> Unit,
@@ -160,6 +164,14 @@ private fun GroupSettingsLayout(
}
}
if (developerTools) {
SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false)
SectionView(title = stringResource(MR.strings.section_title_for_console)) {
InfoRow(stringResource(MR.strings.info_row_local_name), groupInfo.localDisplayName)
InfoRow(stringResource(MR.strings.info_row_database_id), groupInfo.apiId.toString())
}
}
SectionBottomSpacer()
}
}
@@ -1789,12 +1789,12 @@
<string name="button_add_team_members">Add team members</string>
<string name="button_add_friends">Add friends</string>
<string name="group_info_section_title_num_members">%1$s MEMBERS</string>
<string name="group_info_tab_members">MEMBERS</string>
<string name="group_info_tab_images">IMAGES</string>
<string name="group_info_tab_videos">VIDEOS</string>
<string name="group_info_tab_links">LINKS</string>
<string name="group_info_tab_files">FILES</string>
<string name="group_info_tab_voices">VOICES</string>
<string name="group_info_tab_members">Members</string>
<string name="group_info_tab_images">Images</string>
<string name="group_info_tab_videos">Videos</string>
<string name="group_info_tab_links">Links</string>
<string name="group_info_tab_files">Files</string>
<string name="group_info_tab_voice">Voice</string>
<string name="group_info_member_you">you: %1$s</string>
<string name="button_delete_group">Delete group</string>
<string name="button_delete_chat">Delete chat</string>
@@ -2786,4 +2786,4 @@
<!-- GroupMentions.kt -->
<string name="max_group_mentions_per_message_reached">You can mention up to %1$s members per message!</string>
</resources>
</resources>