Add go to indicator for pinned messages.

This commit is contained in:
Michelle Tang
2025-11-26 11:06:07 -05:00
committed by jeffrey-signal
parent 8e2f2b8d1a
commit 864867f60e
13 changed files with 113 additions and 15 deletions

View File

@@ -326,7 +326,7 @@ public class ConversationAdapter
if (conversationMessage == null) return -1;
if (displayMode.getScheduleMessageMode()) {
if (displayMode.getMessageMode() == ConversationItemDisplayMode.MessageMode.SCHEDULED) {
calendar.setTimeInMillis(((MmsMessageRecord) conversationMessage.getMessageRecord()).getScheduledDate());
} else if (displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE) {
calendar.setTimeInMillis(conversationMessage.getMessageRecord().getDateSent());
@@ -346,7 +346,7 @@ public class ConversationAdapter
Context context = viewHolder.itemView.getContext();
ConversationMessage conversationMessage = Objects.requireNonNull(getItem(position));
if (displayMode.getScheduleMessageMode()) {
if (displayMode.getMessageMode() == ConversationItemDisplayMode.MessageMode.SCHEDULED) {
viewHolder.setText(DateUtils.getScheduledMessagesDateHeaderString(viewHolder.itemView.getContext(), locale, ((MmsMessageRecord) conversationMessage.getMessageRecord()).getScheduledDate()));
} else if (displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE) {
viewHolder.setText(DateUtils.getConversationDateHeaderString(viewHolder.itemView.getContext(), locale, conversationMessage.getMessageRecord().getDateSent()));

View File

@@ -221,6 +221,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
private TextView storyReactionLabel;
private View quotedIndicator;
private View scheduledIndicator;
private View goToPinnedIndicator;
private @NonNull Set<MultiselectPart> batchSelected = new HashSet<>();
private final @NonNull Outliner outliner = new Outliner();
@@ -359,6 +360,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
this.paymentViewStub = new Stub<>(findViewById(R.id.payment_view_stub));
this.scheduledIndicator = findViewById(R.id.scheduled_indicator);
this.pollView = new Stub<>(findViewById(R.id.poll));
this.goToPinnedIndicator = findViewById(R.id.go_to_pinned_indicator);
setOnClickListener(new ClickListener(null));
@@ -424,6 +426,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
setStoryReactionLabel(messageRecord);
setHasBeenQuoted(conversationMessage);
setHasBeenScheduled(conversationMessage);
setHasBeenPinned(conversationMessage);
setPoll(messageRecord, messageRecord.getToRecipient().getChatColors().asSingleColor());
if (audioViewStub.resolved()) {
@@ -1260,7 +1263,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
ViewUtil.updateLayoutParamsIfNonNull(groupSenderHolder, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtil.setTopMargin(linkPreviewStub.get(), 0);
} else {
linkPreviewStub.get().setLinkPreview(requestManager, linkPreview, true, !isContentCondensed(), displayMode.getScheduleMessageMode());
linkPreviewStub.get().setLinkPreview(requestManager, linkPreview, true, !isContentCondensed(), displayMode.getMessageMode() == ConversationItemDisplayMode.MessageMode.SCHEDULED);
linkPreviewStub.get().setDownloadClickedListener(downloadClickListener);
setLinkPreviewCorners(messageRecord, previousRecord, nextRecord, isGroupThread, false);
ViewUtil.updateLayoutParams(bodyText, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -1920,6 +1923,17 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
}
}
private void setHasBeenPinned(@NonNull ConversationMessage message) {
if (goToPinnedIndicator == null) {
return;
}
if (message.getMessageRecord().getPinnedUntil() > 0 && displayMode.getMessageMode() == ConversationItemDisplayMode.MessageMode.PINNED) {
goToPinnedIndicator.setVisibility(View.VISIBLE);
} else {
goToPinnedIndicator.setVisibility(View.GONE);
}
}
private boolean forceFooter(@NonNull MessageRecord messageRecord) {
return hasAudio(messageRecord) || MessageRecordUtil.isEditMessage(messageRecord) || displayMode == ConversationItemDisplayMode.EditHistory.INSTANCE || messageRecord.getPinnedUntil() > 0;
}

View File

@@ -1,11 +1,11 @@
package org.thoughtcrime.securesms.conversation
sealed class ConversationItemDisplayMode(val scheduleMessageMode: Boolean = false) {
sealed class ConversationItemDisplayMode(val messageMode: MessageMode = MessageMode.STANDARD) {
/** Normal rendering, used for normal bubbles in the conversation view */
object Standard : ConversationItemDisplayMode()
/** Smaller bubbles, often trimming text and shrinking images. Used for quote threads. */
class Condensed(scheduleMessageMode: Boolean) : ConversationItemDisplayMode(scheduleMessageMode)
class Condensed(messageMode: MessageMode) : ConversationItemDisplayMode(messageMode)
/** Smaller bubbles, always singular bubbles, with a footer. Used for edit message history. */
object EditHistory : ConversationItemDisplayMode()
@@ -16,4 +16,10 @@ sealed class ConversationItemDisplayMode(val scheduleMessageMode: Boolean = fals
fun displayWallpaper(): Boolean {
return this == Standard || this == Detailed
}
enum class MessageMode {
SCHEDULED,
PINNED,
STANDARD
}
}

View File

@@ -76,7 +76,7 @@ class PinnedMessagesBottomSheet : FixedRoundedCornerBottomSheetDialogFragment()
val colorizer = Colorizer()
messageAdapter = ConversationAdapter(requireContext(), viewLifecycleOwner, Glide.with(this), Locale.getDefault(), ConversationAdapterListener(), conversationRecipient.hasWallpaper, colorizer).apply {
setCondensedMode(ConversationItemDisplayMode.Condensed(scheduleMessageMode = false))
setCondensedMode(ConversationItemDisplayMode.Condensed(ConversationItemDisplayMode.MessageMode.PINNED))
}
val list: RecyclerView = view.findViewById<RecyclerView>(R.id.pinned_list).apply {

View File

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

View File

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

View File

@@ -75,7 +75,7 @@ fun PinnedMessagesBanner(
val (glyph, body, showThumbnail) = getMessageMetadata(conversationMessage)
Column {
HorizontalDivider()
HorizontalDivider(thickness = 1.dp)
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
@@ -154,7 +154,7 @@ fun PinnedMessagesBanner(
if (canUnpin) {
DropdownMenus.ItemWithIcon(menuController, R.drawable.symbol_pin_slash_24, R.string.PinnedMessage__unpin_message) { onUnpinMessage(message.id) }
}
DropdownMenus.ItemWithIcon(menuController, R.drawable.symbol_chat_24, R.string.PinnedMessage__go_to_message) { onGoToMessage(message.id) }
DropdownMenus.ItemWithIcon(menuController, R.drawable.symbol_chat_arrow_24, R.string.PinnedMessage__go_to_message) { onGoToMessage(message.id) }
DropdownMenus.ItemWithIcon(menuController, R.drawable.symbol_list_bullet_24, R.string.PinnedMessage__view_all_messages) { onViewAllMessages() }
}
}