Widget: Handle failures on permissions

This commit is contained in:
ganfra 2020-05-29 16:44:17 +02:00
parent 7df8b3a9bf
commit 2002252f72
8 changed files with 85 additions and 35 deletions

View file

@ -30,11 +30,14 @@ import im.vector.riotx.core.extensions.addFragment
import im.vector.riotx.core.platform.ToolbarConfigurable
import im.vector.riotx.core.platform.VectorBaseActivity
import im.vector.riotx.features.widgets.permissions.RoomWidgetPermissionBottomSheet
import im.vector.riotx.features.widgets.permissions.RoomWidgetPermissionViewEvents
import im.vector.riotx.features.widgets.permissions.RoomWidgetPermissionViewModel
import im.vector.riotx.features.widgets.permissions.RoomWidgetPermissionViewState
import kotlinx.android.synthetic.main.activity_widget.*
import java.io.Serializable
import javax.inject.Inject
class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewModel.Factory {
class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewModel.Factory, RoomWidgetPermissionViewModel.Factory {
companion object {
@ -61,7 +64,10 @@ class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewMode
}
@Inject lateinit var viewModelFactory: WidgetViewModel.Factory
@Inject lateinit var permissionsViewModelFactory: RoomWidgetPermissionViewModel.Factory
private val viewModel: WidgetViewModel by viewModel()
private val permissionViewModel: RoomWidgetPermissionViewModel by viewModel()
override fun getLayoutRes() = R.layout.activity_widget
@ -85,6 +91,12 @@ class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewMode
}
}
permissionViewModel.observeViewEvents {
when (it) {
is RoomWidgetPermissionViewEvents.Close -> finish()
}
}
viewModel.selectSubscribe(this, WidgetViewState::status) { ws ->
when (ws) {
WidgetStatus.UNKNOWN -> {
@ -95,11 +107,7 @@ class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewMode
return@selectSubscribe
} else {
RoomWidgetPermissionBottomSheet
.newInstance(widgetArgs).apply {
onFinish = { accepted ->
if (!accepted) finish()
}
}
.newInstance(widgetArgs)
.show(supportFragmentManager, WIDGET_PERMISSION_FRAGMENT_TAG)
}
}
@ -124,6 +132,10 @@ class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewMode
return viewModelFactory.create(initialState)
}
override fun create(initialState: RoomWidgetPermissionViewState): RoomWidgetPermissionViewModel {
return permissionsViewModelFactory.create(initialState)
}
private fun handleClose(event: WidgetViewEvents.Close) {
if (event.content != null) {
val intent = createResultIntent(event.content)

View file

@ -24,7 +24,6 @@ import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.core.view.forEach
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import com.airbnb.mvrx.Fail
@ -76,6 +75,7 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
is WidgetViewEvents.DisplayTerms -> displayTerms(it)
is WidgetViewEvents.LoadFormattedURL -> loadFormattedUrl(it)
is WidgetViewEvents.DisplayIntegrationManager -> displayIntegrationManager(it)
is WidgetViewEvents.Failure -> displayErrorDialog(it.throwable)
}
}
}

View file

