From 591df14450c0c9123c2dc2c323f1745ea3207bc7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 6 May 2024 22:32:54 +0200 Subject: [PATCH] Add distributor selection in advanced settings --- features/preferences/impl/build.gradle.kts | 1 + .../impl/advanced/AdvancedSettingsEvents.kt | 3 ++ .../advanced/AdvancedSettingsPresenter.kt | 44 +++++++++++++++++++ .../impl/advanced/AdvancedSettingsState.kt | 4 ++ .../advanced/AdvancedSettingsStateProvider.kt | 8 ++++ .../impl/advanced/AdvancedSettingsView.kt | 29 ++++++++++++ 6 files changed, 89 insertions(+) diff --git a/features/preferences/impl/build.gradle.kts b/features/preferences/impl/build.gradle.kts index edfb275f17..d0aae53303 100644 --- a/features/preferences/impl/build.gradle.kts +++ b/features/preferences/impl/build.gradle.kts @@ -57,6 +57,7 @@ dependencies { implementation(projects.libraries.mediaupload.api) implementation(projects.libraries.permissions.api) implementation(projects.libraries.push.api) + implementation(projects.libraries.pushproviders.api) implementation(projects.features.rageshake.api) implementation(projects.features.lockscreen.api) implementation(projects.features.analytics.api) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsEvents.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsEvents.kt index ab4987f9d9..31c80acb7d 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsEvents.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsEvents.kt @@ -24,4 +24,7 @@ sealed interface AdvancedSettingsEvents { data object ChangeTheme : AdvancedSettingsEvents data object CancelChangeTheme : AdvancedSettingsEvents data class SetTheme(val theme: Theme) : AdvancedSettingsEvents + data object ChangePushProvider : AdvancedSettingsEvents + data object CancelChangePushProvider : AdvancedSettingsEvents + data class SetPushProvider(val distributorName: String) : AdvancedSettingsEvents } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenter.kt index 67532574b0..3dd9f54e6f 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsPresenter.kt @@ -17,8 +17,10 @@ package io.element.android.features.preferences.impl.advanced import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -28,12 +30,17 @@ import io.element.android.compound.theme.mapToTheme import io.element.android.features.preferences.api.store.AppPreferencesStore import io.element.android.features.preferences.api.store.SessionPreferencesStore import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.matrix.api.MatrixClient +import io.element.android.libraries.push.api.PushService +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.launch import javax.inject.Inject class AdvancedSettingsPresenter @Inject constructor( private val appPreferencesStore: AppPreferencesStore, private val sessionPreferencesStore: SessionPreferencesStore, + private val matrixClient: MatrixClient, + private val pushService: PushService, ) : Presenter { @Composable override fun present(): AdvancedSettingsState { @@ -49,6 +56,21 @@ class AdvancedSettingsPresenter @Inject constructor( } .collectAsState(initial = Theme.System) var showChangeThemeDialog by remember { mutableStateOf(false) } + + var currentPushProvider by remember { mutableStateOf(null) } + var distributors by remember { mutableStateOf>(emptyList()) } + var refreshPushProvider by remember { mutableIntStateOf(0) } + + LaunchedEffect(refreshPushProvider) { + val p = pushService.getCurrentPushProvider() + currentPushProvider = p?.getCurrentDistributor(matrixClient)?.name + distributors = pushService.getAvailablePushProviders() + .flatMap { pushProvider -> + pushProvider.getDistributors().map { it.name } + } + } + + var showChangePushProviderDialog by remember { mutableStateOf(false) } fun handleEvents(event: AdvancedSettingsEvents) { when (event) { is AdvancedSettingsEvents.SetDeveloperModeEnabled -> localCoroutineScope.launch { @@ -63,6 +85,25 @@ class AdvancedSettingsPresenter @Inject constructor( appPreferencesStore.setTheme(event.theme.name) showChangeThemeDialog = false } + AdvancedSettingsEvents.ChangePushProvider -> showChangePushProviderDialog = true + AdvancedSettingsEvents.CancelChangePushProvider -> showChangePushProviderDialog = false + is AdvancedSettingsEvents.SetPushProvider -> { + localCoroutineScope.launch { + // Retrieve the push provider + // TODO rework this + val pushProvider = pushService.getAvailablePushProviders().firstOrNull { pushProvider -> + pushProvider.getDistributors().any { it.name == event.distributorName } + } ?: return@launch + val distributor = pushProvider.getDistributors().firstOrNull { it.name == event.distributorName } ?: return@launch + pushService.registerWith( + matrixClient, + pushProvider = pushProvider, + distributor = distributor + ) + showChangePushProviderDialog = false + refreshPushProvider++ + } + } } } @@ -71,6 +112,9 @@ class AdvancedSettingsPresenter @Inject constructor( isSharePresenceEnabled = isSharePresenceEnabled, theme = theme, showChangeThemeDialog = showChangeThemeDialog, + pushDistributor = currentPushProvider ?: "", + pushDistributors = distributors.toImmutableList(), + showChangePushProviderDialog = showChangePushProviderDialog, eventSink = { handleEvents(it) } ) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt index 527515d867..8a0184bf8b 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsState.kt @@ -17,11 +17,15 @@ package io.element.android.features.preferences.impl.advanced import io.element.android.compound.theme.Theme +import kotlinx.collections.immutable.ImmutableList data class AdvancedSettingsState( val isDeveloperModeEnabled: Boolean, val isSharePresenceEnabled: Boolean, val theme: Theme, val showChangeThemeDialog: Boolean, + val pushDistributor: String, + val pushDistributors: ImmutableList, + val showChangePushProviderDialog: Boolean, val eventSink: (AdvancedSettingsEvents) -> Unit ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsStateProvider.kt index fb6f2a2659..ff15917c91 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsStateProvider.kt @@ -18,6 +18,7 @@ package io.element.android.features.preferences.impl.advanced import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.compound.theme.Theme +import kotlinx.collections.immutable.toImmutableList open class AdvancedSettingsStateProvider : PreviewParameterProvider { override val values: Sequence @@ -26,6 +27,7 @@ open class AdvancedSettingsStateProvider : PreviewParameterProvider = listOf("Firebase", "ntfy"), + showChangePushProviderDialog: Boolean = false, ) = AdvancedSettingsState( isDeveloperModeEnabled = isDeveloperModeEnabled, isSharePresenceEnabled = isSendPublicReadReceiptsEnabled, theme = Theme.System, showChangeThemeDialog = showChangeThemeDialog, + pushDistributor = pushDistributor, + pushDistributors = pushDistributors.toImmutableList(), + showChangePushProviderDialog = showChangePushProviderDialog, eventSink = {} ) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt index 68e1c7ea22..fc0c2d8f69 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/advanced/AdvancedSettingsView.kt @@ -81,6 +81,18 @@ fun AdvancedSettingsView( ), onClick = { state.eventSink(AdvancedSettingsEvents.SetSharePresenceEnabled(!state.isSharePresenceEnabled)) } ) + ListItem( + headlineContent = { + // TODO i18n + Text(text = "Push provider") + }, + trailingContent = ListItemContent.Text( + state.pushDistributor + ), + onClick = { + state.eventSink(AdvancedSettingsEvents.ChangePushProvider) + } + ) } if (state.showChangeThemeDialog) { @@ -97,6 +109,23 @@ fun AdvancedSettingsView( onDismissRequest = { state.eventSink(AdvancedSettingsEvents.CancelChangeTheme) }, ) } + + if (state.showChangePushProviderDialog) { + SingleSelectionDialog( + options = state.pushDistributors.map { + ListOption(title = it) + }.toImmutableList(), + initialSelection = state.pushDistributors.indexOf(state.pushDistributor), + onOptionSelected = { + state.eventSink( + AdvancedSettingsEvents.SetPushProvider( + state.pushDistributors[it] + ) + ) + }, + onDismissRequest = { state.eventSink(AdvancedSettingsEvents.CancelChangePushProvider) }, + ) + } } @Composable