Fix unread decorator position when read follow unread.

This commit is contained in:
Cody Henthorne
2024-01-05 15:15:27 -05:00
committed by Alex Hart
parent 78b714e019
commit 0b4bbd5db2
5 changed files with 46 additions and 24 deletions

View File

@@ -117,7 +117,8 @@ class ConversationElementGenerator {
-1,
null,
null,
0
0,
false
)
val conversationMessage = ConversationMessageFactory.createWithUnresolvedData(

View File

@@ -125,8 +125,8 @@ class ConversationItemDecorations(hasWallpaper: Boolean = false, private val sch
val state: UnreadState = unreadState
if (state is UnreadState.InitialUnreadState) {
val firstUnread = items[(state.unreadCount - 1).coerceIn(items.indices)]
val timestamp = (firstUnread as? ConversationMessageElement)?.timestamp()
val firstUnread: ConversationMessageElement? = findFirstUnreadStartingAt(items, (state.unreadCount - 1).coerceIn(items.indices))
val timestamp = firstUnread?.timestamp()
if (timestamp != null) {
unreadState = UnreadState.CompleteUnreadState(unreadCount = state.unreadCount, firstUnreadTimestamp = timestamp)
}
@@ -149,6 +149,17 @@ class ConversationItemDecorations(hasWallpaper: Boolean = false, private val sch
}
}
private fun findFirstUnreadStartingAt(items: List<ConversationElement?>, startingIndex: Int): ConversationMessageElement? {
val endingIndex = (startingIndex + 20).coerceAtMost(items.lastIndex)
for (index in startingIndex..endingIndex) {
val item = items[index] as? ConversationMessageElement
if ((item?.conversationMessage?.messageRecord as? MmsMessageRecord)?.isRead == false) {
return item
}
}
return items[startingIndex] as? ConversationMessageElement
}
private fun isFirstUnread(bindingAdapterPosition: Int): Boolean {
val state = unreadState

View File

@@ -4995,6 +4995,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
val latestRevisionId: MessageId? = cursor.requireLong(LATEST_REVISION_ID).let { if (it == 0L) null else MessageId(it) }
val originalMessageId: MessageId? = cursor.requireLong(ORIGINAL_MESSAGE_ID).let { if (it == 0L) null else MessageId(it) }
val editCount = cursor.requireInt(REVISION_NUMBER)
val isRead = cursor.requireBoolean(READ)
if (!TextSecurePreferences.isReadReceiptsEnabled(context)) {
hasReadReceipt = false
@@ -5081,7 +5082,8 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
scheduledDate,
latestRevisionId,
originalMessageId,
editCount
editCount,
isRead
)
}

View File

@@ -70,6 +70,7 @@ public class MmsMessageRecord extends MessageRecord {
private final CallTable.Call call;
private final long scheduledDate;
private final MessageId latestRevisionId;
private final boolean isRead;
public MmsMessageRecord(long id,
Recipient fromRecipient,
@@ -109,26 +110,28 @@ public class MmsMessageRecord extends MessageRecord {
long scheduledDate,
@Nullable MessageId latestRevisionId,
@Nullable MessageId originalMessageId,
int revisionNumber)
int revisionNumber,
boolean isRead)
{
super(id, body, fromRecipient, fromDeviceId, toRecipient,
dateSent, dateReceived, dateServer, threadId, Status.STATUS_NONE, hasDeliveryReceipt,
mailbox, mismatches, failures, subscriptionId, expiresIn, expireStarted, hasReadReceipt,
unidentified, reactions, remoteDelete, notifiedTimestamp, viewed, receiptTimestamp, originalMessageId, revisionNumber);
this.slideDeck = slideDeck;
this.quote = quote;
this.viewOnce = viewOnce;
this.storyType = storyType;
this.parentStoryId = parentStoryId;
this.giftBadge = giftBadge;
this.mentionsSelf = mentionsSelf;
this.messageRanges = messageRanges;
this.payment = payment;
this.call = call;
this.scheduledDate = scheduledDate;
this.latestRevisionId = latestRevisionId;
this.slideDeck = slideDeck;
this.quote = quote;
this.viewOnce = viewOnce;
this.storyType = storyType;
this.parentStoryId = parentStoryId;
this.giftBadge = giftBadge;
this.mentionsSelf = mentionsSelf;
this.messageRanges = messageRanges;
this.payment = payment;
this.call = call;
this.scheduledDate = scheduledDate;
this.latestRevisionId = latestRevisionId;
this.isRead = isRead;
this.contacts.addAll(contacts);
this.linkPreviews.addAll(linkPreviews);
}
@@ -197,6 +200,10 @@ public class MmsMessageRecord extends MessageRecord {
return false;
}
public boolean isRead() {
return isRead;
}
@Override
@WorkerThread
public SpannableString getDisplayBody(@NonNull Context context) {
@@ -280,7 +287,7 @@ public class MmsMessageRecord extends MessageRecord {
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
hasReadReceipt(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), reactions, isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), isViewed(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
getOriginalMessageId(), getRevisionNumber(), isRead());
}
public @NonNull MmsMessageRecord withoutQuote() {
@@ -288,7 +295,7 @@ public class MmsMessageRecord extends MessageRecord {
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
hasReadReceipt(), null, getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), isViewed(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
getOriginalMessageId(), getRevisionNumber(), isRead());
}
public @NonNull MmsMessageRecord withAttachments(@NonNull List<DatabaseAttachment> attachments) {
@@ -310,7 +317,7 @@ public class MmsMessageRecord extends MessageRecord {
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
hasReadReceipt(), quote, contacts, linkPreviews, isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), isViewed(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
getOriginalMessageId(), getRevisionNumber(), isRead());
}
public @NonNull MmsMessageRecord withPayment(@NonNull Payment payment) {
@@ -318,7 +325,7 @@ public class MmsMessageRecord extends MessageRecord {
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
hasReadReceipt(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), isViewed(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), payment, getCall(), getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
getOriginalMessageId(), getRevisionNumber(), isRead());
}
@@ -327,7 +334,7 @@ public class MmsMessageRecord extends MessageRecord {
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),
hasReadReceipt(), getQuote(), getSharedContacts(), getLinkPreviews(), isUnidentified(), getReactions(), isRemoteDelete(), mentionsSelf,
getNotifiedTimestamp(), isViewed(), getReceiptTimestamp(), getMessageRanges(), getStoryType(), getParentStoryId(), getGiftBadge(), getPayment(), call, getScheduledDate(), getLatestRevisionId(),
getOriginalMessageId(), getRevisionNumber());
getOriginalMessageId(), getRevisionNumber(), isRead());
}
private static @NonNull List<Contact> updateContacts(@NonNull List<Contact> contacts, @NonNull Map<AttachmentId, DatabaseAttachment> attachmentIdMap) {

View File

@@ -183,7 +183,8 @@ object FakeMessageRecords {
-1,
null,
null,
0
0,
false
)
}
}