From 7f42eb3fb609cb21e268aca2fc0fb792bf49da34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 Apr 2023 10:07:31 +0000 Subject: [PATCH 1/4] Bump peter-evans/create-pull-request from 4 to 5 (#8322) --- .github/workflows/sync-from-external-sources.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sync-from-external-sources.yml b/.github/workflows/sync-from-external-sources.yml index fdc1bbcb96..489ed1646e 100644 --- a/.github/workflows/sync-from-external-sources.yml +++ b/.github/workflows/sync-from-external-sources.yml @@ -23,7 +23,7 @@ jobs: - name: Run Emoji script run: ./tools/import_emojis.py - name: Create Pull Request for Emojis - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v5 with: commit-message: Sync Emojis title: Sync Emojis @@ -49,7 +49,7 @@ jobs: - name: Run SAS String script run: ./tools/import_sas_strings.py - name: Create Pull Request for SAS Strings - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v5 with: commit-message: Sync SAS Strings title: Sync SAS Strings @@ -68,7 +68,7 @@ jobs: - name: Run analytics import script run: ./tools/import_analytic_plan.sh - name: Create Pull Request for analytics plan - uses: peter-evans/create-pull-request@v4 + uses: peter-evans/create-pull-request@v5 with: commit-message: Sync analytics plan title: Sync analytics plan From 99aa9493d6c74aabfe9c489de9fdc06f36ee883a Mon Sep 17 00:00:00 2001 From: Yoan Pintas Date: Wed, 12 Apr 2023 09:18:02 +0200 Subject: [PATCH 2/4] Update read marker when we go back in live (#8306) --- .../app/features/home/room/detail/TimelineViewModel.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index b889c808b3..b2b1f1ef36 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -1325,13 +1325,17 @@ class TimelineViewModel @AssistedInject constructor( computeUnreadState(timelineEvents, roomSummary) } // We don't want live update of unread so we skip when we already had a HasUnread or HasNoUnread - // However, we want to update an existing HasUnread, if the readMarkerId hasn't changed, + // However, we want to update an existing HasUnread, if the readMarkerId hasn't changed or when we go back in live, // as we might be loading new events to fill gaps in the timeline. .distinctUntilChanged { previous, current -> when { previous is UnreadState.Unknown || previous is UnreadState.ReadMarkerNotLoaded -> false previous is UnreadState.HasUnread && current is UnreadState.HasUnread && previous.readMarkerId == current.readMarkerId -> false + previous is UnreadState.HasUnread && ( + current is UnreadState.HasUnread && previous.firstUnreadEventId != current.firstUnreadEventId || + current is UnreadState.HasNoUnread + ) && timeline?.isLive.orFalse() -> false current is UnreadState.HasUnread || current is UnreadState.HasNoUnread -> true else -> false } From fb837fed5a387dd4c9ad018ef88f629d18cc4f39 Mon Sep 17 00:00:00 2001 From: Yoan Pintas Date: Wed, 12 Apr 2023 13:55:20 +0200 Subject: [PATCH 3/4] Keep screen on while recording voicebroadcast (#8313) --- changelog.d/8313.bugfix | 1 + .../home/room/detail/composer/AudioMessageHelper.kt | 2 +- .../timeline/helper/AudioMessagePlaybackTracker.kt | 2 +- .../listening/VoiceBroadcastPlayerImpl.kt | 2 +- .../recording/usecase/StartVoiceBroadcastUseCase.kt | 12 +++++++++--- .../GetVoiceBroadcastStateEventLiveUseCase.kt | 6 +++--- .../usecase/StartVoiceBroadcastUseCaseTest.kt | 1 + 7 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 changelog.d/8313.bugfix diff --git a/changelog.d/8313.bugfix b/changelog.d/8313.bugfix new file mode 100644 index 0000000000..b524678101 --- /dev/null +++ b/changelog.d/8313.bugfix @@ -0,0 +1 @@ +Keep screen on while recording voicebroadcast diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt index c55f8ec047..149f0fb0aa 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt @@ -239,7 +239,7 @@ class AudioMessageHelper @Inject constructor( val percentage = currentPosition.toFloat() / totalDuration playbackTracker.updatePlayingAtPlaybackTime(id, currentPosition, percentage) } else { - playbackTracker.stopPlayback(id) + playbackTracker.stopPlaybackOrRecorder(id) stopPlaybackTicker() } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt index c598a99af7..00382b5a3f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt @@ -100,7 +100,7 @@ class AudioMessagePlaybackTracker @Inject constructor() { } } - fun stopPlayback(id: String) { + fun stopPlaybackOrRecorder(id: String) { val state = getPlaybackState(id) if (state !is Listener.State.Error) { setState(id, Listener.State.Idle) diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt index 5bb890b07c..5a91021089 100644 --- a/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt +++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/listening/VoiceBroadcastPlayerImpl.kt @@ -527,7 +527,7 @@ class VoiceBroadcastPlayerImpl @Inject constructor( State.Idle -> { // restart the playback time if player completed with less than 1s remaining time if (percentage == null || (playlist.duration - position) < 1000) { - playbackTracker.stopPlayback(id) + playbackTracker.stopPlaybackOrRecorder(id) } else { playbackTracker.updatePausedAtPlaybackTime(id, position, percentage) } diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt index d807c67f74..3b0644f6d2 100644 --- a/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/recording/usecase/StartVoiceBroadcastUseCase.kt @@ -20,6 +20,7 @@ import android.content.Context import androidx.core.content.FileProvider import im.vector.app.core.resources.BuildMeta import im.vector.app.features.attachments.toContentAttachmentData +import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker import im.vector.app.features.session.coroutineScope import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants import im.vector.app.features.voicebroadcast.VoiceBroadcastFailure @@ -54,6 +55,7 @@ import javax.inject.Inject class StartVoiceBroadcastUseCase @Inject constructor( private val session: Session, private val voiceBroadcastRecorder: VoiceBroadcastRecorder?, + private val playbackTracker: AudioMessagePlaybackTracker, private val context: Context, private val buildMeta: BuildMeta, private val getRoomLiveVoiceBroadcastsUseCase: GetRoomLiveVoiceBroadcastsUseCase, @@ -106,10 +108,14 @@ class StartVoiceBroadcastUseCase @Inject constructor( } override fun onStateUpdated(state: VoiceBroadcastRecorder.State) { - if (state == VoiceBroadcastRecorder.State.Error) { - session.coroutineScope.launch { - pauseVoiceBroadcastUseCase.execute(room.roomId) + when (state) { + VoiceBroadcastRecorder.State.Recording -> playbackTracker.updateCurrentRecording(AudioMessagePlaybackTracker.RECORDING_ID, emptyList()) + VoiceBroadcastRecorder.State.Idle -> playbackTracker.stopPlaybackOrRecorder(AudioMessagePlaybackTracker.RECORDING_ID) + VoiceBroadcastRecorder.State.Error -> { + playbackTracker.stopPlaybackOrRecorder(AudioMessagePlaybackTracker.RECORDING_ID) + session.coroutineScope.launch { pauseVoiceBroadcastUseCase.execute(room.roomId) } } + else -> Unit } } }) diff --git a/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/GetVoiceBroadcastStateEventLiveUseCase.kt b/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/GetVoiceBroadcastStateEventLiveUseCase.kt index 22fb0df6f9..a27b1689f7 100644 --- a/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/GetVoiceBroadcastStateEventLiveUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/voicebroadcast/usecase/GetVoiceBroadcastStateEventLiveUseCase.kt @@ -47,8 +47,7 @@ class GetVoiceBroadcastStateEventLiveUseCase @Inject constructor( ) { fun execute(voiceBroadcast: VoiceBroadcast): Flow> { - val room = session.getRoom(voiceBroadcast.roomId) ?: error("Unknown roomId: ${voiceBroadcast.roomId}") - return getMostRecentVoiceBroadcastEventFlow(room, voiceBroadcast) + return getMostRecentVoiceBroadcastEventFlow(voiceBroadcast) .onEach { event -> Timber.d( "## VoiceBroadcast | " + @@ -61,7 +60,8 @@ class GetVoiceBroadcastStateEventLiveUseCase @Inject constructor( /** * Get a flow of the most recent event for the given voice broadcast. */ - private fun getMostRecentVoiceBroadcastEventFlow(room: Room, voiceBroadcast: VoiceBroadcast): Flow> { + private fun getMostRecentVoiceBroadcastEventFlow(voiceBroadcast: VoiceBroadcast): Flow> { + val room = session.getRoom(voiceBroadcast.roomId) ?: error("Unknown roomId: ${voiceBroadcast.roomId}") val startedEventFlow = room.flow().liveTimelineEvent(voiceBroadcast.voiceBroadcastId) // observe started event changes return startedEventFlow diff --git a/vector/src/test/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCaseTest.kt index 9aa0ddf3b2..a9a49034fc 100644 --- a/vector/src/test/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCaseTest.kt +++ b/vector/src/test/java/im/vector/app/features/voicebroadcast/usecase/StartVoiceBroadcastUseCaseTest.kt @@ -57,6 +57,7 @@ class StartVoiceBroadcastUseCaseTest { StartVoiceBroadcastUseCase( session = fakeSession, voiceBroadcastRecorder = fakeVoiceBroadcastRecorder, + playbackTracker = mockk(), context = FakeContext().instance, buildMeta = mockk(), getRoomLiveVoiceBroadcastsUseCase = fakeGetRoomLiveVoiceBroadcastsUseCase, From 110b5cfcb4ff48931973a9e11d05c9eb54640c8a Mon Sep 17 00:00:00 2001 From: Yoan Pintas Date: Wed, 12 Apr 2023 14:35:01 +0200 Subject: [PATCH 4/4] Add pills for permalink supported hosts (#8324) --- changelog.d/8307.bugfix | 2 ++ .../session/room/send/TestPermalinkService.kt | 4 ++++ .../matrix/android/sdk/api/MatrixPatterns.kt | 2 +- .../session/permalinks/PermalinkService.kt | 11 ++++++++++ .../permalinks/DefaultPermalinkService.kt | 6 ++++++ .../timeline/render/EventTextRenderer.kt | 6 ++++-- .../app/features/html/PillsPostProcessor.kt | 20 +++++++++++++------ .../features/permalink/PermalinkHandler.kt | 11 ++-------- 8 files changed, 44 insertions(+), 18 deletions(-) create mode 100644 changelog.d/8307.bugfix diff --git a/changelog.d/8307.bugfix b/changelog.d/8307.bugfix new file mode 100644 index 0000000000..b548287ee7 --- /dev/null +++ b/changelog.d/8307.bugfix @@ -0,0 +1,2 @@ + The new permalink rendering is not applied on permalink created with the potential clientPermalinkBaseUrl + \ No newline at end of file diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/TestPermalinkService.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/TestPermalinkService.kt index 3a267ec694..a0986cc55a 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/TestPermalinkService.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/TestPermalinkService.kt @@ -48,4 +48,8 @@ class TestPermalinkService : PermalinkService { MARKDOWN -> "[%2\$s](https://matrix.to/#/%1\$s)" } } + + override fun isPermalinkSupported(supportedHosts: Array, url: String): Boolean { + return false + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt index 2de95850b0..0f7e9ca6a8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixPatterns.kt @@ -62,7 +62,7 @@ object MatrixPatterns { // regex pattern to find permalink with message id. // Android does not support in URL so extract it. private const val PERMALINK_BASE_REGEX = "https://matrix\\.to/#/" - private const val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/[A-Z]{3,}/#/room/" + private const val APP_BASE_REGEX = "https://[A-Z0-9.-]+\\.[A-Z]{2,}/#/(room|user)/" const val SEP_REGEX = "/" private val PATTERN_CONTAIN_MATRIX_TO_PERMALINK = PERMALINK_BASE_REGEX.toRegex(RegexOption.IGNORE_CASE) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt index 1788bf7bd2..0733ac0bc1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/permalinks/PermalinkService.kt @@ -97,4 +97,15 @@ interface PermalinkService { * @return the created template */ fun createMentionSpanTemplate(type: SpanTemplateType, forceMatrixTo: Boolean = false): String + + /** + * Check if the url is a permalink. It must be a matrix.to link + * or a link with host provided by the string-array `permalink_supported_hosts` in the config file + * + * @param supportedHosts the list of hosts supported for permalinks + * @param url the link to check, Ex: "https://matrix.to/#/@benoit:matrix.org" + * + * @return true when url is a permalink + */ + fun isPermalinkSupported(supportedHosts: Array, url: String): Boolean } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt index 196a8c122d..270676ff6d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/permalinks/DefaultPermalinkService.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.permalinks +import androidx.core.net.toUri import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.permalinks.PermalinkService import javax.inject.Inject @@ -47,4 +48,9 @@ internal class DefaultPermalinkService @Inject constructor( override fun createMentionSpanTemplate(type: PermalinkService.SpanTemplateType, forceMatrixTo: Boolean): String { return permalinkFactory.createMentionSpanTemplate(type, forceMatrixTo) } + + override fun isPermalinkSupported(supportedHosts: Array, url: String): Boolean { + return url.startsWith(PermalinkService.MATRIX_TO_URL_BASE) || + supportedHosts.any { url.toUri().host == it } + } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt index cc09ea0296..79e8690c91 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/render/EventTextRenderer.kt @@ -29,7 +29,7 @@ import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.glide.GlideApp import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.html.PillImageSpan -import org.matrix.android.sdk.api.MatrixPatterns +import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.getRoomSummary import org.matrix.android.sdk.api.session.getUserOrDefault import org.matrix.android.sdk.api.session.permalinks.PermalinkData @@ -99,7 +99,9 @@ class EventTextRenderer @AssistedInject constructor( private fun addPermalinksSpans(text: Spannable) { for (match in Patterns.WEB_URL.toRegex().findAll(text)) { val url = text.substring(match.range) - val matrixItem = if (MatrixPatterns.isPermalink(url)) { + val supportedHosts = context.resources.getStringArray(R.array.permalink_supported_hosts) + val isPermalinkSupported = sessionHolder.getSafeActiveSession()?.permalinkService()?.isPermalinkSupported(supportedHosts, url).orFalse() + val matrixItem = if (isPermalinkSupported) { when (val permalinkData = PermalinkParser.parse(url)) { is PermalinkData.UserLink -> permalinkData.toMatrixItem() is PermalinkData.RoomLink -> permalinkData.toMatrixItem() diff --git a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt index 6b23d68e80..92d5b16998 100644 --- a/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt +++ b/vector/src/main/java/im/vector/app/features/html/PillsPostProcessor.kt @@ -22,10 +22,12 @@ import android.text.Spanned import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.glide.GlideApp import im.vector.app.features.home.AvatarRenderer import io.noties.markwon.core.spans.LinkSpan +import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.getRoomSummary import org.matrix.android.sdk.api.session.getUser import org.matrix.android.sdk.api.session.permalinks.PermalinkData @@ -105,12 +107,18 @@ class PillsPostProcessor @AssistedInject constructor( PillImageSpan(GlideApp.with(context), avatarRenderer, context, matrixItem) private fun LinkSpan.createPillSpan(): PillImageSpan? { - val matrixItem = when (val permalinkData = PermalinkParser.parse(url)) { - is PermalinkData.UserLink -> permalinkData.toMatrixItem() - is PermalinkData.RoomLink -> permalinkData.toMatrixItem() - else -> null - } ?: return null - return createPillImageSpan(matrixItem) + val supportedHosts = context.resources.getStringArray(R.array.permalink_supported_hosts) + val isPermalinkSupported = sessionHolder.getSafeActiveSession()?.permalinkService()?.isPermalinkSupported(supportedHosts, url).orFalse() + if (isPermalinkSupported) { + val matrixItem = when (val permalinkData = PermalinkParser.parse(url)) { + is PermalinkData.UserLink -> permalinkData.toMatrixItem() + is PermalinkData.RoomLink -> permalinkData.toMatrixItem() + else -> null + } ?: return null + return createPillImageSpan(matrixItem) + } else { + return null + } } private fun PermalinkData.UserLink.toMatrixItem(): MatrixItem? = diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index 304bfa6d43..f15375c09f 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -18,7 +18,6 @@ package im.vector.app.features.permalink import android.content.Context import android.net.Uri -import androidx.core.net.toUri import androidx.fragment.app.FragmentActivity import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder @@ -38,7 +37,6 @@ import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.getRoomSummary import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.permalinks.PermalinkParser -import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.room.getTimelineEvent import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -68,10 +66,11 @@ class PermalinkHandler @Inject constructor( navigationInterceptor: NavigationInterceptor? = null, buildTask: Boolean = false ): Boolean { + val supportedHosts = fragmentActivity.resources.getStringArray(R.array.permalink_supported_hosts) return when { deepLink == null -> false deepLink.isIgnored() -> true - !isPermalinkSupported(fragmentActivity, deepLink.toString()) -> false + !activeSessionHolder.getSafeActiveSession()?.permalinkService()?.isPermalinkSupported(supportedHosts, deepLink.toString()).orFalse() -> false else -> { tryOrNull { withContext(Dispatchers.Default) { @@ -167,12 +166,6 @@ class PermalinkHandler @Inject constructor( } } - private fun isPermalinkSupported(context: Context, url: String): Boolean { - return url.startsWith(PermalinkService.MATRIX_TO_URL_BASE) || - context.resources.getStringArray(R.array.permalink_supported_hosts) - .any { url.toUri().host == it } - } - private suspend fun PermalinkData.RoomLink.getRoomId(): String? { val session = activeSessionHolder.getSafeActiveSession() return if (isRoomAlias && session != null) {