Migrate Preferences to new architecture

This commit is contained in:
ganfra 2023-01-09 19:27:28 +01:00
parent 9e211b5e04
commit ae273bd4ea
26 changed files with 399 additions and 174 deletions

View file

@ -0,0 +1,6 @@
package io.element.android.x.features.rageshake.preferences
sealed interface RageshakePreferencesEvents {
data class SetSensitivity(val sensitivity: Float) : RageshakePreferencesEvents
data class SetIsEnabled(val isEnabled: Boolean) : RageshakePreferencesEvents
}

View file

@ -0,0 +1,59 @@
package io.element.android.x.features.rageshake.preferences
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import io.element.android.x.architecture.Presenter
import io.element.android.x.features.rageshake.rageshake.RageShake
import io.element.android.x.features.rageshake.rageshake.RageshakeDataStore
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch
import javax.inject.Inject
class RageshakePreferencesPresenter @Inject constructor(
private val rageshake: RageShake,
private val rageshakeDataStore: RageshakeDataStore,
) : Presenter<RageshakePreferencesState, RageshakePreferencesEvents> {
@Composable
override fun present(events: Flow<RageshakePreferencesEvents>): RageshakePreferencesState {
val isSupported: MutableState<Boolean> = rememberSaveable {
mutableStateOf(rageshake.isAvailable())
}
val isEnabled = rageshakeDataStore
.isEnabled()
.collectAsState(initial = false)
val sensitivity = rageshakeDataStore
.sensitivity()
.collectAsState(initial = 0f)
LaunchedEffect(Unit) {
events.collect { event ->
when (event) {
is RageshakePreferencesEvents.SetIsEnabled -> setIsEnabled(event.isEnabled)
is RageshakePreferencesEvents.SetSensitivity -> setSensitivity(event.sensitivity)
}
}
}
return RageshakePreferencesState(
isEnabled = isEnabled.value,
isSupported = isSupported.value,
sensitivity = sensitivity.value
)
}
private fun CoroutineScope.setSensitivity(sensitivity: Float) = launch {
rageshakeDataStore.setSensitivity(sensitivity)
}
private fun CoroutineScope.setIsEnabled(enabled: Boolean) = launch {
rageshakeDataStore.setIsEnabled(enabled)
}
}

View file

@ -0,0 +1,7 @@
package io.element.android.x.features.rageshake.preferences
data class RageshakePreferencesState(
val isEnabled: Boolean = false,
val isSupported: Boolean = true,
val sensitivity: Float = 0.3f,
)

View file

@ -20,42 +20,29 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.BugReport
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.airbnb.mvrx.compose.collectAsState
import com.airbnb.mvrx.compose.mavericksViewModel
import io.element.android.x.designsystem.components.preferences.PreferenceCategory
import io.element.android.x.designsystem.components.preferences.PreferenceSlide
import io.element.android.x.designsystem.components.preferences.PreferenceSwitch
import io.element.android.x.designsystem.components.preferences.PreferenceText
import io.element.android.x.element.resources.R as ElementR
import io.element.android.x.features.rageshake.detection.RageshakeDetectionViewModel
import io.element.android.x.features.rageshake.detection.RageshakeDetectionViewState
@Composable
fun RageshakePreferences(
onOpenRageShake: () -> Unit = {},
) {
RageshakePreferencesContent(
onOpenRageShake = onOpenRageShake,
)
}
@Composable
fun RageshakePreferencesContent(
fun RageshakePreferencesView(
state: RageshakePreferencesState,
modifier: Modifier = Modifier,
viewModel: RageshakeDetectionViewModel = mavericksViewModel(),
onOpenRageShake: () -> Unit = {},
onOpenRageshake: () -> Unit = {},
onIsEnabledChanged: (Boolean) -> Unit = {},
onSensitivityChanged: (Float) -> Unit = {}
) {
val state: RageshakeDetectionViewState by viewModel.collectAsState()
Column(modifier = modifier) {
PreferenceCategory(title = stringResource(id = ElementR.string.send_bug_report)) {
PreferenceText(
title = stringResource(id = ElementR.string.send_bug_report),
icon = Icons.Default.BugReport,
onClick = onOpenRageShake
onClick = onOpenRageshake
)
}
PreferenceCategory(title = stringResource(id = ElementR.string.settings_rageshake)) {
@ -63,7 +50,7 @@ fun RageshakePreferencesContent(
PreferenceSwitch(
title = stringResource(id = ElementR.string.send_bug_report_rage_shake),
isChecked = state.isEnabled,
onCheckedChange = viewModel::onEnableClicked
onCheckedChange = onIsEnabledChanged
)
PreferenceSlide(
title = stringResource(id = ElementR.string.settings_rageshake_detection_threshold),
@ -71,7 +58,7 @@ fun RageshakePreferencesContent(
value = state.sensitivity,
enabled = state.isEnabled,
steps = 3 /* 5 possible values - steps are in ]0, 1[ */,
onValueChange = viewModel::onSensitivityChange
onValueChange = onSensitivityChanged
)
} else {
PreferenceText(title = "Rageshaking is not supported by your device")
@ -82,6 +69,6 @@ fun RageshakePreferencesContent(
@Composable
@Preview
fun RageshakePreferencePreview() {
RageshakePreferences()
fun RageshakePreferencesPreview() {
RageshakePreferencesView(RageshakePreferencesState(isEnabled = true, isSupported = true, sensitivity = 0.5f))
}