diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsEvents.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsEvents.kt new file mode 100644 index 0000000000..005077d81b --- /dev/null +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsEvents.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.lockscreen.impl.settings + +sealed interface LockScreenSettingsEvents { + data object RemovePin : LockScreenSettingsEvents + data object ConfirmRemovePin : LockScreenSettingsEvents + data object CancelRemovePin : LockScreenSettingsEvents + data object ChangePin : LockScreenSettingsEvents + data object ToggleBiometric : LockScreenSettingsEvents +} diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsNode.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsNode.kt new file mode 100644 index 0000000000..6b47984076 --- /dev/null +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsNode.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.lockscreen.impl.settings + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import io.element.android.anvilannotations.ContributesNode +import io.element.android.libraries.di.AppScope + +@ContributesNode(AppScope::class) +class LockScreenSettingsNode @AssistedInject constructor( + @Assisted buildContext: BuildContext, + @Assisted plugins: List, + private val presenter: LockScreenSettingsPresenter, +) : Node(buildContext, plugins = plugins) { + + @Composable + override fun View(modifier: Modifier) { + val state = presenter.present() + LockScreenSettingsView( + state = state, + modifier = modifier + ) + } +} diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsPresenter.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsPresenter.kt new file mode 100644 index 0000000000..2f02bb3982 --- /dev/null +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsPresenter.kt @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.lockscreen.impl.settings + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import io.element.android.libraries.architecture.Presenter +import javax.inject.Inject + +class LockScreenSettingsPresenter @Inject constructor() : Presenter { + + @Composable + override fun present(): LockScreenSettingsState { + + var isLockMandatory by remember { + mutableStateOf(false) + } + var isBiometricEnabled by remember { + mutableStateOf(false) + } + var showRemovePinConfirmation by remember { + mutableStateOf(false) + } + + fun handleEvents(event: LockScreenSettingsEvents) { + when (event) { + LockScreenSettingsEvents.CancelRemovePin -> TODO() + LockScreenSettingsEvents.ChangePin -> TODO() + LockScreenSettingsEvents.ConfirmRemovePin -> TODO() + LockScreenSettingsEvents.RemovePin -> TODO() + LockScreenSettingsEvents.ToggleBiometric -> TODO() + } + } + + return LockScreenSettingsState( + isLockMandatory = isLockMandatory, + isBiometricEnabled = isBiometricEnabled, + showRemovePinConfirmation = showRemovePinConfirmation, + eventSink = ::handleEvents + ) + } +} diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsState.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsState.kt new file mode 100644 index 0000000000..06f74af9c9 --- /dev/null +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsState.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.lockscreen.impl.settings + +data class LockScreenSettingsState( + val isLockMandatory: Boolean, + val isBiometricEnabled: Boolean, + val showRemovePinConfirmation: Boolean, + val eventSink: (LockScreenSettingsEvents) -> Unit +) diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsStateProvider.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsStateProvider.kt new file mode 100644 index 0000000000..3c4ce83452 --- /dev/null +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsStateProvider.kt @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.lockscreen.impl.settings + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +open class LockScreenSettingsStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + aLockScreenSettingsState(), + aLockScreenSettingsState(isLockMandatory = true), + aLockScreenSettingsState(showRemovePinConfirmation = true), + ) +} + +fun aLockScreenSettingsState( + isLockMandatory: Boolean = false, + isBiometricEnabled: Boolean = false, + showRemovePinConfirmation: Boolean = false, +) = LockScreenSettingsState( + isLockMandatory = isLockMandatory, + isBiometricEnabled = isBiometricEnabled, + showRemovePinConfirmation = showRemovePinConfirmation, + eventSink = {} +) diff --git a/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsView.kt b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsView.kt new file mode 100644 index 0000000000..57c07213ce --- /dev/null +++ b/features/lockscreen/impl/src/main/kotlin/io/element/android/features/lockscreen/impl/settings/LockScreenSettingsView.kt @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.features.lockscreen.impl.settings + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewParameter +import io.element.android.features.lockscreen.impl.R +import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog +import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory +import io.element.android.libraries.designsystem.components.preferences.PreferenceDivider +import io.element.android.libraries.designsystem.components.preferences.PreferencePage +import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch +import io.element.android.libraries.designsystem.components.preferences.PreferenceText +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight +import io.element.android.libraries.theme.ElementTheme + +@Composable +fun LockScreenSettingsView( + state: LockScreenSettingsState, + modifier: Modifier = Modifier, +) { + PreferencePage( + title = stringResource(id = io.element.android.libraries.ui.strings.R.string.common_screen_lock), + modifier = modifier + ) { + PreferenceCategory(showDivider = false) { + PreferenceText( + title = stringResource(id = R.string.screen_app_lock_settings_change_pin), + onClick = { + state.eventSink(LockScreenSettingsEvents.ChangePin) + } + ) + PreferenceDivider() + if (!state.isLockMandatory) { + PreferenceText( + title = stringResource(id = R.string.screen_app_lock_settings_remove_pin), + tintColor = ElementTheme.colors.textCriticalPrimary, + onClick = { + state.eventSink(LockScreenSettingsEvents.RemovePin) + } + ) + } + PreferenceDivider() + PreferenceSwitch(title = stringResource(id = R.string.screen_app_lock_settings_enable_biometric_unlock), isChecked = state.isBiometricEnabled) + } + } + if (state.showRemovePinConfirmation) { + ConfirmationDialog( + title = stringResource(id = R.string.screen_app_lock_settings_remove_pin_alert_title), + content = stringResource(id = R.string.screen_app_lock_settings_remove_pin_alert_message), + onSubmitClicked = { + state.eventSink(LockScreenSettingsEvents.ConfirmRemovePin) + }, + onDismiss = { + state.eventSink(LockScreenSettingsEvents.CancelRemovePin) + }) + } +} + +@PreviewsDayNight +@Composable +internal fun LockScreenSettingsViewPreview( + @PreviewParameter(LockScreenSettingsStateProvider::class) state: LockScreenSettingsState, +) { + ElementPreview { + LockScreenSettingsView(state) + } +}