mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 05:31:21 +03:00
Widgets: fix some issues with navigation
This commit is contained in:
parent
ba0823f4d0
commit
234dfa18d3
21 changed files with 198 additions and 133 deletions
|
@ -90,6 +90,6 @@ interface WidgetPostAPIMediator {
|
|||
/**
|
||||
* Triggered when a widget is posting
|
||||
*/
|
||||
fun handleWidgetRequest(eventData: JsonDict): Boolean
|
||||
fun handleWidgetRequest(mediator: WidgetPostAPIMediator, eventData: JsonDict): Boolean
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@ interface WidgetService {
|
|||
fun getWidgetURLFormatter(): WidgetURLFormatter
|
||||
|
||||
/**
|
||||
* Returns an instance of [WidgetPostAPIMediator].
|
||||
* Returns a new instance of [WidgetPostAPIMediator].
|
||||
* Be careful to call clearWebView method and setHandler to null to avoid memory leaks.
|
||||
* This is to be used for "admin" widgets so you can interact through JS.
|
||||
*/
|
||||
fun getWidgetPostAPIMediator(): WidgetPostAPIMediator
|
||||
|
|
|
@ -16,6 +16,22 @@
|
|||
|
||||
package im.vector.matrix.android.api.session.widgets.model
|
||||
|
||||
private val DEFINED_TYPES by lazy {
|
||||
listOf(
|
||||
WidgetType.Jitsi,
|
||||
WidgetType.TradingView,
|
||||
WidgetType.Spotify,
|
||||
WidgetType.Video,
|
||||
WidgetType.GoogleDoc,
|
||||
WidgetType.GoogleCalendar,
|
||||
WidgetType.Etherpad,
|
||||
WidgetType.StickerPicker,
|
||||
WidgetType.Grafana,
|
||||
WidgetType.Custom,
|
||||
WidgetType.IntegrationManager
|
||||
)
|
||||
}
|
||||
|
||||
sealed class WidgetType(open val preferred: String, open val legacy: String = preferred) {
|
||||
object Jitsi : WidgetType("m.jitsi", "jitsi")
|
||||
object TradingView : WidgetType("m.tradingview")
|
||||
|
@ -30,7 +46,7 @@ sealed class WidgetType(open val preferred: String, open val legacy: String = pr
|
|||
object IntegrationManager : WidgetType("m.integration_manager")
|
||||
data class Fallback(override val preferred: String) : WidgetType(preferred)
|
||||
|
||||
fun matches(type: String?): Boolean {
|
||||
fun matches(type: String): Boolean {
|
||||
return type == preferred || type == legacy
|
||||
}
|
||||
|
||||
|
@ -40,20 +56,6 @@ sealed class WidgetType(open val preferred: String, open val legacy: String = pr
|
|||
|
||||
companion object {
|
||||
|
||||
private val DEFINED_TYPES = listOf(
|
||||
Jitsi,
|
||||
TradingView,
|
||||
Spotify,
|
||||
Video,
|
||||
GoogleDoc,
|
||||
GoogleCalendar,
|
||||
Etherpad,
|
||||
StickerPicker,
|
||||
Grafana,
|
||||
Custom,
|
||||
IntegrationManager
|
||||
)
|
||||
|
||||
fun fromString(type: String): WidgetType {
|
||||
val matchingType = DEFINED_TYPES.firstOrNull {
|
||||
it.matches(type)
|
||||
|
|
|
@ -78,7 +78,7 @@ internal class DefaultWidgetPostAPIMediator @Inject constructor(private val mosh
|
|||
|
||||
private fun onWidgetMessage(eventData: JsonDict) {
|
||||
try {
|
||||
if (handler?.handleWidgetRequest(eventData) == false) {
|
||||
if (handler?.handleWidgetRequest(this, eventData) == false) {
|
||||
sendError("", eventData)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
|
|
@ -26,10 +26,11 @@ import im.vector.matrix.android.api.session.widgets.WidgetURLFormatter
|
|||
import im.vector.matrix.android.api.session.widgets.model.Widget
|
||||
import im.vector.matrix.android.api.util.Cancelable
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
internal class DefaultWidgetService @Inject constructor(private val widgetManager: WidgetManager,
|
||||
private val widgetURLFormatter: WidgetURLFormatter,
|
||||
private val widgetPostAPIMediator: WidgetPostAPIMediator)
|
||||
private val widgetPostAPIMediator: Provider<WidgetPostAPIMediator>)
|
||||
: WidgetService {
|
||||
|
||||
override fun getWidgetURLFormatter(): WidgetURLFormatter {
|
||||
|
@ -37,7 +38,7 @@ internal class DefaultWidgetService @Inject constructor(private val widgetManage
|
|||
}
|
||||
|
||||
override fun getWidgetPostAPIMediator(): WidgetPostAPIMediator {
|
||||
return widgetPostAPIMediator
|
||||
return widgetPostAPIMediator.get()
|
||||
}
|
||||
|
||||
override fun getRoomWidgets(
|
||||
|
|
|
@ -25,7 +25,6 @@ import im.vector.matrix.android.api.session.widgets.WidgetManagementFailure
|
|||
import im.vector.matrix.android.internal.session.widgets.WidgetsAPI
|
||||
import im.vector.matrix.android.internal.session.widgets.WidgetsAPIProvider
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
|
||||
|
@ -68,7 +67,7 @@ internal class DefaultGetScalarTokenTask @Inject constructor(private val widgets
|
|||
throw IllegalStateException("Scalar token is null")
|
||||
}
|
||||
scalarTokenStore.setToken(serverUrl, registerWidgetResponse.scalarToken)
|
||||
return validateToken(widgetsAPI,serverUrl, registerWidgetResponse.scalarToken)
|
||||
return validateToken(widgetsAPI, serverUrl, registerWidgetResponse.scalarToken)
|
||||
}
|
||||
|
||||
private suspend fun validateToken(widgetsAPI: WidgetsAPI, serverUrl: String, scalarToken: String): String {
|
||||
|
|
|
@ -76,4 +76,5 @@ sealed class RoomDetailAction : VectorViewModelAction {
|
|||
data class ReRequestKeys(val eventId: String) : RoomDetailAction()
|
||||
|
||||
object SelectStickerAttachment : RoomDetailAction()
|
||||
object OpenIntegrationManager: RoomDetailAction()
|
||||
}
|
||||
|
|
|
@ -134,7 +134,6 @@ import im.vector.riotx.features.crypto.verification.VerificationBottomSheet
|
|||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.home.room.detail.composer.TextComposerView
|
||||
import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.sticker.StickerPickerConstants
|
||||
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
|
||||
import im.vector.riotx.features.home.room.detail.timeline.action.EventSharedAction
|
||||
import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet
|
||||
|
@ -149,6 +148,7 @@ import im.vector.riotx.features.home.room.detail.timeline.item.ReadReceiptData
|
|||
import im.vector.riotx.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.widget.RoomWidgetsBannerView
|
||||
import im.vector.riotx.features.home.room.detail.widget.RoomWidgetsBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.widget.WidgetRequestCodes
|
||||
import im.vector.riotx.features.html.EventHtmlRenderer
|
||||
import im.vector.riotx.features.html.PillImageSpan
|
||||
import im.vector.riotx.features.invite.VectorInviteView
|
||||
|
@ -159,6 +159,7 @@ import im.vector.riotx.features.permalink.NavigationInterceptor
|
|||
import im.vector.riotx.features.permalink.PermalinkHandler
|
||||
import im.vector.riotx.features.reactions.EmojiReactionPickerActivity
|
||||
import im.vector.riotx.features.settings.VectorPreferences
|
||||
import im.vector.riotx.features.settings.VectorSettingsActivity
|
||||
import im.vector.riotx.features.share.SharedData
|
||||
import im.vector.riotx.features.themes.ThemeUtils
|
||||
import im.vector.riotx.features.widgets.WidgetActivity
|
||||
|
@ -302,22 +303,33 @@ class RoomDetailFragment @Inject constructor(
|
|||
|
||||
roomDetailViewModel.observeViewEvents {
|
||||
when (it) {
|
||||
is RoomDetailViewEvents.Failure -> showErrorInSnackbar(it.throwable)
|
||||
is RoomDetailViewEvents.OnNewTimelineEvents -> scrollOnNewMessageCallback.addNewTimelineEventIds(it.eventIds)
|
||||
is RoomDetailViewEvents.ActionSuccess -> displayRoomDetailActionSuccess(it)
|
||||
is RoomDetailViewEvents.ActionFailure -> displayRoomDetailActionFailure(it)
|
||||
is RoomDetailViewEvents.ShowMessage -> showSnackWithMessage(it.message, Snackbar.LENGTH_LONG)
|
||||
is RoomDetailViewEvents.NavigateToEvent -> navigateToEvent(it)
|
||||
is RoomDetailViewEvents.FileTooBigError -> displayFileTooBigError(it)
|
||||
is RoomDetailViewEvents.DownloadFileState -> handleDownloadFileState(it)
|
||||
is RoomDetailViewEvents.JoinRoomCommandSuccess -> handleJoinedToAnotherRoom(it)
|
||||
is RoomDetailViewEvents.SendMessageResult -> renderSendMessageResult(it)
|
||||
RoomDetailViewEvents.DisplayPromptForIntegrationManager -> displayPromptForIntegrationManager()
|
||||
is RoomDetailViewEvents.OpenStickerPicker -> openStickerPicker(it)
|
||||
is RoomDetailViewEvents.Failure -> showErrorInSnackbar(it.throwable)
|
||||
is RoomDetailViewEvents.OnNewTimelineEvents -> scrollOnNewMessageCallback.addNewTimelineEventIds(it.eventIds)
|
||||
is RoomDetailViewEvents.ActionSuccess -> displayRoomDetailActionSuccess(it)
|
||||
is RoomDetailViewEvents.ActionFailure -> displayRoomDetailActionFailure(it)
|
||||
is RoomDetailViewEvents.ShowMessage -> showSnackWithMessage(it.message, Snackbar.LENGTH_LONG)
|
||||
is RoomDetailViewEvents.NavigateToEvent -> navigateToEvent(it)
|
||||
is RoomDetailViewEvents.FileTooBigError -> displayFileTooBigError(it)
|
||||
is RoomDetailViewEvents.DownloadFileState -> handleDownloadFileState(it)
|
||||
is RoomDetailViewEvents.JoinRoomCommandSuccess -> handleJoinedToAnotherRoom(it)
|
||||
is RoomDetailViewEvents.SendMessageResult -> renderSendMessageResult(it)
|
||||
RoomDetailViewEvents.DisplayPromptForIntegrationManager -> displayPromptForIntegrationManager()
|
||||
is RoomDetailViewEvents.OpenStickerPicker -> openStickerPicker(it)
|
||||
is RoomDetailViewEvents.DisplayEnableIntegrationsWarning -> displayEnableIntegrationsWarning()
|
||||
is RoomDetailViewEvents.OpenIntegrationManager -> openIntegrationManager()
|
||||
}.exhaustive
|
||||
}
|
||||
}
|
||||
|
||||
private fun openIntegrationManager(screen: String? = null) {
|
||||
navigator.openIntegrationManager(
|
||||
fragment = this,
|
||||
roomId = roomDetailArgs.roomId,
|
||||
integId = null,
|
||||
screen = screen
|
||||
)
|
||||
}
|
||||
|
||||
private fun setupWidgetsBannerView() {
|
||||
roomWidgetsBannerView.callback = this
|
||||
}
|
||||
|
@ -334,10 +346,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
.setView(v)
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
// Open integration manager, to the sticker installation page
|
||||
navigator.openIntegrationManager(
|
||||
context = requireContext(),
|
||||
roomId = roomDetailArgs.roomId,
|
||||
integId = null,
|
||||
openIntegrationManager(
|
||||
screen = WidgetType.StickerPicker.preferred
|
||||
)
|
||||
}
|
||||
|
@ -345,6 +354,17 @@ class RoomDetailFragment @Inject constructor(
|
|||
.show()
|
||||
}
|
||||
|
||||
private fun displayEnableIntegrationsWarning() {
|
||||
AlertDialog.Builder(requireContext())
|
||||
.setTitle(R.string.integration_manager_not_enabled_title)
|
||||
.setMessage(R.string.integration_manager_not_enabled_msg)
|
||||
.setPositiveButton(R.string.open_settings) { _, _ ->
|
||||
navigator.openSettings(requireContext(), VectorSettingsActivity.EXTRA_DIRECT_ACCESS_GENERAL)
|
||||
}
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun handleJoinedToAnotherRoom(action: RoomDetailViewEvents.JoinRoomCommandSuccess) {
|
||||
updateComposerText("")
|
||||
lockSendButton = false
|
||||
|
@ -469,7 +489,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
true
|
||||
}
|
||||
R.id.open_matrix_apps -> {
|
||||
navigator.openIntegrationManager(requireContext(), roomDetailArgs.roomId, null, null)
|
||||
roomDetailViewModel.handle(RoomDetailAction.OpenIntegrationManager)
|
||||
true
|
||||
}
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
|
@ -548,16 +568,16 @@ class RoomDetailFragment @Inject constructor(
|
|||
val hasBeenHandled = attachmentsHelper.onActivityResult(requestCode, resultCode, data)
|
||||
if (!hasBeenHandled && resultCode == RESULT_OK && data != null) {
|
||||
when (requestCode) {
|
||||
AttachmentsPreviewActivity.REQUEST_CODE -> {
|
||||
AttachmentsPreviewActivity.REQUEST_CODE -> {
|
||||
val sendData = AttachmentsPreviewActivity.getOutput(data)
|
||||
val keepOriginalSize = AttachmentsPreviewActivity.getKeepOriginalSize(data)
|
||||
roomDetailViewModel.handle(RoomDetailAction.SendMedia(sendData, !keepOriginalSize))
|
||||
}
|
||||
REACTION_SELECT_REQUEST_CODE -> {
|
||||
REACTION_SELECT_REQUEST_CODE -> {
|
||||
val (eventId, reaction) = EmojiReactionPickerActivity.getOutput(data) ?: return
|
||||
roomDetailViewModel.handle(RoomDetailAction.SendReaction(eventId, reaction))
|
||||
}
|
||||
StickerPickerConstants.STICKER_PICKER_REQUEST_CODE -> {
|
||||
WidgetRequestCodes.STICKER_PICKER_REQUEST_CODE -> {
|
||||
val content = WidgetActivity.getOutput(data).toModel<MessageStickerContent>() ?: return
|
||||
roomDetailViewModel.handle(RoomDetailAction.SendSticker(content))
|
||||
}
|
||||
|
|
|
@ -52,8 +52,12 @@ sealed class RoomDetailViewEvents : VectorViewEvents {
|
|||
|
||||
object DisplayPromptForIntegrationManager: RoomDetailViewEvents()
|
||||
|
||||
object DisplayEnableIntegrationsWarning: RoomDetailViewEvents()
|
||||
|
||||
data class OpenStickerPicker(val widget: Widget): RoomDetailViewEvents()
|
||||
|
||||
object OpenIntegrationManager: RoomDetailViewEvents()
|
||||
|
||||
object MessageSent : SendMessageResult()
|
||||
data class JoinRoomCommandSuccess(val roomId: String) : SendMessageResult()
|
||||
class SlashCommandError(val command: Command) : SendMessageResult()
|
||||
|
|
|
@ -79,7 +79,9 @@ import io.reactivex.Observable
|
|||
import io.reactivex.functions.BiFunction
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.commonmark.parser.Parser
|
||||
import org.commonmark.renderer.html.HtmlRenderer
|
||||
import timber.log.Timber
|
||||
|
@ -252,6 +254,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
is RoomDetailAction.ResumeVerification -> handleResumeRequestVerification(action)
|
||||
is RoomDetailAction.ReRequestKeys -> handleReRequestKeys(action)
|
||||
is RoomDetailAction.SelectStickerAttachment -> handleSelectStickerAttachment()
|
||||
is RoomDetailAction.OpenIntegrationManager -> handleOpenIntegrationManager()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,6 +269,19 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleOpenIntegrationManager() {
|
||||
viewModelScope.launch {
|
||||
val viewEvent = withContext(Dispatchers.Default) {
|
||||
if (isIntegrationEnabled()) {
|
||||
RoomDetailViewEvents.OpenIntegrationManager
|
||||
} else {
|
||||
RoomDetailViewEvents.DisplayEnableIntegrationsWarning
|
||||
}
|
||||
}
|
||||
_viewEvents.post(viewEvent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startTrackingUnreadMessages() {
|
||||
trackUnreadMessages.set(true)
|
||||
setState { copy(canShowJumpToReadMarker = false) }
|
||||
|
@ -365,13 +381,15 @@ class RoomDetailViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun isIntegrationEnabled() = session.integrationManagerService().isIntegrationEnabled()
|
||||
|
||||
fun isMenuItemVisible(@IdRes itemId: Int) = when (itemId) {
|
||||
R.id.clear_message_queue ->
|
||||
/* For now always disable on production, worker cancellation is not working properly */
|
||||
timeline.pendingEventCount() > 0 && vectorPreferences.developerMode()
|
||||
R.id.resend_all -> timeline.failedToDeliverEventCount() > 0
|
||||
R.id.clear_all -> timeline.failedToDeliverEventCount() > 0
|
||||
R.id.open_matrix_apps -> session.integrationManagerService().isIntegrationEnabled()
|
||||
R.id.open_matrix_apps -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@ class StickerPickerActionHandler @Inject constructor(private val session: Sessio
|
|||
|
||||
suspend fun handle(): RoomDetailViewEvents = withContext(Dispatchers.Default) {
|
||||
// Search for the sticker picker widget in the user account
|
||||
val integrationsEnabled = session.integrationManagerService().isIntegrationEnabled()
|
||||
if (!integrationsEnabled) {
|
||||
return@withContext RoomDetailViewEvents.DisplayEnableIntegrationsWarning
|
||||
}
|
||||
val stickerWidget = session.widgetService().getUserWidgets(WidgetType.StickerPicker.values()).firstOrNull { it.isActive }
|
||||
if (stickerWidget == null || stickerWidget.computedUrl.isNullOrBlank()) {
|
||||
RoomDetailViewEvents.DisplayPromptForIntegrationManager
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.riotx.features.home.room.detail.sticker
|
||||
package im.vector.riotx.features.home.room.detail.widget
|
||||
|
||||
object StickerPickerConstants {
|
||||
object WidgetRequestCodes {
|
||||
const val STICKER_PICKER_REQUEST_CODE = 16000
|
||||
const val INTEGRATION_MANAGER_REQUEST_CODE = 16001
|
||||
}
|
|
@ -30,8 +30,8 @@ import androidx.fragment.app.Fragment
|
|||
import im.vector.matrix.android.api.session.crypto.verification.IncomingSasVerificationTransaction
|
||||
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
|
||||
import im.vector.matrix.android.api.session.terms.TermsService
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.matrix.android.api.session.widgets.model.Widget
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
import im.vector.riotx.core.error.fatalError
|
||||
|
@ -46,7 +46,7 @@ import im.vector.riotx.features.crypto.verification.VerificationBottomSheet
|
|||
import im.vector.riotx.features.debug.DebugMenuActivity
|
||||
import im.vector.riotx.features.home.room.detail.RoomDetailActivity
|
||||
import im.vector.riotx.features.home.room.detail.RoomDetailArgs
|
||||
import im.vector.riotx.features.home.room.detail.sticker.StickerPickerConstants
|
||||
import im.vector.riotx.features.home.room.detail.widget.WidgetRequestCodes
|
||||
import im.vector.riotx.features.home.room.filtered.FilteredRoomsActivity
|
||||
import im.vector.riotx.features.invite.InviteUsersToRoomActivity
|
||||
import im.vector.riotx.features.media.BigImageViewerActivity
|
||||
|
@ -230,12 +230,13 @@ class DefaultNavigator @Inject constructor(
|
|||
override fun openStickerPicker(fragment: Fragment, roomId: String, widget: Widget, requestCode: Int) {
|
||||
val widgetArgs = widgetArgsBuilder.buildStickerPickerArgs(roomId, widget)
|
||||
val intent = WidgetActivity.newIntent(fragment.requireContext(), widgetArgs)
|
||||
fragment.startActivityForResult(intent, StickerPickerConstants.STICKER_PICKER_REQUEST_CODE)
|
||||
fragment.startActivityForResult(intent, WidgetRequestCodes.STICKER_PICKER_REQUEST_CODE)
|
||||
}
|
||||
|
||||
override fun openIntegrationManager(context: Context, roomId: String, integId: String?, screen: String?) {
|
||||
override fun openIntegrationManager(fragment: Fragment, roomId: String, integId: String?, screen: String?) {
|
||||
val widgetArgs = widgetArgsBuilder.buildIntegrationManagerArgs(roomId, integId, screen)
|
||||
context.startActivity(WidgetActivity.newIntent(context, widgetArgs))
|
||||
val intent = WidgetActivity.newIntent(fragment.requireContext(), widgetArgs)
|
||||
fragment.startActivityForResult(intent, WidgetRequestCodes.INTEGRATION_MANAGER_REQUEST_CODE)
|
||||
}
|
||||
|
||||
override fun openRoomWidget(context: Context, roomId: String, widget: Widget) {
|
||||
|
|
|
@ -25,7 +25,7 @@ import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
|
|||
import im.vector.matrix.android.api.session.terms.TermsService
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.matrix.android.api.session.widgets.model.Widget
|
||||
import im.vector.riotx.features.home.room.detail.sticker.StickerPickerConstants
|
||||
import im.vector.riotx.features.home.room.detail.widget.WidgetRequestCodes
|
||||
import im.vector.riotx.features.media.ImageContentRenderer
|
||||
import im.vector.riotx.features.media.VideoContentRenderer
|
||||
import im.vector.riotx.features.settings.VectorSettingsActivity
|
||||
|
@ -85,9 +85,9 @@ interface Navigator {
|
|||
fun openStickerPicker(fragment: Fragment,
|
||||
roomId: String,
|
||||
widget: Widget,
|
||||
requestCode: Int = StickerPickerConstants.STICKER_PICKER_REQUEST_CODE)
|
||||
requestCode: Int = WidgetRequestCodes.STICKER_PICKER_REQUEST_CODE)
|
||||
|
||||
fun openIntegrationManager(context: Context, roomId: String, integId: String?, screen: String?)
|
||||
fun openIntegrationManager(fragment: Fragment, roomId: String, integId: String?, screen: String?)
|
||||
|
||||
fun openRoomWidget(context: Context, roomId: String, widget: Widget)
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@ class VectorSettingsActivity : VectorBaseActivity(),
|
|||
if (isFirstCreation()) {
|
||||
// display the fragment
|
||||
when (intent.getIntExtra(EXTRA_DIRECT_ACCESS, EXTRA_DIRECT_ACCESS_ROOT)) {
|
||||
EXTRA_DIRECT_ACCESS_GENERAL ->
|
||||
replaceFragment(R.id.vector_settings_page, VectorSettingsGeneralFragment::class.java, null, FRAGMENT_TAG)
|
||||
EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS ->
|
||||
replaceFragment(R.id.vector_settings_page, VectorSettingsAdvancedSettingsFragment::class.java, null, FRAGMENT_TAG)
|
||||
EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY ->
|
||||
|
@ -137,6 +139,7 @@ class VectorSettingsActivity : VectorBaseActivity(),
|
|||
const val EXTRA_DIRECT_ACCESS_ADVANCED_SETTINGS = 1
|
||||
const val EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY = 2
|
||||
const val EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY_MANAGE_SESSIONS = 3
|
||||
const val EXTRA_DIRECT_ACCESS_GENERAL = 4
|
||||
|
||||
private const val FRAGMENT_TAG = "VectorSettingsPreferencesFragment"
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import im.vector.riotx.R
|
|||
import im.vector.riotx.core.platform.OnBackPressed
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.utils.openUrlInExternalBrowser
|
||||
import im.vector.riotx.features.home.room.detail.widget.WidgetRequestCodes
|
||||
import im.vector.riotx.features.terms.ReviewTermsActivity
|
||||
import im.vector.riotx.features.webview.WebViewEventListener
|
||||
import im.vector.riotx.features.widgets.webview.clearAfterWidget
|
||||
|
@ -77,7 +78,7 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
|
|||
Timber.v("Observed view events: $it")
|
||||
when (it) {
|
||||
is WidgetViewEvents.DisplayTerms -> displayTerms(it)
|
||||
is WidgetViewEvents.LoadFormattedURL -> loadFormattedUrl(it)
|
||||
is WidgetViewEvents.OnURLFormatted -> loadFormattedUrl(it)
|
||||
is WidgetViewEvents.DisplayIntegrationManager -> displayIntegrationManager(it)
|
||||
is WidgetViewEvents.Failure -> displayErrorDialog(it.throwable)
|
||||
}
|
||||
|
@ -86,11 +87,17 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
|
|||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == ReviewTermsActivity.TERMS_REQUEST_CODE) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
viewModel.handle(WidgetAction.OnTermsReviewed)
|
||||
} else {
|
||||
vectorBaseActivity.finish()
|
||||
when (requestCode) {
|
||||
ReviewTermsActivity.TERMS_REQUEST_CODE -> {
|
||||
Timber.v("On terms results")
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
viewModel.handle(WidgetAction.OnTermsReviewed)
|
||||
} else {
|
||||
vectorBaseActivity.finish()
|
||||
}
|
||||
}
|
||||
WidgetRequestCodes.INTEGRATION_MANAGER_REQUEST_CODE -> {
|
||||
viewModel.handle(WidgetAction.LoadFormattedUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +146,7 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
|
|||
override fun onOptionsItemSelected(item: MenuItem): Boolean = withState(viewModel) { state ->
|
||||
when (item.itemId) {
|
||||
R.id.action_edit -> {
|
||||
navigator.openIntegrationManager(requireContext(), state.roomId, state.widgetId, state.widgetKind.screenId)
|
||||
navigator.openIntegrationManager(this, state.roomId, state.widgetId, state.widgetKind.screenId)
|
||||
return@withState true
|
||||
}
|
||||
R.id.action_delete -> {
|
||||
|
@ -261,9 +268,9 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
|
|||
)
|
||||
}
|
||||
|
||||
private fun loadFormattedUrl(loadFormattedUrl: WidgetViewEvents.LoadFormattedURL) {
|
||||
private fun loadFormattedUrl(event: WidgetViewEvents.OnURLFormatted) {
|
||||
widgetWebView.clearHistory()
|
||||
widgetWebView.loadUrl(loadFormattedUrl.formattedURL)
|
||||
widgetWebView.loadUrl(event.formattedURL)
|
||||
}
|
||||
|
||||
private fun setStateError(message: String?) {
|
||||
|
@ -280,7 +287,7 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
|
|||
|
||||
private fun displayIntegrationManager(event: WidgetViewEvents.DisplayIntegrationManager) {
|
||||
navigator.openIntegrationManager(
|
||||
context = vectorBaseActivity,
|
||||
fragment = this,
|
||||
roomId = fragmentArgs.roomId,
|
||||
integId = event.integId,
|
||||
screen = event.integType
|
||||
|
|
|
@ -39,13 +39,12 @@ import java.util.ArrayList
|
|||
import java.util.HashMap
|
||||
|
||||
class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roomId: String,
|
||||
@Assisted private val navigationCallback: NavigationCallback,
|
||||
private val stringProvider: StringProvider,
|
||||
private val session: Session) : WidgetPostAPIMediator.Handler {
|
||||
|
||||
@AssistedInject.Factory
|
||||
interface Factory {
|
||||
fun create(roomId: String, navigationCallback: NavigationCallback): WidgetPostAPIHandler
|
||||
fun create(roomId: String): WidgetPostAPIHandler
|
||||
}
|
||||
|
||||
interface NavigationCallback {
|
||||
|
@ -54,31 +53,31 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
fun openIntegrationManager(integId: String?, integType: String?)
|
||||
}
|
||||
|
||||
private val widgetPostAPIMediator = session.widgetService().getWidgetPostAPIMediator()
|
||||
private val room = session.getRoom(roomId)!!
|
||||
var navigationCallback: NavigationCallback? = null
|
||||
|
||||
override fun handleWidgetRequest(eventData: JsonDict): Boolean {
|
||||
override fun handleWidgetRequest(mediator: WidgetPostAPIMediator, eventData: JsonDict): Boolean {
|
||||
return when (eventData["action"] as String?) {
|
||||
"integration_manager_open" -> handleIntegrationManagerOpenAction(eventData).run { true }
|
||||
"bot_options" -> getBotOptions(eventData).run { true }
|
||||
"can_send_event" -> canSendEvent(eventData).run { true }
|
||||
"bot_options" -> getBotOptions(mediator, eventData).run { true }
|
||||
"can_send_event" -> canSendEvent(mediator, eventData).run { true }
|
||||
"close_scalar" -> handleCloseScalar().run { true }
|
||||
"get_membership_count" -> getMembershipCount(eventData).run { true }
|
||||
"get_widgets" -> getWidgets(eventData).run { true }
|
||||
"invite" -> inviteUser(eventData).run { true }
|
||||
"join_rules_state" -> getJoinRules(eventData).run { true }
|
||||
"membership_state" -> getMembershipState(eventData).run { true }
|
||||
"set_bot_options" -> setBotOptions(eventData).run { true }
|
||||
"set_bot_power" -> setBotPower(eventData).run { true }
|
||||
"set_plumbing_state" -> setPlumbingState(eventData).run { true }
|
||||
"set_widget" -> setWidget(eventData).run { true }
|
||||
"m.sticker" -> pickStickerData(eventData).run { true }
|
||||
"get_membership_count" -> getMembershipCount(mediator, eventData).run { true }
|
||||
"get_widgets" -> getWidgets(mediator, eventData).run { true }
|
||||
"invite" -> inviteUser(mediator, eventData).run { true }
|
||||
"join_rules_state" -> getJoinRules(mediator, eventData).run { true }
|
||||
"membership_state" -> getMembershipState(mediator, eventData).run { true }
|
||||
"set_bot_options" -> setBotOptions(mediator, eventData).run { true }
|
||||
"set_bot_power" -> setBotPower(mediator, eventData).run { true }
|
||||
"set_plumbing_state" -> setPlumbingState(mediator, eventData).run { true }
|
||||
"set_widget" -> setWidget(mediator, eventData).run { true }
|
||||
"m.sticker" -> pickStickerData(mediator, eventData).run { true }
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleCloseScalar() {
|
||||
navigationCallback.close()
|
||||
navigationCallback?.close()
|
||||
}
|
||||
|
||||
private fun handleIntegrationManagerOpenAction(eventData: JsonDict) {
|
||||
|
@ -101,7 +100,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
// Add "type_" as a prefix
|
||||
integType?.let { integType = "type_$integType" }
|
||||
}
|
||||
navigationCallback.openIntegrationManager(integId, integType)
|
||||
navigationCallback?.openIntegrationManager(integId, integType)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,8 +108,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @param eventData the modular data
|
||||
*/
|
||||
private fun getBotOptions(eventData: JsonDict) {
|
||||
if (checkRoomId(eventData) || checkUserId(eventData)) {
|
||||
private fun getBotOptions(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData) || checkUserId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
val userId = eventData["user_id"] as String
|
||||
|
@ -134,8 +133,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
}
|
||||
}
|
||||
|
||||
private fun canSendEvent(eventData: JsonDict) {
|
||||
if (checkRoomId(eventData)) {
|
||||
private fun canSendEvent(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
Timber.d("Received request canSendEvent in room $roomId")
|
||||
|
@ -170,8 +169,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @param eventData the modular data
|
||||
*/
|
||||
private fun getMembershipState(eventData: JsonDict) {
|
||||
if (checkRoomId(eventData) || checkUserId(eventData)) {
|
||||
private fun getMembershipState(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData) || checkUserId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
val userId = eventData["user_id"] as String
|
||||
|
@ -189,8 +188,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @param eventData the modular data
|
||||
*/
|
||||
private fun getJoinRules(eventData: JsonDict) {
|
||||
if (checkRoomId(eventData)) {
|
||||
private fun getJoinRules(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
Timber.d("Received request join rules in room $roomId")
|
||||
|
@ -207,8 +206,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @param eventData the modular data
|
||||
*/
|
||||
private fun getWidgets(eventData: JsonDict) {
|
||||
if (checkRoomId(eventData)) {
|
||||
private fun getWidgets(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
Timber.d("Received request to get widget in room $roomId")
|
||||
|
@ -227,12 +226,12 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @param eventData the modular data
|
||||
*/
|
||||
private fun setWidget(eventData: JsonDict) {
|
||||
private fun setWidget(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
val userWidget = eventData["userWidget"] as Boolean?
|
||||
if (userWidget == true) {
|
||||
Timber.d("Received request to set widget for user")
|
||||
} else {
|
||||
if (checkRoomId(eventData)) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
Timber.d("Received request to set widget in room $roomId")
|
||||
|
@ -283,14 +282,14 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
session.updateAccountData(
|
||||
type = UserAccountData.TYPE_WIDGETS,
|
||||
content = addUserWidgetBody,
|
||||
callback = createWidgetAPICallback(eventData)
|
||||
callback = createWidgetAPICallback(widgetPostAPIMediator, eventData)
|
||||
)
|
||||
} else {
|
||||
session.widgetService().createRoomWidget(
|
||||
roomId = roomId,
|
||||
widgetId = widgetId,
|
||||
content = widgetEventContent,
|
||||
callback = createWidgetAPICallback(eventData)
|
||||
callback = createWidgetAPICallback(widgetPostAPIMediator, eventData)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -300,8 +299,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @param eventData the modular data
|
||||
*/
|
||||
private fun setPlumbingState(eventData: JsonDict) {
|
||||
if (checkRoomId(eventData)) {
|
||||
private fun setPlumbingState(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
val description = "Received request to set plumbing state to status " + eventData["status"] + " in room " + roomId + " requested"
|
||||
|
@ -315,7 +314,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
eventType = EventType.PLUMBING,
|
||||
stateKey = null,
|
||||
body = params,
|
||||
callback = createWidgetAPICallback(eventData)
|
||||
callback = createWidgetAPICallback(widgetPostAPIMediator, eventData)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -325,8 +324,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
* @param eventData the modular data
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun setBotOptions(eventData: JsonDict) {
|
||||
if (checkRoomId(eventData) || checkUserId(eventData)) {
|
||||
private fun setBotOptions(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData) || checkUserId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
val userId = eventData["user_id"] as String
|
||||
|
@ -338,7 +337,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
eventType = EventType.BOT_OPTIONS,
|
||||
stateKey = stateKey,
|
||||
body = content,
|
||||
callback = createWidgetAPICallback(eventData)
|
||||
callback = createWidgetAPICallback(widgetPostAPIMediator, eventData)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -347,8 +346,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @param eventData the modular data
|
||||
*/
|
||||
private fun setBotPower(eventData: JsonDict) {
|
||||
if (checkRoomId(eventData) || checkUserId(eventData)) {
|
||||
private fun setBotPower(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData) || checkUserId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
val userId = eventData["user_id"] as String
|
||||
|
@ -369,8 +368,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @param eventData the modular data
|
||||
*/
|
||||
private fun inviteUser(eventData: JsonDict) {
|
||||
if (checkRoomId(eventData) || checkUserId(eventData)) {
|
||||
private fun inviteUser(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData) || checkUserId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
val userId = eventData["user_id"] as String
|
||||
|
@ -380,7 +379,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
if (member != null && member.membership == Membership.JOIN) {
|
||||
widgetPostAPIMediator.sendSuccess(eventData)
|
||||
} else {
|
||||
room.invite(userId = userId, callback = createWidgetAPICallback(eventData))
|
||||
room.invite(userId = userId, callback = createWidgetAPICallback(widgetPostAPIMediator, eventData))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -389,8 +388,8 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @param eventData the modular data
|
||||
*/
|
||||
private fun getMembershipCount(eventData: JsonDict) {
|
||||
if (checkRoomId(eventData)) {
|
||||
private fun getMembershipCount(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
if (checkRoomId(widgetPostAPIMediator, eventData)) {
|
||||
return
|
||||
}
|
||||
val numberOfJoinedMembers = room.getNumberOfJoinedMembers()
|
||||
|
@ -398,7 +397,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun pickStickerData(eventData: JsonDict) {
|
||||
private fun pickStickerData(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict) {
|
||||
Timber.d("Received request send sticker")
|
||||
val data = eventData["data"]
|
||||
if (data == null) {
|
||||
|
@ -411,7 +410,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
return
|
||||
}
|
||||
widgetPostAPIMediator.sendSuccess(eventData)
|
||||
navigationCallback.closeWithResult(content)
|
||||
navigationCallback?.closeWithResult(content)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -420,7 +419,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @return true in case of error
|
||||
*/
|
||||
private fun checkRoomId(eventData: JsonDict): Boolean {
|
||||
private fun checkRoomId(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict): Boolean {
|
||||
val roomIdInEvent = eventData["room_id"] as String?
|
||||
// Check if param is present
|
||||
if (null == roomIdInEvent) {
|
||||
|
@ -443,7 +442,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
*
|
||||
* @return true in case of error
|
||||
*/
|
||||
private fun checkUserId(eventData: JsonDict): Boolean {
|
||||
private fun checkUserId(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict): Boolean {
|
||||
val userIdInEvent = eventData["user_id"] as String?
|
||||
// Check if param is present
|
||||
if (null == userIdInEvent) {
|
||||
|
@ -454,7 +453,7 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
|
|||
return false
|
||||
}
|
||||
|
||||
private fun createWidgetAPICallback(eventData: JsonDict): WidgetAPICallback {
|
||||
private fun createWidgetAPICallback(widgetPostAPIMediator: WidgetPostAPIMediator, eventData: JsonDict): WidgetAPICallback {
|
||||
return WidgetAPICallback(widgetPostAPIMediator, eventData, stringProvider)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,6 @@ 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()
|
||||
data class OnURLFormatted(val formattedURL: String) : WidgetViewEvents()
|
||||
data class DisplayTerms(val url: String, val token: String) : WidgetViewEvents()
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
|
|||
private val integrationManagerService = session.integrationManagerService()
|
||||
private val widgetURLFormatter = widgetService.getWidgetURLFormatter()
|
||||
private val postAPIMediator = widgetService.getWidgetPostAPIMediator()
|
||||
private var widgetPostAPIHandler: WidgetPostAPIHandler? = null
|
||||
|
||||
// Flag to avoid infinite loop
|
||||
private var canRefreshToken = true
|
||||
|
@ -83,9 +84,14 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
|
|||
init {
|
||||
integrationManagerService.addListener(this)
|
||||
if (initialState.widgetKind.isAdmin()) {
|
||||
val widgetPostAPIHandler = widgetPostAPIHandlerFactory.create(initialState.roomId, this)
|
||||
widgetPostAPIHandler = widgetPostAPIHandlerFactory.create(initialState.roomId).apply {
|
||||
navigationCallback = this@WidgetViewModel
|
||||
}
|
||||
postAPIMediator.setHandler(widgetPostAPIHandler)
|
||||
}
|
||||
if (!integrationManagerService.isIntegrationEnabled()) {
|
||||
_viewEvents.post(WidgetViewEvents.Close(null))
|
||||
}
|
||||
setupName()
|
||||
refreshPermissionStatus()
|
||||
observePowerLevel()
|
||||
|
@ -142,10 +148,10 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
|
|||
is WidgetAction.OnWebViewLoadingError -> handleWebViewLoadingError(action)
|
||||
is WidgetAction.OnWebViewLoadingSuccess -> handleWebViewLoadingSuccess(action)
|
||||
is WidgetAction.OnWebViewStartedToLoad -> handleWebViewStartLoading()
|
||||
WidgetAction.LoadFormattedUrl -> loadFormattedUrl()
|
||||
WidgetAction.LoadFormattedUrl -> loadFormattedUrl(forceFetchToken = false)
|
||||
WidgetAction.DeleteWidget -> handleDeleteWidget()
|
||||
WidgetAction.RevokeWidget -> handleRevokeWidget()
|
||||
WidgetAction.OnTermsReviewed -> refreshPermissionStatus()
|
||||
WidgetAction.OnTermsReviewed -> loadFormattedUrl(forceFetchToken = false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +233,7 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
|
|||
)
|
||||
setState { copy(formattedURL = Success(formattedUrl)) }
|
||||
Timber.v("Post load formatted url event: $formattedUrl")
|
||||
_viewEvents.post(WidgetViewEvents.LoadFormattedURL(formattedUrl))
|
||||
_viewEvents.post(WidgetViewEvents.OnURLFormatted(formattedUrl))
|
||||
} catch (failure: Throwable) {
|
||||
if (failure is WidgetManagementFailure.TermsNotSignedException) {
|
||||
_viewEvents.post(WidgetViewEvents.DisplayTerms(initialState.baseUrl, failure.token))
|
||||
|
@ -265,17 +271,24 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
|
|||
|
||||
override fun onCleared() {
|
||||
integrationManagerService.removeListener(this)
|
||||
widgetPostAPIHandler?.navigationCallback = null
|
||||
postAPIMediator.setHandler(null)
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
// IntegrationManagerService.Listener
|
||||
// IntegrationManagerService.Listener
|
||||
|
||||
override fun onWidgetPermissionsChanged(widgets: Map<String, Boolean>) {
|
||||
refreshPermissionStatus()
|
||||
}
|
||||
|
||||
// WidgetPostAPIHandler.NavigationCallback
|
||||
override fun onIsEnabledChanged(enabled: Boolean) {
|
||||
if (!enabled) {
|
||||
_viewEvents.post(WidgetViewEvents.Close(null))
|
||||
}
|
||||
}
|
||||
|
||||
// WidgetPostAPIHandler.NavigationCallback
|
||||
|
||||
override fun close() {
|
||||
_viewEvents.post(WidgetViewEvents.Close(null))
|
||||
|
|
|
@ -81,22 +81,10 @@ fun WebView.clearAfterWidget() {
|
|||
webChromeClient = null
|
||||
webViewClient = null
|
||||
clearHistory()
|
||||
|
||||
// NOTE: clears RAM cache, if you pass true, it will also clear the disk cache.
|
||||
clearCache(true)
|
||||
|
||||
// Loading a blank page is optional, but will ensure that the WebView isn't doing anything when you destroy it.
|
||||
loadUrl("about:blank")
|
||||
|
||||
onPause()
|
||||
removeAllViews()
|
||||
|
||||
// NOTE: This pauses JavaScript execution for ALL WebViews,
|
||||
// do not use if you have other WebViews still alive.
|
||||
// If you create another WebView after calling this,
|
||||
// make sure to call mWebView.resumeTimers().
|
||||
pauseTimers()
|
||||
|
||||
// NOTE: This can occasionally cause a segfault below API 17 (4.2)
|
||||
destroy()
|
||||
}
|
||||
|
|
|
@ -1162,6 +1162,9 @@
|
|||
<string name="room_widget_webview_read_protected_media">Read DRM protected Media</string>
|
||||
|
||||
<!-- Widget Integration Manager -->
|
||||
<string name="integration_manager_not_enabled_title">Integrations are disabled</string>
|
||||
<string name="integration_manager_not_enabled_msg">Enable integrations in settings to allow this action.</string>
|
||||
|
||||
<string name="widget_integration_unable_to_create">Unable to create widget.</string>
|
||||
<string name="widget_integration_failed_to_send_request">Failed to send request.</string>
|
||||
<string name="widget_integration_positive_power_level">Power level must be positive integer.</string>
|
||||
|
|
Loading…
Reference in a new issue