Convert WidgetService to suspend functions

Signed-off-by: Dominic Fischer <dominicfischer7@gmail.com>
This commit is contained in:
Dominic Fischer 2021-03-27 19:38:09 +00:00
parent 2045a164c1
commit c548a3d2fa
6 changed files with 115 additions and 140 deletions

View file

@ -17,10 +17,8 @@
package org.matrix.android.sdk.api.session.widgets
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.api.session.widgets.model.Widget
/**
@ -107,20 +105,16 @@ interface WidgetService {
* @param roomId the room where you want to create the widget.
* @param widgetId the widget to create.
* @param content the content of the widget
* @param callback the matrix callback to listen for result.
* @return Cancelable
*/
fun createRoomWidget(roomId: String, widgetId: String, content: Content, callback: MatrixCallback<Widget>): Cancelable
suspend fun createRoomWidget(roomId: String, widgetId: String, content: Content): Widget
/**
* Deactivate a widget in a room. It makes sure you have the rights to handle this.
*
* @param roomId: the room where you want to deactivate the widget.
* @param widgetId: the widget to deactivate.
* @param callback the matrix callback to listen for result.
* @return Cancelable
*/
fun destroyRoomWidget(roomId: String, widgetId: String, callback: MatrixCallback<Unit>): Cancelable
suspend fun destroyRoomWidget(roomId: String, widgetId: String)
/**
* Returns true if you can add/remove widgets. It goes through

View file

@ -17,14 +17,12 @@
package org.matrix.android.sdk.internal.session.widgets
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.widgets.WidgetPostAPIMediator
import org.matrix.android.sdk.api.session.widgets.WidgetService
import org.matrix.android.sdk.api.session.widgets.WidgetURLFormatter
import org.matrix.android.sdk.api.session.widgets.model.Widget
import org.matrix.android.sdk.api.util.Cancelable
import javax.inject.Inject
import javax.inject.Provider
@ -77,21 +75,19 @@ internal class DefaultWidgetService @Inject constructor(private val widgetManage
return widgetManager.getUserWidgets(widgetTypes, excludedTypes)
}
override fun createRoomWidget(
override suspend fun createRoomWidget(
roomId: String,
widgetId: String,
content: Content,
callback: MatrixCallback<Widget>
): Cancelable {
return widgetManager.createRoomWidget(roomId, widgetId, content, callback)
content: Content
): Widget {
return widgetManager.createRoomWidget(roomId, widgetId, content)
}
override fun destroyRoomWidget(
override suspend fun destroyRoomWidget(
roomId: String,
widgetId: String,
callback: MatrixCallback<Unit>
): Cancelable {
return widgetManager.destroyRoomWidget(roomId, widgetId, callback)
widgetId: String
) {
return widgetManager.destroyRoomWidget(roomId, widgetId)
}
override fun hasPermissionsToHandleWidgets(roomId: String): Boolean {

View file

@ -21,7 +21,6 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
@ -34,7 +33,6 @@ import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.widgets.WidgetManagementFailure
import org.matrix.android.sdk.api.session.widgets.model.Widget
import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.SessionLifecycleObserver
import org.matrix.android.sdk.internal.session.SessionScope
@ -43,8 +41,6 @@ import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource
import org.matrix.android.sdk.internal.session.user.accountdata.AccountDataDataSource
import org.matrix.android.sdk.internal.session.widgets.helper.WidgetFactory
import org.matrix.android.sdk.internal.session.widgets.helper.extractWidgetSequence
import org.matrix.android.sdk.internal.task.TaskExecutor
import org.matrix.android.sdk.internal.task.launchToCallback
import java.util.HashMap
import javax.inject.Inject
@ -52,7 +48,6 @@ import javax.inject.Inject
internal class WidgetManager @Inject constructor(private val integrationManager: IntegrationManager,
private val accountDataDataSource: AccountDataDataSource,
private val stateEventDataSource: StateEventDataSource,
private val taskExecutor: TaskExecutor,
private val createWidgetTask: CreateWidgetTask,
private val widgetFactory: WidgetFactory,
@UserId private val userId: String)
@ -165,37 +160,33 @@ internal class WidgetManager @Inject constructor(private val integrationManager:
.toList()
}
fun createRoomWidget(roomId: String, widgetId: String, content: Content, callback: MatrixCallback<Widget>): Cancelable {
return taskExecutor.executorScope.launchToCallback(callback = callback) {
if (!hasPermissionsToHandleWidgets(roomId)) {
throw WidgetManagementFailure.NotEnoughPower
}
val params = CreateWidgetTask.Params(
roomId = roomId,
widgetId = widgetId,
content = content
)
createWidgetTask.execute(params)
try {
getRoomWidgets(roomId, widgetId = QueryStringValue.Equals(widgetId, QueryStringValue.Case.INSENSITIVE)).first()
} catch (failure: Throwable) {
throw WidgetManagementFailure.CreationFailed
}
suspend fun createRoomWidget(roomId: String, widgetId: String, content: Content): Widget {
if (!hasPermissionsToHandleWidgets(roomId)) {
throw WidgetManagementFailure.NotEnoughPower
}
val params = CreateWidgetTask.Params(
roomId = roomId,
widgetId = widgetId,
content = content
)
createWidgetTask.execute(params)
try {
return getRoomWidgets(roomId, widgetId = QueryStringValue.Equals(widgetId, QueryStringValue.Case.INSENSITIVE)).first()
} catch (failure: Throwable) {
throw WidgetManagementFailure.CreationFailed
}
}
fun destroyRoomWidget(roomId: String, widgetId: String, callback: MatrixCallback<Unit>): Cancelable {
return taskExecutor.executorScope.launchToCallback(callback = callback) {
if (!hasPermissionsToHandleWidgets(roomId)) {
throw WidgetManagementFailure.NotEnoughPower
}
val params = CreateWidgetTask.Params(
roomId = roomId,
widgetId = widgetId,
content = emptyMap()
)
createWidgetTask.execute(params)
suspend fun destroyRoomWidget(roomId: String, widgetId: String) {
if (!hasPermissionsToHandleWidgets(roomId)) {
throw WidgetManagementFailure.NotEnoughPower
}
val params = CreateWidgetTask.Params(
roomId = roomId,
widgetId = widgetId,
content = emptyMap()
)
createWidgetTask.execute(params)
}
fun hasPermissionsToHandleWidgets(roomId: String): Boolean {

View file

@ -97,12 +97,10 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent
import org.matrix.android.sdk.api.session.room.timeline.getRelationContent
import org.matrix.android.sdk.api.session.room.timeline.getTextEditableContent
import org.matrix.android.sdk.api.session.widgets.model.Widget
import org.matrix.android.sdk.api.session.widgets.model.WidgetType
import org.matrix.android.sdk.api.util.appendParamToUrl
import org.matrix.android.sdk.api.util.toOptional
import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode
import org.matrix.android.sdk.internal.util.awaitCallback
import org.matrix.android.sdk.rx.rx
import org.matrix.android.sdk.rx.unwrap
import timber.log.Timber
@ -262,68 +260,68 @@ class RoomDetailViewModel @AssistedInject constructor(
override fun handle(action: RoomDetailAction) {
when (action) {
is RoomDetailAction.UserIsTyping -> handleUserIsTyping(action)
is RoomDetailAction.ComposerFocusChange -> handleComposerFocusChange(action)
is RoomDetailAction.SaveDraft -> handleSaveDraft(action)
is RoomDetailAction.SendMessage -> handleSendMessage(action)
is RoomDetailAction.SendMedia -> handleSendMedia(action)
is RoomDetailAction.SendSticker -> handleSendSticker(action)
is RoomDetailAction.TimelineEventTurnsVisible -> handleEventVisible(action)
is RoomDetailAction.TimelineEventTurnsInvisible -> handleEventInvisible(action)
is RoomDetailAction.LoadMoreTimelineEvents -> handleLoadMore(action)
is RoomDetailAction.SendReaction -> handleSendReaction(action)
is RoomDetailAction.AcceptInvite -> handleAcceptInvite()
is RoomDetailAction.RejectInvite -> handleRejectInvite()
is RoomDetailAction.RedactAction -> handleRedactEvent(action)
is RoomDetailAction.UndoReaction -> handleUndoReact(action)
is RoomDetailAction.UpdateQuickReactAction -> handleUpdateQuickReaction(action)
is RoomDetailAction.EnterRegularMode -> handleEnterRegularMode(action)
is RoomDetailAction.EnterEditMode -> handleEditAction(action)
is RoomDetailAction.EnterQuoteMode -> handleQuoteAction(action)
is RoomDetailAction.EnterReplyMode -> handleReplyAction(action)
is RoomDetailAction.DownloadOrOpen -> handleOpenOrDownloadFile(action)
is RoomDetailAction.NavigateToEvent -> handleNavigateToEvent(action)
is RoomDetailAction.HandleTombstoneEvent -> handleTombstoneEvent(action)
is RoomDetailAction.ResendMessage -> handleResendEvent(action)
is RoomDetailAction.RemoveFailedEcho -> handleRemove(action)
is RoomDetailAction.ResendAll -> handleResendAll()
is RoomDetailAction.MarkAllAsRead -> handleMarkAllAsRead()
is RoomDetailAction.ReportContent -> handleReportContent(action)
is RoomDetailAction.IgnoreUser -> handleIgnoreUser(action)
is RoomDetailAction.UserIsTyping -> handleUserIsTyping(action)
is RoomDetailAction.ComposerFocusChange -> handleComposerFocusChange(action)
is RoomDetailAction.SaveDraft -> handleSaveDraft(action)
is RoomDetailAction.SendMessage -> handleSendMessage(action)
is RoomDetailAction.SendMedia -> handleSendMedia(action)
is RoomDetailAction.SendSticker -> handleSendSticker(action)
is RoomDetailAction.TimelineEventTurnsVisible -> handleEventVisible(action)
is RoomDetailAction.TimelineEventTurnsInvisible -> handleEventInvisible(action)
is RoomDetailAction.LoadMoreTimelineEvents -> handleLoadMore(action)
is RoomDetailAction.SendReaction -> handleSendReaction(action)
is RoomDetailAction.AcceptInvite -> handleAcceptInvite()
is RoomDetailAction.RejectInvite -> handleRejectInvite()
is RoomDetailAction.RedactAction -> handleRedactEvent(action)
is RoomDetailAction.UndoReaction -> handleUndoReact(action)
is RoomDetailAction.UpdateQuickReactAction -> handleUpdateQuickReaction(action)
is RoomDetailAction.EnterRegularMode -> handleEnterRegularMode(action)
is RoomDetailAction.EnterEditMode -> handleEditAction(action)
is RoomDetailAction.EnterQuoteMode -> handleQuoteAction(action)
is RoomDetailAction.EnterReplyMode -> handleReplyAction(action)
is RoomDetailAction.DownloadOrOpen -> handleOpenOrDownloadFile(action)
is RoomDetailAction.NavigateToEvent -> handleNavigateToEvent(action)
is RoomDetailAction.HandleTombstoneEvent -> handleTombstoneEvent(action)
is RoomDetailAction.ResendMessage -> handleResendEvent(action)
is RoomDetailAction.RemoveFailedEcho -> handleRemove(action)
is RoomDetailAction.ResendAll -> handleResendAll()
is RoomDetailAction.MarkAllAsRead -> handleMarkAllAsRead()
is RoomDetailAction.ReportContent -> handleReportContent(action)
is RoomDetailAction.IgnoreUser -> handleIgnoreUser(action)
is RoomDetailAction.EnterTrackingUnreadMessagesState -> startTrackingUnreadMessages()
is RoomDetailAction.ExitTrackingUnreadMessagesState -> stopTrackingUnreadMessages()
is RoomDetailAction.ReplyToOptions -> handleReplyToOptions(action)
is RoomDetailAction.AcceptVerificationRequest -> handleAcceptVerification(action)
is RoomDetailAction.DeclineVerificationRequest -> handleDeclineVerification(action)
is RoomDetailAction.RequestVerification -> handleRequestVerification(action)
is RoomDetailAction.ResumeVerification -> handleResumeRequestVerification(action)
is RoomDetailAction.ReRequestKeys -> handleReRequestKeys(action)
is RoomDetailAction.TapOnFailedToDecrypt -> handleTapOnFailedToDecrypt(action)
is RoomDetailAction.SelectStickerAttachment -> handleSelectStickerAttachment()
is RoomDetailAction.OpenIntegrationManager -> handleOpenIntegrationManager()
is RoomDetailAction.StartCallWithPhoneNumber -> handleStartCallWithPhoneNumber(action)
is RoomDetailAction.StartCall -> handleStartCall(action)
is RoomDetailAction.AcceptCall -> handleAcceptCall(action)
is RoomDetailAction.EndCall -> handleEndCall()
is RoomDetailAction.ManageIntegrations -> handleManageIntegrations()
is RoomDetailAction.AddJitsiWidget -> handleAddJitsiConference(action)
is RoomDetailAction.RemoveWidget -> handleDeleteWidget(action.widgetId)
is RoomDetailAction.EnsureNativeWidgetAllowed -> handleCheckWidgetAllowed(action)
is RoomDetailAction.CancelSend -> handleCancel(action)
is RoomDetailAction.OpenOrCreateDm -> handleOpenOrCreateDm(action)
is RoomDetailAction.JumpToReadReceipt -> handleJumpToReadReceipt(action)
RoomDetailAction.QuickActionInvitePeople -> handleInvitePeople()
RoomDetailAction.QuickActionSetAvatar -> handleQuickSetAvatar()
is RoomDetailAction.SetAvatarAction -> handleSetNewAvatar(action)
RoomDetailAction.QuickActionSetTopic -> _viewEvents.post(RoomDetailViewEvents.OpenRoomSettings)
is RoomDetailAction.ShowRoomAvatarFullScreen -> {
is RoomDetailAction.ExitTrackingUnreadMessagesState -> stopTrackingUnreadMessages()
is RoomDetailAction.ReplyToOptions -> handleReplyToOptions(action)
is RoomDetailAction.AcceptVerificationRequest -> handleAcceptVerification(action)
is RoomDetailAction.DeclineVerificationRequest -> handleDeclineVerification(action)
is RoomDetailAction.RequestVerification -> handleRequestVerification(action)
is RoomDetailAction.ResumeVerification -> handleResumeRequestVerification(action)
is RoomDetailAction.ReRequestKeys -> handleReRequestKeys(action)
is RoomDetailAction.TapOnFailedToDecrypt -> handleTapOnFailedToDecrypt(action)
is RoomDetailAction.SelectStickerAttachment -> handleSelectStickerAttachment()
is RoomDetailAction.OpenIntegrationManager -> handleOpenIntegrationManager()
is RoomDetailAction.StartCallWithPhoneNumber -> handleStartCallWithPhoneNumber(action)
is RoomDetailAction.StartCall -> handleStartCall(action)
is RoomDetailAction.AcceptCall -> handleAcceptCall(action)
is RoomDetailAction.EndCall -> handleEndCall()
is RoomDetailAction.ManageIntegrations -> handleManageIntegrations()
is RoomDetailAction.AddJitsiWidget -> handleAddJitsiConference(action)
is RoomDetailAction.RemoveWidget -> handleDeleteWidget(action.widgetId)
is RoomDetailAction.EnsureNativeWidgetAllowed -> handleCheckWidgetAllowed(action)
is RoomDetailAction.CancelSend -> handleCancel(action)
is RoomDetailAction.OpenOrCreateDm -> handleOpenOrCreateDm(action)
is RoomDetailAction.JumpToReadReceipt -> handleJumpToReadReceipt(action)
RoomDetailAction.QuickActionInvitePeople -> handleInvitePeople()
RoomDetailAction.QuickActionSetAvatar -> handleQuickSetAvatar()
is RoomDetailAction.SetAvatarAction -> handleSetNewAvatar(action)
RoomDetailAction.QuickActionSetTopic -> _viewEvents.post(RoomDetailViewEvents.OpenRoomSettings)
is RoomDetailAction.ShowRoomAvatarFullScreen -> {
_viewEvents.post(
RoomDetailViewEvents.ShowRoomAvatarFullScreen(action.matrixItem, action.transitionView)
)
}
is RoomDetailAction.DoNotShowPreviewUrlFor -> handleDoNotShowPreviewUrlFor(action)
RoomDetailAction.RemoveAllFailedMessages -> handleRemoveAllFailedMessages()
RoomDetailAction.ResendAll -> handleResendAll()
is RoomDetailAction.DoNotShowPreviewUrlFor -> handleDoNotShowPreviewUrlFor(action)
RoomDetailAction.RemoveAllFailedMessages -> handleRemoveAllFailedMessages()
RoomDetailAction.ResendAll -> handleResendAll()
}.exhaustive
}
@ -483,9 +481,7 @@ class RoomDetailViewModel @AssistedInject constructor(
)
try {
val widget = awaitCallback<Widget> {
session.widgetService().createRoomWidget(roomId, widgetId, widgetEventContent, it)
}
val widget = session.widgetService().createRoomWidget(roomId, widgetId, widgetEventContent)
_viewEvents.post(RoomDetailViewEvents.JoinJitsiConference(widget, action.withVideo))
} catch (failure: Throwable) {
_viewEvents.post(RoomDetailViewEvents.ShowMessage(stringProvider.getString(R.string.failed_to_add_widget)))
@ -499,7 +495,7 @@ class RoomDetailViewModel @AssistedInject constructor(
_viewEvents.post(RoomDetailViewEvents.ShowWaitingView)
viewModelScope.launch(Dispatchers.IO) {
try {
awaitCallback<Unit> { session.widgetService().destroyRoomWidget(room.roomId, widgetId, it) }
session.widgetService().destroyRoomWidget(room.roomId, widgetId)
// local echo
setState {
copy(
@ -663,13 +659,13 @@ class RoomDetailViewModel @AssistedInject constructor(
}
when (itemId) {
R.id.timeline_setting -> true
R.id.invite -> state.canInvite
R.id.invite -> state.canInvite
R.id.open_matrix_apps -> true
R.id.voice_call,
R.id.video_call -> callManager.getCallsByRoomId(state.roomId).isEmpty()
R.id.hangup_call -> callManager.getCallsByRoomId(state.roomId).isNotEmpty()
R.id.search -> true
R.id.dev_tools -> vectorPreferences.developerMode()
R.id.video_call -> callManager.getCallsByRoomId(state.roomId).isEmpty()
R.id.hangup_call -> callManager.getCallsByRoomId(state.roomId).isNotEmpty()
R.id.search -> true
R.id.dev_tools -> vectorPreferences.developerMode()
else -> false
}
}
@ -816,7 +812,7 @@ class RoomDetailViewModel @AssistedInject constructor(
}
}.exhaustive
}
is SendMode.EDIT -> {
is SendMode.EDIT -> {
// is original event a reply?
val inReplyTo = state.sendMode.timelineEvent.getRelationContent()?.inReplyTo?.eventId
if (inReplyTo != null) {
@ -839,7 +835,7 @@ class RoomDetailViewModel @AssistedInject constructor(
_viewEvents.post(RoomDetailViewEvents.MessageSent)
popDraft()
}
is SendMode.QUOTE -> {
is SendMode.QUOTE -> {
val messageContent = state.sendMode.timelineEvent.getLastMessageContent()
val textMsg = messageContent?.body
@ -860,7 +856,7 @@ class RoomDetailViewModel @AssistedInject constructor(
_viewEvents.post(RoomDetailViewEvents.MessageSent)
popDraft()
}
is SendMode.REPLY -> {
is SendMode.REPLY -> {
state.sendMode.timelineEvent.let {
room.replyToMessage(it, action.text.toString(), action.autoMarkdown)
_viewEvents.post(RoomDetailViewEvents.MessageSent)

View file

@ -289,12 +289,13 @@ class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roo
callback = createWidgetAPICallback(widgetPostAPIMediator, eventData)
)
} else {
session.widgetService().createRoomWidget(
roomId = roomId,
widgetId = widgetId,
content = widgetEventContent,
callback = createWidgetAPICallback(widgetPostAPIMediator, eventData)
)
launchWidgetAPIAction(widgetPostAPIMediator, eventData) {
session.widgetService().createRoomWidget(
roomId = roomId,
widgetId = widgetId,
content = widgetEventContent
)
}
}
}

View file

@ -41,7 +41,6 @@ import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerS
import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
import org.matrix.android.sdk.api.session.widgets.WidgetManagementFailure
import org.matrix.android.sdk.internal.util.awaitCallback
import org.matrix.android.sdk.rx.mapOptional
import org.matrix.android.sdk.rx.rx
import org.matrix.android.sdk.rx.unwrap
@ -147,13 +146,13 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
override fun handle(action: WidgetAction) {
when (action) {
is WidgetAction.OnWebViewLoadingError -> handleWebViewLoadingError(action)
is WidgetAction.OnWebViewLoadingError -> handleWebViewLoadingError(action)
is WidgetAction.OnWebViewLoadingSuccess -> handleWebViewLoadingSuccess(action)
is WidgetAction.OnWebViewStartedToLoad -> handleWebViewStartLoading()
WidgetAction.LoadFormattedUrl -> loadFormattedUrl(forceFetchToken = false)
WidgetAction.DeleteWidget -> handleDeleteWidget()
WidgetAction.RevokeWidget -> handleRevokeWidget()
WidgetAction.OnTermsReviewed -> loadFormattedUrl(forceFetchToken = false)
is WidgetAction.OnWebViewStartedToLoad -> handleWebViewStartLoading()
WidgetAction.LoadFormattedUrl -> loadFormattedUrl(forceFetchToken = false)
WidgetAction.DeleteWidget -> handleDeleteWidget()
WidgetAction.RevokeWidget -> handleRevokeWidget()
WidgetAction.OnTermsReviewed -> loadFormattedUrl(forceFetchToken = false)
}
}
@ -173,10 +172,8 @@ class WidgetViewModel @AssistedInject constructor(@Assisted val initialState: Wi
viewModelScope.launch {
val widgetId = initialState.widgetId ?: return@launch
try {
awaitCallback<Unit> {
widgetService.destroyRoomWidget(initialState.roomId, widgetId, it)
_viewEvents.post(WidgetViewEvents.Close())
}
widgetService.destroyRoomWidget(initialState.roomId, widgetId)
_viewEvents.post(WidgetViewEvents.Close())
} catch (failure: Throwable) {
_viewEvents.post(WidgetViewEvents.Failure(failure))
}