Fix several over-the-wire story issues.
Co-authored-by: Rashad Sookram <rashad@signal.org>
This commit is contained in:
parent
e701e4bff0
commit
d5fd424b95
12 changed files with 98 additions and 58 deletions
|
@ -54,6 +54,7 @@ import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord;
|
|||
import org.thoughtcrime.securesms.database.model.Quote;
|
||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.StoryViewState;
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.groups.GroupMigrationMembershipChange;
|
||||
|
@ -813,7 +814,7 @@ public class MmsDatabase extends MessageDatabase {
|
|||
public int getMessageCountForThread(long threadId) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
|
||||
String query = THREAD_ID + " = ? AND " + IS_STORY + " = ? AND " + PARENT_STORY_ID + " = ?";
|
||||
String query = THREAD_ID + " = ? AND " + IS_STORY + " = ? AND " + PARENT_STORY_ID + " <= ?";
|
||||
String[] args = SqlUtil.buildArgs(threadId, 0, 0);
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_NAME, COUNT, query, args, null, null, null)) {
|
||||
|
@ -829,7 +830,7 @@ public class MmsDatabase extends MessageDatabase {
|
|||
public int getMessageCountForThread(long threadId, long beforeTime) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
|
||||
String query = THREAD_ID + " = ? AND " + DATE_RECEIVED + " < ? AND " + IS_STORY + " = ? AND " + PARENT_STORY_ID + " = ?";
|
||||
String query = THREAD_ID + " = ? AND " + DATE_RECEIVED + " < ? AND " + IS_STORY + " = ? AND " + PARENT_STORY_ID + " <= ?";
|
||||
String[] args = SqlUtil.buildArgs(threadId, beforeTime, 0, 0);
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_NAME, COUNT, query, args, null, null, null)) {
|
||||
|
@ -1207,20 +1208,20 @@ public class MmsDatabase extends MessageDatabase {
|
|||
@Override
|
||||
public List<MarkedMessageInfo> setMessagesReadSince(long threadId, long sinceTimestamp) {
|
||||
if (sinceTimestamp == -1) {
|
||||
return setMessagesRead(THREAD_ID + " = ? AND " + IS_STORY + " = 0 AND " + PARENT_STORY_ID + " = 0 AND (" + READ + " = 0 OR (" + REACTIONS_UNREAD + " = 1 AND (" + getOutgoingTypeClause() + ")))", new String[] {String.valueOf(threadId)});
|
||||
return setMessagesRead(THREAD_ID + " = ? AND " + IS_STORY + " = 0 AND " + PARENT_STORY_ID + " <= 0 AND (" + READ + " = 0 OR (" + REACTIONS_UNREAD + " = 1 AND (" + getOutgoingTypeClause() + ")))", new String[] {String.valueOf(threadId)});
|
||||
} else {
|
||||
return setMessagesRead(THREAD_ID + " = ? AND " + IS_STORY + " = 0 AND " + PARENT_STORY_ID + " = 0 AND (" + READ + " = 0 OR (" + REACTIONS_UNREAD + " = 1 AND ( " + getOutgoingTypeClause() + " ))) AND " + DATE_RECEIVED + " <= ?", new String[]{String.valueOf(threadId), String.valueOf(sinceTimestamp)});
|
||||
return setMessagesRead(THREAD_ID + " = ? AND " + IS_STORY + " = 0 AND " + PARENT_STORY_ID + " <= 0 AND (" + READ + " = 0 OR (" + REACTIONS_UNREAD + " = 1 AND ( " + getOutgoingTypeClause() + " ))) AND " + DATE_RECEIVED + " <= ?", new String[]{String.valueOf(threadId), String.valueOf(sinceTimestamp)});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MarkedMessageInfo> setEntireThreadRead(long threadId) {
|
||||
return setMessagesRead(THREAD_ID + " = ? AND " + IS_STORY + " = 0 AND " + PARENT_STORY_ID + " = 0", new String[] {String.valueOf(threadId)});
|
||||
return setMessagesRead(THREAD_ID + " = ? AND " + IS_STORY + " = 0 AND " + PARENT_STORY_ID + " <= 0", new String[] {String.valueOf(threadId)});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MarkedMessageInfo> setAllMessagesRead() {
|
||||
return setMessagesRead(IS_STORY+ " = 0 AND " + PARENT_STORY_ID + " = 0 AND (" + READ + " = 0 OR (" + REACTIONS_UNREAD + " = 1 AND (" + getOutgoingTypeClause() + ")))", null);
|
||||
return setMessagesRead(IS_STORY+ " = 0 AND " + PARENT_STORY_ID + " <= 0 AND (" + READ + " = 0 OR (" + REACTIONS_UNREAD + " = 1 AND (" + getOutgoingTypeClause() + ")))", null);
|
||||
}
|
||||
|
||||
private List<MarkedMessageInfo> setMessagesRead(String where, String[] arguments) {
|
||||
|
@ -1419,7 +1420,7 @@ public class MmsDatabase extends MessageDatabase {
|
|||
String mismatchDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.MISMATCHED_IDENTITIES));
|
||||
String networkDocument = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.NETWORK_FAILURE));
|
||||
boolean isStory = CursorUtil.requireBoolean(cursor, IS_STORY);
|
||||
MessageId parentStoryId = MessageId.fromNullable(CursorUtil.requireLong(cursor, PARENT_STORY_ID), true);
|
||||
ParentStoryId parentStoryId = ParentStoryId.deserialize(CursorUtil.requireLong(cursor, PARENT_STORY_ID));
|
||||
|
||||
long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID));
|
||||
long quoteAuthor = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR));
|
||||
|
@ -1590,7 +1591,7 @@ public class MmsDatabase extends MessageDatabase {
|
|||
contentValues.put(EXPIRES_IN, retrieved.getExpiresIn());
|
||||
contentValues.put(VIEW_ONCE, retrieved.isViewOnce() ? 1 : 0);
|
||||
contentValues.put(IS_STORY, retrieved.isStory() ? 1 : 0);
|
||||
contentValues.put(PARENT_STORY_ID, retrieved.getParentStoryId() != null ? retrieved.getParentStoryId().getId() : 0);
|
||||
contentValues.put(PARENT_STORY_ID, retrieved.getParentStoryId() != null ? retrieved.getParentStoryId().serialize() : 0);
|
||||
contentValues.put(READ, retrieved.isExpirationUpdate() ? 1 : 0);
|
||||
contentValues.put(UNIDENTIFIED, retrieved.isUnidentified());
|
||||
contentValues.put(SERVER_GUID, retrieved.getServerGuid());
|
||||
|
@ -1785,7 +1786,7 @@ public class MmsDatabase extends MessageDatabase {
|
|||
contentValues.put(DELIVERY_RECEIPT_COUNT, Stream.of(earlyDeliveryReceipts.values()).mapToLong(EarlyReceiptCache.Receipt::getCount).sum());
|
||||
contentValues.put(RECEIPT_TIMESTAMP, Stream.of(earlyDeliveryReceipts.values()).mapToLong(EarlyReceiptCache.Receipt::getTimestamp).max().orElse(-1));
|
||||
contentValues.put(IS_STORY, message.isStory() ? 1 : 0);
|
||||
contentValues.put(PARENT_STORY_ID, message.getParentStoryId() != null ? message.getParentStoryId().getId() : 0);
|
||||
contentValues.put(PARENT_STORY_ID, message.getParentStoryId() != null ? message.getParentStoryId().serialize() : 0);
|
||||
|
||||
if (message.getRecipient().isSelf() && hasAudioAttachment(message.getAttachments())) {
|
||||
contentValues.put(VIEWED_RECEIPT_COUNT, 1L);
|
||||
|
|
|
@ -118,7 +118,7 @@ public class MmsSmsDatabase extends Database {
|
|||
"WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + SmsDatabase.TYPE + " NOT IN (" + SmsDatabase.Types.PROFILE_CHANGE_TYPE + ", " + SmsDatabase.Types.GV1_MIGRATION_TYPE + ", " + SmsDatabase.Types.CHANGE_NUMBER_TYPE + ", " + SmsDatabase.Types.BOOST_REQUEST_TYPE + ") AND " + SmsDatabase.TYPE + " & " + GROUP_V2_LEAVE_BITS + " != " + GROUP_V2_LEAVE_BITS + " " +
|
||||
"UNION ALL " +
|
||||
"SELECT " + MmsSmsColumns.ID + ", 1 AS " + TRANSPORT + ", " + MmsDatabase.MESSAGE_BOX + " AS " + MmsSmsColumns.NORMALIZED_TYPE + ", " + MmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " FROM " + MmsDatabase.TABLE_NAME + " " +
|
||||
"WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + MmsDatabase.MESSAGE_BOX + " & " + GROUP_V2_LEAVE_BITS + " != " + GROUP_V2_LEAVE_BITS + " AND " + MmsDatabase.IS_STORY + " = 0 AND " + MmsDatabase.PARENT_STORY_ID + " = 0 " +
|
||||
"WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + MmsDatabase.MESSAGE_BOX + " & " + GROUP_V2_LEAVE_BITS + " != " + GROUP_V2_LEAVE_BITS + " AND " + MmsDatabase.IS_STORY + " = 0 AND " + MmsDatabase.PARENT_STORY_ID + " <= 0 " +
|
||||
"ORDER BY " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC " +
|
||||
"LIMIT 1";
|
||||
|
||||
|
@ -202,7 +202,7 @@ public class MmsSmsDatabase extends Database {
|
|||
public Cursor getConversation(long threadId, long offset, long limit) {
|
||||
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
|
||||
String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
|
||||
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsDatabase.IS_STORY + " = 0 AND " + MmsDatabase.PARENT_STORY_ID + " = 0";
|
||||
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsDatabase.IS_STORY + " = 0 AND " + MmsDatabase.PARENT_STORY_ID + " <= 0";
|
||||
String limitStr = limit > 0 || offset > 0 ? offset + ", " + limit : null;
|
||||
String query = buildQuery(PROJECTION, selection, order, limitStr, false);
|
||||
|
||||
|
@ -264,19 +264,16 @@ public class MmsSmsDatabase extends Database {
|
|||
}
|
||||
|
||||
String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " ASC";
|
||||
String selection = MmsSmsColumns.NOTIFIED + " = 0 AND (" + MmsSmsColumns.READ + " = 0 OR " + MmsSmsColumns.REACTIONS_UNREAD + " = 1" + (stickyQuery.length() > 0 ? " OR (" + stickyQuery.toString() + ")" : "") + ")";
|
||||
String selection = MmsSmsColumns.NOTIFIED + " = 0 AND " + MmsDatabase.IS_STORY + " = 0 AND " + MmsDatabase.PARENT_STORY_ID + " <= 0 AND (" + MmsSmsColumns.READ + " = 0 OR " + MmsSmsColumns.REACTIONS_UNREAD + " = 1" + (stickyQuery.length() > 0 ? " OR (" + stickyQuery.toString() + ")" : "") + ")";
|
||||
|
||||
return queryTables(PROJECTION, selection, order, null);
|
||||
}
|
||||
|
||||
public int getUnreadCount(long threadId) {
|
||||
String selection = MmsSmsColumns.READ + " = 0 AND " + MmsSmsColumns.THREAD_ID + " = " + threadId;
|
||||
Cursor cursor = queryTables(PROJECTION, selection, null, null);
|
||||
String selection = MmsSmsColumns.READ + " = 0 AND " + MmsDatabase.IS_STORY + " = 0 AND " + MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsDatabase.PARENT_STORY_ID + " <= 0";
|
||||
|
||||
try {
|
||||
try (Cursor cursor = queryTables(PROJECTION, selection, null, null)) {
|
||||
return cursor != null ? cursor.getCount() : 0;
|
||||
} finally {
|
||||
if (cursor != null) cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package org.thoughtcrime.securesms.database.model
|
||||
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* Abstract representation of a message id for a story.
|
||||
*
|
||||
* At the database layer, the sign of the id is dependant on whether a reply is meant for
|
||||
* a group thread or a direct reply. This class facilitates that, while still allowing for
|
||||
* normal behaviour elsewhere.
|
||||
*/
|
||||
sealed class ParentStoryId(protected val id: Long) {
|
||||
abstract fun serialize(): Long
|
||||
|
||||
fun asMessageId(): MessageId = MessageId(abs(id), true)
|
||||
|
||||
/**
|
||||
* A parent story who's child should be displayed in a group reply thread.
|
||||
*/
|
||||
class GroupReply(id: Long) : ParentStoryId(id) {
|
||||
override fun serialize(): Long = abs(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* A parent story who's child should be displayed in a 1:1 conversation.
|
||||
*/
|
||||
class DirectReply(id: Long) : ParentStoryId(id) {
|
||||
override fun serialize(): Long = -abs(id)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Takes a long stored in the database and converts it to an appropriate subclass of ParentStoryId.
|
||||
* If the passed value is 0L, null is returned.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun deserialize(id: Long): ParentStoryId? {
|
||||
return when {
|
||||
id > 0L -> GroupReply(id)
|
||||
id < 0L -> DirectReply(id)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -222,7 +222,6 @@ public final class PushGroupSendJob extends PushSendJob {
|
|||
|
||||
GroupId.Push groupId = groupRecipient.requireGroupId().requirePush();
|
||||
Optional<byte[]> profileKey = getProfileKey(groupRecipient);
|
||||
Optional<Quote> quote = getQuoteFor(message);
|
||||
Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
|
||||
List<SharedContact> sharedContacts = getSharedContactsFor(message);
|
||||
List<SignalServicePreview> previews = getPreviewsFor(message);
|
||||
|
@ -290,7 +289,6 @@ public final class PushGroupSendJob extends PushSendJob {
|
|||
.withViewOnce(message.isViewOnce())
|
||||
.asExpirationUpdate(message.isExpirationUpdate())
|
||||
.withProfileKey(profileKey.orNull())
|
||||
.withQuote(quote.orNull())
|
||||
.withSticker(sticker.orNull())
|
||||
.withSharedContacts(sharedContacts)
|
||||
.withPreviews(previews)
|
||||
|
@ -298,7 +296,7 @@ public final class PushGroupSendJob extends PushSendJob {
|
|||
|
||||
if (message.getParentStoryId() != null) {
|
||||
try {
|
||||
MessageRecord storyRecord = SignalDatabase.mms().getMessageRecord(message.getParentStoryId().getId());
|
||||
MessageRecord storyRecord = SignalDatabase.mms().getMessageRecord(message.getParentStoryId().asMessageId().getId());
|
||||
Recipient recipient = storyRecord.isOutgoing() ? Recipient.self() : storyRecord.getIndividualRecipient();
|
||||
|
||||
groupMessageBuilder.withStoryContext(new SignalServiceDataMessage.StoryContext(recipient.requireServiceId(), storyRecord.getDateSent()));
|
||||
|
@ -307,6 +305,8 @@ public final class PushGroupSendJob extends PushSendJob {
|
|||
// TODO [stories] check what should happen in this case
|
||||
throw new UndeliverableMessageException(e);
|
||||
}
|
||||
} else {
|
||||
groupMessageBuilder.withQuote(getQuoteFor(message).orNull());
|
||||
}
|
||||
|
||||
Log.i(TAG, JobLogger.format(this, "Beginning message send."));
|
||||
|
|
|
@ -208,7 +208,6 @@ public class PushMediaSendJob extends PushSendJob {
|
|||
List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
|
||||
List<SignalServiceAttachment> serviceAttachments = getAttachmentPointersFor(attachments);
|
||||
Optional<byte[]> profileKey = getProfileKey(messageRecipient);
|
||||
Optional<SignalServiceDataMessage.Quote> quote = getQuoteFor(message);
|
||||
Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
|
||||
List<SharedContact> sharedContacts = getSharedContactsFor(message);
|
||||
List<SignalServicePreview> previews = getPreviewsFor(message);
|
||||
|
@ -219,7 +218,6 @@ public class PushMediaSendJob extends PushSendJob {
|
|||
.withExpiration((int)(message.getExpiresIn() / 1000))
|
||||
.withViewOnce(message.isViewOnce())
|
||||
.withProfileKey(profileKey.orNull())
|
||||
.withQuote(quote.orNull())
|
||||
.withSticker(sticker.orNull())
|
||||
.withSharedContacts(sharedContacts)
|
||||
.withPreviews(previews)
|
||||
|
@ -227,13 +225,15 @@ public class PushMediaSendJob extends PushSendJob {
|
|||
|
||||
if (message.getParentStoryId() != null) {
|
||||
try {
|
||||
MessageRecord storyRecord = SignalDatabase.mms().getMessageRecord(message.getParentStoryId().getId());
|
||||
MessageRecord storyRecord = SignalDatabase.mms().getMessageRecord(message.getParentStoryId().asMessageId().getId());
|
||||
mediaMessageBuilder.withStoryContext(new SignalServiceDataMessage.StoryContext(address.getServiceId(), storyRecord.getDateSent()));
|
||||
} catch (NoSuchMessageException e) {
|
||||
// The story has probably expired
|
||||
// TODO [stories] check what should happen in this case
|
||||
throw new UndeliverableMessageException(e);
|
||||
}
|
||||
} else {
|
||||
mediaMessageBuilder.withQuote(getQuoteFor(message).orNull());
|
||||
}
|
||||
|
||||
SignalServiceDataMessage mediaMessage = mediaMessageBuilder.build();
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.thoughtcrime.securesms.database.model.MessageId;
|
|||
import org.thoughtcrime.securesms.database.model.MessageLogEntry;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId;
|
||||
import org.thoughtcrime.securesms.database.model.PendingRetryReceiptModel;
|
||||
import org.thoughtcrime.securesms.database.model.ReactionRecord;
|
||||
import org.thoughtcrime.securesms.database.model.StickerRecord;
|
||||
|
@ -1376,11 +1377,20 @@ public final class MessageContentProcessor {
|
|||
database.beginTransaction();
|
||||
|
||||
try {
|
||||
// TODO [stories] check if this works for group stories
|
||||
RecipientId storyAuthorRecipient = RecipientId.from(storyContext.getAuthorServiceId(), null);
|
||||
MessageId storyId;
|
||||
RecipientId storyAuthorRecipient = RecipientId.from(storyContext.getAuthorServiceId(), null);
|
||||
ParentStoryId parentStoryId;
|
||||
QuoteModel quoteModel = null;
|
||||
try {
|
||||
storyId = database.getStoryId(storyAuthorRecipient, storyContext.getSentTimestamp());
|
||||
MessageId storyMessageId = database.getStoryId(storyAuthorRecipient, storyContext.getSentTimestamp());
|
||||
|
||||
if (message.getGroupContext().isPresent()) {
|
||||
parentStoryId = new ParentStoryId.GroupReply(storyMessageId.getId());
|
||||
} else {
|
||||
MmsMessageRecord story = (MmsMessageRecord) database.getMessageRecord(storyMessageId.getId());
|
||||
|
||||
parentStoryId = new ParentStoryId.DirectReply(storyMessageId.getId());
|
||||
quoteModel = new QuoteModel(storyContext.getSentTimestamp(), storyAuthorRecipient, "", false, story.getSlideDeck().asAttachments(), Collections.emptyList());
|
||||
}
|
||||
} catch (NoSuchMessageException e) {
|
||||
warn(content.getTimestamp(), "Couldn't find story for reply.", e);
|
||||
return;
|
||||
|
@ -1391,7 +1401,7 @@ public final class MessageContentProcessor {
|
|||
content.getServerReceivedTimestamp(),
|
||||
System.currentTimeMillis(),
|
||||
false,
|
||||
storyId,
|
||||
parentStoryId,
|
||||
-1,
|
||||
0,
|
||||
false,
|
||||
|
@ -1400,7 +1410,7 @@ public final class MessageContentProcessor {
|
|||
message.getBody(),
|
||||
Optional.fromNullable(GroupUtil.getGroupContextIfPresent(content)),
|
||||
Optional.absent(),
|
||||
Optional.absent(),
|
||||
Optional.fromNullable(quoteModel),
|
||||
Optional.absent(),
|
||||
Optional.absent(),
|
||||
Optional.absent(),
|
||||
|
|
|
@ -4,7 +4,7 @@ import org.thoughtcrime.securesms.attachments.Attachment
|
|||
import org.thoughtcrime.securesms.attachments.PointerAttachment
|
||||
import org.thoughtcrime.securesms.contactshare.Contact
|
||||
import org.thoughtcrime.securesms.database.model.Mention
|
||||
import org.thoughtcrime.securesms.database.model.MessageId
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview
|
||||
|
@ -20,7 +20,7 @@ class IncomingMediaMessage(
|
|||
val body: String? = null,
|
||||
val isPushMessage: Boolean = false,
|
||||
val isStory: Boolean = false,
|
||||
val parentStoryId: MessageId? = null,
|
||||
val parentStoryId: ParentStoryId? = null,
|
||||
val sentTimeMillis: Long,
|
||||
val serverTimeMillis: Long,
|
||||
val receivedTimeMillis: Long,
|
||||
|
@ -84,7 +84,7 @@ class IncomingMediaMessage(
|
|||
serverTimeMillis: Long,
|
||||
receivedTimeMillis: Long,
|
||||
isStory: Boolean,
|
||||
parentStoryId: MessageId?,
|
||||
parentStoryId: ParentStoryId?,
|
||||
subscriptionId: Int,
|
||||
expiresIn: Long,
|
||||
expirationUpdate: Boolean,
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.thoughtcrime.securesms.contactshare.Contact;
|
|||
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
|
||||
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
|
||||
import org.thoughtcrime.securesms.database.model.Mention;
|
||||
import org.thoughtcrime.securesms.database.model.MessageId;
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
|
@ -31,7 +31,7 @@ public class OutgoingMediaMessage {
|
|||
private final boolean viewOnce;
|
||||
private final QuoteModel outgoingQuote;
|
||||
private final boolean isStory;
|
||||
private final MessageId parentStoryId;
|
||||
private final ParentStoryId parentStoryId;
|
||||
|
||||
private final Set<NetworkFailure> networkFailures = new HashSet<>();
|
||||
private final Set<IdentityKeyMismatch> identityKeyMismatches = new HashSet<>();
|
||||
|
@ -48,7 +48,7 @@ public class OutgoingMediaMessage {
|
|||
boolean viewOnce,
|
||||
int distributionType,
|
||||
boolean isStory,
|
||||
@Nullable MessageId parentStoryId,
|
||||
@Nullable ParentStoryId parentStoryId,
|
||||
@Nullable QuoteModel outgoingQuote,
|
||||
@NonNull List<Contact> contacts,
|
||||
@NonNull List<LinkPreview> linkPreviews,
|
||||
|
@ -84,7 +84,7 @@ public class OutgoingMediaMessage {
|
|||
boolean viewOnce,
|
||||
int distributionType,
|
||||
boolean isStory,
|
||||
@Nullable MessageId parentStoryId,
|
||||
@Nullable ParentStoryId parentStoryId,
|
||||
@Nullable QuoteModel outgoingQuote,
|
||||
@NonNull List<Contact> contacts,
|
||||
@NonNull List<LinkPreview> linkPreviews,
|
||||
|
@ -197,7 +197,7 @@ public class OutgoingMediaMessage {
|
|||
return isStory;
|
||||
}
|
||||
|
||||
public @Nullable MessageId getParentStoryId() {
|
||||
public @Nullable ParentStoryId getParentStoryId() {
|
||||
return parentStoryId;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import androidx.annotation.Nullable;
|
|||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.contactshare.Contact;
|
||||
import org.thoughtcrime.securesms.database.model.Mention;
|
||||
import org.thoughtcrime.securesms.database.model.MessageId;
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId;
|
||||
import org.thoughtcrime.securesms.linkpreview.LinkPreview;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class OutgoingSecureMediaMessage extends OutgoingMediaMessage {
|
|||
long expiresIn,
|
||||
boolean viewOnce,
|
||||
boolean isStory,
|
||||
@Nullable MessageId parentStoryId,
|
||||
@Nullable ParentStoryId parentStoryId,
|
||||
@Nullable QuoteModel quote,
|
||||
@NonNull List<Contact> contacts,
|
||||
@NonNull List<LinkPreview> previews,
|
||||
|
|
|
@ -8,7 +8,6 @@ import io.reactivex.rxjava3.core.Completable
|
|||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||
import io.reactivex.rxjava3.subjects.BehaviorSubject
|
||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||
import io.reactivex.rxjava3.subjects.Subject
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
|
@ -26,26 +25,13 @@ class StoryViewerPageViewModel(
|
|||
|
||||
private val store = Store(StoryViewerPageState())
|
||||
private val disposables = CompositeDisposable()
|
||||
private val storyViewerDialogSubject: Subject<Optional<StoryViewerDialog>> = BehaviorSubject.createDefault(Optional.empty())
|
||||
private val dismissSubject = PublishSubject.create<StoryViewerDialog.Type>()
|
||||
private val storyViewerDialogSubject: Subject<Optional<StoryViewerDialog>> = PublishSubject.create()
|
||||
|
||||
private val storyViewerPlaybackStore = Store(StoryViewerPlaybackState())
|
||||
|
||||
val storyViewerPlaybackState: LiveData<StoryViewerPlaybackState> = storyViewerPlaybackStore.stateLiveData
|
||||
|
||||
val groupDirectReplyObservable: Observable<Optional<StoryViewerDialog>> = Observable.combineLatest(storyViewerDialogSubject, dismissSubject) { sheet, dismissed ->
|
||||
if (sheet.isPresent && sheet.get().type != dismissed) {
|
||||
sheet
|
||||
} else {
|
||||
Optional.empty()
|
||||
}
|
||||
}.distinctUntilChanged { previous, current ->
|
||||
if (current.isPresent) {
|
||||
previous == current
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
val groupDirectReplyObservable: Observable<Optional<StoryViewerDialog>> = storyViewerDialogSubject
|
||||
|
||||
val state: LiveData<StoryViewerPageState> = store.stateLiveData
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import io.reactivex.rxjava3.schedulers.Schedulers
|
|||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage
|
||||
import org.thoughtcrime.securesms.mms.QuoteModel
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
|
@ -53,7 +54,7 @@ class StoryDirectReplyRepository {
|
|||
false,
|
||||
0,
|
||||
false,
|
||||
null,
|
||||
ParentStoryId.DirectReply(storyId),
|
||||
QuoteModel(message.dateSent, quoteAuthor.id, "", false, message.slideDeck.asAttachments(), null),
|
||||
emptyList(),
|
||||
emptyList(),
|
||||
|
|
|
@ -5,7 +5,7 @@ import io.reactivex.rxjava3.core.Completable
|
|||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.Mention
|
||||
import org.thoughtcrime.securesms.database.model.MessageId
|
||||
import org.thoughtcrime.securesms.database.model.ParentStoryId
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage
|
||||
import org.thoughtcrime.securesms.sms.MessageSender
|
||||
|
||||
|
@ -31,7 +31,7 @@ object StoryGroupReplySender {
|
|||
false,
|
||||
0,
|
||||
false,
|
||||
MessageId.fromNullable(message.id, true),
|
||||
ParentStoryId.GroupReply(message.id),
|
||||
null,
|
||||
emptyList(),
|
||||
emptyList(),
|
||||
|
|
Loading…
Add table
Reference in a new issue