feat(security&privacy) : manage encryption settings

This commit is contained in:
ganfra 2025-01-22 17:55:37 +01:00
parent 392299d5ce
commit 7eda9453df
5 changed files with 55 additions and 15 deletions

View file

@ -11,7 +11,9 @@ sealed interface SecurityAndPrivacyEvents {
data object EditRoomAddress : SecurityAndPrivacyEvents
data object Save : SecurityAndPrivacyEvents
data class ChangeRoomAccess(val roomAccess: SecurityAndPrivacyRoomAccess) : SecurityAndPrivacyEvents
data object EnableEncryption: SecurityAndPrivacyEvents
data object ToggleEncryptionState: SecurityAndPrivacyEvents
data object CancelEnableEncryption : SecurityAndPrivacyEvents
data object ConfirmEnableEncryption: SecurityAndPrivacyEvents
data class ChangeHistoryVisibility(val historyVisibility: SecurityAndPrivacyHistoryVisibility) : SecurityAndPrivacyEvents
data class ChangeRoomVisibility(val isVisibleInRoomDirectory: Boolean) : SecurityAndPrivacyEvents
}

View file

@ -71,6 +71,9 @@ class SecurityAndPrivacyPresenter @AssistedInject constructor(
var currentIsEncrypted by remember(savedSettings.isEncrypted) {
mutableStateOf(savedSettings.isEncrypted)
}
var showEncryptionConfirmation by remember { mutableStateOf(false) }
val currentSettings = SecurityAndPrivacySettings(
roomAccess = currentRoomAccess,
isEncrypted = currentIsEncrypted,
@ -86,8 +89,12 @@ class SecurityAndPrivacyPresenter @AssistedInject constructor(
is SecurityAndPrivacyEvents.ChangeRoomAccess -> {
currentRoomAccess = event.roomAccess
}
is SecurityAndPrivacyEvents.EnableEncryption -> {
currentIsEncrypted = true
is SecurityAndPrivacyEvents.ToggleEncryptionState -> {
if(currentSettings.isEncrypted) {
currentIsEncrypted = false
} else {
showEncryptionConfirmation = true
}
}
is SecurityAndPrivacyEvents.ChangeHistoryVisibility -> {
currentHistoryVisibility = Optional.of(event.historyVisibility)
@ -96,12 +103,20 @@ class SecurityAndPrivacyPresenter @AssistedInject constructor(
currentVisibleInRoomDirectory = Optional.of(AsyncData.Success(event.isVisibleInRoomDirectory))
}
SecurityAndPrivacyEvents.EditRoomAddress -> navigator.openEditRoomAddress()
SecurityAndPrivacyEvents.CancelEnableEncryption -> {
showEncryptionConfirmation = false
}
SecurityAndPrivacyEvents.ConfirmEnableEncryption -> {
showEncryptionConfirmation = false
currentIsEncrypted = true
}
}
}
return SecurityAndPrivacyState(
savedSettings = savedSettings,
currentSettings = currentSettings,
homeserverName = homeserverName,
showEncryptionConfirmation = showEncryptionConfirmation,
eventSink = ::handleEvents
)
}

View file

@ -15,6 +15,7 @@ data class SecurityAndPrivacyState(
val savedSettings: SecurityAndPrivacySettings,
val currentSettings: SecurityAndPrivacySettings,
val homeserverName: String,
val showEncryptionConfirmation: Boolean,
val eventSink: (SecurityAndPrivacyEvents) -> Unit
) {

View file

@ -41,6 +41,9 @@ open class SecurityAndPrivacyStateProvider : PreviewParameterProvider<SecurityAn
isVisibleInRoomDirectory = Optional.of(AsyncData.Success(true))
)
),
aSecurityAndPrivacyState(
showEncryptionConfirmation = true
),
)
}
@ -62,10 +65,12 @@ fun aSecurityAndPrivacyState(
currentSettings: SecurityAndPrivacySettings = aSecurityAndPrivacySettings(),
savedSettings: SecurityAndPrivacySettings = currentSettings,
homeserverName: String = "myserver.xyz",
showEncryptionConfirmation: Boolean = false,
eventSink: (SecurityAndPrivacyEvents) -> Unit = {}
) = SecurityAndPrivacyState(
currentSettings = currentSettings,
savedSettings = savedSettings,
homeserverName = homeserverName,
showEncryptionConfirmation = showEncryptionConfirmation,
eventSink = eventSink
)

