From 01a048e2198b56c254d0a9efb8327c2f6eeb64ba Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Mon, 6 May 2024 17:20:03 +0200 Subject: [PATCH] UX cleanup: reorder options in the main settings screen (#2802) * UX cleanup: reorder options in the main settings screen * Update screenshots * Group sections in composables * Add some horizontal padding to the `Footer` component --------- Co-authored-by: ElementBot --- changelog.d/2801.misc | 1 + .../impl/root/PreferencesRootView.kt | 219 +++++++++++------- ...otViewDark--1_1_null_0,NEXUS_5,1.0,en].png | 4 +- ...otViewDark--1_1_null_1,NEXUS_5,1.0,en].png | 4 +- ...tViewLight--0_0_null_0,NEXUS_5,1.0,en].png | 4 +- ...tViewLight--0_0_null_1,NEXUS_5,1.0,en].png | 4 +- 6 files changed, 149 insertions(+), 87 deletions(-) create mode 100644 changelog.d/2801.misc diff --git a/changelog.d/2801.misc b/changelog.d/2801.misc new file mode 100644 index 0000000000..571d0296e0 --- /dev/null +++ b/changelog.d/2801.misc @@ -0,0 +1 @@ +UX cleanup: reorder options in the main settings screen. diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt index 21132df5c9..a70f73fa6e 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootView.kt @@ -17,6 +17,7 @@ package io.element.android.features.preferences.impl.root import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable @@ -81,87 +82,33 @@ fun PreferencesRootView( }, user = state.myUser, ) - if (state.showSecureBackup) { - ListItem( - headlineContent = { Text(stringResource(id = CommonStrings.common_chat_backup)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.KeySolid())), - trailingContent = ListItemContent.Badge.takeIf { state.showSecureBackupBadge }, - onClick = onSecureBackupClicked, - ) - HorizontalDivider() - } - if (state.accountManagementUrl != null) { - ListItem( - headlineContent = { Text(stringResource(id = CommonStrings.action_manage_account)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.UserProfile())), - trailingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.PopOut())), - onClick = { onManageAccountClicked(state.accountManagementUrl) }, - ) - HorizontalDivider() - } - if (state.showAnalyticsSettings) { - ListItem( - headlineContent = { Text(stringResource(id = CommonStrings.common_analytics)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Chart())), - onClick = onOpenAnalytics, - ) - } - if (state.showNotificationSettings) { - ListItem( - headlineContent = { Text(stringResource(id = R.string.screen_notification_settings_title)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Notifications())), - onClick = onOpenNotificationSettings, - ) - } - if (state.showBlockedUsersItem) { - ListItem( - headlineContent = { Text(stringResource(id = CommonStrings.common_blocked_users)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Block())), - onClick = onOpenBlockedUsers, - ) - } - ListItem( - headlineContent = { Text(stringResource(id = CommonStrings.common_report_a_problem)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.ChatProblem())), - onClick = onOpenRageShake + + // 'Manage my app' section + ManageAppSection( + state = state, + onOpenNotificationSettings = onOpenNotificationSettings, + onOpenLockScreenSettings = onOpenLockScreenSettings, + onSecureBackupClicked = onSecureBackupClicked, ) - ListItem( - headlineContent = { Text(stringResource(id = CommonStrings.common_about)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Info())), - onClick = onOpenAbout, + + // 'Account' section + ManageAccountSection( + state = state, + onManageAccountClicked = onManageAccountClicked, + onOpenBlockedUsers = onOpenBlockedUsers ) - if (state.showLockScreenSettings) { - ListItem( - headlineContent = { Text(stringResource(id = CommonStrings.common_screen_lock)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Lock())), - onClick = onOpenLockScreenSettings, - ) - } - HorizontalDivider() - if (state.devicesManagementUrl != null) { - ListItem( - headlineContent = { Text(stringResource(id = CommonStrings.action_manage_devices)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Devices())), - trailingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.PopOut())), - onClick = { onManageAccountClicked(state.devicesManagementUrl) }, - ) - HorizontalDivider() - } - ListItem( - headlineContent = { Text(stringResource(id = CommonStrings.common_advanced_settings)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Settings())), - onClick = onOpenAdvancedSettings, - ) - if (state.showDeveloperSettings) { - DeveloperPreferencesView(onOpenDeveloperSettings) - } - HorizontalDivider() - ListItem( - headlineContent = { Text(stringResource(id = CommonStrings.action_signout)) }, - leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.SignOut())), - style = ListItemStyle.Destructive, - onClick = onSignOutClicked, + + // General section + GeneralSection( + state = state, + onOpenAbout = onOpenAbout, + onOpenAnalytics = onOpenAnalytics, + onOpenRageShake = onOpenRageShake, + onOpenAdvancedSettings = onOpenAdvancedSettings, + onOpenDeveloperSettings = onOpenDeveloperSettings, + onSignOutClicked = onSignOutClicked, ) + Footer( version = state.version, deviceId = state.deviceId, @@ -169,6 +116,120 @@ fun PreferencesRootView( } } +@Composable +private fun ColumnScope.ManageAppSection( + state: PreferencesRootState, + onOpenNotificationSettings: () -> Unit, + onOpenLockScreenSettings: () -> Unit, + onSecureBackupClicked: () -> Unit, +) { + if (state.showNotificationSettings) { + ListItem( + headlineContent = { Text(stringResource(id = R.string.screen_notification_settings_title)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Notifications())), + onClick = onOpenNotificationSettings, + ) + } + if (state.showLockScreenSettings) { + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.common_screen_lock)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Lock())), + onClick = onOpenLockScreenSettings, + ) + } + if (state.showSecureBackup) { + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.common_chat_backup)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.KeySolid())), + trailingContent = ListItemContent.Badge.takeIf { state.showSecureBackupBadge }, + onClick = onSecureBackupClicked, + ) + } + if (state.showNotificationSettings || state.showLockScreenSettings || state.showSecureBackup) { + HorizontalDivider() + } +} + +@Composable +private fun ColumnScope.ManageAccountSection( + state: PreferencesRootState, + onManageAccountClicked: (url: String) -> Unit, + onOpenBlockedUsers: () -> Unit, +) { + state.accountManagementUrl?.let { url -> + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.action_manage_account)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.UserProfile())), + trailingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.PopOut())), + onClick = { onManageAccountClicked(url) }, + ) + } + + state.devicesManagementUrl?.let { url -> + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.action_manage_devices)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Devices())), + trailingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.PopOut())), + onClick = { onManageAccountClicked(url) }, + ) + } + + if (state.showBlockedUsersItem) { + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.common_blocked_users)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Block())), + onClick = onOpenBlockedUsers, + ) + } + + if (state.accountManagementUrl != null || state.devicesManagementUrl != null || state.showBlockedUsersItem) { + HorizontalDivider() + } +} + +@Composable +private fun ColumnScope.GeneralSection( + state: PreferencesRootState, + onOpenAbout: () -> Unit, + onOpenAnalytics: () -> Unit, + onOpenRageShake: () -> Unit, + onOpenAdvancedSettings: () -> Unit, + onOpenDeveloperSettings: () -> Unit, + onSignOutClicked: () -> Unit, +) { + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.common_about)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Info())), + onClick = onOpenAbout, + ) + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.common_report_a_problem)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.ChatProblem())), + onClick = onOpenRageShake + ) + if (state.showAnalyticsSettings) { + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.common_analytics)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Chart())), + onClick = onOpenAnalytics, + ) + } + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.common_advanced_settings)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Settings())), + onClick = onOpenAdvancedSettings, + ) + if (state.showDeveloperSettings) { + DeveloperPreferencesView(onOpenDeveloperSettings) + } + ListItem( + headlineContent = { Text(stringResource(id = CommonStrings.action_signout)) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.SignOut())), + style = ListItemStyle.Destructive, + onClick = onSignOutClicked, + ) +} + @Composable private fun Footer( version: String, @@ -186,7 +247,7 @@ private fun Footer( Text( modifier = Modifier .fillMaxWidth() - .padding(top = 40.dp, bottom = 24.dp), + .padding(start = 16.dp, end = 16.dp, top = 40.dp, bottom = 24.dp), textAlign = TextAlign.Center, text = text, style = ElementTheme.typography.fontBodySmRegular, diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewDark_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewDark_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png index c54c15e9ca..4973ac1c53 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewDark_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewDark_null_PreferencesRootViewDark--1_1_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:75fb611e02345fe1cf7947d1e160e309cf8520f0256ebd25b43bab8c3102f3f8 -size 37138 +oid sha256:9e1156c479fdd3ebb2487373103183ae6a21ba618da2c58dc26f19fc02bbad2b +size 37171 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewDark_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewDark_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png index 90e78c16a5..f2c55ee046 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewDark_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewDark_null_PreferencesRootViewDark--1_1_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7be4df5a4e391d2253f283acf0fb9362b965fa887235221b794915d74891899 -size 36783 +oid sha256:752003ec1c673d18f445d47e5acbafd4b435371832baa5ebd220e5ee1c62fa07 +size 36805 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewLight_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewLight_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png index 4f2683cf78..d0d405e630 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewLight_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewLight_null_PreferencesRootViewLight--0_0_null_0,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:67503a61f560ef79d7e981057094dccf46eda167ee84427c1aceb9f83edf0146 -size 39080 +oid sha256:a278e774320a876d6c65a2178de2b73cb0da20df18cad293b6969a81cb16d6d5 +size 39076 diff --git a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewLight_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewLight_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png index 12e2374878..14aed1cb7c 100644 --- a/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewLight_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/ui_S_t[f.preferences.impl.root_PreferencesRootViewLight_null_PreferencesRootViewLight--0_0_null_1,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5cb3be70de8e3878bdd90db9945aed60fb2b38d8c66ea610806226c21b1f5a5a -size 39052 +oid sha256:72d4f6e89026ffc7155828c38b7e013a703497725ba3c6b667c7eb97015750fb +size 39050