Browse Source

Move open system setting to the PermissionsPresenter

pull/1400/head
Benoit Marty 1 year ago committed by Benoit Marty
parent
commit
dd5d67d186
  1. 4
      features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt
  2. 3
      features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt
  3. 4
      features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt
  4. 3
      features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt
  5. 4
      features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditNode.kt
  6. 3
      features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt
  7. 1
      libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsEvents.kt
  8. 5
      libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsView.kt
  9. 6
      libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt
  10. 34
      libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/AndroidLocationActions.kt
  11. 21
      libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/PermissionActions.kt
  12. 55
      libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt
  13. 26
      libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/action/FakePermissionActions.kt
  14. 1
      libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionsPresenter.kt

4
features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomNode.kt

@ -18,7 +18,6 @@ package io.element.android.features.createroom.impl.configureroom @@ -18,7 +18,6 @@ package io.element.android.features.createroom.impl.configureroom
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
@ -29,7 +28,6 @@ import dagger.assisted.AssistedInject @@ -29,7 +28,6 @@ import dagger.assisted.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode
import io.element.android.features.createroom.impl.di.CreateRoomScope
import io.element.android.libraries.androidutils.system.openAppSettingsPage
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.services.analytics.api.AnalyticsService
@ -60,13 +58,11 @@ class ConfigureRoomNode @AssistedInject constructor( @@ -60,13 +58,11 @@ class ConfigureRoomNode @AssistedInject constructor(
@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
val context = LocalContext.current
ConfigureRoomView(
state = state,
modifier = modifier,
onBackPressed = this::navigateUp,
onRoomCreated = this::onRoomCreated,
onOpenSystemSettings = { context.openAppSettingsPage() }
)
}
}

3
features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomView.kt