View file

@ -33,6 +33,7 @@ import io.element.android.features.roomdetails.impl.R
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.designsystem.components.list.ListItemContent
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
@ -69,10 +70,10 @@ fun SecurityAndPrivacyView(
) { padding ->
Column(
modifier = Modifier
.padding(padding)
.imePadding()
.verticalScroll(rememberScrollState())
.consumeWindowInsets(padding),
.padding(padding)
.imePadding()
.verticalScroll(rememberScrollState())
.consumeWindowInsets(padding),
verticalArrangement = Arrangement.spacedBy(32.dp),
) {
RoomAccessSection(
@ -93,9 +94,12 @@ fun SecurityAndPrivacyView(
)
}
EncryptionSection(
isEncryptionEnabled = state.currentSettings.isEncrypted,
isRoomEncrypted = state.currentSettings.isEncrypted,
isSectionEnabled = !state.savedSettings.isEncrypted,
onEnableEncryption = { state.eventSink(SecurityAndPrivacyEvents.EnableEncryption) },
onToggleEncryption = { state.eventSink(SecurityAndPrivacyEvents.ToggleEncryptionState) },
showConfirmation = state.showEncryptionConfirmation,
onDismissConfirmation = { state.eventSink(SecurityAndPrivacyEvents.CancelEnableEncryption) },
onConfirmEncryption = { state.eventSink(SecurityAndPrivacyEvents.ConfirmEnableEncryption) },
)
if (state.showRoomHistoryVisibilitySection) {
RoomHistorySection(
@ -246,8 +250,8 @@ private fun RoomAddressSection(
ListItemContent.Custom {
CircularProgressIndicator(
modifier = Modifier
.progressSemantics()
.size(20.dp),
.progressSemantics()
.size(20.dp),
strokeWidth = 2.dp
)
}
@ -272,9 +276,12 @@ private fun RoomAddressSection(
@Composable
private fun EncryptionSection(
isEncryptionEnabled: Boolean,
isRoomEncrypted: Boolean,
isSectionEnabled: Boolean,
onEnableEncryption: () -> Unit,
showConfirmation: Boolean,
onToggleEncryption: () -> Unit,
onConfirmEncryption: () -> Unit,
onDismissConfirmation: () -> Unit,
modifier: Modifier = Modifier,
) {
SecurityAndPrivacySection(
@ -285,10 +292,20 @@ private fun EncryptionSection(
headlineContent = { Text(text = stringResource(CommonStrings.screen_security_and_privacy_encryption_toggle_title)) },
supportingContent = { Text(text = stringResource(CommonStrings.screen_security_and_privacy_encryption_section_footer)) },
trailingContent = ListItemContent.Switch(
checked = isEncryptionEnabled,
checked = isRoomEncrypted,
enabled = isSectionEnabled,
onChange = { onEnableEncryption() }
onChange = { onToggleEncryption() },
),
onClick = onToggleEncryption,
)
}
if (showConfirmation) {
ConfirmationDialog(
title = stringResource(CommonStrings.screen_security_and_privacy_enable_encryption_alert_title),
content = stringResource(CommonStrings.screen_security_and_privacy_enable_encryption_alert_description),
submitText = stringResource(CommonStrings.screen_security_and_privacy_enable_encryption_alert_confirm_button_title),
onSubmitClick = onConfirmEncryption,
onDismiss = onDismissConfirmation,
)
}
}