diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index cf11ddb080..ef2bf15514 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -38,7 +38,6 @@ import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.text.style.URLSpan; -import android.text.util.Linkify; import android.util.AttributeSet; import android.util.TypedValue; import android.view.HapticFeedbackConstants; @@ -55,14 +54,11 @@ import androidx.annotation.ColorInt; import androidx.annotation.DimenRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; -import androidx.core.text.util.LinkifyCompat; import androidx.lifecycle.LifecycleOwner; import androidx.recyclerview.widget.RecyclerView; -import com.annimon.stream.Stream; import com.google.android.exoplayer2.MediaItem; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.common.collect.Sets; @@ -138,7 +134,6 @@ import org.thoughtcrime.securesms.revealable.ViewOnceMessageView; import org.thoughtcrime.securesms.util.DateUtils; import org.thoughtcrime.securesms.util.FeatureFlags; import org.thoughtcrime.securesms.util.InterceptableLongClickCopyLinkSpan; -import org.thoughtcrime.securesms.util.LinkUtil; import org.thoughtcrime.securesms.util.LongClickMovementMethod; import org.thoughtcrime.securesms.util.MessageRecordUtil; import org.thoughtcrime.securesms.util.PlaceholderURLSpan; @@ -371,8 +366,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo @NonNull Colorizer colorizer, @NonNull ConversationItemDisplayMode displayMode) { - if (this.author != null) this.author.removeForeverObserver(this); - if (this.conversationRecipient != null) this.conversationRecipient.removeForeverObserver(this); + unbind(); lastYDownRelativeToThis = 0; @@ -692,12 +686,15 @@ public final class ConversationItem extends RelativeLayout implements BindableCo if (author != null) { author.removeForeverObserver(this); } + if (conversationRecipient != null) { conversationRecipient.removeForeverObserver(this); } bodyBubble.setVideoPlayerProjection(null); bodyBubble.setQuoteViewProjection(null); + + glideRequests = null; } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapterV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapterV2.kt index 63b0b5458a..2043534b8c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapterV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapterV2.kt @@ -9,6 +9,7 @@ import android.text.TextUtils import android.view.View import android.view.ViewGroup import androidx.core.text.HtmlCompat +import androidx.core.view.children import androidx.lifecycle.LifecycleOwner import androidx.recyclerview.widget.RecyclerView import com.google.android.exoplayer2.MediaItem @@ -16,6 +17,7 @@ import org.signal.core.util.logging.Log import org.signal.core.util.toOptional import org.thoughtcrime.securesms.BindableConversationItem import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.Unbindable import org.thoughtcrime.securesms.conversation.ConversationAdapter.ItemClickListener import org.thoughtcrime.securesms.conversation.ConversationAdapterBridge import org.thoughtcrime.securesms.conversation.ConversationHeaderView @@ -144,6 +146,21 @@ class ConversationAdapterV2( } } } + + override fun onViewRecycled(holder: MappingViewHolder<*>) { + if (holder is ConversationViewHolder) { + holder.bindable.unbind() + } + } + + /** Triggered when switching addapters or by setting adapter to null on [recyclerView] in [ConversationFragment] */ + override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) { + recyclerView + .children + .filterIsInstance() + .forEach { it.unbind() } + } + override val displayMode: ConversationItemDisplayMode get() = condensedMode ?: ConversationItemDisplayMode.STANDARD diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index 61c66ec426..04e6884163 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -370,6 +370,8 @@ class ConversationFragment : adapter.unregisterAdapterDataObserver(it) } + _binding.conversationItemRecycler.adapter = null + textDraftSaveDebouncer.clear() }