android: improve UX to create groups and UI of group preferences (#1496)

This commit is contained in:
Evgeny Poberezkin
2022-12-04 15:16:41 +00:00
committed by GitHub
parent 358712fa31
commit ff17f89551
9 changed files with 69 additions and 13 deletions
@@ -210,7 +210,7 @@ fun ChatView(chatId: String, chatModel: ChatModel, onComposed: () -> Unit) {
withApi {
setGroupMembers(groupInfo, chatModel)
ModalManager.shared.showModalCloseable(true) { close ->
AddGroupMembersView(groupInfo, chatModel, close)
AddGroupMembersView(groupInfo, false, chatModel, close)
}
}
},
@@ -31,17 +31,23 @@ import chat.simplex.app.views.helpers.*
import chat.simplex.app.views.usersettings.SettingsActionItem
@Composable
fun AddGroupMembersView(groupInfo: GroupInfo, chatModel: ChatModel, close: () -> Unit) {
fun AddGroupMembersView(groupInfo: GroupInfo, creatingGroup: Boolean = false, chatModel: ChatModel, close: () -> Unit) {
val selectedContacts = remember { mutableStateListOf<Long>() }
val selectedRole = remember { mutableStateOf(GroupMemberRole.Member) }
var allowModifyMembers by remember { mutableStateOf(true) }
BackHandler(onBack = close)
AddGroupMembersLayout(
groupInfo = groupInfo,
creatingGroup = creatingGroup,
contactsToAdd = getContactsToAdd(chatModel),
selectedContacts = selectedContacts,
selectedRole = selectedRole,
allowModifyMembers = allowModifyMembers,
openPreferences = {
ModalManager.shared.showModal(true) {
GroupPreferencesView(chatModel, groupInfo.id)
}
},
inviteMembers = {
allowModifyMembers = false
withApi {
@@ -59,6 +65,7 @@ fun AddGroupMembersView(groupInfo: GroupInfo, chatModel: ChatModel, close: () ->
clearSelection = { selectedContacts.clear() },
addContact = { contactId -> if (contactId !in selectedContacts) selectedContacts.add(contactId) },
removeContact = { contactId -> selectedContacts.removeIf { it == contactId } },
close = close,
)
}
@@ -79,14 +86,17 @@ fun getContactsToAdd(chatModel: ChatModel): List<Contact> {
@Composable
fun AddGroupMembersLayout(
groupInfo: GroupInfo,
creatingGroup: Boolean,
contactsToAdd: List<Contact>,
selectedContacts: List<Long>,
selectedRole: MutableState<GroupMemberRole>,
allowModifyMembers: Boolean,
openPreferences: () -> Unit,
inviteMembers: () -> Unit,
clearSelection: () -> Unit,
addContact: (Long) -> Unit,
removeContact: (Long) -> Unit,
close: () -> Unit,
) {
Column(
Modifier
@@ -120,18 +130,28 @@ fun AddGroupMembersLayout(
}
} else {
SectionView {
if (creatingGroup) {
SectionItemView(openPreferences) {
Text(stringResource(R.string.set_group_preferences))
}
SectionDivider()
}
SectionItemView {
RoleSelectionRow(groupInfo, selectedRole, allowModifyMembers)
}
SectionDivider()
InviteMembersButton(inviteMembers, disabled = selectedContacts.isEmpty() || !allowModifyMembers)
if (creatingGroup && selectedContacts.isEmpty()) {
SkipInvitingButton(close)
} else {
InviteMembersButton(inviteMembers, disabled = selectedContacts.isEmpty() || !allowModifyMembers)
}
}
SectionCustomFooter {
InviteSectionFooter(selectedContactsCount = selectedContacts.size, allowModifyMembers, clearSelection)
}
SectionSpacer()
SectionView {
SectionView(stringResource(R.string.select_contacts)) {
ContactList(contacts = contactsToAdd, selectedContacts, groupInfo, allowModifyMembers, addContact, removeContact)
}
SectionSpacer()
@@ -170,6 +190,17 @@ fun InviteMembersButton(onClick: () -> Unit, disabled: Boolean) {
)
}
@Composable
fun SkipInvitingButton(onClick: () -> Unit) {
SettingsActionItem(
Icons.Outlined.Check,
stringResource(R.string.skip_inviting_button),
click = onClick,
textColor = MaterialTheme.colors.primary,
iconColor = MaterialTheme.colors.primary,
)
}
@Composable
fun InviteSectionFooter(selectedContactsCount: Int, enabled: Boolean, clearSelection: () -> Unit) {
Row(
@@ -288,14 +319,17 @@ fun PreviewAddGroupMembersLayout() {
SimpleXTheme {
AddGroupMembersLayout(
groupInfo = GroupInfo.sampleData,
creatingGroup = false,
contactsToAdd = listOf(Contact.sampleData, Contact.sampleData, Contact.sampleData),
selectedContacts = remember { mutableStateListOf() },
selectedRole = remember { mutableStateOf(GroupMemberRole.Admin) },
allowModifyMembers = true,
openPreferences = {},
inviteMembers = {},
clearSelection = {},
addContact = {},
removeContact = {}
removeContact = {},
close = {},
)
}
}
@@ -49,7 +49,7 @@ fun GroupChatInfoView(chatModel: ChatModel, close: () -> Unit) {
withApi {
setGroupMembers(groupInfo, chatModel)
ModalManager.shared.showModalCloseable(true) { close ->
AddGroupMembersView(groupInfo, chatModel, close)
AddGroupMembersView(groupInfo, false, chatModel, close)
}
}
},
@@ -13,10 +13,12 @@ import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import chat.simplex.app.R
import chat.simplex.app.model.*
import chat.simplex.app.ui.theme.HighOrLowlight
import chat.simplex.app.ui.theme.SimplexGreen
import chat.simplex.app.views.helpers.*
@Composable
@@ -66,6 +68,7 @@ private fun GroupPreferencesLayout(
FeatureSection(GroupFeature.DirectMessages, allowDirectMessages, groupInfo) {
applyPrefs(preferences.copy(directMessages = GroupPreference(enable = it)))
}
SectionSpacer()
val allowFullDeletion = remember(preferences) { mutableStateOf(preferences.fullDelete.enable) }
FeatureSection(GroupFeature.FullDelete, allowFullDeletion, groupInfo) {
applyPrefs(preferences.copy(fullDelete = GroupPreference(enable = it)))
@@ -89,20 +92,26 @@ private fun GroupPreferencesLayout(
@Composable
private fun FeatureSection(feature: GroupFeature, enableFeature: State<GroupFeatureEnabled>, groupInfo: GroupInfo, onSelected: (GroupFeatureEnabled) -> Unit) {
SectionView {
val on = enableFeature.value == GroupFeatureEnabled.ON
val icon = if (on) feature.iconFilled else feature.icon
val iconTint = if (on) SimplexGreen else HighOrLowlight
if (groupInfo.canEdit) {
SectionItemView {
ExposedDropDownSettingRow(
feature.text,
GroupFeatureEnabled.values().map { it to it.text },
enableFeature,
icon = feature.icon,
icon = icon,
iconTint = iconTint,
onSelected = onSelected
)
}
} else {
InfoRow(
feature.text,
enableFeature.value.text
enableFeature.value.text,
icon = icon,
iconTint = iconTint,
)
}
}
@@ -186,9 +186,13 @@ fun SectionSpacer() {
}
@Composable
fun InfoRow(title: String, value: String) {
fun InfoRow(title: String, value: String, icon: ImageVector? = null, iconTint: Color? = null) {
SectionItemViewSpaceBetween {
Text(title)
Row {
val iconSize = with(LocalDensity.current) { 21.sp.toDp() }
if (icon != null) Icon(icon, title, Modifier.padding(end = 8.dp).size(iconSize), tint = iconTint ?: HighOrLowlight)
Text(title)
}
Text(value, color = HighOrLowlight)
}
}
@@ -47,7 +47,7 @@ fun AddGroupView(chatModel: ChatModel, close: () -> Unit) {
setGroupMembers(groupInfo, chatModel)
close.invoke()
ModalManager.shared.showModalCloseable(true) { close ->
AddGroupMembersView(groupInfo, chatModel, close)
AddGroupMembersView(groupInfo, true, chatModel, close)
}
}
}
@@ -21,7 +21,7 @@
<!-- Item Content - ChatModel.kt -->
<string name="deleted_description">Gelöscht</string>
<string name="marked_deleted_description">***marked deleted</string>
<string name="marked_deleted_description">***markiert gelöscht</string>
<string name="sending_files_not_yet_supported">Das Senden von Dateien wird noch nicht unterstützt</string>
<string name="receiving_files_not_yet_supported">Der Empfang von Dateien wird noch nicht unterstützt</string>
<string name="sender_you_pronoun">Meine Daten</string>
@@ -61,7 +61,7 @@
<!-- API Error Responses - SimpleXAPI.kt -->
<string name="connection_timeout">Verbindungszeitüberschreitung</string>
<string name="connection_error">Verbindungsfehler</string>
<string name="network_error_desc">*** Bitte überprüfen Sie Ihre Netzwerkverbindung mit <xliff:g id="serverHost" example="smp.simplex.im">%1$s</xliff:g> und versuchen Sie es erneut.</string>
<string name="network_error_desc">Bitte überprüfen Sie Ihre Netzwerkverbindung mit <xliff:g id="serverHost" example="smp.simplex.im">%1$s</xliff:g> und versuchen Sie es erneut.</string>
<string name="error_sending_message">Fehler beim Senden der Nachricht</string>
<string name="error_adding_members">Fehler beim Hinzufügen von Mitgliedern</string>
<string name="error_joining_group">Fehler beim Beitritt zur Gruppe</string>
@@ -832,6 +832,8 @@
<string name="new_member_role">Neue Mitgliedsrolle</string>
<string name="icon_descr_expand_role">Rollenauswahl erweitern</string>
<string name="invite_to_group_button">In Gruppe einladen</string>
<string name="skip_inviting_button">***Skip inviting members</string>
<string name="select_contacts">***Select contacts</string>
<string name="icon_descr_contact_checked">Kontakt geprüft</string>
<string name="clear_contacts_selection_button">Löschen</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g> Kontakt(e) ausgewählt</string>
@@ -952,6 +954,7 @@
<string name="chat_preferences">Chat Präferenzen</string>
<string name="contact_preferences">Kontakt Präferenzen</string>
<string name="group_preferences">Gruppen Präferenzen</string>
<string name="set_group_preferences">***Gruppenpräferenzen einstellen</string>
<string name="your_preferences">Ihre Präferenzen</string>
<string name="direct_messages">***Direct messages</string>
<string name="full_deletion">***Beseitigung für alle</string>
@@ -832,6 +832,8 @@
<string name="new_member_role">Роль члена группы</string>
<string name="icon_descr_expand_role">Развернуть выбор роли</string>
<string name="invite_to_group_button">Пригласить в группу</string>
<string name="skip_inviting_button">Не приглашать членов</string>
<string name="select_contacts">Выберите контакты</string>
<string name="icon_descr_contact_checked">Контакт выбран</string>
<string name="clear_contacts_selection_button">Очистить</string>
<string name="num_contacts_selected">Выбрано контактов: <xliff:g id="num_contacts">%1$s</xliff:g></string>
@@ -951,6 +953,7 @@
<string name="chat_preferences">Предпочтения</string>
<string name="contact_preferences">Предпочтения контакта</string>
<string name="group_preferences">Предпочтения группы</string>
<string name="set_group_preferences">Предпочтения группы</string>
<string name="your_preferences">Ваши предпочтения</string>
<string name="direct_messages">Прямые сообщения</string>
<string name="full_deletion">Удаление для всех</string>
@@ -832,6 +832,8 @@
<string name="new_member_role">New member role</string>
<string name="icon_descr_expand_role">Expand role selection</string>
<string name="invite_to_group_button">Invite to group</string>
<string name="skip_inviting_button">Skip inviting members</string>
<string name="select_contacts">Select contacts</string>
<string name="icon_descr_contact_checked">Contact checked</string>
<string name="clear_contacts_selection_button">Clear</string>
<string name="num_contacts_selected"><xliff:g id="num_contacts">%1$s</xliff:g> contact(s) selected</string>
@@ -952,6 +954,7 @@
<string name="chat_preferences">Chat preferences</string>
<string name="contact_preferences">Contact preferences</string>
<string name="group_preferences">Group preferences</string>
<string name="set_group_preferences">Set group preferences</string>
<string name="your_preferences">Your preferences</string>
<string name="direct_messages">Direct messages</string>
<string name="full_deletion">Delete for everyone</string>