mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-02 12:06:39 +00:00
ui: channel preferences (#6842)
This commit is contained in:
@@ -157,19 +157,17 @@ struct GroupChatInfoView: View {
|
||||
if groupInfo.groupProfile.description != nil || (groupInfo.isOwner && groupInfo.businessChat == nil) {
|
||||
addOrEditWelcomeMessage()
|
||||
}
|
||||
if !groupInfo.useRelays {
|
||||
GroupPreferencesButton(groupInfo: $groupInfo, preferences: groupInfo.fullGroupPreferences, currentPreferences: groupInfo.fullGroupPreferences)
|
||||
}
|
||||
GroupPreferencesButton(groupInfo: $groupInfo, preferences: groupInfo.fullGroupPreferences, currentPreferences: groupInfo.fullGroupPreferences)
|
||||
} footer: {
|
||||
if !groupInfo.useRelays {
|
||||
let label: LocalizedStringKey = (
|
||||
groupInfo.businessChat == nil
|
||||
? "Only group owners can change group preferences."
|
||||
: "Only chat owners can change preferences."
|
||||
)
|
||||
Text(label)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
let label: LocalizedStringKey = (
|
||||
groupInfo.useRelays
|
||||
? "Only channel owners can change channel preferences."
|
||||
: groupInfo.businessChat == nil
|
||||
? "Only group owners can change group preferences."
|
||||
: "Only chat owners can change preferences."
|
||||
)
|
||||
Text(label)
|
||||
.foregroundColor(theme.colors.secondary)
|
||||
}
|
||||
|
||||
Section {
|
||||
@@ -988,7 +986,9 @@ struct GroupPreferencesButton: View {
|
||||
var creatingGroup: Bool = false
|
||||
|
||||
private var label: LocalizedStringKey {
|
||||
groupInfo.businessChat == nil ? "Group preferences" : "Chat preferences"
|
||||
groupInfo.useRelays ? "Channel preferences"
|
||||
: groupInfo.businessChat == nil ? "Group preferences"
|
||||
: "Chat preferences"
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@@ -1005,7 +1005,9 @@ struct GroupPreferencesButton: View {
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.onDisappear {
|
||||
let saveText = NSLocalizedString(
|
||||
creatingGroup ? "Save" : "Save and notify group members",
|
||||
creatingGroup ? "Save"
|
||||
: groupInfo.useRelays ? "Save and notify subscribers"
|
||||
: "Save and notify group members",
|
||||
comment: "alert button"
|
||||
)
|
||||
|
||||
|
||||
@@ -27,26 +27,33 @@ struct GroupPreferencesView: View {
|
||||
@State private var showSaveDialogue = false
|
||||
|
||||
var body: some View {
|
||||
let saveText: LocalizedStringKey = creatingGroup ? "Save" : "Save and notify group members"
|
||||
let saveText: LocalizedStringKey = creatingGroup ? "Save" : groupInfo.useRelays ? "Save and notify subscribers" : "Save and notify group members"
|
||||
VStack {
|
||||
List {
|
||||
Section {
|
||||
MemberAdmissionButton(
|
||||
groupInfo: $groupInfo,
|
||||
admission: groupInfo.groupProfile.memberAdmission_,
|
||||
currentAdmission: groupInfo.groupProfile.memberAdmission_,
|
||||
creatingGroup: creatingGroup
|
||||
)
|
||||
if !groupInfo.useRelays {
|
||||
Section {
|
||||
MemberAdmissionButton(
|
||||
groupInfo: $groupInfo,
|
||||
admission: groupInfo.groupProfile.memberAdmission_,
|
||||
currentAdmission: groupInfo.groupProfile.memberAdmission_,
|
||||
creatingGroup: creatingGroup
|
||||
)
|
||||
}
|
||||
featureSection(.timedMessages, $preferences.timedMessages.enable)
|
||||
featureSection(.fullDelete, $preferences.fullDelete.enable)
|
||||
featureSection(.directMessages, $preferences.directMessages.enable, $preferences.directMessages.role)
|
||||
featureSection(.reactions, $preferences.reactions.enable)
|
||||
featureSection(.voice, $preferences.voice.enable, $preferences.voice.role)
|
||||
featureSection(.files, $preferences.files.enable, $preferences.files.role)
|
||||
featureSection(.simplexLinks, $preferences.simplexLinks.enable, $preferences.simplexLinks.role)
|
||||
featureSection(.reports, $preferences.reports.enable)
|
||||
featureSection(.history, $preferences.history.enable)
|
||||
} else {
|
||||
featureSection(.timedMessages, $preferences.timedMessages.enable)
|
||||
featureSection(.fullDelete, $preferences.fullDelete.enable)
|
||||
featureSection(.reactions, $preferences.reactions.enable)
|
||||
featureSection(.history, $preferences.history.enable)
|
||||
}
|
||||
featureSection(.timedMessages, $preferences.timedMessages.enable)
|
||||
featureSection(.fullDelete, $preferences.fullDelete.enable)
|
||||
featureSection(.directMessages, $preferences.directMessages.enable, $preferences.directMessages.role)
|
||||
featureSection(.reactions, $preferences.reactions.enable)
|
||||
featureSection(.voice, $preferences.voice.enable, $preferences.voice.role)
|
||||
featureSection(.files, $preferences.files.enable, $preferences.files.role)
|
||||
featureSection(.simplexLinks, $preferences.simplexLinks.enable, $preferences.simplexLinks.role)
|
||||
featureSection(.reports, $preferences.reports.enable)
|
||||
featureSection(.history, $preferences.history.enable)
|
||||
|
||||
if groupInfo.isOwner {
|
||||
Section {
|
||||
|
||||
+15
-20
@@ -599,32 +599,27 @@ fun ModalData.GroupChatInfoLayout(
|
||||
}
|
||||
}
|
||||
}
|
||||
val showEditSection = (groupInfo.isOwner && groupInfo.businessChat?.chatType == null)
|
||||
|| groupInfo.groupProfile.description != null
|
||||
|| !groupInfo.useRelays
|
||||
if (anyTopSectionRowShow) {
|
||||
SectionDividerSpaced(maxBottomPadding = false)
|
||||
}
|
||||
if (showEditSection) {
|
||||
SectionView {
|
||||
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)
|
||||
}
|
||||
if (groupInfo.groupProfile.description != null || (groupInfo.isOwner && groupInfo.businessChat?.chatType == null)) {
|
||||
AddOrEditWelcomeMessage(groupInfo.groupProfile.description, addOrEditWelcomeMessage)
|
||||
}
|
||||
if (!groupInfo.useRelays) {
|
||||
val prefsTitleId = if (groupInfo.businessChat == null) MR.strings.group_preferences else MR.strings.chat_preferences
|
||||
GroupPreferencesButton(prefsTitleId, openPreferences)
|
||||
}
|
||||
SectionView {
|
||||
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)
|
||||
}
|
||||
if (!groupInfo.useRelays) {
|
||||
val footerId = if (groupInfo.businessChat == null) MR.strings.only_group_owners_can_change_prefs else MR.strings.only_chat_owners_can_change_prefs
|
||||
SectionTextFooter(stringResource(footerId))
|
||||
if (groupInfo.groupProfile.description != null || (groupInfo.isOwner && groupInfo.businessChat?.chatType == null)) {
|
||||
AddOrEditWelcomeMessage(groupInfo.groupProfile.description, addOrEditWelcomeMessage)
|
||||
}
|
||||
SectionDividerSpaced(maxTopPadding = true, maxBottomPadding = false)
|
||||
val prefsTitleId = if (groupInfo.useRelays) MR.strings.channel_preferences
|
||||
else if (groupInfo.businessChat == null) MR.strings.group_preferences
|
||||
else MR.strings.chat_preferences
|
||||
GroupPreferencesButton(prefsTitleId, openPreferences)
|
||||
}
|
||||
val footerId = if (groupInfo.useRelays) MR.strings.only_channel_owners_can_change_prefs
|
||||
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(maxTopPadding = true, maxBottomPadding = false)
|
||||
|
||||
SectionView {
|
||||
if (!groupInfo.useRelays) {
|
||||
|
||||
+69
-26
@@ -10,6 +10,7 @@ import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
@@ -56,10 +57,12 @@ fun GroupPreferencesView(m: ChatModel, rhId: Long?, chatId: String, close: () ->
|
||||
afterSave()
|
||||
}
|
||||
}
|
||||
val saveTextId = if (gInfo.useRelays) MR.strings.save_and_notify_channel_subscribers
|
||||
else MR.strings.save_and_notify_group_members
|
||||
ModalView(
|
||||
close = {
|
||||
if (preferences == currentPreferences) close()
|
||||
else showUnsavedChangesAlert({ savePrefs(close) }, close)
|
||||
else showUnsavedChangesAlert({ savePrefs(close) }, close, saveTextId)
|
||||
},
|
||||
) {
|
||||
GroupPreferencesLayout(
|
||||
@@ -97,17 +100,11 @@ private fun GroupPreferencesLayout(
|
||||
savePrefs: () -> Unit,
|
||||
openMemberAdmission: () -> Unit,
|
||||
) {
|
||||
ColumnWithScrollBar {
|
||||
val titleId = if (groupInfo.businessChat == null) MR.strings.group_preferences else MR.strings.chat_preferences
|
||||
AppBarTitle(stringResource(titleId))
|
||||
if (groupInfo.businessChat == null) {
|
||||
MemberAdmissionButton(openMemberAdmission)
|
||||
SectionDividerSpaced(maxBottomPadding = false)
|
||||
}
|
||||
val onTTLUpdated = { ttl: Int? ->
|
||||
applyPrefs(preferences.copy(timedMessages = preferences.timedMessages.copy(ttl = ttl)))
|
||||
}
|
||||
@Composable fun TimedMessagesPreference() {
|
||||
val timedMessages = remember(preferences) { mutableStateOf(preferences.timedMessages.enable) }
|
||||
val onTTLUpdated = { ttl: Int? ->
|
||||
applyPrefs(preferences.copy(timedMessages = preferences.timedMessages.copy(ttl = ttl)))
|
||||
}
|
||||
FeatureSection(GroupFeature.TimedMessages, timedMessages, null, groupInfo, preferences, onTTLUpdated) { enable, _ ->
|
||||
if (enable == GroupFeatureEnabled.ON) {
|
||||
applyPrefs(preferences.copy(timedMessages = TimedMessagesGroupPreference(enable = enable, ttl = preferences.timedMessages.ttl ?: 86400)))
|
||||
@@ -115,58 +112,104 @@ private fun GroupPreferencesLayout(
|
||||
applyPrefs(preferences.copy(timedMessages = TimedMessagesGroupPreference(enable = enable, ttl = currentPreferences.timedMessages.ttl)))
|
||||
}
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
}
|
||||
@Composable fun DirectMessagesPreference() {
|
||||
val allowDirectMessages = remember(preferences) { mutableStateOf(preferences.directMessages.enable) }
|
||||
val directMessagesRole = remember(preferences) { mutableStateOf(preferences.directMessages.role) }
|
||||
FeatureSection(GroupFeature.DirectMessages, allowDirectMessages, directMessagesRole, groupInfo, preferences, onTTLUpdated) { enable, role ->
|
||||
applyPrefs(preferences.copy(directMessages = RoleGroupPreference(enable = enable, role)))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
}
|
||||
@Composable fun FullDeletePreference() {
|
||||
val allowFullDeletion = remember(preferences) { mutableStateOf(preferences.fullDelete.enable) }
|
||||
FeatureSection(GroupFeature.FullDelete, allowFullDeletion, null, groupInfo, preferences, onTTLUpdated) { enable, _ ->
|
||||
applyPrefs(preferences.copy(fullDelete = GroupPreference(enable = enable)))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
}
|
||||
@Composable fun ReactionsPreference() {
|
||||
val allowReactions = remember(preferences) { mutableStateOf(preferences.reactions.enable) }
|
||||
FeatureSection(GroupFeature.Reactions, allowReactions, null, groupInfo, preferences, onTTLUpdated) { enable, _ ->
|
||||
applyPrefs(preferences.copy(reactions = GroupPreference(enable = enable)))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
}
|
||||
@Composable fun VoicePreference() {
|
||||
val allowVoice = remember(preferences) { mutableStateOf(preferences.voice.enable) }
|
||||
val voiceRole = remember(preferences) { mutableStateOf(preferences.voice.role) }
|
||||
FeatureSection(GroupFeature.Voice, allowVoice, voiceRole, groupInfo, preferences, onTTLUpdated) { enable, role ->
|
||||
applyPrefs(preferences.copy(voice = RoleGroupPreference(enable = enable, role)))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
}
|
||||
@Composable fun FilesPreference() {
|
||||
val allowFiles = remember(preferences) { mutableStateOf(preferences.files.enable) }
|
||||
val filesRole = remember(preferences) { mutableStateOf(preferences.files.role) }
|
||||
FeatureSection(GroupFeature.Files, allowFiles, filesRole, groupInfo, preferences, onTTLUpdated) { enable, role ->
|
||||
applyPrefs(preferences.copy(files = RoleGroupPreference(enable = enable, role)))
|
||||
}
|
||||
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
}
|
||||
@Composable fun SimplexLinksPreference() {
|
||||
val allowSimplexLinks = remember(preferences) { mutableStateOf(preferences.simplexLinks.enable) }
|
||||
val simplexLinksRole = remember(preferences) { mutableStateOf(preferences.simplexLinks.role) }
|
||||
FeatureSection(GroupFeature.SimplexLinks, allowSimplexLinks, simplexLinksRole, groupInfo, preferences, onTTLUpdated) { enable, role ->
|
||||
applyPrefs(preferences.copy(simplexLinks = RoleGroupPreference(enable = enable, role)))
|
||||
}
|
||||
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
}
|
||||
@Composable fun ReportsPreference() {
|
||||
val enableReports = remember(preferences) { mutableStateOf(preferences.reports.enable) }
|
||||
FeatureSection(GroupFeature.Reports, enableReports, null, groupInfo, preferences, onTTLUpdated) { enable, _ ->
|
||||
applyPrefs(preferences.copy(reports = GroupPreference(enable = enable)))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
}
|
||||
@Composable fun HistoryPreference() {
|
||||
val enableHistory = remember(preferences) { mutableStateOf(preferences.history.enable) }
|
||||
FeatureSection(GroupFeature.History, enableHistory, null, groupInfo, preferences, onTTLUpdated) { enable, _ ->
|
||||
applyPrefs(preferences.copy(history = GroupPreference(enable = enable)))
|
||||
}
|
||||
}
|
||||
ColumnWithScrollBar {
|
||||
val titleId = if (groupInfo.useRelays) MR.strings.channel_preferences
|
||||
else if (groupInfo.businessChat == null) MR.strings.group_preferences
|
||||
else MR.strings.chat_preferences
|
||||
AppBarTitle(stringResource(titleId))
|
||||
if (!groupInfo.useRelays) {
|
||||
if (groupInfo.businessChat == null) {
|
||||
MemberAdmissionButton(openMemberAdmission)
|
||||
SectionDividerSpaced(maxBottomPadding = false)
|
||||
}
|
||||
TimedMessagesPreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
DirectMessagesPreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
FullDeletePreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
ReactionsPreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
VoicePreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
FilesPreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
SimplexLinksPreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
ReportsPreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
HistoryPreference()
|
||||
} else {
|
||||
TimedMessagesPreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
FullDeletePreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
ReactionsPreference()
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
HistoryPreference()
|
||||
}
|
||||
if (groupInfo.isOwner) {
|
||||
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(
|
||||
reset = reset,
|
||||
save = savePrefs,
|
||||
disabled = preferences == currentPreferences
|
||||
disabled = preferences == currentPreferences,
|
||||
saveTextId = saveTextId
|
||||
)
|
||||
}
|
||||
SectionBottomSpacer()
|
||||
@@ -253,21 +296,21 @@ private fun FeatureSection(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ResetSaveButtons(reset: () -> Unit, save: () -> Unit, disabled: Boolean) {
|
||||
private fun ResetSaveButtons(reset: () -> Unit, save: () -> Unit, disabled: Boolean, saveTextId: StringResource) {
|
||||
SectionView {
|
||||
SectionItemView(reset, disabled = disabled) {
|
||||
Text(stringResource(MR.strings.reset_verb), color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary)
|
||||
}
|
||||
SectionItemView(save, disabled = disabled) {
|
||||
Text(stringResource(MR.strings.save_and_notify_group_members), color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary)
|
||||
Text(stringResource(saveTextId), color = if (disabled) MaterialTheme.colors.secondary else MaterialTheme.colors.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showUnsavedChangesAlert(save: () -> Unit, revert: () -> Unit) {
|
||||
private fun showUnsavedChangesAlert(save: () -> Unit, revert: () -> Unit, confirmTextId: StringResource) {
|
||||
AlertManager.shared.showAlertDialogStacked(
|
||||
title = generalGetString(MR.strings.save_preferences_question),
|
||||
confirmText = generalGetString(MR.strings.save_and_notify_group_members),
|
||||
confirmText = generalGetString(confirmTextId),
|
||||
dismissText = generalGetString(MR.strings.exit_without_saving),
|
||||
onConfirm = save,
|
||||
onDismiss = revert,
|
||||
|
||||
@@ -1875,6 +1875,7 @@
|
||||
<string name="error_creating_member_contact">Error creating member contact</string>
|
||||
<string name="error_sending_message_contact_invitation">Error sending invitation</string>
|
||||
<string name="only_group_owners_can_change_prefs">Only group owners can change group preferences.</string>
|
||||
<string name="only_channel_owners_can_change_prefs">Only channel owners can change channel preferences.</string>
|
||||
<string name="only_chat_owners_can_change_prefs">Only chat owners can change preferences.</string>
|
||||
<string name="address_section_title">Address</string>
|
||||
<string name="share_address">Share address</string>
|
||||
@@ -2217,6 +2218,7 @@
|
||||
<string name="chat_preferences">Chat preferences</string>
|
||||
<string name="contact_preferences">Contact preferences</string>
|
||||
<string name="group_preferences">Group preferences</string>
|
||||
<string name="channel_preferences">Channel preferences</string>
|
||||
<string name="set_group_preferences">Set group preferences</string>
|
||||
<string name="set_member_admission">Set member admission</string>
|
||||
<string name="your_preferences">Your preferences</string>
|
||||
|
||||
Reference in New Issue
Block a user