From 7869d731d47e2b306a00b728c68abfc58cecbeae Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 7 Dec 2020 10:38:34 +0100 Subject: [PATCH] Fix the rotate screen issue --- .../features/home/room/detail/RoomDetailAction.kt | 3 +++ .../features/home/room/detail/RoomDetailFragment.kt | 7 +++++-- .../home/room/detail/RoomDetailViewModel.kt | 9 ++++++++- .../room/detail/timeline/TimelineEventController.kt | 3 +++ .../detail/timeline/factory/MessageItemFactory.kt | 6 ++---- .../room/detail/timeline/item/MessageTextItem.kt | 2 ++ .../room/detail/timeline/url/PreviewUrlRetriever.kt | 13 +++++-------- 7 files changed, 28 insertions(+), 15 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt index 8891218a11..e034e373f3 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt @@ -98,4 +98,7 @@ sealed class RoomDetailAction : VectorViewModelAction { data class SetAvatarAction(val newAvatarUri: Uri, val newAvatarFileName: String) : RoomDetailAction() object QuickActionSetTopic : RoomDetailAction() data class ShowRoomAvatarFullScreen(val matrixItem: MatrixItem?, val transitionView: View?) : RoomDetailAction() + + // Preview URL + data class DoNotShowPreviewUrlFor(val eventId: String, val url: String) : RoomDetailAction() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index f211e89e7d..399bf564bf 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -216,7 +216,6 @@ class RoomDetailFragment @Inject constructor( private val session: Session, private val avatarRenderer: AvatarRenderer, private val timelineEventController: TimelineEventController, - private val previewUrlRetriever: PreviewUrlRetriever, autoCompleterFactory: AutoCompleter.Factory, private val permalinkHandler: PermalinkHandler, private val notificationDrawerManager: NotificationDrawerManager, @@ -1632,6 +1631,10 @@ class RoomDetailFragment @Inject constructor( roomDetailViewModel.handle(itemAction) } + override fun getPreviewUrlRetriever(): PreviewUrlRetriever { + return roomDetailViewModel.previewUrlRetriever + } + override fun onRoomCreateLinkClicked(url: String) { permalinkHandler .launch(requireContext(), url, object : NavigationInterceptor { @@ -1659,7 +1662,7 @@ class RoomDetailFragment @Inject constructor( } override fun onPreviewUrlCloseClicked(eventId: String, url: String) { - previewUrlRetriever.doNotShowPreviewUrlFor(eventId, url) + roomDetailViewModel.handle(RoomDetailAction.DoNotShowPreviewUrlFor(eventId, url)) } private fun onShareActionClicked(action: EventSharedAction.Share) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt index 40dbf9627c..ed25d41e9f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewModel.kt @@ -113,7 +113,6 @@ class RoomDetailViewModel @AssistedInject constructor( private val rainbowGenerator: RainbowGenerator, private val session: Session, private val rawService: RawService, - private val previewUrlRetriever: PreviewUrlRetriever, private val supportedVerificationMethodsProvider: SupportedVerificationMethodsProvider, private val stickerPickerActionHandler: StickerPickerActionHandler, private val roomSummaryHolder: RoomSummaryHolder, @@ -130,6 +129,9 @@ class RoomDetailViewModel @AssistedInject constructor( private var timelineEvents = PublishRelay.create>() val timeline = room.createTimeline(eventId, timelineSettings) + // Same lifecycle than the ViewModel (survive to screen rotation) + val previewUrlRetriever = PreviewUrlRetriever(session) + // Slot to keep a pending action during permission request var pendingAction: RoomDetailAction? = null @@ -288,9 +290,14 @@ class RoomDetailViewModel @AssistedInject constructor( RoomDetailViewEvents.ShowRoomAvatarFullScreen(action.matrixItem, action.transitionView) ) } + is RoomDetailAction.DoNotShowPreviewUrlFor -> handleDoNotShowPreviewUrlFor(action) }.exhaustive } + private fun handleDoNotShowPreviewUrlFor(action: RoomDetailAction.DoNotShowPreviewUrlFor) { + previewUrlRetriever.doNotShowPreviewUrlFor(action.eventId, action.url) + } + private fun handleSetNewAvatar(action: RoomDetailAction.SetAvatarAction) { viewModelScope.launch(Dispatchers.IO) { try { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt index 693383c751..ba3ffe3174 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt @@ -48,6 +48,7 @@ import im.vector.app.features.home.room.detail.timeline.item.DaySeparatorItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData import im.vector.app.features.home.room.detail.timeline.item.TimelineReadMarkerItem_ +import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever import im.vector.app.features.media.ImageContentRenderer import im.vector.app.features.media.VideoContentRenderer import im.vector.app.features.settings.VectorPreferences @@ -97,6 +98,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec // TODO move all callbacks to this? fun onTimelineItemAction(itemAction: RoomDetailAction) + + fun getPreviewUrlRetriever(): PreviewUrlRetriever } interface ReactionPillCallback { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 0a88f81a02..cd4f798769 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -58,7 +58,6 @@ import im.vector.app.features.home.room.detail.timeline.item.VerificationRequest import im.vector.app.features.home.room.detail.timeline.item.VerificationRequestItem_ import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod import im.vector.app.features.home.room.detail.timeline.tools.linkify -import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever import im.vector.app.features.html.CodeVisitor import im.vector.app.features.html.EventHtmlRenderer import im.vector.app.features.html.PillsPostProcessor @@ -108,7 +107,6 @@ class MessageItemFactory @Inject constructor( private val defaultItemFactory: DefaultItemFactory, private val noticeItemFactory: NoticeItemFactory, private val avatarSizeProvider: AvatarSizeProvider, - private val previewUrlRetriever: PreviewUrlRetriever, private val pillsPostProcessorFactory: PillsPostProcessor.Factory, private val session: Session) { @@ -426,7 +424,7 @@ class MessageItemFactory @Inject constructor( } .useBigFont(linkifiedBody.length <= MAX_NUMBER_OF_EMOJI_FOR_BIG_FONT * 2 && containsOnlyEmojis(linkifiedBody.toString())) .searchForPills(isFormatted) - .previewUrlRetriever(previewUrlRetriever) + .previewUrlRetriever(callback?.getPreviewUrlRetriever()) .imageContentRenderer(imageContentRenderer) .previewUrlCallback(callback) .leftGuideline(avatarSizeProvider.leftGuideline) @@ -534,7 +532,7 @@ class MessageItemFactory @Inject constructor( } } .leftGuideline(avatarSizeProvider.leftGuideline) - .previewUrlRetriever(previewUrlRetriever) + .previewUrlRetriever(callback?.getPreviewUrlRetriever()) .imageContentRenderer(imageContentRenderer) .previewUrlCallback(callback) .attributes(attributes) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt index 5bb7aff194..66d9808d2b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageTextItem.kt @@ -89,6 +89,8 @@ abstract class MessageTextItem : AbsMessageItem() { override fun unbind(holder: Holder) { super.unbind(holder) + previewUrlViewUpdater.previewUrlView = null + previewUrlViewUpdater.imageContentRenderer = null previewUrlRetriever?.removeListener(attributes.informationData.eventId, previewUrlViewUpdater) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt index 174841b599..695661feeb 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlRetriever.kt @@ -17,18 +17,15 @@ package im.vector.app.features.home.room.detail.timeline.url import im.vector.app.BuildConfig -import im.vector.app.core.di.ScreenScope import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import org.matrix.android.sdk.api.cache.CacheStrategy import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.Event -import javax.inject.Inject -@ScreenScope -class PreviewUrlRetriever @Inject constructor( - private val session: Session -) { +class PreviewUrlRetriever(session: Session) { + private val mediaService = session.mediaService() + private val data = mutableMapOf() private val listeners = mutableMapOf>() @@ -41,7 +38,7 @@ class PreviewUrlRetriever @Inject constructor( synchronized(data) { if (data[eventId] == null) { // Keep only the first URL for the moment - val url = session.mediaService().extractUrls(event) + val url = mediaService.extractUrls(event) .firstOrNull() ?.takeIf { it !in blockedUrl } if (url == null) { @@ -57,7 +54,7 @@ class PreviewUrlRetriever @Inject constructor( }?.let { urlToRetrieve -> coroutineScope.launch { runCatching { - session.mediaService().getPreviewUrl( + mediaService.getPreviewUrl( url = urlToRetrieve, timestamp = null, cacheStrategy = if (BuildConfig.DEBUG) CacheStrategy.NoCache else CacheStrategy.TtlCache(CACHE_VALIDITY, false)