feat(security&privacy) : get data from sdk
This commit is contained in:
parent
6e4bcedc4c
commit
6e43c2d659
5 changed files with 118 additions and 33 deletions
|
|
@ -12,5 +12,5 @@ sealed interface SecurityAndPrivacyEvents {
|
||||||
data class ChangeRoomAccess(val roomAccess: SecurityAndPrivacyRoomAccess) : SecurityAndPrivacyEvents
|
data class ChangeRoomAccess(val roomAccess: SecurityAndPrivacyRoomAccess) : SecurityAndPrivacyEvents
|
||||||
data object EnableEncryption: SecurityAndPrivacyEvents
|
data object EnableEncryption: SecurityAndPrivacyEvents
|
||||||
data class ChangeHistoryVisibility(val historyVisibility: SecurityAndPrivacyHistoryVisibility) : SecurityAndPrivacyEvents
|
data class ChangeHistoryVisibility(val historyVisibility: SecurityAndPrivacyHistoryVisibility) : SecurityAndPrivacyEvents
|
||||||
data class ChangeVisibleInRoomDirectory(val isVisibleInRoomDirectory: Boolean) : SecurityAndPrivacyEvents
|
data class ChangeRoomVisibility(val isVisibleInRoomDirectory: Boolean) : SecurityAndPrivacyEvents
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,47 +8,129 @@
|
||||||
package io.element.android.features.roomdetails.impl.securityandprivacy
|
package io.element.android.features.roomdetails.impl.securityandprivacy
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import io.element.android.libraries.architecture.AsyncData
|
import io.element.android.libraries.architecture.AsyncData
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
|
import io.element.android.libraries.matrix.api.room.MatrixRoom
|
||||||
|
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
|
||||||
|
import io.element.android.libraries.matrix.api.room.join.JoinRule
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SecurityAndPrivacyPresenter @Inject constructor() : Presenter<SecurityAndPrivacyState> {
|
class SecurityAndPrivacyPresenter @Inject constructor() : Presenter<SecurityAndPrivacyState> {
|
||||||
|
private val matrixClient: MatrixClient,
|
||||||
|
private val room: MatrixRoom,
|
||||||
|
) : Presenter<SecurityAndPrivacyState> {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): SecurityAndPrivacyState {
|
override fun present(): SecurityAndPrivacyState {
|
||||||
|
val homeserverName = remember { matrixClient.userIdServerName() }
|
||||||
|
val roomInfo by room.roomInfoFlow.collectAsState(initial = null)
|
||||||
|
|
||||||
val savedSettings by remember {
|
val isVisibleInRoomDirectory = remember {
|
||||||
mutableStateOf(
|
mutableStateOf<AsyncData<Boolean>>(AsyncData.Uninitialized)
|
||||||
SecurityAndPrivacySettings(
|
|
||||||
roomAccess = SecurityAndPrivacyRoomAccess.InviteOnly,
|
|
||||||
isEncrypted = true,
|
|
||||||
isVisibleInRoomDirectory = Optional.empty(),
|
|
||||||
historyVisibility = Optional.empty(),
|
|
||||||
formattedAddress = Optional.empty(),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleEvents(event: SecurityAndPrivacyEvents) {
|
val savedSettings by remember {
|
||||||
when (event) {
|
derivedStateOf {
|
||||||
SecurityAndPrivacyEvents.Save -> {}
|
SecurityAndPrivacySettings(
|
||||||
is SecurityAndPrivacyEvents.ChangeRoomAccess -> {}
|
roomAccess = roomInfo?.joinRule.map(),
|
||||||
is SecurityAndPrivacyEvents.EnableEncryption -> {}
|
isEncrypted = room.isEncrypted,
|
||||||
is SecurityAndPrivacyEvents.ChangeHistoryVisibility -> {}
|
isVisibleInRoomDirectory = Optional.ofNullable(isVisibleInRoomDirectory.value),
|
||||||
is SecurityAndPrivacyEvents.ChangeVisibleInRoomDirectory -> {}
|
historyVisibility = Optional.ofNullable(roomInfo?.historyVisibility?.map()),
|
||||||
|
formattedAddress = Optional.ofNullable(roomInfo?.canonicalAlias?.value),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var currentRoomAccess by remember(savedSettings.roomAccess) {
|
||||||
|
mutableStateOf(savedSettings.roomAccess)
|
||||||
|
}
|
||||||
|
var currentHistoryVisibility by remember(savedSettings.historyVisibility) {
|
||||||
|
mutableStateOf(savedSettings.historyVisibility)
|
||||||
|
}
|
||||||
|
var currentVisibleInRoomDirectory by remember(savedSettings.isVisibleInRoomDirectory) {
|
||||||
|
mutableStateOf(savedSettings.isVisibleInRoomDirectory)
|
||||||
|
}
|
||||||
|
var currentIsEncrypted by remember(savedSettings.isEncrypted) {
|
||||||
|
mutableStateOf(savedSettings.isEncrypted)
|
||||||
|
}
|
||||||
|
val currentSettings = SecurityAndPrivacySettings(
|
||||||
|
roomAccess = currentRoomAccess,
|
||||||
|
isEncrypted = currentIsEncrypted,
|
||||||
|
isVisibleInRoomDirectory = currentVisibleInRoomDirectory,
|
||||||
|
historyVisibility = currentHistoryVisibility,
|
||||||
|
formattedAddress = savedSettings.formattedAddress,
|
||||||
|
)
|
||||||
|
|
||||||
|
fun handleEvents(event: SecurityAndPrivacyEvents) {
|
||||||
|
when (event) {
|
||||||
|
SecurityAndPrivacyEvents.Save -> {
|
||||||
|
}
|
||||||
|
is SecurityAndPrivacyEvents.ChangeRoomAccess -> {
|
||||||
|
currentRoomAccess = event.roomAccess
|
||||||
|
}
|
||||||
|
is SecurityAndPrivacyEvents.EnableEncryption -> {
|
||||||
|
currentIsEncrypted = true
|
||||||
|
}
|
||||||
|
is SecurityAndPrivacyEvents.ChangeHistoryVisibility -> {
|
||||||
|
currentHistoryVisibility = Optional.of(event.historyVisibility)
|
||||||
|
}
|
||||||
|
is SecurityAndPrivacyEvents.ChangeRoomVisibility -> {
|
||||||
|
currentVisibleInRoomDirectory = Optional.of(AsyncData.Success(event.isVisibleInRoomDirectory))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return SecurityAndPrivacyState(
|
return SecurityAndPrivacyState(
|
||||||
savedSettings = savedSettings,
|
savedSettings = savedSettings,
|
||||||
currentSettings = savedSettings,
|
currentSettings = currentSettings,
|
||||||
homeserverName = "",
|
homeserverName = homeserverName,
|
||||||
canBeSaved = true,
|
|
||||||
eventSink = ::handleEvents
|
eventSink = ::handleEvents
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun JoinRule?.map(): SecurityAndPrivacyRoomAccess {
|
||||||
|
return when (this) {
|
||||||
|
JoinRule.Public -> SecurityAndPrivacyRoomAccess.Anyone
|
||||||
|
JoinRule.Knock, is JoinRule.KnockRestricted -> SecurityAndPrivacyRoomAccess.AskToJoin
|
||||||
|
is JoinRule.Restricted -> SecurityAndPrivacyRoomAccess.SpaceMember
|
||||||
|
is JoinRule.Custom,
|
||||||
|
JoinRule.Invite,
|
||||||
|
JoinRule.Private,
|
||||||
|
null -> SecurityAndPrivacyRoomAccess.InviteOnly
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun SecurityAndPrivacyRoomAccess.map(): JoinRule {
|
||||||
|
return when (this) {
|
||||||
|
SecurityAndPrivacyRoomAccess.Anyone -> JoinRule.Public
|
||||||
|
SecurityAndPrivacyRoomAccess.AskToJoin -> JoinRule.Knock
|
||||||
|
SecurityAndPrivacyRoomAccess.InviteOnly -> JoinRule.Private
|
||||||
|
SecurityAndPrivacyRoomAccess.SpaceMember -> error("Unsupported")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun RoomHistoryVisibility.map(): SecurityAndPrivacyHistoryVisibility {
|
||||||
|
return when (this) {
|
||||||
|
RoomHistoryVisibility.Joined,
|
||||||
|
RoomHistoryVisibility.Invited -> SecurityAndPrivacyHistoryVisibility.SinceInvite
|
||||||
|
RoomHistoryVisibility.Shared,
|
||||||
|
is RoomHistoryVisibility.Custom -> SecurityAndPrivacyHistoryVisibility.SinceSelection
|
||||||
|
RoomHistoryVisibility.WorldReadable -> SecurityAndPrivacyHistoryVisibility.Anyone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun SecurityAndPrivacyHistoryVisibility.map(): RoomHistoryVisibility {
|
||||||
|
return when (this) {
|
||||||
|
SecurityAndPrivacyHistoryVisibility.SinceSelection -> RoomHistoryVisibility.Shared
|
||||||
|
SecurityAndPrivacyHistoryVisibility.SinceInvite -> RoomHistoryVisibility.Invited
|
||||||
|
SecurityAndPrivacyHistoryVisibility.Anyone -> RoomHistoryVisibility.WorldReadable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,11 @@ data class SecurityAndPrivacyState(
|
||||||
val savedSettings: SecurityAndPrivacySettings,
|
val savedSettings: SecurityAndPrivacySettings,
|
||||||
val currentSettings: SecurityAndPrivacySettings,
|
val currentSettings: SecurityAndPrivacySettings,
|
||||||
val homeserverName: String,
|
val homeserverName: String,
|
||||||
val canBeSaved: Boolean,
|
|
||||||
val eventSink: (SecurityAndPrivacyEvents) -> Unit
|
val eventSink: (SecurityAndPrivacyEvents) -> Unit
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
val canBeSaved = savedSettings != currentSettings
|
||||||
|
|
||||||
val showRoomVisibilitySections = currentSettings.roomAccess != SecurityAndPrivacyRoomAccess.InviteOnly && currentSettings.historyVisibility.isPresent
|
val showRoomVisibilitySections = currentSettings.roomAccess != SecurityAndPrivacyRoomAccess.InviteOnly && currentSettings.historyVisibility.isPresent
|
||||||
|
|
||||||
val availableHistoryVisibilities = buildSet {
|
val availableHistoryVisibilities = buildSet {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ open class SecurityAndPrivacyStateProvider : PreviewParameterProvider<SecurityAn
|
||||||
isVisibleInRoomDirectory = Optional.of(AsyncData.Success(true))
|
isVisibleInRoomDirectory = Optional.of(AsyncData.Success(true))
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
aSecurityAndPrivacyState(canBeSaved = false)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,13 +61,11 @@ fun aSecurityAndPrivacySettings(
|
||||||
fun aSecurityAndPrivacyState(
|
fun aSecurityAndPrivacyState(
|
||||||
currentSettings: SecurityAndPrivacySettings = aSecurityAndPrivacySettings(),
|
currentSettings: SecurityAndPrivacySettings = aSecurityAndPrivacySettings(),
|
||||||
savedSettings: SecurityAndPrivacySettings = currentSettings,
|
savedSettings: SecurityAndPrivacySettings = currentSettings,
|
||||||
canBeSaved: Boolean = true,
|
|
||||||
homeserverName: String = "myserver.xyz",
|
homeserverName: String = "myserver.xyz",
|
||||||
eventSink: (SecurityAndPrivacyEvents) -> Unit = {}
|
eventSink: (SecurityAndPrivacyEvents) -> Unit = {}
|
||||||
) = SecurityAndPrivacyState(
|
) = SecurityAndPrivacyState(
|
||||||
currentSettings = currentSettings,
|
currentSettings = currentSettings,
|
||||||
savedSettings = savedSettings,
|
savedSettings = savedSettings,
|
||||||
homeserverName = homeserverName,
|
homeserverName = homeserverName,
|
||||||
canBeSaved = canBeSaved,
|
|
||||||
eventSink = eventSink
|
eventSink = eventSink
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -69,10 +69,10 @@ fun SecurityAndPrivacyView(
|
||||||
) { padding ->
|
) { padding ->
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(padding)
|
.padding(padding)
|
||||||
.imePadding()
|
.imePadding()
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
.consumeWindowInsets(padding),
|
.consumeWindowInsets(padding),
|
||||||
verticalArrangement = Arrangement.spacedBy(32.dp),
|
verticalArrangement = Arrangement.spacedBy(32.dp),
|
||||||
) {
|
) {
|
||||||
RoomAccessSection(
|
RoomAccessSection(
|
||||||
|
|
@ -87,11 +87,14 @@ fun SecurityAndPrivacyView(
|
||||||
homeserverName = state.homeserverName,
|
homeserverName = state.homeserverName,
|
||||||
onRoomAddressClick = { },
|
onRoomAddressClick = { },
|
||||||
isVisibleInPublicDirectory = state.currentSettings.isVisibleInRoomDirectory,
|
isVisibleInPublicDirectory = state.currentSettings.isVisibleInRoomDirectory,
|
||||||
onVisibilityChange = { },
|
onVisibilityChange = { isVisible ->
|
||||||
|
state.eventSink(SecurityAndPrivacyEvents.ChangeRoomVisibility(isVisible))
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
EncryptionSection(
|
EncryptionSection(
|
||||||
isEncryptionEnabled = state.currentSettings.isEncrypted,
|
isEncryptionEnabled = state.currentSettings.isEncrypted,
|
||||||
|
isSectionEnabled = !state.savedSettings.isEncrypted,
|
||||||
onEnableEncryption = { state.eventSink(SecurityAndPrivacyEvents.EnableEncryption) },
|
onEnableEncryption = { state.eventSink(SecurityAndPrivacyEvents.EnableEncryption) },
|
||||||
)
|
)
|
||||||
if (state.showRoomHistoryVisibilitySection) {
|
if (state.showRoomHistoryVisibilitySection) {
|
||||||
|
|
@ -243,8 +246,8 @@ private fun RoomAddressSection(
|
||||||
ListItemContent.Custom {
|
ListItemContent.Custom {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.progressSemantics()
|
.progressSemantics()
|
||||||
.size(20.dp),
|
.size(20.dp),
|
||||||
strokeWidth = 2.dp
|
strokeWidth = 2.dp
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -270,6 +273,7 @@ private fun RoomAddressSection(
|
||||||
@Composable
|
@Composable
|
||||||
private fun EncryptionSection(
|
private fun EncryptionSection(
|
||||||
isEncryptionEnabled: Boolean,
|
isEncryptionEnabled: Boolean,
|
||||||
|
isSectionEnabled: Boolean,
|
||||||
onEnableEncryption: () -> Unit,
|
onEnableEncryption: () -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
|
|
@ -282,7 +286,7 @@ private fun EncryptionSection(
|
||||||
supportingContent = { Text(text = stringResource(CommonStrings.screen_security_and_privacy_encryption_section_footer)) },
|
supportingContent = { Text(text = stringResource(CommonStrings.screen_security_and_privacy_encryption_section_footer)) },
|
||||||
trailingContent = ListItemContent.Switch(
|
trailingContent = ListItemContent.Switch(
|
||||||
checked = isEncryptionEnabled,
|
checked = isEncryptionEnabled,
|
||||||
enabled = !isEncryptionEnabled,
|
enabled = isSectionEnabled,
|
||||||
onChange = { onEnableEncryption() }
|
onChange = { onEnableEncryption() }
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue