mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-26 11:51:10 +01:00
Use resolved recipients in the conversation list.
This commit is contained in:
@@ -40,7 +40,6 @@ public final class LiveRecipient {
|
||||
private final AtomicReference<Recipient> recipient;
|
||||
private final RecipientDatabase recipientDatabase;
|
||||
private final GroupDatabase groupDatabase;
|
||||
private final String unnamedGroupName;
|
||||
|
||||
LiveRecipient(@NonNull Context context, @NonNull MutableLiveData<Recipient> liveData, @NonNull Recipient defaultRecipient) {
|
||||
this.context = context.getApplicationContext();
|
||||
@@ -48,7 +47,6 @@ public final class LiveRecipient {
|
||||
this.recipient = new AtomicReference<>(defaultRecipient);
|
||||
this.recipientDatabase = DatabaseFactory.getRecipientDatabase(context);
|
||||
this.groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
this.unnamedGroupName = context.getString(R.string.RecipientProvider_unnamed_group);
|
||||
this.observers = new CopyOnWriteArraySet<>();
|
||||
this.foreverObserver = recipient -> {
|
||||
for (RecipientForeverObserver o : observers) {
|
||||
@@ -175,21 +173,13 @@ public final class LiveRecipient {
|
||||
private @NonNull Recipient fetchAndCacheRecipientFromDisk(@NonNull RecipientId id) {
|
||||
RecipientSettings settings = recipientDatabase.getRecipientSettings(id);
|
||||
RecipientDetails details = settings.getGroupId() != null ? getGroupRecipientDetails(settings)
|
||||
: getIndividualRecipientDetails(settings);
|
||||
: RecipientDetails.forIndividual(context, settings);
|
||||
|
||||
Recipient recipient = new Recipient(id, details);
|
||||
Recipient recipient = new Recipient(id, details, true);
|
||||
RecipientIdCache.INSTANCE.put(recipient);
|
||||
return recipient;
|
||||
}
|
||||
|
||||
private @NonNull RecipientDetails getIndividualRecipientDetails(RecipientSettings settings) {
|
||||
boolean systemContact = !TextUtils.isEmpty(settings.getSystemDisplayName());
|
||||
boolean isLocalNumber = (settings.getE164() != null && settings.getE164().equals(TextSecurePreferences.getLocalNumber(context))) ||
|
||||
(settings.getUuid() != null && settings.getUuid().equals(TextSecurePreferences.getLocalUuid(context)));
|
||||
|
||||
return new RecipientDetails(context, null, Optional.absent(), systemContact, isLocalNumber, settings, null);
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private @NonNull RecipientDetails getGroupRecipientDetails(@NonNull RecipientSettings settings) {
|
||||
Optional<GroupRecord> groupRecord = groupDatabase.getGroup(settings.getId());
|
||||
@@ -199,21 +189,17 @@ public final class LiveRecipient {
|
||||
List<Recipient> members = Stream.of(groupRecord.get().getMembers()).filterNot(RecipientId::isUnknown).map(this::fetchAndCacheRecipientFromDisk).toList();
|
||||
Optional<Long> avatarId = Optional.absent();
|
||||
|
||||
if (settings.getGroupId() != null && settings.getGroupId().isPush() && title == null) {
|
||||
title = unnamedGroupName;
|
||||
}
|
||||
|
||||
if (groupRecord.get().hasAvatar()) {
|
||||
avatarId = Optional.of(groupRecord.get().getAvatarId());
|
||||
}
|
||||
|
||||
return new RecipientDetails(context, title, avatarId, false, false, settings, members);
|
||||
return new RecipientDetails(title, avatarId, false, false, settings, members);
|
||||
}
|
||||
|
||||
return new RecipientDetails(context, unnamedGroupName, Optional.absent(), false, false, settings, null);
|
||||
return new RecipientDetails(null, Optional.absent(), false, false, settings, null);
|
||||
}
|
||||
|
||||
private synchronized void set(@NonNull Recipient recipient) {
|
||||
synchronized void set(@NonNull Recipient recipient) {
|
||||
this.recipient.set(recipient);
|
||||
this.liveData.postValue(recipient);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -75,6 +76,40 @@ public final class LiveRecipientCache {
|
||||
return live;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a recipient to the cache if we don't have an entry. This will also update a cache entry
|
||||
* if the provided recipient is resolved, or if the existing cache entry is unresolved.
|
||||
*
|
||||
* If the recipient you add is unresolved, this will enqueue a resolve on a background thread.
|
||||
*/
|
||||
@AnyThread
|
||||
public synchronized void addToCache(@NonNull Collection<Recipient> newRecipients) {
|
||||
for (Recipient recipient : newRecipients) {
|
||||
LiveRecipient live = recipients.get(recipient.getId());
|
||||
boolean needsResolve = false;
|
||||
|
||||
if (live == null) {
|
||||
live = new LiveRecipient(context, new MutableLiveData<>(), recipient);
|
||||
recipients.put(recipient.getId(), live);
|
||||
needsResolve = recipient.isResolving();
|
||||
} else if (live.get().isResolving() || !recipient.isResolving()) {
|
||||
live.set(recipient);
|
||||
needsResolve = recipient.isResolving();
|
||||
}
|
||||
|
||||
if (needsResolve) {
|
||||
MissingRecipientException prettyStackTraceError = new MissingRecipientException(recipient.getId());
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
try {
|
||||
recipient.resolve();
|
||||
} catch (MissingRecipientException e) {
|
||||
throw prettyStackTraceError;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull Recipient getSelf() {
|
||||
synchronized (this) {
|
||||
if (localRecipientId == null) {
|
||||
@@ -107,23 +142,22 @@ public final class LiveRecipientCache {
|
||||
}
|
||||
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
List<Recipient> recipients = new ArrayList<>();
|
||||
|
||||
try (ThreadDatabase.Reader reader = threadDatabase.readerFor(threadDatabase.getConversationList())) {
|
||||
int i = 0;
|
||||
ThreadRecord record = null;
|
||||
List<Recipient> recipients = new ArrayList<>();
|
||||
int i = 0;
|
||||
ThreadRecord record = null;
|
||||
|
||||
while ((record = reader.getNext()) != null && i < CACHE_WARM_MAX) {
|
||||
recipients.add(record.getRecipient());
|
||||
i++;
|
||||
}
|
||||
|
||||
Log.d(TAG, "Warming up " + recipients.size() + " recipients.");
|
||||
|
||||
Collections.reverse(recipients);
|
||||
Stream.of(recipients).map(Recipient::getId).forEach(this::getLive);
|
||||
}
|
||||
|
||||
Log.d(TAG, "Warming up " + recipients.size() + " recipients.");
|
||||
Collections.reverse(recipients);
|
||||
Stream.of(recipients).map(Recipient::getId).forEach(this::getLive);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ import static org.thoughtcrime.securesms.database.RecipientDatabase.InsightsBann
|
||||
|
||||
public class Recipient {
|
||||
|
||||
public static final Recipient UNKNOWN = new Recipient(RecipientId.UNKNOWN, new RecipientDetails());
|
||||
public static final Recipient UNKNOWN = new Recipient(RecipientId.UNKNOWN, new RecipientDetails(), true);
|
||||
|
||||
private static final FallbackPhotoProvider DEFAULT_FALLBACK_PHOTO_PROVIDER = new FallbackPhotoProvider();
|
||||
private static final String TAG = Log.tag(Recipient.class);
|
||||
@@ -344,9 +344,9 @@ public class Recipient {
|
||||
this.identityStatus = VerifiedStatus.DEFAULT;
|
||||
}
|
||||
|
||||
Recipient(@NonNull RecipientId id, @NonNull RecipientDetails details) {
|
||||
public Recipient(@NonNull RecipientId id, @NonNull RecipientDetails details, boolean resolved) {
|
||||
this.id = id;
|
||||
this.resolving = false;
|
||||
this.resolving = !resolved;
|
||||
this.uuid = details.uuid;
|
||||
this.username = details.username;
|
||||
this.e164 = details.e164;
|
||||
@@ -408,9 +408,11 @@ public class Recipient {
|
||||
}
|
||||
|
||||
return Util.join(names, ", ");
|
||||
} else if (name == null && groupId != null && groupId.isPush()) {
|
||||
return context.getString(R.string.RecipientProvider_unnamed_group);
|
||||
} else {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -657,7 +659,7 @@ public class Recipient {
|
||||
|
||||
public @NonNull FallbackContactPhoto getFallbackContactPhoto(@NonNull FallbackPhotoProvider fallbackPhotoProvider) {
|
||||
if (localNumber) return fallbackPhotoProvider.getPhotoForLocalNumber();
|
||||
if (isResolving()) return fallbackPhotoProvider.getPhotoForResolvingRecipient();
|
||||
else if (isResolving()) return fallbackPhotoProvider.getPhotoForResolvingRecipient();
|
||||
else if (isGroupInternal()) return fallbackPhotoProvider.getPhotoForGroup();
|
||||
else if (isGroup()) return fallbackPhotoProvider.getPhotoForGroup();
|
||||
else if (!TextUtils.isEmpty(name)) return fallbackPhotoProvider.getPhotoForRecipientWithName(name);
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.recipients;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -66,13 +67,12 @@ public class RecipientDetails {
|
||||
final byte[] identityKey;
|
||||
final VerifiedStatus identityStatus;
|
||||
|
||||
RecipientDetails(@NonNull Context context,
|
||||
@Nullable String name,
|
||||
@NonNull Optional<Long> groupAvatarId,
|
||||
boolean systemContact,
|
||||
boolean isLocalNumber,
|
||||
@NonNull RecipientSettings settings,
|
||||
@Nullable List<Recipient> participants)
|
||||
public RecipientDetails(@Nullable String name,
|
||||
@NonNull Optional<Long> groupAvatarId,
|
||||
boolean systemContact,
|
||||
boolean isLocalNumber,
|
||||
@NonNull RecipientSettings settings,
|
||||
@Nullable List<Recipient> participants)
|
||||
{
|
||||
this.groupAvatarId = groupAvatarId;
|
||||
this.systemContactPhoto = Util.uri(settings.getSystemContactPhotoUri());
|
||||
@@ -161,4 +161,12 @@ public class RecipientDetails {
|
||||
this.identityKey = null;
|
||||
this.identityStatus = VerifiedStatus.DEFAULT;
|
||||
}
|
||||
|
||||
public static @NonNull RecipientDetails forIndividual(@NonNull Context context, @NonNull RecipientSettings settings) {
|
||||
boolean systemContact = !TextUtils.isEmpty(settings.getSystemDisplayName());
|
||||
boolean isLocalNumber = (settings.getE164() != null && settings.getE164().equals(TextSecurePreferences.getLocalNumber(context))) ||
|
||||
(settings.getUuid() != null && settings.getUuid().equals(TextSecurePreferences.getLocalUuid(context)));
|
||||
|
||||
return new RecipientDetails(null, Optional.absent(), systemContact, isLocalNumber, settings, null);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user