@ -76,7 +76,6 @@ fun ConfigureRoomView( @@ -76,7 +76,6 @@ fun ConfigureRoomView(
state: ConfigureRoomState,
onBackPressed: () -> Unit,
onRoomCreated: (RoomId) -> Unit,
onOpenSystemSettings: () -> Unit,
modifier: Modifier = Modifier,
) {
val coroutineScope = rememberCoroutineScope()
@ -177,7 +176,6 @@ fun ConfigureRoomView( @@ -177,7 +176,6 @@ fun ConfigureRoomView(
PermissionsView(
state = state.cameraPermissionState,
onOpenSystemSettings = onOpenSystemSettings,
)
}
@ -287,6 +285,5 @@ internal fun ConfigureRoomViewPreview(@PreviewParameter(ConfigureRoomStateProvid @@ -287,6 +285,5 @@ internal fun ConfigureRoomViewPreview(@PreviewParameter(ConfigureRoomStateProvid
state = state,
onBackPressed = {},
onRoomCreated = {},
onOpenSystemSettings = {},
)
}

4
features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt

@ -18,14 +18,12 @@ package io.element.android.features.preferences.impl.user.editprofile @@ -18,14 +18,12 @@ package io.element.android.features.preferences.impl.user.editprofile
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
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.androidutils.system.openAppSettingsPage
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.SessionScope
@ -48,12 +46,10 @@ class EditUserProfileNode @AssistedInject constructor( @@ -48,12 +46,10 @@ class EditUserProfileNode @AssistedInject constructor(
@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
val context = LocalContext.current
EditUserProfileView(
state = state,
onBackPressed = ::navigateUp,
onProfileEdited = ::navigateUp,
onOpenSystemSettings = { context.openAppSettingsPage() },
modifier = modifier
)
}

3
features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt

@ -69,7 +69,6 @@ fun EditUserProfileView( @@ -69,7 +69,6 @@ fun EditUserProfileView(
state: EditUserProfileState,
onBackPressed: () -> Unit,
onProfileEdited: () -> Unit,
onOpenSystemSettings: () -> Unit,
modifier: Modifier = Modifier,
) {
val coroutineScope = rememberCoroutineScope()
@ -172,7 +171,6 @@ fun EditUserProfileView( @@ -172,7 +171,6 @@ fun EditUserProfileView(
}
PermissionsView(
state = state.cameraPermissionState,
onOpenSystemSettings = onOpenSystemSettings,
)
}
@ -190,7 +188,6 @@ internal fun EditUserProfileViewPreview(@PreviewParameter(EditUserProfileStatePr @@ -190,7 +188,6 @@ internal fun EditUserProfileViewPreview(@PreviewParameter(EditUserProfileStatePr
EditUserProfileView(
onBackPressed = {},
onProfileEdited = {},
onOpenSystemSettings = {},
state = state,
)
}

4
features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditNode.kt

@ -18,7 +18,6 @@ package io.element.android.features.roomdetails.impl.edit @@ -18,7 +18,6 @@ package io.element.android.features.roomdetails.impl.edit
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
@ -27,7 +26,6 @@ import dagger.assisted.Assisted @@ -27,7 +26,6 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.anvilannotations.ContributesNode
import io.element.android.libraries.androidutils.system.openAppSettingsPage
import io.element.android.libraries.di.RoomScope
import io.element.android.services.analytics.api.AnalyticsService
@ -50,12 +48,10 @@ class RoomDetailsEditNode @AssistedInject constructor( @@ -50,12 +48,10 @@ class RoomDetailsEditNode @AssistedInject constructor(
@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
val context = LocalContext.current
RoomDetailsEditView(
state = state,
onBackPressed = ::navigateUp,
onRoomEdited = ::navigateUp,
onOpenSystemSettings = { context.openAppSettingsPage() },
modifier = modifier,
)
}

3
features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/edit/RoomDetailsEditView.kt

@ -73,7 +73,6 @@ fun RoomDetailsEditView( @@ -73,7 +73,6 @@ fun RoomDetailsEditView(
state: RoomDetailsEditState,
onBackPressed: () -> Unit,
onRoomEdited: () -> Unit,
onOpenSystemSettings: () -> Unit,
modifier: Modifier = Modifier,
) {
val coroutineScope = rememberCoroutineScope()
@ -198,7 +197,6 @@ fun RoomDetailsEditView( @@ -198,7 +197,6 @@ fun RoomDetailsEditView(
PermissionsView(
state = state.cameraPermissionState,
onOpenSystemSettings = onOpenSystemSettings,
)
}
@ -242,6 +240,5 @@ internal fun RoomDetailsEditViewPreview(@PreviewParameter(RoomDetailsEditStatePr @@ -242,6 +240,5 @@ internal fun RoomDetailsEditViewPreview(@PreviewParameter(RoomDetailsEditStatePr
state = state,
onBackPressed = {},
onRoomEdited = {},
onOpenSystemSettings = {},
)
}

1
libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsEvents.kt

@ -19,4 +19,5 @@ package io.element.android.libraries.permissions.api @@ -19,4 +19,5 @@ package io.element.android.libraries.permissions.api
sealed interface PermissionsEvents {
data object AskPermissionToUser : PermissionsEvents
data object CloseDialog : PermissionsEvents
data object OpenSystemSettingAndCloseDialog : PermissionsEvents
}

5
libraries/permissions/api/src/main/kotlin/io/element/android/libraries/permissions/api/PermissionsView.kt

@ -29,7 +29,6 @@ import io.element.android.libraries.ui.strings.CommonStrings @@ -29,7 +29,6 @@ import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun PermissionsView(
state: PermissionsState,
onOpenSystemSettings: () -> Unit,
modifier: Modifier = Modifier,
) {
if (state.showDialog.not()) return
@ -40,8 +39,7 @@ fun PermissionsView( @@ -40,8 +39,7 @@ fun PermissionsView(
content = state.permission.toDialogContent(),
submitText = stringResource(id = CommonStrings.action_open_settings),
onSubmitClicked = {
state.eventSink.invoke(PermissionsEvents.CloseDialog)
onOpenSystemSettings()
state.eventSink.invoke(PermissionsEvents.OpenSystemSettingAndCloseDialog)
},
onDismiss = { state.eventSink.invoke(PermissionsEvents.CloseDialog) },
)
@ -62,6 +60,5 @@ private fun String.toDialogContent(): String { @@ -62,6 +60,5 @@ private fun String.toDialogContent(): String {
internal fun PermissionsViewPreview(@PreviewParameter(PermissionsViewStateProvider::class) state: PermissionsState) = ElementPreview {
PermissionsView(
state = state,
onOpenSystemSettings = {},
)
}

6
libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenter.kt

@ -39,6 +39,7 @@ import io.element.android.libraries.permissions.api.PermissionsEvents @@ -39,6 +39,7 @@ import io.element.android.libraries.permissions.api.PermissionsEvents
import io.element.android.libraries.permissions.api.PermissionsPresenter
import io.element.android.libraries.permissions.api.PermissionsState
import io.element.android.libraries.permissions.api.PermissionsStore
import io.element.android.libraries.permissions.impl.action.PermissionActions
import kotlinx.coroutines.launch
import timber.log.Timber
@ -48,6 +49,7 @@ class DefaultPermissionsPresenter @AssistedInject constructor( @@ -48,6 +49,7 @@ class DefaultPermissionsPresenter @AssistedInject constructor(
@Assisted val permission: String,
private val permissionsStore: PermissionsStore,
private val composablePermissionStateProvider: ComposablePermissionStateProvider,
private val permissionActions: PermissionActions,
) : PermissionsPresenter {
@AssistedFactory
@ -117,6 +119,10 @@ class DefaultPermissionsPresenter @AssistedInject constructor( @@ -117,6 +119,10 @@ class DefaultPermissionsPresenter @AssistedInject constructor(
permissionState.launchPermissionRequest()
}
}
PermissionsEvents.OpenSystemSettingAndCloseDialog -> {
permissionActions.openSettings()
showDialog.value = false
}
}
}

34
libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/AndroidLocationActions.kt

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
/*
* 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.libraries.permissions.impl.action
import android.content.Context
import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.androidutils.system.openAppSettingsPage
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import javax.inject.Inject
@ContributesBinding(AppScope::class)
class AndroidPermissionActions @Inject constructor(
@ApplicationContext private val context: Context
) : PermissionActions {
override fun openSettings() {
context.openAppSettingsPage()
}
}

21
libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/action/PermissionActions.kt

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
/*
* 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.libraries.permissions.impl.action
interface PermissionActions {
fun openSettings()
}

55
libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/DefaultPermissionsPresenterTest.kt

@ -25,6 +25,7 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi @@ -25,6 +25,7 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.PermissionStatus
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.permissions.api.PermissionsEvents
import io.element.android.libraries.permissions.impl.action.FakePermissionActions
import io.element.android.libraries.permissions.test.InMemoryPermissionsStore
import io.element.android.tests.testutils.WarmUpRule
import kotlinx.coroutines.test.runTest
@ -52,7 +53,8 @@ class DefaultPermissionsPresenterTest { @@ -52,7 +53,8 @@ class DefaultPermissionsPresenterTest {
val presenter = DefaultPermissionsPresenter(
A_PERMISSION,
permissionsStore,
permissionStateProvider
permissionStateProvider,
FakePermissionActions(),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -84,7 +86,8 @@ class DefaultPermissionsPresenterTest { @@ -84,7 +86,8 @@ class DefaultPermissionsPresenterTest {
val presenter = DefaultPermissionsPresenter(
A_PERMISSION,
permissionsStore,
permissionStateProvider
permissionStateProvider,
FakePermissionActions(),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -99,6 +102,42 @@ class DefaultPermissionsPresenterTest { @@ -99,6 +102,42 @@ class DefaultPermissionsPresenterTest {
}
}
@Test
fun `present - user open settings`() = runTest {
val permissionsStore = InMemoryPermissionsStore(
permissionDenied = true,
permissionAsked = true
)
val permissionState = FakePermissionState(
A_PERMISSION,
PermissionStatus.Denied(shouldShowRationale = false)
)
val permissionStateProvider =
FakeComposablePermissionStateProvider(
permissionState
)
val permissionActions = FakePermissionActions()
val presenter = DefaultPermissionsPresenter(
A_PERMISSION,
permissionsStore,
permissionStateProvider,
permissionActions,
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
}.test {
skipItems(1)
val initialState = awaitItem()
initialState.eventSink.invoke(PermissionsEvents.AskPermissionToUser)
val withDialogState = awaitItem()
assertThat(withDialogState.showDialog).isTrue()
assertThat(permissionActions.openSettingsCalled).isFalse()
withDialogState.eventSink.invoke(PermissionsEvents.OpenSystemSettingAndCloseDialog)
assertThat(awaitItem().showDialog).isFalse()
assertThat(permissionActions.openSettingsCalled).isTrue()
}
}
@Test
fun `present - user does not grant permission`() = runTest {
val permissionsStore = InMemoryPermissionsStore()
@ -113,7 +152,8 @@ class DefaultPermissionsPresenterTest { @@ -113,7 +152,8 @@ class DefaultPermissionsPresenterTest {
val presenter = DefaultPermissionsPresenter(
A_PERMISSION,
permissionsStore,
permissionStateProvider
permissionStateProvider,
FakePermissionActions(),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -147,7 +187,8 @@ class DefaultPermissionsPresenterTest { @@ -147,7 +187,8 @@ class DefaultPermissionsPresenterTest {
val presenter = DefaultPermissionsPresenter(
A_PERMISSION,
permissionsStore,
permissionStateProvider
permissionStateProvider,
FakePermissionActions(),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -185,7 +226,8 @@ class DefaultPermissionsPresenterTest { @@ -185,7 +226,8 @@ class DefaultPermissionsPresenterTest {
val presenter = DefaultPermissionsPresenter(
A_PERMISSION,
permissionsStore,
permissionStateProvider
permissionStateProvider,
FakePermissionActions(),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()
@ -215,7 +257,8 @@ class DefaultPermissionsPresenterTest { @@ -215,7 +257,8 @@ class DefaultPermissionsPresenterTest {
val presenter = DefaultPermissionsPresenter(
A_PERMISSION,
permissionsStore,
permissionStateProvider
permissionStateProvider,
FakePermissionActions(),
)
moleculeFlow(RecompositionMode.Immediate) {
presenter.present()

26
libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/action/FakePermissionActions.kt

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
/*
* 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.libraries.permissions.impl.action
class FakePermissionActions : PermissionActions {
var openSettingsCalled = false
private set
override fun openSettings() {
openSettingsCalled = true
}
}

1
libraries/permissions/test/src/main/kotlin/io/element/android/libraries/permissions/test/FakePermissionsPresenter.kt

@ -31,6 +31,7 @@ class FakePermissionsPresenter( @@ -31,6 +31,7 @@ class FakePermissionsPresenter(
when (events) {
PermissionsEvents.AskPermissionToUser -> state.value = state.value.copy(showDialog = true, permissionAlreadyAsked = true)
PermissionsEvents.CloseDialog -> state.value = state.value.copy(showDialog = false)
PermissionsEvents.OpenSystemSettingAndCloseDialog -> state.value = state.value.copy(showDialog = false)
}
}

Loading…
Cancel
Save