Jitsi call: add join status for Jitsi in RoomDetailViewState
This commit is contained in:
parent
7f74278a73
commit
47d2d31a94
|
@ -108,8 +108,7 @@ class JitsiService @Inject constructor(
|
||||||
this.avatar = userAvatar?.let { URL(it) }
|
this.avatar = userAvatar?.let { URL(it) }
|
||||||
}
|
}
|
||||||
val roomName = session.getRoomSummary(roomId)?.displayName
|
val roomName = session.getRoomSummary(roomId)?.displayName
|
||||||
val properties = session.widgetService().getWidgetComputedUrl(jitsiWidget, themeProvider.isLightTheme())
|
val properties = extractProperties(jitsiWidget) ?: throw IllegalStateException()
|
||||||
?.let { url -> jitsiWidgetPropertiesFactory.create(url) } ?: throw IllegalStateException()
|
|
||||||
|
|
||||||
val token = if (jitsiWidget.isOpenIdJWTAuthenticationRequired()) {
|
val token = if (jitsiWidget.isOpenIdJWTAuthenticationRequired()) {
|
||||||
getOpenIdJWTToken(roomId, properties.domain, userDisplayName ?: session.myUserId, userAvatar ?: "")
|
getOpenIdJWTToken(roomId, properties.domain, userDisplayName ?: session.myUserId, userAvatar ?: "")
|
||||||
|
@ -126,6 +125,11 @@ class JitsiService @Inject constructor(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun extractProperties(jitsiWidget: Widget): JitsiWidgetProperties? {
|
||||||
|
return session.widgetService().getWidgetComputedUrl(jitsiWidget, themeProvider.isLightTheme())
|
||||||
|
?.let { url -> jitsiWidgetPropertiesFactory.create(url) }
|
||||||
|
}
|
||||||
|
|
||||||
private fun Widget.isOpenIdJWTAuthenticationRequired(): Boolean {
|
private fun Widget.isOpenIdJWTAuthenticationRequired(): Boolean {
|
||||||
return widgetContent.data[JITSI_AUTH_KEY] == JITSI_OPEN_ID_TOKEN_JWT_AUTH
|
return widgetContent.data[JITSI_AUTH_KEY] == JITSI_OPEN_ID_TOKEN_JWT_AUTH
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.home.room.detail
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import im.vector.app.core.platform.VectorViewModelAction
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
|
import org.jitsi.meet.sdk.BroadcastEvent
|
||||||
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
|
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.session.room.model.message.MessageStickerContent
|
import org.matrix.android.sdk.api.session.room.model.message.MessageStickerContent
|
||||||
|
@ -92,6 +93,7 @@ sealed class RoomDetailAction : VectorViewModelAction {
|
||||||
data class EnsureNativeWidgetAllowed(val widget: Widget,
|
data class EnsureNativeWidgetAllowed(val widget: Widget,
|
||||||
val userJustAccepted: Boolean,
|
val userJustAccepted: Boolean,
|
||||||
val grantedEvents: RoomDetailViewEvents) : RoomDetailAction()
|
val grantedEvents: RoomDetailViewEvents) : RoomDetailAction()
|
||||||
|
data class UpdateJoinJitsiCallStatus(val broadcastEvent: BroadcastEvent): RoomDetailAction()
|
||||||
|
|
||||||
data class OpenOrCreateDm(val userId: String) : RoomDetailAction()
|
data class OpenOrCreateDm(val userId: String) : RoomDetailAction()
|
||||||
data class JumpToReadReceipt(val userId: String) : RoomDetailAction()
|
data class JumpToReadReceipt(val userId: String) : RoomDetailAction()
|
||||||
|
@ -101,6 +103,7 @@ sealed class RoomDetailAction : VectorViewModelAction {
|
||||||
object QuickActionSetTopic : RoomDetailAction()
|
object QuickActionSetTopic : RoomDetailAction()
|
||||||
data class ShowRoomAvatarFullScreen(val matrixItem: MatrixItem?, val transitionView: View?) : RoomDetailAction()
|
data class ShowRoomAvatarFullScreen(val matrixItem: MatrixItem?, val transitionView: View?) : RoomDetailAction()
|
||||||
|
|
||||||
|
|
||||||
// Preview URL
|
// Preview URL
|
||||||
data class DoNotShowPreviewUrlFor(val eventId: String, val url: String) : RoomDetailAction()
|
data class DoNotShowPreviewUrlFor(val eventId: String, val url: String) : RoomDetailAction()
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,9 @@ import im.vector.app.features.attachments.preview.AttachmentsPreviewArgs
|
||||||
import im.vector.app.features.attachments.toGroupedContentAttachmentData
|
import im.vector.app.features.attachments.toGroupedContentAttachmentData
|
||||||
import im.vector.app.features.call.SharedKnownCallsViewModel
|
import im.vector.app.features.call.SharedKnownCallsViewModel
|
||||||
import im.vector.app.features.call.VectorCallActivity
|
import im.vector.app.features.call.VectorCallActivity
|
||||||
|
import im.vector.app.features.call.conference.JitsiBroadcastEventObserver
|
||||||
import im.vector.app.features.call.conference.JitsiCallViewModel
|
import im.vector.app.features.call.conference.JitsiCallViewModel
|
||||||
|
import im.vector.app.features.call.conference.extractConferenceUrl
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||||
import im.vector.app.features.command.Command
|
import im.vector.app.features.command.Command
|
||||||
import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity
|
import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity
|
||||||
|
@ -174,6 +176,7 @@ import nl.dionsegijn.konfetti.models.Shape
|
||||||
import nl.dionsegijn.konfetti.models.Size
|
import nl.dionsegijn.konfetti.models.Size
|
||||||
import org.billcarsonfr.jsonviewer.JSonViewerDialog
|
import org.billcarsonfr.jsonviewer.JSonViewerDialog
|
||||||
import org.commonmark.parser.Parser
|
import org.commonmark.parser.Parser
|
||||||
|
import org.jitsi.meet.sdk.BroadcastEvent
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
|
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
|
@ -301,6 +304,7 @@ class RoomDetailFragment @Inject constructor(
|
||||||
private lateinit var emojiPopup: EmojiPopup
|
private lateinit var emojiPopup: EmojiPopup
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
lifecycle.addObserver(JitsiBroadcastEventObserver(vectorBaseActivity, this::onBroadcastEvent))
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java)
|
sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java)
|
||||||
knownCallsViewModel = activityViewModelProvider.get(SharedKnownCallsViewModel::class.java)
|
knownCallsViewModel = activityViewModelProvider.get(SharedKnownCallsViewModel::class.java)
|
||||||
|
@ -412,6 +416,10 @@ class RoomDetailFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onBroadcastEvent(event: BroadcastEvent) {
|
||||||
|
roomDetailViewModel.handle(RoomDetailAction.UpdateJoinJitsiCallStatus(event))
|
||||||
|
}
|
||||||
|
|
||||||
private fun acceptIncomingCall(event: RoomDetailViewEvents.DisplayAndAcceptCall) {
|
private fun acceptIncomingCall(event: RoomDetailViewEvents.DisplayAndAcceptCall) {
|
||||||
val intent = VectorCallActivity.newIntent(
|
val intent = VectorCallActivity.newIntent(
|
||||||
context = vectorBaseActivity,
|
context = vectorBaseActivity,
|
||||||
|
|
|
@ -39,6 +39,7 @@ import im.vector.app.core.mvrx.runCatchingToAsync
|
||||||
import im.vector.app.core.platform.VectorViewModel
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.call.conference.JitsiService
|
import im.vector.app.features.call.conference.JitsiService
|
||||||
|
import im.vector.app.features.call.conference.extractConferenceUrl
|
||||||
import im.vector.app.features.call.lookup.CallProtocolsChecker
|
import im.vector.app.features.call.lookup.CallProtocolsChecker
|
||||||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||||
import im.vector.app.features.command.CommandParser
|
import im.vector.app.features.command.CommandParser
|
||||||
|
@ -63,8 +64,10 @@ import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.commonmark.parser.Parser
|
import org.commonmark.parser.Parser
|
||||||
import org.commonmark.renderer.html.HtmlRenderer
|
import org.commonmark.renderer.html.HtmlRenderer
|
||||||
|
import org.jitsi.meet.sdk.BroadcastEvent
|
||||||
import org.matrix.android.sdk.api.MatrixCallback
|
import org.matrix.android.sdk.api.MatrixCallback
|
||||||
import org.matrix.android.sdk.api.MatrixPatterns
|
import org.matrix.android.sdk.api.MatrixPatterns
|
||||||
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
@ -236,8 +239,11 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
.map { widgets ->
|
.map { widgets ->
|
||||||
widgets.filter { it.isActive }
|
widgets.filter { it.isActive }
|
||||||
}
|
}
|
||||||
.execute {
|
.execute { widgets ->
|
||||||
copy(activeRoomWidgets = it)
|
val jitsiConfId = widgets()?.firstOrNull { it.type == WidgetType.Jitsi }?.let { jitsiWidget ->
|
||||||
|
jitsiService.extractProperties(jitsiWidget)?.confId
|
||||||
|
}
|
||||||
|
copy(activeRoomWidgets = widgets, jitsiConfId = jitsiConfId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,6 +309,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
is RoomDetailAction.EndCall -> handleEndCall()
|
is RoomDetailAction.EndCall -> handleEndCall()
|
||||||
is RoomDetailAction.ManageIntegrations -> handleManageIntegrations()
|
is RoomDetailAction.ManageIntegrations -> handleManageIntegrations()
|
||||||
is RoomDetailAction.AddJitsiWidget -> handleAddJitsiConference(action)
|
is RoomDetailAction.AddJitsiWidget -> handleAddJitsiConference(action)
|
||||||
|
is RoomDetailAction.UpdateJoinJitsiCallStatus -> handleJitsiCallJoinStatus(action)
|
||||||
is RoomDetailAction.RemoveWidget -> handleDeleteWidget(action.widgetId)
|
is RoomDetailAction.RemoveWidget -> handleDeleteWidget(action.widgetId)
|
||||||
is RoomDetailAction.EnsureNativeWidgetAllowed -> handleCheckWidgetAllowed(action)
|
is RoomDetailAction.EnsureNativeWidgetAllowed -> handleCheckWidgetAllowed(action)
|
||||||
is RoomDetailAction.CancelSend -> handleCancel(action)
|
is RoomDetailAction.CancelSend -> handleCancel(action)
|
||||||
|
@ -323,6 +330,25 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleJitsiCallJoinStatus(action: RoomDetailAction.UpdateJoinJitsiCallStatus) = withState { state ->
|
||||||
|
if (state.jitsiConfId == null) {
|
||||||
|
// If jitsi widget is removed while on the call
|
||||||
|
if (state.hasJoinedActiveJitsiConference) {
|
||||||
|
setState { copy(hasJoinedActiveJitsiConference = false) }
|
||||||
|
}
|
||||||
|
return@withState
|
||||||
|
}
|
||||||
|
when (action.broadcastEvent.type) {
|
||||||
|
BroadcastEvent.Type.CONFERENCE_JOINED,
|
||||||
|
BroadcastEvent.Type.CONFERENCE_TERMINATED -> {
|
||||||
|
if (action.broadcastEvent.extractConferenceUrl()?.endsWith(state.jitsiConfId).orFalse()) {
|
||||||
|
setState { copy(hasJoinedActiveJitsiConference = action.broadcastEvent.type == BroadcastEvent.Type.CONFERENCE_JOINED) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleAcceptCall(action: RoomDetailAction.AcceptCall) {
|
private fun handleAcceptCall(action: RoomDetailAction.AcceptCall) {
|
||||||
callManager.getCallById(action.callId)?.also {
|
callManager.getCallById(action.callId)?.also {
|
||||||
_viewEvents.post(RoomDetailViewEvents.DisplayAndAcceptCall(it))
|
_viewEvents.post(RoomDetailViewEvents.DisplayAndAcceptCall(it))
|
||||||
|
@ -607,7 +633,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
R.id.invite -> state.canInvite
|
R.id.invite -> state.canInvite
|
||||||
R.id.open_matrix_apps -> true
|
R.id.open_matrix_apps -> true
|
||||||
R.id.voice_call -> state.isWebRTCCallOptionAvailable()
|
R.id.voice_call -> state.isWebRTCCallOptionAvailable()
|
||||||
R.id.video_call -> state.isWebRTCCallOptionAvailable() || !state.hasActiveJitsiWidget()
|
R.id.video_call -> true
|
||||||
R.id.search -> true
|
R.id.search -> true
|
||||||
R.id.dev_tools -> vectorPreferences.developerMode()
|
R.id.dev_tools -> vectorPreferences.developerMode()
|
||||||
else -> false
|
else -> false
|
||||||
|
|
|
@ -19,7 +19,6 @@ package im.vector.app.features.home.room.detail
|
||||||
import com.airbnb.mvrx.Async
|
import com.airbnb.mvrx.Async
|
||||||
import com.airbnb.mvrx.MvRxState
|
import com.airbnb.mvrx.MvRxState
|
||||||
import com.airbnb.mvrx.Uninitialized
|
import com.airbnb.mvrx.Uninitialized
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
||||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||||
|
@ -27,7 +26,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import org.matrix.android.sdk.api.session.sync.SyncState
|
import org.matrix.android.sdk.api.session.sync.SyncState
|
||||||
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
||||||
import org.matrix.android.sdk.api.session.widgets.model.WidgetType
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the current send mode:
|
* Describes the current send mode:
|
||||||
|
@ -77,7 +75,10 @@ data class RoomDetailViewState(
|
||||||
val canInvite: Boolean = true,
|
val canInvite: Boolean = true,
|
||||||
val isAllowedToManageWidgets: Boolean = false,
|
val isAllowedToManageWidgets: Boolean = false,
|
||||||
val isAllowedToStartWebRTCCall: Boolean = true,
|
val isAllowedToStartWebRTCCall: Boolean = true,
|
||||||
val hasFailedSending: Boolean = false
|
val hasFailedSending: Boolean = false,
|
||||||
|
val hasJoinedActiveJitsiConference: Boolean = false,
|
||||||
|
// Not null if we have an active jitsi widget on the room
|
||||||
|
val jitsiConfId: String? = null
|
||||||
) : MvRxState {
|
) : MvRxState {
|
||||||
|
|
||||||
constructor(args: RoomDetailArgs) : this(
|
constructor(args: RoomDetailArgs) : this(
|
||||||
|
@ -89,7 +90,7 @@ data class RoomDetailViewState(
|
||||||
|
|
||||||
fun isWebRTCCallOptionAvailable() = (asyncRoomSummary.invoke()?.joinedMembersCount ?: 0) <= 2
|
fun isWebRTCCallOptionAvailable() = (asyncRoomSummary.invoke()?.joinedMembersCount ?: 0) <= 2
|
||||||
|
|
||||||
fun hasActiveJitsiWidget() = activeRoomWidgets()?.any { it.type == WidgetType.Jitsi }.orFalse()
|
fun hasActiveJitsiWidget() =jitsiConfId != null
|
||||||
|
|
||||||
fun isDm() = asyncRoomSummary()?.isDirect == true
|
fun isDm() = asyncRoomSummary()?.isDirect == true
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue