Add poll icon when quoting a poll.

This commit is contained in:
Michelle Tang
2025-10-16 13:32:33 -04:00
committed by Cody Henthorne
parent 91b70038e6
commit b3f74d37e1
9 changed files with 39 additions and 15 deletions

View File

@@ -1117,6 +1117,7 @@ private fun BackupMessageRecord.toRemoteQuote(exportState: ExportState, attachme
}
}
QuoteModel.Type.GIFT_BADGE -> Quote.Type.GIFT_BADGE
QuoteModel.Type.POLL -> Quote.Type.POLL
}
val bodyRanges = this.quoteBodyRanges?.toRemoteBodyRanges(dateSent) ?: emptyList()

View File

@@ -1053,6 +1053,7 @@ class ChatItemArchiveImporter(
Quote.Type.NORMAL -> QuoteModel.Type.NORMAL.code
Quote.Type.GIFT_BADGE -> QuoteModel.Type.GIFT_BADGE.code
Quote.Type.VIEW_ONCE -> QuoteModel.Type.NORMAL.code
Quote.Type.POLL -> QuoteModel.Type.POLL.code
}
}

View File

@@ -4,6 +4,7 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
@@ -32,6 +33,7 @@ import org.thoughtcrime.securesms.components.quotes.QuoteViewColorTheme;
import org.thoughtcrime.securesms.conversation.MessageStyler;
import org.thoughtcrime.securesms.database.model.Mention;
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
import org.thoughtcrime.securesms.fonts.SignalSymbols;
import org.thoughtcrime.securesms.mms.DecryptableUri;
import org.thoughtcrime.securesms.mms.QuoteModel;
import org.thoughtcrime.securesms.mms.Slide;
@@ -43,6 +45,7 @@ import org.thoughtcrime.securesms.stories.StoryTextPostModel;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.Projection;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.views.Stub;
import java.io.IOException;
@@ -231,7 +234,14 @@ public class QuoteView extends ConstraintLayout implements RecipientForeverObser
}
private @Nullable CharSequence resolveBody(@Nullable CharSequence body, @NonNull QuoteModel.Type quoteType) {
return quoteType == QuoteModel.Type.GIFT_BADGE ? getContext().getString(R.string.QuoteView__donation_for_a_friend) : body;
switch (quoteType) {
case GIFT_BADGE:
return getContext().getString(R.string.QuoteView__donation_for_a_friend);
case POLL:
return getContext().getString(R.string.Poll__poll_question, body);
default:
return body;
}
}
public void setTopCornerSizes(boolean topLeftLarge, boolean topRightLarge) {
@@ -317,6 +327,14 @@ public class QuoteView extends ConstraintLayout implements RecipientForeverObser
Log.w(TAG, "Could not parse body of text post.", e);
bodyView.setText("");
}
} else if (quoteType == QuoteModel.Type.POLL) {
CharSequence glyph = SignalSymbols.getSpannedString(getContext(), SignalSymbols.Weight.REGULAR, SignalSymbols.Glyph.POLL, -1);
// TODO(michelle): Update with RTL poll icon
SpannableStringBuilder builder = new SpannableStringBuilder()
.append(glyph)
.append(" ")
.append(body);
bodyView.setText(body == null ? "" : builder);
} else {
bodyView.setText(body == null ? "" : body);
}

View File

@@ -85,11 +85,9 @@ import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.MessageUtil
import org.thoughtcrime.securesms.util.SignalLocalMetrics
import org.thoughtcrime.securesms.util.Util
import org.thoughtcrime.securesms.util.getPoll
import org.thoughtcrime.securesms.util.hasLinkPreview
import org.thoughtcrime.securesms.util.hasSharedContact
import org.thoughtcrime.securesms.util.hasTextSlide
import org.thoughtcrime.securesms.util.isPoll
import org.thoughtcrime.securesms.util.isViewOnceMessage
import org.thoughtcrime.securesms.util.requireTextSlide
import java.io.IOException
@@ -562,11 +560,6 @@ class ConversationRepository(
}
slideDeck to conversationMessage.getDisplayBody(context)
} else if (messageRecord.isPoll()) {
val poll = messageRecord.getPoll()!!
val slideDeck = SlideDeck()
slideDeck to SpannableStringBuilder().append(context.getString(R.string.Poll__poll_question, poll.question))
} else {
var slideDeck = if (messageRecord.isMms) {
(messageRecord as MmsMessageRecord).slideDeck

View File

@@ -26,7 +26,8 @@ class QuoteModel(
enum class Type(val code: Int, val dataMessageType: SignalServiceDataMessage.Quote.Type) {
NORMAL(0, SignalServiceDataMessage.Quote.Type.NORMAL),
GIFT_BADGE(1, SignalServiceDataMessage.Quote.Type.GIFT_BADGE);
GIFT_BADGE(1, SignalServiceDataMessage.Quote.Type.GIFT_BADGE),
POLL(2, SignalServiceDataMessage.Quote.Type.POLL);
companion object {
@JvmStatic
@@ -50,10 +51,11 @@ class QuoteModel(
}
fun fromProto(type: DataMessage.Quote.Type?): Type {
return if (type == DataMessage.Quote.Type.GIFT_BADGE) {
GIFT_BADGE
} else {
NORMAL
return when (type) {
DataMessage.Quote.Type.NORMAL -> NORMAL
DataMessage.Quote.Type.GIFT_BADGE -> GIFT_BADGE
DataMessage.Quote.Type.POLL -> POLL
null -> NORMAL
}
}
}

View File

@@ -164,7 +164,13 @@ fun MessageRecord.isScheduled(): Boolean {
* Returns the QuoteType for this record, as if it was being quoted.
*/
fun MessageRecord.getRecordQuoteType(): QuoteModel.Type {
return if (hasGiftBadge()) QuoteModel.Type.GIFT_BADGE else QuoteModel.Type.NORMAL
return if (hasGiftBadge()) {
QuoteModel.Type.GIFT_BADGE
} else if (hasPoll()) {
QuoteModel.Type.POLL
} else {
QuoteModel.Type.NORMAL
}
}
fun MessageRecord.isEditMessage(): Boolean {

View File

@@ -760,6 +760,7 @@ message Quote {
NORMAL = 1;
GIFT_BADGE = 2;
VIEW_ONCE = 3;
POLL = 4;
}
message QuotedAttachment {

View File

@@ -291,7 +291,8 @@ class SignalServiceDataMessage private constructor(
) {
enum class Type(val protoType: QuoteProto.Type) {
NORMAL(QuoteProto.Type.NORMAL),
GIFT_BADGE(QuoteProto.Type.GIFT_BADGE);
GIFT_BADGE(QuoteProto.Type.GIFT_BADGE),
POLL(QuoteProto.Type.POLL);
companion object {
@JvmStatic

View File

@@ -177,6 +177,7 @@ message DataMessage {
enum Type {
NORMAL = 0;
GIFT_BADGE = 1;
POLL = 2;
}
message QuotedAttachment {