Fix infinite spinner on scheduled link preview bug.

This commit is contained in:
Cody Henthorne 2023-09-11 08:41:30 -04:00 committed by Alex Hart
parent cd38c99f7e
commit 9ed3e8befb
14 changed files with 40 additions and 47 deletions

View file

@ -210,7 +210,7 @@ class V2ConversationItemShapeTest {
private val colorizer = Colorizer() private val colorizer = Colorizer()
override val displayMode: ConversationItemDisplayMode = ConversationItemDisplayMode.STANDARD override val displayMode: ConversationItemDisplayMode = ConversationItemDisplayMode.Standard
override val clickListener: ConversationAdapter.ItemClickListener = FakeConversationItemClickListener override val clickListener: ConversationAdapter.ItemClickListener = FakeConversationItemClickListener
override val selectedItems: Set<MultiselectPart> = emptySet() override val selectedItems: Set<MultiselectPart> = emptySet()

View file

@ -322,12 +322,12 @@ public class ConversationItemFooter extends ConstraintLayout {
} else { } else {
long timestamp = messageRecord.getTimestamp(); long timestamp = messageRecord.getTimestamp();
if (messageRecord.isEditMessage()) { if (messageRecord.isEditMessage()) {
if (displayMode == ConversationItemDisplayMode.EDIT_HISTORY) { if (displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE) {
timestamp = messageRecord.getDateSent(); timestamp = messageRecord.getDateSent();
} }
} }
String date = DateUtils.getDatelessRelativeTimeSpanString(getContext(), locale, timestamp); String date = DateUtils.getDatelessRelativeTimeSpanString(getContext(), locale, timestamp);
if (displayMode != ConversationItemDisplayMode.DETAILED && messageRecord.isEditMessage() && messageRecord.isLatestRevision()) { if (displayMode != ConversationItemDisplayMode.Detailed.INSTANCE && messageRecord.isEditMessage() && messageRecord.isLatestRevision()) {
date = getContext().getString(R.string.ConversationItem_edited_timestamp_footer, date); date = getContext().getString(R.string.ConversationItem_edited_timestamp_footer, date);
} }
dateView.setText(date); dateView.setText(date);

View file

@ -163,10 +163,10 @@ public class LinkPreviewView extends FrameLayout {
} }
public void setLinkPreview(@NonNull GlideRequests glideRequests, @NonNull LinkPreview linkPreview, boolean showThumbnail) { public void setLinkPreview(@NonNull GlideRequests glideRequests, @NonNull LinkPreview linkPreview, boolean showThumbnail) {
setLinkPreview(glideRequests, linkPreview, showThumbnail, true); setLinkPreview(glideRequests, linkPreview, showThumbnail, true, false);
} }
public void setLinkPreview(@NonNull GlideRequests glideRequests, @NonNull LinkPreview linkPreview, boolean showThumbnail, boolean showDescription) { public void setLinkPreview(@NonNull GlideRequests glideRequests, @NonNull LinkPreview linkPreview, boolean showThumbnail, boolean showDescription, boolean scheduleMessageMode) {
spinner.setVisibility(GONE); spinner.setVisibility(GONE);
noPreview.setVisibility(GONE); noPreview.setVisibility(GONE);
@ -216,7 +216,7 @@ public class LinkPreviewView extends FrameLayout {
if (showThumbnail && linkPreview.getThumbnail().isPresent()) { if (showThumbnail && linkPreview.getThumbnail().isPresent()) {
thumbnail.setVisibility(VISIBLE); thumbnail.setVisibility(VISIBLE);
thumbnailState.applyState(thumbnail); thumbnailState.applyState(thumbnail);
thumbnail.get().setImageResource(glideRequests, new ImageSlide(linkPreview.getThumbnail().get()), type == TYPE_CONVERSATION, false); thumbnail.get().setImageResource(glideRequests, new ImageSlide(linkPreview.getThumbnail().get()), type == TYPE_CONVERSATION && !scheduleMessageMode, false);
thumbnail.get().showDownloadText(false); thumbnail.get().showDownloadText(false);
} else if (callLinkRootKey != null) { } else if (callLinkRootKey != null) {
thumbnail.setVisibility(VISIBLE); thumbnail.setVisibility(VISIBLE);

View file

@ -114,8 +114,7 @@ public class ConversationAdapter
private ConversationMessage inlineContent; private ConversationMessage inlineContent;
private Colorizer colorizer; private Colorizer colorizer;
private boolean isTypingViewEnabled; private boolean isTypingViewEnabled;
private ConversationItemDisplayMode condensedMode; private ConversationItemDisplayMode displayMode;
private boolean scheduledMessagesMode;
private PulseRequest pulseRequest; private PulseRequest pulseRequest;
public ConversationAdapter(@NonNull Context context, public ConversationAdapter(@NonNull Context context,
@ -252,12 +251,7 @@ public class ConversationAdapter
} }
public void setCondensedMode(ConversationItemDisplayMode condensedMode) { public void setCondensedMode(ConversationItemDisplayMode condensedMode) {
this.condensedMode = condensedMode; this.displayMode = condensedMode;
notifyDataSetChanged();
}
public void setScheduledMessagesMode(boolean scheduledMessagesMode) {
this.scheduledMessagesMode = scheduledMessagesMode;
notifyDataSetChanged(); notifyDataSetChanged();
} }
@ -276,7 +270,7 @@ public class ConversationAdapter
ConversationMessage previousMessage = adapterPosition < getItemCount() - 1 && !isFooterPosition(adapterPosition + 1) ? getItem(adapterPosition + 1) : null; ConversationMessage previousMessage = adapterPosition < getItemCount() - 1 && !isFooterPosition(adapterPosition + 1) ? getItem(adapterPosition + 1) : null;
ConversationMessage nextMessage = adapterPosition > 0 && !isHeaderPosition(adapterPosition - 1) ? getItem(adapterPosition - 1) : null; ConversationMessage nextMessage = adapterPosition > 0 && !isHeaderPosition(adapterPosition - 1) ? getItem(adapterPosition - 1) : null;
ConversationItemDisplayMode displayMode = condensedMode != null ? condensedMode : ConversationItemDisplayMode.STANDARD; ConversationItemDisplayMode itemDisplayMode = displayMode != null ? displayMode : ConversationItemDisplayMode.Standard.INSTANCE;
conversationViewHolder.getBindable().bind(lifecycleOwner, conversationViewHolder.getBindable().bind(lifecycleOwner,
conversationMessage, conversationMessage,
@ -288,11 +282,11 @@ public class ConversationAdapter
conversationMessage.getThreadRecipient(), conversationMessage.getThreadRecipient(),
searchQuery, searchQuery,
conversationMessage == recordToPulse, conversationMessage == recordToPulse,
hasWallpaper && displayMode.displayWallpaper(), hasWallpaper && itemDisplayMode.displayWallpaper(),
isMessageRequestAccepted, isMessageRequestAccepted,
conversationMessage == inlineContent, conversationMessage == inlineContent,
colorizer, colorizer,
displayMode); itemDisplayMode);
if (conversationMessage == recordToPulse) { if (conversationMessage == recordToPulse) {
recordToPulse = null; recordToPulse = null;
@ -331,9 +325,9 @@ public class ConversationAdapter
if (conversationMessage == null) return -1; if (conversationMessage == null) return -1;
if (scheduledMessagesMode) { if (displayMode.getScheduleMessageMode()) {
calendar.setTimeInMillis(((MediaMmsMessageRecord) conversationMessage.getMessageRecord()).getScheduledDate()); calendar.setTimeInMillis(((MediaMmsMessageRecord) conversationMessage.getMessageRecord()).getScheduledDate());
} else if (condensedMode == ConversationItemDisplayMode.EDIT_HISTORY) { } else if (displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE) {
calendar.setTimeInMillis(conversationMessage.getMessageRecord().getDateSent()); calendar.setTimeInMillis(conversationMessage.getMessageRecord().getDateSent());
} else { } else {
calendar.setTimeInMillis(conversationMessage.getConversationTimestamp()); calendar.setTimeInMillis(conversationMessage.getConversationTimestamp());
@ -351,9 +345,9 @@ public class ConversationAdapter
Context context = viewHolder.itemView.getContext(); Context context = viewHolder.itemView.getContext();
ConversationMessage conversationMessage = Objects.requireNonNull(getItem(position)); ConversationMessage conversationMessage = Objects.requireNonNull(getItem(position));
if (scheduledMessagesMode) { if (displayMode.getScheduleMessageMode()) {
viewHolder.setText(DateUtils.getScheduledMessagesDateHeaderString(viewHolder.itemView.getContext(), locale, ((MediaMmsMessageRecord) conversationMessage.getMessageRecord()).getScheduledDate())); viewHolder.setText(DateUtils.getScheduledMessagesDateHeaderString(viewHolder.itemView.getContext(), locale, ((MediaMmsMessageRecord) conversationMessage.getMessageRecord()).getScheduledDate()));
} else if (condensedMode == ConversationItemDisplayMode.EDIT_HISTORY) { } else if (displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE) {
viewHolder.setText(DateUtils.getConversationDateHeaderString(viewHolder.itemView.getContext(), locale, conversationMessage.getMessageRecord().getDateSent())); viewHolder.setText(DateUtils.getConversationDateHeaderString(viewHolder.itemView.getContext(), locale, conversationMessage.getMessageRecord().getDateSent()));
} else { } else {
viewHolder.setText(DateUtils.getConversationDateHeaderString(viewHolder.itemView.getContext(), locale, conversationMessage.getConversationTimestamp())); viewHolder.setText(DateUtils.getConversationDateHeaderString(viewHolder.itemView.getContext(), locale, conversationMessage.getConversationTimestamp()));

View file

@ -928,7 +928,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
* Today this is only {@link org.thoughtcrime.securesms.conversation.quotes.MessageQuotesBottomSheet}. * Today this is only {@link org.thoughtcrime.securesms.conversation.quotes.MessageQuotesBottomSheet}.
*/ */
private boolean isCondensedMode() { private boolean isCondensedMode() {
return displayMode == ConversationItemDisplayMode.CONDENSED; return displayMode instanceof ConversationItemDisplayMode.Condensed;
} }
/** /**
@ -1182,7 +1182,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
ViewUtil.updateLayoutParamsIfNonNull(groupSenderHolder, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); ViewUtil.updateLayoutParamsIfNonNull(groupSenderHolder, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtil.setTopMargin(linkPreviewStub.get(), 0); ViewUtil.setTopMargin(linkPreviewStub.get(), 0);
} else { } else {
linkPreviewStub.get().setLinkPreview(glideRequests, linkPreview, true, !isContentCondensed()); linkPreviewStub.get().setLinkPreview(glideRequests, linkPreview, true, !isContentCondensed(), displayMode.getScheduleMessageMode());
linkPreviewStub.get().setDownloadClickedListener(downloadClickListener); linkPreviewStub.get().setDownloadClickedListener(downloadClickListener);
setLinkPreviewCorners(messageRecord, previousRecord, nextRecord, isGroupThread, false); setLinkPreviewCorners(messageRecord, previousRecord, nextRecord, isGroupThread, false);
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@ -1242,7 +1242,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
documentViewStub.get().setDocument( documentViewStub.get().setDocument(
((MediaMmsMessageRecord) messageRecord).getSlideDeck().getDocumentSlide(), ((MediaMmsMessageRecord) messageRecord).getSlideDeck().getDocumentSlide(),
showControls, showControls,
displayMode != ConversationItemDisplayMode.DETAILED displayMode != ConversationItemDisplayMode.Detailed.INSTANCE
); );
documentViewStub.get().setDocumentClickListener(new ThumbnailClickListener()); documentViewStub.get().setDocumentClickListener(new ThumbnailClickListener());
documentViewStub.get().setDownloadClickListener(singleDownloadClickListener); documentViewStub.get().setDownloadClickListener(singleDownloadClickListener);
@ -1764,7 +1764,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
} }
private void setHasBeenQuoted(@NonNull ConversationMessage message) { private void setHasBeenQuoted(@NonNull ConversationMessage message) {
if (message.hasBeenQuoted() && !isCondensedMode() && quotedIndicator != null && batchSelected.isEmpty() && displayMode != ConversationItemDisplayMode.EDIT_HISTORY) { if (message.hasBeenQuoted() && !isCondensedMode() && quotedIndicator != null && batchSelected.isEmpty() && displayMode != ConversationItemDisplayMode.EditHistory.INSTANCE) {
quotedIndicator.setVisibility(VISIBLE); quotedIndicator.setVisibility(VISIBLE);
quotedIndicator.setOnClickListener(quotedIndicatorClickListener); quotedIndicator.setOnClickListener(quotedIndicatorClickListener);
} else if (quotedIndicator != null) { } else if (quotedIndicator != null) {
@ -1787,11 +1787,11 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
} }
private boolean forceFooter(@NonNull MessageRecord messageRecord) { private boolean forceFooter(@NonNull MessageRecord messageRecord) {
return hasAudio(messageRecord) || MessageRecordUtil.isEditMessage(messageRecord) || displayMode == ConversationItemDisplayMode.EDIT_HISTORY; return hasAudio(messageRecord) || MessageRecordUtil.isEditMessage(messageRecord) || displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE;
} }
private boolean forceGroupHeader(@NonNull MessageRecord messageRecord) { private boolean forceGroupHeader(@NonNull MessageRecord messageRecord) {
return displayMode == ConversationItemDisplayMode.EDIT_HISTORY; return displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE;
} }
private ConversationItemFooter getActiveFooter(@NonNull MessageRecord messageRecord) { private ConversationItemFooter getActiveFooter(@NonNull MessageRecord messageRecord) {
@ -1895,7 +1895,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
int background; int background;
if (isSingularMessage(current, previous, next, isGroupThread) || displayMode == ConversationItemDisplayMode.EDIT_HISTORY) { if (isSingularMessage(current, previous, next, isGroupThread) || displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE) {
if (current.isOutgoing()) { if (current.isOutgoing()) {
background = R.drawable.message_bubble_background_sent_alone; background = R.drawable.message_bubble_background_sent_alone;
outliner.setRadius(bigRadius); outliner.setRadius(bigRadius);
@ -1991,11 +1991,11 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
int spacingTop = readDimen(context, R.dimen.conversation_vertical_message_spacing_collapse); int spacingTop = readDimen(context, R.dimen.conversation_vertical_message_spacing_collapse);
int spacingBottom = spacingTop; int spacingBottom = spacingTop;
if (isStartOfMessageCluster(current, previous, isGroupThread) && (displayMode != ConversationItemDisplayMode.EDIT_HISTORY || next.isEmpty())) { if (isStartOfMessageCluster(current, previous, isGroupThread) && (displayMode != ConversationItemDisplayMode.EditHistory.INSTANCE || next.isEmpty())) {
spacingTop = readDimen(context, R.dimen.conversation_vertical_message_spacing_default); spacingTop = readDimen(context, R.dimen.conversation_vertical_message_spacing_default);
} }
if (isEndOfMessageCluster(current, next, isGroupThread) || displayMode == ConversationItemDisplayMode.EDIT_HISTORY) { if (isEndOfMessageCluster(current, next, isGroupThread) || displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE) {
spacingBottom = readDimen(context, R.dimen.conversation_vertical_message_spacing_default); spacingBottom = readDimen(context, R.dimen.conversation_vertical_message_spacing_default);
} }

View file

@ -1,19 +1,19 @@
package org.thoughtcrime.securesms.conversation package org.thoughtcrime.securesms.conversation
enum class ConversationItemDisplayMode { sealed class ConversationItemDisplayMode(val scheduleMessageMode: Boolean = false) {
/** Normal rendering, used for normal bubbles in the conversation view */ /** Normal rendering, used for normal bubbles in the conversation view */
STANDARD, object Standard : ConversationItemDisplayMode()
/** Smaller bubbles, often trimming text and shrinking images. Used for quote threads. */ /** Smaller bubbles, often trimming text and shrinking images. Used for quote threads. */
CONDENSED, class Condensed(scheduleMessageMode: Boolean) : ConversationItemDisplayMode(scheduleMessageMode)
/** Smaller bubbles, always singular bubbles, with a footer. Used for edit message history. */ /** Smaller bubbles, always singular bubbles, with a footer. Used for edit message history. */
EDIT_HISTORY, object EditHistory : ConversationItemDisplayMode()
/** Less length restrictions. Used to show more info in message details. */ /** Less length restrictions. Used to show more info in message details. */
DETAILED; object Detailed : ConversationItemDisplayMode()
fun displayWallpaper(): Boolean { fun displayWallpaper(): Boolean {
return this == STANDARD || this == DETAILED return this == Standard || this == Detailed
} }
} }

View file

@ -93,8 +93,7 @@ class ScheduledMessagesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment
val colorizer = Colorizer() val colorizer = Colorizer()
messageAdapter = ConversationAdapter(requireContext(), viewLifecycleOwner, GlideApp.with(this), Locale.getDefault(), ConversationAdapterListener(), conversationRecipient.hasWallpaper(), colorizer).apply { messageAdapter = ConversationAdapter(requireContext(), viewLifecycleOwner, GlideApp.with(this), Locale.getDefault(), ConversationAdapterListener(), conversationRecipient.hasWallpaper(), colorizer).apply {
setCondensedMode(ConversationItemDisplayMode.CONDENSED) setCondensedMode(ConversationItemDisplayMode.Condensed(scheduleMessageMode = true))
setScheduledMessagesMode(true)
} }
val list: RecyclerView = view.findViewById<RecyclerView>(R.id.scheduled_list).apply { val list: RecyclerView = view.findViewById<RecyclerView>(R.id.scheduled_list).apply {

View file

@ -74,7 +74,7 @@ class MessageQuotesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment() {
val colorizer = Colorizer() val colorizer = Colorizer()
messageAdapter = ConversationAdapter(requireContext(), viewLifecycleOwner, GlideApp.with(this), Locale.getDefault(), ConversationAdapterListener(), conversationRecipient.hasWallpaper(), colorizer).apply { messageAdapter = ConversationAdapter(requireContext(), viewLifecycleOwner, GlideApp.with(this), Locale.getDefault(), ConversationAdapterListener(), conversationRecipient.hasWallpaper(), colorizer).apply {
setCondensedMode(ConversationItemDisplayMode.CONDENSED) setCondensedMode(ConversationItemDisplayMode.Condensed(scheduleMessageMode = false))
} }
val list: RecyclerView = view.findViewById<RecyclerView>(R.id.quotes_list).apply { val list: RecyclerView = view.findViewById<RecyclerView>(R.id.quotes_list).apply {

View file

@ -91,7 +91,7 @@ class EditMessageHistoryDialog : FixedRoundedCornerBottomSheetDialogFragment() {
conversationRecipient.hasWallpaper(), conversationRecipient.hasWallpaper(),
colorizer colorizer
).apply { ).apply {
setCondensedMode(ConversationItemDisplayMode.EDIT_HISTORY) setCondensedMode(ConversationItemDisplayMode.EditHistory)
} }
binding.editHistoryList.apply { binding.editHistoryList.apply {

View file

@ -187,7 +187,7 @@ class ConversationAdapterV2(
} }
override val displayMode: ConversationItemDisplayMode override val displayMode: ConversationItemDisplayMode
get() = condensedMode ?: ConversationItemDisplayMode.STANDARD get() = condensedMode ?: ConversationItemDisplayMode.Standard
override fun onStartExpirationTimeout(messageRecord: MessageRecord) { override fun onStartExpirationTimeout(messageRecord: MessageRecord) {
startExpirationTimeout(messageRecord) startExpirationTimeout(messageRecord)
@ -484,7 +484,7 @@ class ConversationAdapterV2(
get() = getConversationMessage(bindingAdapterPosition - 1)?.messageRecord.toOptional() get() = getConversationMessage(bindingAdapterPosition - 1)?.messageRecord.toOptional()
protected val displayMode: ConversationItemDisplayMode protected val displayMode: ConversationItemDisplayMode
get() = condensedMode ?: ConversationItemDisplayMode.STANDARD get() = condensedMode ?: ConversationItemDisplayMode.Standard
override val conversationMessage: ConversationMessage override val conversationMessage: ConversationMessage
get() = bindable.conversationMessage get() = bindable.conversationMessage

View file

@ -448,7 +448,7 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
} }
private fun isContentCondensed(): Boolean { private fun isContentCondensed(): Boolean {
return conversationContext.displayMode == ConversationItemDisplayMode.CONDENSED && conversationContext.getPreviousMessage(bindingAdapterPosition) == null return conversationContext.displayMode is ConversationItemDisplayMode.Condensed && conversationContext.getPreviousMessage(bindingAdapterPosition) == null
} }
private fun presentFooterExpiry() { private fun presentFooterExpiry() {
@ -605,7 +605,7 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
binding.conversationItemFooterDate.text = conversationMessage.formattedDate binding.conversationItemFooterDate.text = conversationMessage.formattedDate
} else { } else {
var date = conversationMessage.formattedDate var date = conversationMessage.formattedDate
if (conversationContext.displayMode != ConversationItemDisplayMode.DETAILED && record is MediaMmsMessageRecord && record.isEditMessage()) { if (conversationContext.displayMode != ConversationItemDisplayMode.Detailed && record is MediaMmsMessageRecord && record.isEditMessage()) {
date = getContext().getString(R.string.ConversationItem_edited_timestamp_footer, date) date = getContext().getString(R.string.ConversationItem_edited_timestamp_footer, date)
} }

View file

@ -48,7 +48,7 @@ class V2OnDispatchTouchEventListener(
} }
override fun onDispatchTouchEvent(view: View, motionEvent: MotionEvent) { override fun onDispatchTouchEvent(view: View, motionEvent: MotionEvent) {
if (conversationContext.displayMode == ConversationItemDisplayMode.CONDENSED) { if (conversationContext.displayMode is ConversationItemDisplayMode.Condensed) {
return return
} }

View file

@ -138,7 +138,7 @@ public class LongMessageFragment extends FullScreenDialogFragment {
} else { } else {
text.setMentionBackgroundTint(ContextCompat.getColor(requireContext(), R.color.transparent_black_40)); text.setMentionBackgroundTint(ContextCompat.getColor(requireContext(), R.color.transparent_black_40));
} }
footer.setMessageRecord(message.get().getMessageRecord(), Locale.getDefault(), ConversationItemDisplayMode.STANDARD); footer.setMessageRecord(message.get().getMessageRecord(), Locale.getDefault(), ConversationItemDisplayMode.Standard.INSTANCE);
}); });
} }

View file

@ -111,7 +111,7 @@ final class MessageHeaderViewHolder extends RecyclerView.ViewHolder implements G
false, false,
true, true,
colorizer, colorizer,
ConversationItemDisplayMode.DETAILED); ConversationItemDisplayMode.Detailed.INSTANCE);
} }
private void bindErrorState(MessageRecord messageRecord) { private void bindErrorState(MessageRecord messageRecord) {