Split settings: app settings / account settings

This commit is contained in:
Benoit Marty
2026-09-21 15:55:36 +02:00
committed by Benoit Marty
parent bec3780c9c
commit 9b2577f1dd
55 changed files with 1947 additions and 1153 deletions
@@ -35,8 +35,8 @@ import io.element.android.libraries.ui.strings.CommonStrings
import kotlinx.coroutines.launch
@Composable
fun RoomPreviewAliasAtom(
alias: String,
fun CopiableTextAtom(
text: String,
modifier: Modifier = Modifier,
copiable: Boolean = true
) {
@@ -46,7 +46,7 @@ fun RoomPreviewAliasAtom(
modifier = modifier
.clickable(enabled = copiable) {
coroutineScope.launch {
val clipData = ClipData.newPlainText(alias, alias)
val clipData = ClipData.newPlainText(text, text)
clipboard.setClipEntry(clipData.toClipEntry())
}
},
@@ -55,7 +55,7 @@ fun RoomPreviewAliasAtom(
) {
Text(
modifier = Modifier.weight(weight = 1f, fill = false),
text = alias,
text = text,
style = ElementTheme.typography.fontBodyLgRegular,
textAlign = TextAlign.Center,
maxLines = 1,
@@ -75,9 +75,9 @@ fun RoomPreviewAliasAtom(
@PreviewsDayNight
@Composable
internal fun RoomPreviewAliasAtomPreview() = ElementPreview {
RoomPreviewAliasAtom(
alias = "#room-alias:matrix.org",
internal fun CopiableTextAtomPreview() = ElementPreview {
CopiableTextAtom(
text = "#room-alias:matrix.org",
copiable = true
)
}
@@ -55,6 +55,7 @@ fun <T : DropdownOption> PreferenceDropdown(
supportingText: String? = null,
enabled: Boolean = true,
icon: ImageVector? = null,
dropDownIcon: ImageVector = CompoundIcons.ChevronDown(),
@DrawableRes iconResourceId: Int? = null,
showIconAreaIfNoIcon: Boolean = false,
) {
@@ -84,13 +85,14 @@ fun <T : DropdownOption> PreferenceDropdown(
trailingContent = ListItemContent.Custom(
content = { enabled ->
DropdownTrailingContent(
dropDownIcon = dropDownIcon,
selectedOption = selectedOption,
options = options,
onSelectOption = onSelectOption,
expanded = isDropdownExpanded,
onExpandedChange = { isDropdownExpanded = it },
enabled = enabled,
modifier = Modifier.fillMaxSize(0.3f)
modifier = Modifier.fillMaxSize(0.3f),
)
}
),
@@ -119,6 +121,7 @@ private fun <T : DropdownOption> DropdownTrailingContent(
onSelectOption: (T) -> Unit,
enabled: Boolean,
modifier: Modifier = Modifier,
dropDownIcon: ImageVector = CompoundIcons.ChevronDown(),
) {
Row(
modifier = modifier,
@@ -135,7 +138,7 @@ private fun <T : DropdownOption> DropdownTrailingContent(
modifier = Modifier.weight(1f),
)
Icon(
imageVector = CompoundIcons.ChevronDown(),
imageVector = dropDownIcon,
contentDescription = null,
tint = enabled.toIconSecondaryEnabledColor(),
)
@@ -20,7 +20,7 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.tooling.preview.datasource.LoremIpsum
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewAliasAtom
import io.element.android.libraries.designsystem.atomic.atoms.CopiableTextAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewDescriptionAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoomPreviewTitleAtom
import io.element.android.libraries.designsystem.atomic.organisms.RoomPreviewOrganism
@@ -87,7 +87,7 @@ fun SpaceHeaderView(
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
if (alias != null) {
RoomPreviewAliasAtom(alias = alias.value)
CopiableTextAtom(text = alias.value)
}
SpaceInfoRow(visibility = visibility)
}
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.ui.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.atomic.atoms.CopiableTextAtom
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.avatar.AvatarType
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.model.getAvatarData
import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun UserHeaderView(
matrixUser: MatrixUser,
onAvatarClick: (String) -> Unit,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier
.fillMaxWidth()
.padding(start = 16.dp, end = 16.dp, top = 24.dp, bottom = 8.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Avatar(
avatarData = matrixUser.getAvatarData(AvatarSize.UserHeader),
avatarType = AvatarType.User,
contentDescription = stringResource(CommonStrings.a11y_user_avatar),
modifier = Modifier
.clip(CircleShape)
.clickable(
enabled = matrixUser.avatarUrl != null,
onClickLabel = stringResource(CommonStrings.action_view),
) {
onAvatarClick(matrixUser.avatarUrl!!)
}
)
Spacer(modifier = Modifier.height(16.dp))
matrixUser.displayName?.let { displayName ->
Text(
modifier = Modifier
.clipToBounds()
.semantics {
heading()
},
text = displayName,
style = ElementTheme.typography.fontHeadingMdRegular,
textAlign = TextAlign.Center,
)
Spacer(modifier = Modifier.height(16.dp))
}
CopiableTextAtom(
text = matrixUser.userId.value,
)
Spacer(modifier = Modifier.height(12.dp))
}
}
@PreviewsDayNight
@Composable
internal fun UserHeaderViewPreview() = ElementPreview {
UserHeaderView(
aMatrixUser(),
onAvatarClick = {},
)
}
@@ -223,6 +223,7 @@
<string name="banner_migrate_to_native_sliding_sync_title">"Upgrade available"</string>
<string name="common_about">"About"</string>
<string name="common_acceptable_use_policy">"Acceptable use policy"</string>
<string name="common_account_settings">"Account settings"</string>
<string name="common_add_account">"Add an account"</string>
<string name="common_add_another_account">"Add account"</string>
<string name="common_adding_caption">"Adding caption"</string>
@@ -231,6 +232,7 @@
<string name="common_analytics">"Analytics"</string>
<string name="common_android_shortcuts_remove_reason_left_room">"You left the room"</string>
<string name="common_android_shortcuts_remove_reason_session_logged_out">"You were logged out of the session"</string>
<string name="common_app_settings">"App settings"</string>
<string name="common_appearance">"Appearance"</string>
<string name="common_audio">"Audio"</string>
<string name="common_beta">"Beta"</string>
@@ -306,10 +308,12 @@ Reason: %1$s."</string>
<string name="common_live_location_ended">"Live location ended"</string>
<string name="common_loading">"Loading…"</string>
<string name="common_loading_more">"Loading more…"</string>
<string name="common_location_sharing">"Location sharing"</string>
<plurals name="common_many_members">
<item quantity="one">"%d other"</item>
<item quantity="other">"%d others"</item>
</plurals>
<string name="common_media_upload_quality">"Media upload quality"</string>
<plurals name="common_member_count">
<item quantity="one">"%1$d Member"</item>
<item quantity="other">"%1$d Members"</item>
@@ -319,6 +323,7 @@ Reason: %1$s."</string>
<string name="common_message_failed_to_send">"Message failed to send"</string>
<string name="common_message_layout">"Message layout"</string>
<string name="common_message_removed">"Message removed"</string>
<string name="common_moderation_and_safety">"Moderation &amp; safety"</string>
<string name="common_modern">"Modern"</string>
<string name="common_mute">"Mute"</string>
<string name="common_name">"Name"</string>
@@ -419,6 +424,7 @@ Reason: %1$s."</string>
<string name="common_success">"Success"</string>
<string name="common_suggested">"Suggested"</string>
<string name="common_suggestions">"Suggestions"</string>
<string name="common_switch_accounts">"Switch accounts"</string>
<string name="common_syncing">"Syncing"</string>
<string name="common_text">"Text"</string>
<string name="common_third_party_notices">"Third-party notices"</string>
@@ -458,6 +464,7 @@ Reason: %1$s."</string>
<string name="common_waiting_live_location">"Waiting for live location…"</string>
<string name="common_world_readable_history">"Anyone can see history"</string>
<string name="common_you">"You"</string>
<string name="common_your_account">"Your account"</string>
<string name="content_scanner_not_found">"Download not available."</string>
<string name="content_scanner_not_found_title">"Something went wrong"</string>
<string name="content_scanner_scanning">"Scanning…"</string>
@@ -552,12 +559,6 @@ Are you sure you want to continue?"</string>
<string name="screen_resolve_send_failure_you_unsigned_device_subtitle">"One or more of your devices are unverified. You can send the message anyway, or you can cancel for now and try again later after you have verified all of your devices."</string>
<string name="screen_resolve_send_failure_you_unsigned_device_title">"Your message was not sent because you have not verified one or more of your devices"</string>
<string name="screen_room_change_role_administrators_or_owners_title">"Edit Admins or Owners"</string>
<string name="screen_room_confirm_removal_message">"Are you sure you wish to remove this message?"</string>
<string name="screen_room_confirm_removal_reason_label">"Reason (optional)"</string>
<string name="screen_room_confirm_removal_reason_placeholder">"Enter…"</string>
<string name="screen_room_confirm_removal_reason_placeholder_android">"Reason…"</string>
<string name="screen_room_confirm_removal_reason_supporting_text">"(Optional)"</string>
<string name="screen_room_confirm_removal_title">"Confirm removal"</string>
<string name="screen_room_error_failed_processing_media">"Failed processing media to upload, please try again."</string>
<string name="screen_room_error_failed_retrieving_user_details">"Could not retrieve user details"</string>
<string name="screen_room_event_pill">"Message in %1$s"</string>