diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt
index de38dc6bba..832d4f836f 100644
--- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt
+++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt
@@ -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 {
diff --git a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetAction.kt b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetAction.kt
index af81d8eb0f..06a27a7084 100644
--- a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetAction.kt
+++ b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetAction.kt
@@ -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()
}
diff --git a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetFragment.kt b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetFragment.kt
index 762a0d7ef4..14b25d0439 100644
--- a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetFragment.kt
+++ b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetFragment.kt
@@ -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))
}
diff --git a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetViewModel.kt b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetViewModel.kt
index 8762bf574a..1a7ca0c885 100644
--- a/vector/src/main/java/im/vector/riotx/features/widgets/WidgetViewModel.kt
+++ b/vector/src/main/java/im/vector/riotx/features/widgets/WidgetViewModel.kt
@@ -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))) }
}
}
diff --git a/vector/src/main/res/layout/fragment_room_widget.xml b/vector/src/main/res/layout/fragment_room_widget.xml
index 4fc8f47685..05b317ebf4 100644
--- a/vector/src/main/res/layout/fragment_room_widget.xml
+++ b/vector/src/main/res/layout/fragment_room_widget.xml
@@ -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" />