@ -20,6 +20,7 @@ import im.vector.matrix.android.api.session.events.model.Content
import im.vector.riotx.core.platform.VectorViewEvents
sealed class WidgetViewEvents : VectorViewEvents {
data class Failure(val throwable: Throwable): WidgetViewEvents()
data class Close(val content: Content? = null) : WidgetViewEvents()
data class DisplayIntegrationManager(val integId: String?, val integType: String?) : WidgetViewEvents()
data class LoadFormattedURL(val formattedURL: String) : WidgetViewEvents()

View file

@ -158,18 +158,27 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
private fun handleRevokeWidget() {
viewModelScope.launch {
val widgetId = initialState.widgetId ?: return@launch
WidgetPermissionsHelper(integrationManagerService, widgetService).changePermission(initialState.roomId, widgetId, false)
_viewEvents.post(WidgetViewEvents.Close())
try {
WidgetPermissionsHelper(integrationManagerService, widgetService).changePermission(initialState.roomId, widgetId, false)
_viewEvents.post(WidgetViewEvents.Close())
} catch (failure: Throwable) {
_viewEvents.post(WidgetViewEvents.Failure(failure))
}
}
}
private fun handleDeleteWidget() {
viewModelScope.launch {
val widgetId = initialState.widgetId ?: return@launch
awaitCallback<Unit> {
widgetService.destroyRoomWidget(initialState.roomId, widgetId, it)
_viewEvents.post(WidgetViewEvents.Close())
try {
awaitCallback<Unit> {
widgetService.destroyRoomWidget(initialState.roomId, widgetId, it)
_viewEvents.post(WidgetViewEvents.Close())
}
} catch (failure: Throwable) {
_viewEvents.post(WidgetViewEvents.Failure(failure))
}
}
}

View file

@ -21,4 +21,5 @@ import im.vector.riotx.core.platform.VectorViewModelAction
sealed class RoomWidgetPermissionActions : VectorViewModelAction {
object AllowWidget: RoomWidgetPermissionActions()
object BlockWidget: RoomWidgetPermissionActions()
object DoClose: RoomWidgetPermissionActions()
}

View file

@ -25,7 +25,7 @@ import android.widget.TextView
import butterknife.BindView
import butterknife.OnClick
import com.airbnb.mvrx.MvRx
import com.airbnb.mvrx.fragmentViewModel
import com.airbnb.mvrx.activityViewModel
import com.airbnb.mvrx.withState
import im.vector.matrix.android.api.util.toMatrixItem
import im.vector.riotx.R
@ -36,11 +36,11 @@ import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.widgets.WidgetArgs
import javax.inject.Inject
class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomWidgetPermissionViewModel.Factory {
class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment() {
override fun getLayoutResId(): Int = R.layout.bottom_sheet_room_widget_permission
private val viewModel: RoomWidgetPermissionViewModel by fragmentViewModel()
private val viewModel: RoomWidgetPermissionViewModel by activityViewModel()
@BindView(R.id.bottom_sheet_widget_permission_shared_info)
lateinit var sharedInfoTextView: TextView
@ -55,9 +55,6 @@ class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment(), R
lateinit var authorAvatarView: ImageView
@Inject lateinit var avatarRenderer: AvatarRenderer
@Inject lateinit var viewModelFactory: RoomWidgetPermissionViewModel.Factory
var onFinish: ((Boolean) -> Unit)? = null
override val showExpanded = true
@ -65,10 +62,6 @@ class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment(), R
injector.inject(this)
}
override fun create(initialState: RoomWidgetPermissionViewState): RoomWidgetPermissionViewModel {
return viewModelFactory.create(initialState)
}
override fun invalidate() = withState(viewModel) { state ->
super.invalidate()
val permissionData = state.permissionData() ?: return@withState
@ -112,7 +105,6 @@ class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment(), R
viewModel.handle(RoomWidgetPermissionActions.BlockWidget)
//optimistic dismiss
dismiss()
onFinish?.invoke(false)
}
@OnClick(R.id.bottom_sheet_widget_permission_continue_button)
@ -120,12 +112,11 @@ class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment(), R
viewModel.handle(RoomWidgetPermissionActions.AllowWidget)
//optimistic dismiss
dismiss()
onFinish?.invoke(true)
}
override fun onCancel(dialog: DialogInterface) {
super.onCancel(dialog)
onFinish?.invoke(false)
viewModel.handle(RoomWidgetPermissionActions.DoClose)
}
companion object {

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2020 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 im.vector.riotx.features.widgets.permissions
import im.vector.riotx.core.platform.VectorViewEvents
sealed class RoomWidgetPermissionViewEvents : VectorViewEvents {
object Close : RoomWidgetPermissionViewEvents()
}

View file

@ -27,14 +27,14 @@ import im.vector.matrix.android.api.query.QueryStringValue
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.rx.rx
import im.vector.riotx.R
import im.vector.riotx.core.platform.EmptyViewEvents
import im.vector.riotx.core.platform.VectorViewModel
import kotlinx.coroutines.launch
import timber.log.Timber
import java.net.URL
class RoomWidgetPermissionViewModel @AssistedInject constructor(@Assisted val initialState: RoomWidgetPermissionViewState,
private val session: Session)
: VectorViewModel<RoomWidgetPermissionViewState, RoomWidgetPermissionActions, EmptyViewEvents>(initialState) {
: VectorViewModel<RoomWidgetPermissionViewState, RoomWidgetPermissionActions, RoomWidgetPermissionViewEvents>(initialState) {
private val widgetService = session.widgetService()
private val integrationManagerService = session.integrationManagerService()
@ -86,20 +86,33 @@ class RoomWidgetPermissionViewModel @AssistedInject constructor(@Assisted val in
private fun handleRevokeWidget() = withState { state ->
viewModelScope.launch {
if (state.permissionData()?.isWebviewWidget.orFalse()) {
WidgetPermissionsHelper(integrationManagerService, widgetService).changePermission(state.roomId, state.widgetId, false)
} else {
//TODO JITSI
try {
if (state.permissionData()?.isWebviewWidget.orFalse()) {
WidgetPermissionsHelper(integrationManagerService, widgetService).changePermission(state.roomId, state.widgetId, false)
} else {
//TODO JITSI
}
} catch (failure: Throwable) {
Timber.v("Failure revoking widget: ${state.widgetId}")
} finally {
// We send close event in every situation
_viewEvents.post(RoomWidgetPermissionViewEvents.Close)
}
}
}
private fun handleAllowWidget() = withState { state ->
viewModelScope.launch {
if (state.permissionData()?.isWebviewWidget.orFalse()) {
WidgetPermissionsHelper(integrationManagerService, widgetService).changePermission(state.roomId, state.widgetId, true)
} else {
//TODO JITSI
try {
if (state.permissionData()?.isWebviewWidget.orFalse()) {
WidgetPermissionsHelper(integrationManagerService, widgetService).changePermission(state.roomId, state.widgetId, true)
} else {
//TODO JITSI
}
} catch (failure: Throwable) {
Timber.v("Failure allowing widget: ${state.widgetId}")
// We send close event only when it's failed
_viewEvents.post(RoomWidgetPermissionViewEvents.Close)
}
}
}