From 750f07547c1a727127338743a175fd2e31448523 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 15:46:19 +0200 Subject: [PATCH 01/12] Fix PiP crash with IllegalStateException. Activity must be resumed to enter PiP mode. https://sentry.tools.element.io/organizations/element/issues/1449388/events/2eb06349f6224481960a64916d51ae60/?project=59 --- .../android/features/call/impl/ui/ElementCallActivity.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/ElementCallActivity.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/ElementCallActivity.kt index 5cd8b55158..b55c39f41b 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/ElementCallActivity.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/ElementCallActivity.kt @@ -281,7 +281,11 @@ class ElementCallActivity : @RequiresApi(Build.VERSION_CODES.O) override fun enterPipMode(): Boolean { - return enterPictureInPictureMode(getPictureInPictureParams()) + return if (lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) { + enterPictureInPictureMode(getPictureInPictureParams()) + } else { + false + } } @RequiresApi(Build.VERSION_CODES.O) From 4a1aafae4315fa39e8d4959a28aef8ba0ee507d9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 15:59:48 +0200 Subject: [PATCH 02/12] mxCallbackFlow already contains a `tryOrNull` wrapper around the block, so not need to add an extra one. Also the block can return a non-null TaskHandle. --- .../matrix/impl/roomlist/RoomListExtensions.kt | 16 ++++++---------- .../matrix/impl/sync/SyncServiceExtension.kt | 5 +---- .../libraries/matrix/impl/util/CallbackFlow.kt | 2 +- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt index 334e42e266..46ef84ef73 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt @@ -97,9 +97,7 @@ internal fun RoomListServiceInterface.stateFlow(): Flow = trySendBlocking(state) } } - tryOrNull { - state(listener) - } + state(listener) }.buffer(Channel.UNLIMITED) internal fun RoomListServiceInterface.syncIndicator(): Flow = @@ -109,13 +107,11 @@ internal fun RoomListServiceInterface.syncIndicator(): Flow = trySendBlocking(state) } } - tryOrNull { - state(listener) - } + state(listener) }.buffer(Channel.UNLIMITED) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/CallbackFlow.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/CallbackFlow.kt index f071589078..a12a7c606b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/CallbackFlow.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/util/CallbackFlow.kt @@ -13,7 +13,7 @@ import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.callbackFlow import org.matrix.rustcomponents.sdk.TaskHandle -internal fun mxCallbackFlow(block: suspend ProducerScope.() -> TaskHandle?) = +internal fun mxCallbackFlow(block: suspend ProducerScope.() -> TaskHandle) = callbackFlow { val taskHandle: TaskHandle? = tryOrNull { block(this) From 72ca2f9eb0965105ce86a89eecc4cfe51eb6df96 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 16:01:58 +0200 Subject: [PATCH 03/12] No need to launch a coroutine to send the first value. --- .../android/libraries/matrix/impl/room/RustMatrixRoom.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index b871062f70..74b6027cc7 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -116,10 +116,8 @@ class RustMatrixRoom( } override val roomTypingMembersFlow: Flow> = mxCallbackFlow { - launch { - val initial = emptyList() - channel.trySend(initial) - } + val initial = emptyList() + channel.trySend(initial) innerRoom.subscribeToTypingNotifications(object : TypingNotificationsListener { override fun call(typingUserIds: List) { channel.trySend( From 8b161bf72cbd3385dcc9a682fe51e5cf677ed48f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 16:13:39 +0200 Subject: [PATCH 04/12] Add some missing runCatching to protect innerRoom access. May fix https://sentry.tools.element.io/organizations/element/issues/533226/events/e22d3a80ab204ce392e65c989c2753ac/ --- .../matrix/impl/room/RustMatrixRoom.kt | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index 74b6027cc7..2f4f6270d8 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -105,8 +105,12 @@ class RustMatrixRoom( override val roomInfoFlow: Flow = mxCallbackFlow { launch { - val initial = innerRoom.roomInfo().let(matrixRoomInfoMapper::map) - channel.trySend(initial) + runCatching { innerRoom.roomInfo() } + .getOrNull() + ?.let(matrixRoomInfoMapper::map) + ?.let { initial -> + channel.trySend(initial) + } } innerRoom.subscribeToRoomInfoUpdates(object : RoomInfoListener { override fun call(roomInfo: RoomInfo) { @@ -623,9 +627,13 @@ class RustMatrixRoom( innerRoom.sendCallNotificationIfNeeded() } - override suspend fun setSendQueueEnabled(enabled: Boolean) = withContext(roomDispatcher) { - Timber.d("setSendQueuesEnabled: $enabled") - innerRoom.enableSendQueue(enabled) + override suspend fun setSendQueueEnabled(enabled: Boolean) { + withContext(roomDispatcher) { + Timber.d("setSendQueuesEnabled: $enabled") + runCatching { + innerRoom.enableSendQueue(enabled) + } + } } override suspend fun saveComposerDraft(composerDraft: ComposerDraft): Result = runCatching { From 7a9a7c4af568db7ec725f57fbf20d24e6c407ecc Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 16:21:41 +0200 Subject: [PATCH 05/12] Protection against ActivityNotFoundException. --- .../androidutils/system/SystemUtils.kt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt index 1c213dd0ab..4a55b8549e 100644 --- a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/system/SystemUtils.kt @@ -71,7 +71,10 @@ fun Context.copyToClipboard( * Shows notification settings for the current app. * In android O will directly opens the notification settings, in lower version it will show the App settings */ -fun Context.startNotificationSettingsIntent(activityResultLauncher: ActivityResultLauncher? = null) { +fun Context.startNotificationSettingsIntent( + activityResultLauncher: ActivityResultLauncher? = null, + noActivityFoundMessage: String = getString(R.string.error_no_compatible_app_found), +) { val intent = Intent() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS @@ -85,10 +88,14 @@ fun Context.startNotificationSettingsIntent(activityResultLauncher: ActivityResu intent.data = Uri.fromParts("package", packageName, null) } - if (activityResultLauncher != null) { - activityResultLauncher.launch(intent) - } else { - startActivity(intent) + try { + if (activityResultLauncher != null) { + activityResultLauncher.launch(intent) + } else { + startActivity(intent) + } + } catch (activityNotFoundException: ActivityNotFoundException) { + toast(noActivityFoundMessage) } } From 31ccdeab51ec4a11ded673bf546657a09a5729fb Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 16:28:43 +0200 Subject: [PATCH 06/12] Protection against ActivityNotFoundException. Should fix https://sentry.tools.element.io/organizations/element/issues/974670/events/f074c0a4da444a5bacc4ef8f8fd5dbea/ --- .../libraries/mediapickers/api/PickerLauncher.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerLauncher.kt b/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerLauncher.kt index 719ee29651..0c47059ec1 100644 --- a/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerLauncher.kt +++ b/libraries/mediapickers/api/src/main/kotlin/io/element/android/libraries/mediapickers/api/PickerLauncher.kt @@ -7,7 +7,9 @@ package io.element.android.libraries.mediapickers.api +import android.content.ActivityNotFoundException import androidx.activity.compose.ManagedActivityResultLauncher +import timber.log.Timber /** * Wrapper around [ManagedActivityResultLauncher] to be used with media/file pickers. @@ -25,11 +27,19 @@ class ComposePickerLauncher( private val defaultRequest: Input, ) : PickerLauncher { override fun launch() { - managedLauncher.launch(defaultRequest) + try { + managedLauncher.launch(defaultRequest) + } catch (activityNotFoundException: ActivityNotFoundException) { + Timber.w(activityNotFoundException, "No activity found") + } } override fun launch(customInput: Input) { - managedLauncher.launch(customInput) + try { + managedLauncher.launch(customInput) + } catch (activityNotFoundException: ActivityNotFoundException) { + Timber.w(activityNotFoundException, "No activity found") + } } } From efe47d6c80a435310b0564e7168c13c59194d7ad Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 16:37:32 +0200 Subject: [PATCH 07/12] `flatMap` with `runCatching` is more appropriate here. --- .../impl/voicemessages/timeline/VoiceMessagePresenter.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt index a288309422..3ab00a71bc 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/VoiceMessagePresenter.kt @@ -27,6 +27,7 @@ import io.element.android.features.messages.impl.voicemessages.VoiceMessageExcep import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runUpdatingState +import io.element.android.libraries.core.extensions.flatMap import io.element.android.libraries.di.RoomScope import io.element.android.libraries.ui.utils.time.formatShort import io.element.android.services.analytics.api.AnalyticsService @@ -126,8 +127,8 @@ class VoiceMessagePresenter @AssistedInject constructor( it }, ) { - player.prepare().apply { - player.play() + player.prepare().flatMap { + runCatching { player.play() } } } } From 4d91260a8eb0f87721398d631123aeb67535151f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 17:14:20 +0200 Subject: [PATCH 08/12] Fix crash when pdf cannot be opened. https://sentry.tools.element.io/organizations/element/issues/1570011/events/efcaaf7382194fd4b7991ca6b05e7532/ --- .../api/local/pdf/PdfRendererManager.kt | 31 ++++++---- .../mediaviewer/api/local/pdf/PdfViewer.kt | 60 ++++++++++++++++++- .../api/local/pdf/PdfViewerState.kt | 6 +- 3 files changed, 83 insertions(+), 14 deletions(-) diff --git a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfRendererManager.kt b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfRendererManager.kt index b0b6fcb307..203df46aa3 100644 --- a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfRendererManager.kt +++ b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfRendererManager.kt @@ -9,6 +9,9 @@ package io.element.android.libraries.mediaviewer.api.local.pdf import android.graphics.pdf.PdfRenderer import android.os.ParcelFileDescriptor +import io.element.android.libraries.architecture.AsyncData +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -25,20 +28,28 @@ class PdfRendererManager( ) { private val mutex = Mutex() private var pdfRenderer: PdfRenderer? = null - private val mutablePdfPages = MutableStateFlow>(emptyList()) - val pdfPages: StateFlow> = mutablePdfPages + private val mutablePdfPages = MutableStateFlow>>(AsyncData.Uninitialized) + val pdfPages: StateFlow>> = mutablePdfPages fun open() { coroutineScope.launch { mutex.withLock { withContext(Dispatchers.IO) { - pdfRenderer = PdfRenderer(parcelFileDescriptor).apply { - // Preload just 3 pages so we can render faster - val firstPages = loadPages(from = 0, to = 3) - mutablePdfPages.value = firstPages - val nextPages = loadPages(from = 3, to = pageCount) - mutablePdfPages.value = firstPages + nextPages - } + runCatching { + PdfRenderer(parcelFileDescriptor) + }.fold( + onSuccess = { pdfRenderer -> + this@PdfRendererManager.pdfRenderer = pdfRenderer + // Preload just 3 pages so we can render faster + val firstPages = pdfRenderer.loadPages(from = 0, to = 3) + mutablePdfPages.value = AsyncData.Success(firstPages.toImmutableList()) + val nextPages = pdfRenderer.loadPages(from = 3, to = pdfRenderer.pageCount) + mutablePdfPages.value = AsyncData.Success((firstPages + nextPages).toImmutableList()) + }, + onFailure = { + mutablePdfPages.value = AsyncData.Failure(it) + } + ) } } } @@ -47,7 +58,7 @@ class PdfRendererManager( fun close() { coroutineScope.launch { mutex.withLock { - mutablePdfPages.value.forEach { pdfPage -> + mutablePdfPages.value.dataOrNull()?.forEach { pdfPage -> pdfPage.close() } pdfRenderer?.close() diff --git a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewer.kt b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewer.kt index 014efdad80..1185a2cef4 100644 --- a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewer.kt +++ b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewer.kt @@ -28,13 +28,19 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.text.roundToPx import io.element.android.libraries.designsystem.text.toDp +import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.toImmutableList import me.saket.telephoto.zoomable.zoomable +import java.io.IOException @Composable fun PdfViewer( @@ -59,7 +65,7 @@ fun PdfViewer( } val pdfPages = pdfViewerState.getPages() PdfPagesView( - pdfPages = pdfPages.toImmutableList(), + pdfPages = pdfPages, lazyListState = pdfViewerState.lazyListState, ) } @@ -67,6 +73,48 @@ fun PdfViewer( @Composable private fun PdfPagesView( + pdfPages: AsyncData>, + lazyListState: LazyListState, + modifier: Modifier = Modifier, +) { + when (pdfPages) { + is AsyncData.Uninitialized, + is AsyncData.Loading -> Unit + is AsyncData.Failure -> PdfPagesErrorView( + pdfPages.error, + modifier, + ) + is AsyncData.Success -> PdfPagesContentView( + pdfPages = pdfPages.data, + lazyListState = lazyListState, + modifier = modifier + ) + } +} + +@Composable +fun PdfPagesErrorView( + error: Throwable, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier.fillMaxSize(), + contentAlignment = Alignment.Center, + ) { + Text( + text = buildString { + append(stringResource(id = CommonStrings.error_unknown)) + append("\n\n") + append(error.localizedMessage) + }, + textAlign = TextAlign.Center, + style = ElementTheme.typography.fontBodyLgRegular, + ) + } +} + +@Composable +private fun PdfPagesContentView( pdfPages: ImmutableList, lazyListState: LazyListState, modifier: Modifier = Modifier, @@ -117,3 +165,11 @@ private fun PdfPageView( } } } + +@PreviewsDayNight +@Composable +internal fun PdfPagesErrorViewPreview() = ElementPreview { + PdfPagesErrorView( + error = IOException("file not in PDF format or corrupted"), + ) +} diff --git a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewerState.kt b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewerState.kt index c27b36554a..72eb73c301 100644 --- a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewerState.kt +++ b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewerState.kt @@ -19,6 +19,8 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext +import io.element.android.libraries.architecture.AsyncData +import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.CoroutineScope import me.saket.telephoto.zoomable.ZoomableState import me.saket.telephoto.zoomable.rememberZoomableState @@ -35,10 +37,10 @@ class PdfViewerState( private var pdfRendererManager by mutableStateOf(null) @Composable - fun getPages(): List { + fun getPages(): AsyncData> { return pdfRendererManager?.run { pdfPages.collectAsState().value - } ?: emptyList() + } ?: AsyncData.Uninitialized } fun openForWidth(maxWidth: Int) { From 7113795df290f1ff530357a33914bdd8ee5cf974 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 24 Sep 2024 15:40:44 +0000 Subject: [PATCH 09/12] Update screenshots --- ...es.mediaviewer.api.local.pdf_PdfPagesErrorView_Day_0_en.png | 3 +++ ....mediaviewer.api.local.pdf_PdfPagesErrorView_Night_0_en.png | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/libraries.mediaviewer.api.local.pdf_PdfPagesErrorView_Day_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.mediaviewer.api.local.pdf_PdfPagesErrorView_Night_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.api.local.pdf_PdfPagesErrorView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.api.local.pdf_PdfPagesErrorView_Day_0_en.png new file mode 100644 index 0000000000..a038c331fb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.api.local.pdf_PdfPagesErrorView_Day_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb0e18f25f8cd978830eb2a4db0cbef76376cdd34c025dc5e21dca39f0b8bd25 +size 13315 diff --git a/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.api.local.pdf_PdfPagesErrorView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.api.local.pdf_PdfPagesErrorView_Night_0_en.png new file mode 100644 index 0000000000..d07665658b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.mediaviewer.api.local.pdf_PdfPagesErrorView_Night_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:336450bda0f5438f30b14fdb9d3a1d95ff9fe3a9ff325c4f860c50dbf6e7256b +size 13056 From ae2616d6a23632343eda5ae73868a986ea334384 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 18:21:30 +0200 Subject: [PATCH 10/12] Less ugly code. --- .../api/local/pdf/PdfRendererManager.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfRendererManager.kt b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfRendererManager.kt index 203df46aa3..255822b853 100644 --- a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfRendererManager.kt +++ b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfRendererManager.kt @@ -35,19 +35,21 @@ class PdfRendererManager( coroutineScope.launch { mutex.withLock { withContext(Dispatchers.IO) { - runCatching { + pdfRenderer = runCatching { PdfRenderer(parcelFileDescriptor) }.fold( onSuccess = { pdfRenderer -> - this@PdfRendererManager.pdfRenderer = pdfRenderer - // Preload just 3 pages so we can render faster - val firstPages = pdfRenderer.loadPages(from = 0, to = 3) - mutablePdfPages.value = AsyncData.Success(firstPages.toImmutableList()) - val nextPages = pdfRenderer.loadPages(from = 3, to = pdfRenderer.pageCount) - mutablePdfPages.value = AsyncData.Success((firstPages + nextPages).toImmutableList()) + pdfRenderer.apply { + // Preload just 3 pages so we can render faster + val firstPages = loadPages(from = 0, to = 3) + mutablePdfPages.value = AsyncData.Success(firstPages.toImmutableList()) + val nextPages = loadPages(from = 3, to = pageCount) + mutablePdfPages.value = AsyncData.Success((firstPages + nextPages).toImmutableList()) + } }, onFailure = { mutablePdfPages.value = AsyncData.Failure(it) + null } ) } From cfcd7518dcde94d2465aefe5080d9b5ca8b1c4a6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 18:23:19 +0200 Subject: [PATCH 11/12] Fix visibility issue. --- .../android/libraries/mediaviewer/api/local/pdf/PdfViewer.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewer.kt b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewer.kt index 1185a2cef4..6202db88b1 100644 --- a/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewer.kt +++ b/libraries/mediaviewer/api/src/main/kotlin/io/element/android/libraries/mediaviewer/api/local/pdf/PdfViewer.kt @@ -93,7 +93,7 @@ private fun PdfPagesView( } @Composable -fun PdfPagesErrorView( +private fun PdfPagesErrorView( error: Throwable, modifier: Modifier = Modifier, ) { From e1cebc2e95f160ddabfe6982280af97a24edb758 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 24 Sep 2024 21:29:25 +0200 Subject: [PATCH 12/12] Remove the no needed `launch`. --- .../libraries/matrix/impl/room/RustMatrixRoom.kt | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index 2f4f6270d8..5f9b00da35 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -68,7 +68,6 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart -import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.matrix.rustcomponents.sdk.RoomInfo import org.matrix.rustcomponents.sdk.RoomInfoListener @@ -104,14 +103,12 @@ class RustMatrixRoom( override val roomId = RoomId(innerRoom.id()) override val roomInfoFlow: Flow = mxCallbackFlow { - launch { - runCatching { innerRoom.roomInfo() } - .getOrNull() - ?.let(matrixRoomInfoMapper::map) - ?.let { initial -> - channel.trySend(initial) - } - } + runCatching { innerRoom.roomInfo() } + .getOrNull() + ?.let(matrixRoomInfoMapper::map) + ?.let { initial -> + channel.trySend(initial) + } innerRoom.subscribeToRoomInfoUpdates(object : RoomInfoListener { override fun call(roomInfo: RoomInfo) { channel.trySend(matrixRoomInfoMapper.map(roomInfo))