mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Widget: fix loading widgets without scalar token
This commit is contained in:
parent
440c21e9f3
commit
82b4415f7d
@ -22,14 +22,12 @@ import butterknife.BindView
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.matrix.android.api.session.widgets.model.Widget
|
||||
import im.vector.matrix.android.api.session.widgets.model.WidgetType
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.cleanup
|
||||
import im.vector.riotx.core.extensions.configureWith
|
||||
import im.vector.riotx.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.riotx.core.resources.ColorProvider
|
||||
import im.vector.riotx.core.utils.openUrlInExternalBrowser
|
||||
import im.vector.riotx.features.home.room.detail.RoomDetailViewModel
|
||||
import im.vector.riotx.features.home.room.detail.RoomDetailViewState
|
||||
import im.vector.riotx.features.navigation.Navigator
|
||||
@ -75,13 +73,8 @@ class RoomWidgetsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomWidget
|
||||
}
|
||||
|
||||
override fun didSelectWidget(widget: Widget) = withState(roomDetailViewModel) {
|
||||
if (widget.type == WidgetType.Jitsi) {
|
||||
openUrlInExternalBrowser(requireContext(), widget.computedUrl)
|
||||
dismiss()
|
||||
} else {
|
||||
navigator.openRoomWidget(requireContext(), it.roomId, widget)
|
||||
dismiss()
|
||||
}
|
||||
navigator.openRoomWidget(requireContext(), it.roomId, widget)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -22,7 +22,8 @@ sealed class WidgetAction : VectorViewModelAction {
|
||||
data class OnWebViewStartedToLoad(val url: String) : WidgetAction()
|
||||
data class OnWebViewLoadingError(val url: String, val isHttpError: Boolean, val errorCode: Int, val errorDescription: String) : WidgetAction()
|
||||
data class OnWebViewLoadingSuccess(val url: String) : WidgetAction()
|
||||
object DeleteWidget: WidgetAction()
|
||||
object RevokeWidget: WidgetAction()
|
||||
object OnTermsReviewed: WidgetAction()
|
||||
object LoadFormattedUrl : WidgetAction()
|
||||
object DeleteWidget : WidgetAction()
|
||||
object RevokeWidget : WidgetAction()
|
||||
object OnTermsReviewed : WidgetAction()
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package im.vector.riotx.features.widgets
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.Menu
|
||||
@ -27,6 +28,7 @@ import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.Incomplete
|
||||
import com.airbnb.mvrx.Loading
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
@ -45,6 +47,7 @@ import im.vector.riotx.features.widgets.webview.setupForWidget
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.fragment_room_widget.*
|
||||
import timber.log.Timber
|
||||
import java.net.URISyntaxException
|
||||
import javax.inject.Inject
|
||||
|
||||
@Parcelize
|
||||
@ -71,6 +74,7 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
|
||||
viewModel.getPostAPIMediator().setWebView(widgetWebView)
|
||||
}
|
||||
viewModel.observeViewEvents {
|
||||
Timber.v("Observed view events: $it")
|
||||
when (it) {
|
||||
is WidgetViewEvents.DisplayTerms -> displayTerms(it)
|
||||
is WidgetViewEvents.LoadFormattedURL -> loadFormattedUrl(it)
|
||||
@ -78,6 +82,7 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
|
||||
is WidgetViewEvents.Failure -> displayErrorDialog(it.throwable)
|
||||
}
|
||||
}
|
||||
viewModel.handle(WidgetAction.LoadFormattedUrl)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
@ -169,58 +174,68 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
|
||||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
Timber.v("Invalidate state: $state")
|
||||
when (state.status) {
|
||||
WidgetStatus.UNKNOWN -> {
|
||||
// Hide all?
|
||||
widgetWebView.isVisible = false
|
||||
when (state.formattedURL) {
|
||||
is Incomplete -> {
|
||||
setStateError(null)
|
||||
widgetWebView.isInvisible = true
|
||||
widgetProgressBar.isIndeterminate = true
|
||||
widgetProgressBar.isVisible = true
|
||||
}
|
||||
WidgetStatus.WIDGET_NOT_ALLOWED -> {
|
||||
widgetWebView.isVisible = false
|
||||
}
|
||||
WidgetStatus.WIDGET_ALLOWED -> {
|
||||
widgetWebView.isVisible = true
|
||||
when (state.formattedURL) {
|
||||
is Success -> {
|
||||
setStateError(null)
|
||||
when (state.webviewLoadedUrl) {
|
||||
Uninitialized -> {
|
||||
widgetWebView.isInvisible = true
|
||||
}
|
||||
is Loading -> {
|
||||
setStateError(null)
|
||||
widgetWebView.isInvisible = false
|
||||
widgetProgressBar.isIndeterminate = true
|
||||
widgetProgressBar.isVisible = true
|
||||
}
|
||||
is Success -> {
|
||||
widgetWebView.isInvisible = false
|
||||
widgetProgressBar.isVisible = false
|
||||
setStateError(null)
|
||||
when (state.webviewLoadedUrl) {
|
||||
Uninitialized -> {
|
||||
widgetWebView.isInvisible = true
|
||||
}
|
||||
is Loading -> {
|
||||
setStateError(null)
|
||||
widgetWebView.isInvisible = false
|
||||
widgetProgressBar.isIndeterminate = true
|
||||
widgetProgressBar.isVisible = true
|
||||
}
|
||||
is Success -> {
|
||||
widgetWebView.isInvisible = false
|
||||
widgetProgressBar.isVisible = false
|
||||
setStateError(null)
|
||||
}
|
||||
is Fail -> {
|
||||
widgetProgressBar.isInvisible = true
|
||||
setStateError(state.webviewLoadedUrl.error.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
is Fail -> {
|
||||
// we need to show Error
|
||||
widgetWebView.isInvisible = true
|
||||
widgetProgressBar.isVisible = false
|
||||
setStateError(state.formattedURL.error.message)
|
||||
widgetProgressBar.isInvisible = true
|
||||
setStateError(state.webviewLoadedUrl.error.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
is Fail -> {
|
||||
// we need to show Error
|
||||
widgetWebView.isInvisible = true
|
||||
widgetProgressBar.isVisible = false
|
||||
setStateError(state.formattedURL.error.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun shouldOverrideUrlLoading(url: String): Boolean {
|
||||
if (url.startsWith("intent://")) {
|
||||
try {
|
||||
val context = requireContext()
|
||||
val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
|
||||
if (intent != null) {
|
||||
val packageManager: PackageManager = context.packageManager
|
||||
val info = packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY)
|
||||
if (info != null) {
|
||||
context.startActivity(intent)
|
||||
} else {
|
||||
val fallbackUrl = intent.getStringExtra("browser_fallback_url")
|
||||
openUrlInExternalBrowser(context, fallbackUrl)
|
||||
}
|
||||
return true
|
||||
}
|
||||
} catch (e: URISyntaxException) {
|
||||
Timber.d("Can't resolve intent://")
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onPageStarted(url: String) {
|
||||
viewModel.handle(WidgetAction.OnWebViewStartedToLoad(url))
|
||||
}
|
||||
|
@ -85,7 +85,6 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
|
||||
}
|
||||
setupName()
|
||||
refreshPermissionStatus()
|
||||
subscribeToPermissionStatus()
|
||||
observePowerLevel()
|
||||
observeWidgetIfNeeded()
|
||||
subscribeToWidget()
|
||||
@ -133,22 +132,14 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeToPermissionStatus() {
|
||||
selectSubscribe(WidgetViewState::status) {
|
||||
Timber.v("Widget status: $it")
|
||||
if (it == WidgetStatus.WIDGET_ALLOWED) {
|
||||
loadFormattedUrl()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getPostAPIMediator() = postAPIMediator
|
||||
|
||||
override fun handle(action: WidgetAction) {
|
||||
when (action) {
|
||||
is WidgetAction.OnWebViewLoadingError -> handleWebViewLoadingError(action.isHttpError, action.errorCode, action.errorDescription)
|
||||
is WidgetAction.OnWebViewLoadingSuccess -> handleWebViewLoadingSuccess(action.url)
|
||||
is WidgetAction.OnWebViewLoadingError -> handleWebViewLoadingError(action)
|
||||
is WidgetAction.OnWebViewLoadingSuccess -> handleWebViewLoadingSuccess(action)
|
||||
is WidgetAction.OnWebViewStartedToLoad -> handleWebViewStartLoading()
|
||||
WidgetAction.LoadFormattedUrl -> loadFormattedUrl()
|
||||
WidgetAction.DeleteWidget -> handleDeleteWidget()
|
||||
WidgetAction.RevokeWidget -> handleRevokeWidget()
|
||||
WidgetAction.OnTermsReviewed -> refreshPermissionStatus()
|
||||
@ -232,6 +223,7 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
|
||||
bypassWhitelist = initialState.widgetKind == WidgetKind.INTEGRATION_MANAGER
|
||||
)
|
||||
setState { copy(formattedURL = Success(formattedUrl)) }
|
||||
Timber.v("Post load formatted url event: $formattedUrl")
|
||||
_viewEvents.post(WidgetViewEvents.LoadFormattedURL(formattedUrl))
|
||||
} catch (failure: Throwable) {
|
||||
if (failure is WidgetManagementFailure.TermsNotSignedException) {
|
||||
@ -246,23 +238,24 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
|
||||
setState { copy(webviewLoadedUrl = Loading()) }
|
||||
}
|
||||
|
||||
private fun handleWebViewLoadingSuccess(url: String) {
|
||||
private fun handleWebViewLoadingSuccess(action: WidgetAction.OnWebViewLoadingSuccess) {
|
||||
if (initialState.widgetKind.isAdmin()) {
|
||||
postAPIMediator.injectAPI()
|
||||
}
|
||||
setState { copy(webviewLoadedUrl = Success(url)) }
|
||||
setState { copy(webviewLoadedUrl = Success(action.url)) }
|
||||
}
|
||||
|
||||
private fun handleWebViewLoadingError(isHttpError: Boolean, reason: Int, errorDescription: String) {
|
||||
if (isHttpError) {
|
||||
private fun handleWebViewLoadingError(action: WidgetAction.OnWebViewLoadingError) = withState {
|
||||
if (!action.url.startsWith(it.baseUrl)) {
|
||||
return@withState
|
||||
}
|
||||
if (action.isHttpError) {
|
||||
// In case of 403, try to refresh the scalar token
|
||||
withState {
|
||||
if (it.formattedURL is Success && reason == HttpsURLConnection.HTTP_FORBIDDEN) {
|
||||
loadFormattedUrl(true)
|
||||
}
|
||||
if (it.formattedURL is Success && action.errorCode == HttpsURLConnection.HTTP_FORBIDDEN) {
|
||||
loadFormattedUrl(true)
|
||||
}
|
||||
} else {
|
||||
setState { copy(webviewLoadedUrl = Fail(Throwable(errorDescription))) }
|
||||
setState { copy(webviewLoadedUrl = Fail(Throwable(action.errorDescription))) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,15 +10,14 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:background="@android:color/transparent" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/widgetProgressBar"
|
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="6dp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="?colorPrimary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:indeterminate="true" />
|
||||
|
||||
<LinearLayout
|
||||
|
Loading…
Reference in New Issue
Block a user