mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-27 13:13:43 +00:00
Update group update messages faster.
This commit is contained in:
committed by
Cody Henthorne
parent
f91494f813
commit
945c308cf5
@@ -22,17 +22,23 @@ import org.thoughtcrime.securesms.database.model.MessageId;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.ReactionRecord;
|
||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.UpdateDescription;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -90,6 +96,7 @@ class ConversationDataSource implements PagedDataSource<MessageId, ConversationM
|
||||
MentionHelper mentionHelper = new MentionHelper();
|
||||
AttachmentHelper attachmentHelper = new AttachmentHelper();
|
||||
ReactionHelper reactionHelper = new ReactionHelper();
|
||||
Set<ServiceId> referencedIds = new HashSet<>();
|
||||
|
||||
try (MmsSmsDatabase.Reader reader = MmsSmsDatabase.readerFor(db.getConversation(threadId, start, length))) {
|
||||
MessageRecord record;
|
||||
@@ -98,6 +105,11 @@ class ConversationDataSource implements PagedDataSource<MessageId, ConversationM
|
||||
mentionHelper.add(record);
|
||||
reactionHelper.add(record);
|
||||
attachmentHelper.add(record);
|
||||
|
||||
UpdateDescription description = record.getUpdateDisplayBody(context);
|
||||
if (description != null) {
|
||||
referencedIds.addAll(description.getMentioned());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +138,11 @@ class ConversationDataSource implements PagedDataSource<MessageId, ConversationM
|
||||
records = attachmentHelper.buildUpdatedModels(context, records);
|
||||
stopwatch.split("attachment-models");
|
||||
|
||||
for (ServiceId serviceId : referencedIds) {
|
||||
Recipient.resolved(RecipientId.from(serviceId, null));
|
||||
}
|
||||
stopwatch.split("recipient-resolves");
|
||||
|
||||
List<ConversationMessage> messages = Stream.of(records)
|
||||
.map(m -> ConversationMessageFactory.createWithUnresolvedData(context, m, mentionHelper.getMentions(m.getId())))
|
||||
.toList();
|
||||
|
||||
@@ -73,13 +73,12 @@ public final class ConversationUpdateItem extends FrameLayout
|
||||
private Stub<CardView> donateButtonStub;
|
||||
private View background;
|
||||
private ConversationMessage conversationMessage;
|
||||
private Recipient conversationRecipient;
|
||||
private Optional<MessageRecord> nextMessageRecord;
|
||||
private MessageRecord messageRecord;
|
||||
private Recipient conversationRecipient;
|
||||
private Optional<MessageRecord> nextMessageRecord;
|
||||
private MessageRecord messageRecord;
|
||||
private boolean isMessageRequestAccepted;
|
||||
private LiveData<SpannableString> displayBody;
|
||||
private EventListener eventListener;
|
||||
private boolean hasWallpaper;
|
||||
|
||||
private final UpdateObserver updateObserver = new UpdateObserver();
|
||||
|
||||
@@ -146,7 +145,6 @@ public final class ConversationUpdateItem extends FrameLayout
|
||||
boolean hasWallpaper,
|
||||
boolean isMessageRequestAccepted)
|
||||
{
|
||||
this.hasWallpaper = hasWallpaper;
|
||||
this.conversationMessage = conversationMessage;
|
||||
this.messageRecord = conversationMessage.getMessageRecord();
|
||||
this.nextMessageRecord = nextMessageRecord;
|
||||
|
||||
@@ -14,15 +14,22 @@ import org.signal.paging.PagedDataSource;
|
||||
import org.thoughtcrime.securesms.conversationlist.model.Conversation;
|
||||
import org.thoughtcrime.securesms.conversationlist.model.ConversationReader;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.database.model.UpdateDescription;
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.Stopwatch;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
abstract class ConversationListDataSource implements PagedDataSource<Long, Conversation> {
|
||||
|
||||
@@ -53,22 +60,32 @@ abstract class ConversationListDataSource implements PagedDataSource<Long, Conve
|
||||
Stopwatch stopwatch = new Stopwatch("load(" + start + ", " + length + "), " + getClass().getSimpleName());
|
||||
|
||||
List<Conversation> conversations = new ArrayList<>(length);
|
||||
List<Recipient> recipients = new LinkedList<>();
|
||||
List<Recipient> recipients = new LinkedList<>();
|
||||
Set<RecipientId> needsResolve = new HashSet<>();
|
||||
|
||||
try (ConversationReader reader = new ConversationReader(getCursor(start, length))) {
|
||||
ThreadRecord record;
|
||||
while ((record = reader.getNext()) != null && !cancellationSignal.isCanceled()) {
|
||||
conversations.add(new Conversation(record));
|
||||
recipients.add(record.getRecipient());
|
||||
|
||||
if (!record.getRecipient().isPushV2Group()) {
|
||||
needsResolve.add(record.getRecipient().getId());
|
||||
} else if (SmsDatabase.Types.isGroupUpdate(record.getType())) {
|
||||
UpdateDescription description = MessageRecord.getGv2ChangeDescription(ApplicationDependencies.getApplication(), record.getBody());
|
||||
needsResolve.addAll(description.getMentioned().stream().map(sid -> RecipientId.from(sid, null)).collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stopwatch.split("cursor");
|
||||
|
||||
ApplicationDependencies.getRecipientCache().addToCache(recipients);
|
||||
|
||||
stopwatch.split("cache-recipients");
|
||||
|
||||
Recipient.resolvedList(needsResolve);
|
||||
stopwatch.split("recipient-resolve");
|
||||
|
||||
stopwatch.stop(TAG);
|
||||
|
||||
return conversations;
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.database.model;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.WorkerThread;
|
||||
@@ -763,11 +764,9 @@ final class GroupsV2UpdateMessageProducer {
|
||||
interface DescribeMemberStrategy {
|
||||
|
||||
/**
|
||||
* Map an ACI to a string that describes the group member.
|
||||
* @param serviceId
|
||||
* Map a ServiceId to a string that describes the group member.
|
||||
*/
|
||||
@NonNull
|
||||
@WorkerThread
|
||||
String describe(@NonNull ServiceId serviceId);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,10 @@ import android.text.SpannableStringBuilder;
|
||||
|
||||
import androidx.annotation.AnyThread;
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.Transformations;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
@@ -34,11 +36,12 @@ public final class LiveUpdateMessage {
|
||||
* Creates a live data that observes the recipients mentioned in the {@link UpdateDescription} and
|
||||
* recreates the string asynchronously when they change.
|
||||
*/
|
||||
@AnyThread
|
||||
@MainThread
|
||||
public static LiveData<SpannableString> fromMessageDescription(@NonNull Context context,
|
||||
@NonNull UpdateDescription updateDescription,
|
||||
@ColorInt int defaultTint,
|
||||
boolean adjustPosition) {
|
||||
boolean adjustPosition)
|
||||
{
|
||||
if (updateDescription.isStringStatic()) {
|
||||
return LiveDataUtil.just(toSpannable(context, updateDescription, updateDescription.getStaticString(), defaultTint, adjustPosition));
|
||||
}
|
||||
@@ -50,16 +53,17 @@ public final class LiveUpdateMessage {
|
||||
LiveData<?> mentionedRecipientChangeStream = allMentionedRecipients.isEmpty() ? LiveDataUtil.just(new Object())
|
||||
: LiveDataUtil.merge(allMentionedRecipients);
|
||||
|
||||
return LiveDataUtil.mapAsync(mentionedRecipientChangeStream, event -> toSpannable(context, updateDescription, updateDescription.getString(), defaultTint, adjustPosition));
|
||||
return Transformations.map(mentionedRecipientChangeStream, event -> toSpannable(context, updateDescription, updateDescription.getString(), defaultTint, adjustPosition));
|
||||
}
|
||||
|
||||
/**
|
||||
* Observes a single recipient and recreates the string asynchronously when they change.
|
||||
*/
|
||||
@MainThread
|
||||
public static LiveData<SpannableString> recipientToStringAsync(@NonNull RecipientId recipientId,
|
||||
@NonNull Function<Recipient, SpannableString> createStringInBackground)
|
||||
{
|
||||
return LiveDataUtil.mapAsync(Recipient.live(recipientId).getLiveDataResolved(), createStringInBackground);
|
||||
return Transformations.map(Recipient.live(recipientId).getLiveDataResolved(), createStringInBackground::apply);
|
||||
}
|
||||
|
||||
private static @NonNull SpannableString toSpannable(@NonNull Context context, @NonNull UpdateDescription updateDescription, @NonNull String string, @ColorInt int defaultTint, boolean adjustPosition) {
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.util.Set;
|
||||
public final class UpdateDescription {
|
||||
|
||||
public interface StringFactory {
|
||||
@WorkerThread
|
||||
String create();
|
||||
}
|
||||
|
||||
@@ -109,14 +108,12 @@ public final class UpdateDescription {
|
||||
return staticString;
|
||||
}
|
||||
|
||||
ThreadUtil.assertNotMainThread();
|
||||
|
||||
//noinspection ConstantConditions
|
||||
return stringFactory.create();
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
public Collection<ServiceId> getMentioned() {
|
||||
public @NonNull Collection<ServiceId> getMentioned() {
|
||||
return mentioned;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user