kopia lustrzana https://github.com/ryukoposting/Signal-Android
Improve cold start performance.
rodzic
d159a0482a
commit
fe6058e0df
|
@ -381,7 +381,7 @@ sealed class ConversationSettingsViewModel(
|
||||||
private fun getLegacyGroupState(recipient: Recipient): LegacyGroupPreference.State {
|
private fun getLegacyGroupState(recipient: Recipient): LegacyGroupPreference.State {
|
||||||
val showLegacyInfo = recipient.requireGroupId().isV1
|
val showLegacyInfo = recipient.requireGroupId().isV1
|
||||||
|
|
||||||
return if (showLegacyInfo && recipient.participants.size > FeatureFlags.groupLimits().hardLimit) {
|
return if (showLegacyInfo && recipient.participantIds.size > FeatureFlags.groupLimits().hardLimit) {
|
||||||
LegacyGroupPreference.State.TOO_LARGE
|
LegacyGroupPreference.State.TOO_LARGE
|
||||||
} else if (showLegacyInfo) {
|
} else if (showLegacyInfo) {
|
||||||
LegacyGroupPreference.State.UPGRADE
|
LegacyGroupPreference.State.UPGRADE
|
||||||
|
|
|
@ -216,7 +216,7 @@ public class ContactSelectionListItem extends ConstraintLayout implements Recipi
|
||||||
if (!recipient.isGroup()) {
|
if (!recipient.isGroup()) {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
int memberCount = recipient.getParticipants().size();
|
int memberCount = recipient.getParticipantIds().size();
|
||||||
return getContext().getResources().getQuantityString(R.plurals.contact_selection_list_item__number_of_members, memberCount, memberCount);
|
return getContext().getResources().getQuantityString(R.plurals.contact_selection_list_item__number_of_members, memberCount, memberCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ object ContactSearchItems {
|
||||||
number.visible = true
|
number.visible = true
|
||||||
|
|
||||||
val count = if (model.story.recipient.isGroup) {
|
val count = if (model.story.recipient.isGroup) {
|
||||||
model.story.recipient.participants.size
|
model.story.recipient.participantIds.size
|
||||||
} else {
|
} else {
|
||||||
model.story.viewerCount
|
model.story.viewerCount
|
||||||
}
|
}
|
||||||
|
@ -227,8 +227,9 @@ object ContactSearchItems {
|
||||||
protected open fun bindNumberField(model: T) {
|
protected open fun bindNumberField(model: T) {
|
||||||
number.visible = getRecipient(model).isGroup
|
number.visible = getRecipient(model).isGroup
|
||||||
if (getRecipient(model).isGroup) {
|
if (getRecipient(model).isGroup) {
|
||||||
number.text = getRecipient(model).participants
|
number.text = getRecipient(model).participantIds
|
||||||
.take(10)
|
.take(10)
|
||||||
|
.map { id -> Recipient.resolved(id) }
|
||||||
.sortedWith(IsSelfComparator()).joinToString(", ") {
|
.sortedWith(IsSelfComparator()).joinToString(", ") {
|
||||||
if (it.isSelf) {
|
if (it.isSelf) {
|
||||||
context.getString(R.string.ConversationTitleView_you)
|
context.getString(R.string.ConversationTitleView_you)
|
||||||
|
|
|
@ -84,7 +84,7 @@ open class ContactSearchPagedDataSourceRepository(
|
||||||
open fun getGroupStories(): Set<ContactSearchData.Story> {
|
open fun getGroupStories(): Set<ContactSearchData.Story> {
|
||||||
return SignalDatabase.groups.groupsToDisplayAsStories.map {
|
return SignalDatabase.groups.groupsToDisplayAsStories.map {
|
||||||
val recipient = Recipient.resolved(SignalDatabase.recipients.getOrInsertFromGroupId(it))
|
val recipient = Recipient.resolved(SignalDatabase.recipients.getOrInsertFromGroupId(it))
|
||||||
ContactSearchData.Story(recipient, recipient.participants.size)
|
ContactSearchData.Story(recipient, recipient.participantIds.size)
|
||||||
}.toSet()
|
}.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ class ContactSearchViewModel(
|
||||||
state.copy(
|
state.copy(
|
||||||
groupStories = state.groupStories + groupStories.map {
|
groupStories = state.groupStories + groupStories.map {
|
||||||
val recipient = Recipient.resolved(it.recipientId)
|
val recipient = Recipient.resolved(it.recipientId)
|
||||||
ContactSearchData.Story(recipient, recipient.participants.size)
|
ContactSearchData.Story(recipient, recipient.participantIds.size)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,8 +329,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import io.reactivex.rxjava3.core.Flowable;
|
import io.reactivex.rxjava3.core.Flowable;
|
||||||
import io.reactivex.rxjava3.core.Observable;
|
|
||||||
import io.reactivex.rxjava3.disposables.Disposable;
|
|
||||||
|
|
||||||
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
import static org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord;
|
||||||
|
|
||||||
|
@ -2359,8 +2357,8 @@ public class ConversationParentFragment extends Fragment
|
||||||
return annotations;
|
return annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> validRecipientIds = Stream.of(getRecipient().getParticipants())
|
Set<String> validRecipientIds = Stream.of(getRecipient().getParticipantIds())
|
||||||
.map(r -> MentionAnnotation.idToMentionAnnotationValue(r.getId()))
|
.map(id -> MentionAnnotation.idToMentionAnnotationValue(id))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
return Stream.of(annotations)
|
return Stream.of(annotations)
|
||||||
|
|
|
@ -192,7 +192,9 @@ public class ConversationTitleView extends RelativeLayout {
|
||||||
|
|
||||||
private void setGroupRecipientTitle(@NonNull Recipient recipient) {
|
private void setGroupRecipientTitle(@NonNull Recipient recipient) {
|
||||||
this.title.setText(recipient.getDisplayName(getContext()));
|
this.title.setText(recipient.getDisplayName(getContext()));
|
||||||
this.subtitle.setText(Stream.of(recipient.getParticipants())
|
this.subtitle.setText(Stream.of(recipient.getParticipantIds())
|
||||||
|
.limit(10)
|
||||||
|
.map(Recipient::resolved)
|
||||||
.sorted((a, b) -> Boolean.compare(a.isSelf(), b.isSelf()))
|
.sorted((a, b) -> Boolean.compare(a.isSelf(), b.isSelf()))
|
||||||
.map(r -> r.isSelf() ? getResources().getString(R.string.ConversationTitleView_you)
|
.map(r -> r.isSelf() ? getResources().getString(R.string.ConversationTitleView_you)
|
||||||
: r.getDisplayName(getContext()))
|
: r.getDisplayName(getContext()))
|
||||||
|
|
|
@ -70,7 +70,7 @@ abstract class ConversationListDataSource implements PagedDataSource<Long, Conve
|
||||||
recipients.add(record.getRecipient());
|
recipients.add(record.getRecipient());
|
||||||
needsResolve.add(record.getGroupMessageSender());
|
needsResolve.add(record.getGroupMessageSender());
|
||||||
|
|
||||||
if (!record.getRecipient().isPushV2Group()) {
|
if (!SmsDatabase.Types.isGroupV2(record.getType())) {
|
||||||
needsResolve.add(record.getRecipient().getId());
|
needsResolve.add(record.getRecipient().getId());
|
||||||
} else if (SmsDatabase.Types.isGroupUpdate(record.getType())) {
|
} else if (SmsDatabase.Types.isGroupUpdate(record.getType())) {
|
||||||
UpdateDescription description = MessageRecord.getGv2ChangeDescription(ApplicationDependencies.getApplication(), record.getBody(), null);
|
UpdateDescription description = MessageRecord.getGv2ChangeDescription(ApplicationDependencies.getApplication(), record.getBody(), null);
|
||||||
|
|
|
@ -426,7 +426,6 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
ConversationFragment.prepare(requireContext());
|
|
||||||
ApplicationDependencies.getAppForegroundObserver().addListener(appForegroundObserver);
|
ApplicationDependencies.getAppForegroundObserver().addListener(appForegroundObserver);
|
||||||
itemAnimator.disable();
|
itemAnimator.disable();
|
||||||
}
|
}
|
||||||
|
@ -689,6 +688,7 @@ public class ConversationListFragment extends MainFragment implements ActionMode
|
||||||
AppStartup.getInstance().onCriticalRenderEventEnd();
|
AppStartup.getInstance().onCriticalRenderEventEnd();
|
||||||
startupStopwatch.split("first-render");
|
startupStopwatch.split("first-render");
|
||||||
startupStopwatch.stop(TAG);
|
startupStopwatch.stop(TAG);
|
||||||
|
ConversationFragment.prepare(requireContext());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2892,7 +2892,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
||||||
*/
|
*/
|
||||||
fun getRecipientsForRoutineProfileFetch(lastInteractionThreshold: Long, lastProfileFetchThreshold: Long, limit: Int): List<RecipientId> {
|
fun getRecipientsForRoutineProfileFetch(lastInteractionThreshold: Long, lastProfileFetchThreshold: Long, limit: Int): List<RecipientId> {
|
||||||
val threadDatabase = threads
|
val threadDatabase = threads
|
||||||
val recipientsWithinInteractionThreshold: MutableSet<Recipient> = LinkedHashSet()
|
val recipientsWithinInteractionThreshold: MutableSet<RecipientId> = LinkedHashSet()
|
||||||
|
|
||||||
threadDatabase.readerFor(threadDatabase.getRecentPushConversationList(-1, false)).use { reader ->
|
threadDatabase.readerFor(threadDatabase.getRecentPushConversationList(-1, false)).use { reader ->
|
||||||
var record: ThreadRecord? = reader.next
|
var record: ThreadRecord? = reader.next
|
||||||
|
@ -2900,15 +2900,16 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
||||||
while (record != null && record.date > lastInteractionThreshold) {
|
while (record != null && record.date > lastInteractionThreshold) {
|
||||||
val recipient = Recipient.resolved(record.recipient.id)
|
val recipient = Recipient.resolved(record.recipient.id)
|
||||||
if (recipient.isGroup) {
|
if (recipient.isGroup) {
|
||||||
recipientsWithinInteractionThreshold.addAll(recipient.participants)
|
recipientsWithinInteractionThreshold.addAll(recipient.participantIds)
|
||||||
} else {
|
} else {
|
||||||
recipientsWithinInteractionThreshold.add(recipient)
|
recipientsWithinInteractionThreshold.add(recipient.id)
|
||||||
}
|
}
|
||||||
record = reader.next
|
record = reader.next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return recipientsWithinInteractionThreshold
|
return Recipient.resolvedList(recipientsWithinInteractionThreshold)
|
||||||
|
.asSequence()
|
||||||
.filterNot { it.isSelf }
|
.filterNot { it.isSelf }
|
||||||
.filter { it.lastProfileFetchTime < lastProfileFetchThreshold }
|
.filter { it.lastProfileFetchTime < lastProfileFetchThreshold }
|
||||||
.take(limit)
|
.take(limit)
|
||||||
|
|
|
@ -52,8 +52,8 @@ public final class GroupsV1MigrationUtil {
|
||||||
throw new InvalidMigrationStateException();
|
throw new InvalidMigrationStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupRecipient.getParticipants().size() > FeatureFlags.groupLimits().getHardLimit()) {
|
if (groupRecipient.getParticipantIds().size() > FeatureFlags.groupLimits().getHardLimit()) {
|
||||||
Log.w(TAG, "Too many members! Size: " + groupRecipient.getParticipants().size());
|
Log.w(TAG, "Too many members! Size: " + groupRecipient.getParticipantIds().size());
|
||||||
throw new InvalidMigrationStateException();
|
throw new InvalidMigrationStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ public final class GroupsV1MigrationUtil {
|
||||||
throw new InvalidMigrationStateException();
|
throw new InvalidMigrationStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Recipient> registeredMembers = RecipientUtil.getEligibleForSending(groupRecipient.getParticipants());
|
List<Recipient> registeredMembers = RecipientUtil.getEligibleForSending(Recipient.resolvedList(groupRecipient.getParticipantIds()));
|
||||||
|
|
||||||
if (RecipientUtil.ensureUuidsAreAvailable(context, registeredMembers)) {
|
if (RecipientUtil.ensureUuidsAreAvailable(context, registeredMembers)) {
|
||||||
Log.i(TAG, "Newly-discovered UUIDs. Getting fresh recipients.");
|
Log.i(TAG, "Newly-discovered UUIDs. Getting fresh recipients.");
|
||||||
|
|
|
@ -68,7 +68,8 @@ final class GroupsV1MigrationRepository {
|
||||||
return new MigrationState(Collections.emptyList(), Collections.emptyList());
|
return new MigrationState(Collections.emptyList(), Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<RecipientId> needsRefresh = Stream.of(group.getParticipants())
|
List<Recipient> members = Recipient.resolvedList(group.getParticipantIds());
|
||||||
|
Set<RecipientId> needsRefresh = Stream.of(members)
|
||||||
.filter(r -> r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED)
|
.filter(r -> r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED)
|
||||||
.map(Recipient::getId)
|
.map(Recipient::getId)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
@ -82,7 +83,7 @@ final class GroupsV1MigrationRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<Recipient> registered = Stream.of(group.getParticipants())
|
List<Recipient> registered = Stream.of(members)
|
||||||
.filter(Recipient::isRegistered)
|
.filter(Recipient::isRegistered)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
@ -93,13 +94,13 @@ final class GroupsV1MigrationRepository {
|
||||||
|
|
||||||
group = group.fresh();
|
group = group.fresh();
|
||||||
|
|
||||||
List<Recipient> ineligible = Stream.of(group.getParticipants())
|
List<Recipient> ineligible = Stream.of(members)
|
||||||
.filter(r -> !r.hasServiceId() ||
|
.filter(r -> !r.hasServiceId() ||
|
||||||
r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED ||
|
r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED ||
|
||||||
r.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED)
|
r.getRegistered() != RecipientDatabase.RegisteredState.REGISTERED)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
List<Recipient> invites = Stream.of(group.getParticipants())
|
List<Recipient> invites = Stream.of(members)
|
||||||
.filterNot(ineligible::contains)
|
.filterNot(ineligible::contains)
|
||||||
.filterNot(Recipient::isSelf)
|
.filterNot(Recipient::isSelf)
|
||||||
.filter(r -> r.getProfileKey() == null)
|
.filter(r -> r.getProfileKey() == null)
|
||||||
|
|
|
@ -21,7 +21,6 @@ import org.whispersystems.signalservice.api.crypto.ContentHint;
|
||||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||||
import org.whispersystems.signalservice.api.messages.SendMessageResult;
|
import org.whispersystems.signalservice.api.messages.SendMessageResult;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
|
||||||
import org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException;
|
|
||||||
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
|
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -57,15 +56,15 @@ public class GroupCallUpdateSendJob extends BaseJob {
|
||||||
throw new AssertionError("We have a recipient, but it's not a V2 Group");
|
throw new AssertionError("We have a recipient, but it's not a V2 Group");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RecipientId> recipients = Stream.of(RecipientUtil.getEligibleForSending(conversationRecipient.getParticipants()))
|
List<RecipientId> recipientIds = Stream.of(RecipientUtil.getEligibleForSending(Recipient.resolvedList(conversationRecipient.getParticipantIds())))
|
||||||
.filterNot(Recipient::isSelf)
|
.filterNot(Recipient::isSelf)
|
||||||
.map(Recipient::getId)
|
.map(Recipient::getId)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return new GroupCallUpdateSendJob(recipientId,
|
return new GroupCallUpdateSendJob(recipientId,
|
||||||
eraId,
|
eraId,
|
||||||
recipients,
|
recipientIds,
|
||||||
recipients.size(),
|
recipientIds.size(),
|
||||||
new Parameters.Builder()
|
new Parameters.Builder()
|
||||||
.setQueue(conversationRecipient.getId().toQueueKey())
|
.setQueue(conversationRecipient.getId().toQueueKey())
|
||||||
.setLifespan(TimeUnit.MINUTES.toMillis(5))
|
.setLifespan(TimeUnit.MINUTES.toMillis(5))
|
||||||
|
|
|
@ -96,7 +96,7 @@ public class GroupV1MigrationJob extends BaseJob {
|
||||||
for (ThreadRecord thread : threads) {
|
for (ThreadRecord thread : threads) {
|
||||||
jobManager.add(new GroupV1MigrationJob(thread.getRecipient().getId()));
|
jobManager.add(new GroupV1MigrationJob(thread.getRecipient().getId()));
|
||||||
|
|
||||||
needsRefresh.addAll(Stream.of(thread.getRecipient().getParticipants())
|
needsRefresh.addAll(Stream.of(Recipient.resolvedList(thread.getRecipient().getParticipantIds()))
|
||||||
.filter(r -> r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED)
|
.filter(r -> r.getGroupsV1MigrationCapability() != Recipient.Capability.SUPPORTED)
|
||||||
.map(Recipient::getId)
|
.map(Recipient::getId)
|
||||||
.toList());
|
.toList());
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
package org.thoughtcrime.securesms.jobs;
|
package org.thoughtcrime.securesms.jobs;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.WorkerThread;
|
import androidx.annotation.WorkerThread;
|
||||||
|
@ -62,8 +60,11 @@ public class ProfileKeySendJob extends BaseJob {
|
||||||
throw new AssertionError("Do not send profile keys directly for GV2");
|
throw new AssertionError("Do not send profile keys directly for GV2");
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RecipientId> recipients = conversationRecipient.isGroup() ? Stream.of(RecipientUtil.getEligibleForSending(conversationRecipient.getParticipants())).map(Recipient::getId).toList()
|
List<RecipientId> recipients = conversationRecipient.isGroup() ? Stream.of(RecipientUtil.getEligibleForSending(Recipient.resolvedList(conversationRecipient.getParticipantIds())))
|
||||||
: Stream.of(conversationRecipient.getId()).toList();
|
.map(Recipient::getId)
|
||||||
|
.toList()
|
||||||
|
: Stream.of(conversationRecipient.getId())
|
||||||
|
.toList();
|
||||||
|
|
||||||
recipients.remove(Recipient.self().getId());
|
recipients.remove(Recipient.self().getId());
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class ReactionSendJob extends BaseJob {
|
||||||
}
|
}
|
||||||
|
|
||||||
RecipientId selfId = Recipient.self().getId();
|
RecipientId selfId = Recipient.self().getId();
|
||||||
List<RecipientId> recipients = conversationRecipient.isGroup() ? RecipientUtil.getEligibleForSending(conversationRecipient.getParticipants())
|
List<RecipientId> recipients = conversationRecipient.isGroup() ? RecipientUtil.getEligibleForSending(Recipient.resolvedList(conversationRecipient.getParticipantIds()))
|
||||||
.stream()
|
.stream()
|
||||||
.map(Recipient::getId)
|
.map(Recipient::getId)
|
||||||
.filter(r -> !r.equals(selfId))
|
.filter(r -> !r.equals(selfId))
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class RemoteDeleteSendJob extends BaseJob {
|
||||||
return ApplicationDependencies.getJobManager().startChain(MultiDeviceStorySendSyncJob.create(message.getDateSent(), messageId));
|
return ApplicationDependencies.getJobManager().startChain(MultiDeviceStorySendSyncJob.create(message.getDateSent(), messageId));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
recipients = conversationRecipient.isGroup() ? Stream.of(conversationRecipient.getParticipants()).map(Recipient::getId).toList()
|
recipients = conversationRecipient.isGroup() ? Stream.of(conversationRecipient.getParticipantIds()).toList()
|
||||||
: Stream.of(conversationRecipient.getId()).toList();
|
: Stream.of(conversationRecipient.getId()).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.thoughtcrime.securesms.mediasend.v2
|
package org.thoughtcrime.securesms.mediasend.v2
|
||||||
|
|
||||||
|
import androidx.annotation.WorkerThread
|
||||||
import androidx.core.util.Consumer
|
import androidx.core.util.Consumer
|
||||||
import io.reactivex.rxjava3.core.Completable
|
import io.reactivex.rxjava3.core.Completable
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||||
|
@ -27,12 +28,13 @@ object UntrustedRecords {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
private fun checkForBadIdentityRecordsSync(contactSearchKeys: Set<ContactSearchKey.RecipientSearchKey>): List<IdentityRecord> {
|
private fun checkForBadIdentityRecordsSync(contactSearchKeys: Set<ContactSearchKey.RecipientSearchKey>): List<IdentityRecord> {
|
||||||
val recipients: List<Recipient> = contactSearchKeys
|
val recipients: List<Recipient> = contactSearchKeys
|
||||||
.map { Recipient.resolved(it.recipientId) }
|
.map { Recipient.resolved(it.recipientId) }
|
||||||
.map { recipient ->
|
.map { recipient ->
|
||||||
when {
|
when {
|
||||||
recipient.isGroup -> recipient.participants
|
recipient.isGroup -> Recipient.resolvedList(recipient.participantIds)
|
||||||
recipient.isDistributionList -> Recipient.resolvedList(SignalDatabase.distributionLists.getMembers(recipient.distributionListId.get()))
|
recipient.isDistributionList -> Recipient.resolvedList(SignalDatabase.distributionLists.getMembers(recipient.distributionListId.get()))
|
||||||
else -> listOf(recipient)
|
else -> listOf(recipient)
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,8 +153,8 @@ class AddMessageDialogFragment : KeyboardEntryDialogFragment(R.layout.v2_media_a
|
||||||
annotations
|
annotations
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
val validRecipientIds: Set<String> = recipient.participants
|
val validRecipientIds: Set<String> = recipient.participantIds
|
||||||
.map { r -> MentionAnnotation.idToMentionAnnotationValue(r.id) }
|
.map { id -> MentionAnnotation.idToMentionAnnotationValue(id) }
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
annotations
|
annotations
|
||||||
|
|
|
@ -102,7 +102,7 @@ final class MessageRequestRepository {
|
||||||
}
|
}
|
||||||
} else if (recipient.isPushV1Group()) {
|
} else if (recipient.isPushV1Group()) {
|
||||||
if (RecipientUtil.isMessageRequestAccepted(context, threadId)) {
|
if (RecipientUtil.isMessageRequestAccepted(context, threadId)) {
|
||||||
if (recipient.getParticipants().size() > FeatureFlags.groupLimits().getHardLimit()) {
|
if (recipient.getParticipantIds().size() > FeatureFlags.groupLimits().getHardLimit()) {
|
||||||
return MessageRequestState.DEPRECATED_GROUP_V1_TOO_LARGE;
|
return MessageRequestState.DEPRECATED_GROUP_V1_TOO_LARGE;
|
||||||
} else {
|
} else {
|
||||||
return MessageRequestState.DEPRECATED_GROUP_V1;
|
return MessageRequestState.DEPRECATED_GROUP_V1;
|
||||||
|
|
|
@ -963,7 +963,7 @@ public final class MessageContentProcessor {
|
||||||
|
|
||||||
Recipient threadRecipient = targetThread.getRecipient().resolve();
|
Recipient threadRecipient = targetThread.getRecipient().resolve();
|
||||||
|
|
||||||
if (threadRecipient.isGroup() && !threadRecipient.getParticipants().contains(senderRecipient)) {
|
if (threadRecipient.isGroup() && !threadRecipient.getParticipantIds().contains(senderRecipient.getId())) {
|
||||||
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Reaction author is not in the group! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
|
warn(String.valueOf(content.getTimestamp()), "[handleReaction] Reaction author is not in the group! timestamp: " + reaction.getTargetSentTimestamp() + " author: " + targetAuthor.getId());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,18 +153,7 @@ public final class LiveRecipient {
|
||||||
}
|
}
|
||||||
|
|
||||||
Recipient updated = fetchAndCacheRecipientFromDisk(getId());
|
Recipient updated = fetchAndCacheRecipientFromDisk(getId());
|
||||||
List<Recipient> participants = Stream.of(updated.getParticipants())
|
|
||||||
.filter(Recipient::isResolving)
|
|
||||||
.map(Recipient::getId)
|
|
||||||
.map(this::fetchAndCacheRecipientFromDisk)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
for (Recipient participant : participants) {
|
|
||||||
participant.live().set(participant);
|
|
||||||
}
|
|
||||||
|
|
||||||
set(updated);
|
set(updated);
|
||||||
|
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,15 +178,6 @@ public final class LiveRecipient {
|
||||||
}
|
}
|
||||||
|
|
||||||
Recipient recipient = fetchAndCacheRecipientFromDisk(id);
|
Recipient recipient = fetchAndCacheRecipientFromDisk(id);
|
||||||
List<Recipient> participants = Stream.of(recipient.getParticipants())
|
|
||||||
.map(Recipient::getId)
|
|
||||||
.map(this::fetchAndCacheRecipientFromDisk)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
for (Recipient participant : participants) {
|
|
||||||
participant.live().set(participant);
|
|
||||||
}
|
|
||||||
|
|
||||||
set(recipient);
|
set(recipient);
|
||||||
refreshForceNotify.postValue(new Object());
|
refreshForceNotify.postValue(new Object());
|
||||||
}
|
}
|
||||||
|
@ -232,7 +212,7 @@ public final class LiveRecipient {
|
||||||
|
|
||||||
if (groupRecord.isPresent()) {
|
if (groupRecord.isPresent()) {
|
||||||
String title = groupRecord.get().getTitle();
|
String title = groupRecord.get().getTitle();
|
||||||
List<Recipient> members = Stream.of(groupRecord.get().getMembers()).filterNot(RecipientId::isUnknown).map(this::fetchAndCacheRecipientFromDisk).toList();
|
List<RecipientId> members = Stream.of(groupRecord.get().getMembers()).filterNot(RecipientId::isUnknown).toList();
|
||||||
Optional<Long> avatarId = Optional.empty();
|
Optional<Long> avatarId = Optional.empty();
|
||||||
|
|
||||||
if (groupRecord.get().hasAvatar()) {
|
if (groupRecord.get().hasAvatar()) {
|
||||||
|
@ -252,7 +232,7 @@ public final class LiveRecipient {
|
||||||
// TODO [stories] We'll have to see what the perf is like for very large distribution lists. We may not be able to support fetching all the members.
|
// TODO [stories] We'll have to see what the perf is like for very large distribution lists. We may not be able to support fetching all the members.
|
||||||
if (groupRecord != null) {
|
if (groupRecord != null) {
|
||||||
String title = groupRecord.isUnknown() ? null : groupRecord.getName();
|
String title = groupRecord.isUnknown() ? null : groupRecord.getName();
|
||||||
List<Recipient> members = Stream.of(groupRecord.getMembers()).filterNot(RecipientId::isUnknown).map(this::fetchAndCacheRecipientFromDisk).toList();
|
List<RecipientId> members = Stream.of(groupRecord.getMembers()).filterNot(RecipientId::isUnknown).toList();
|
||||||
|
|
||||||
return RecipientDetails.forDistributionList(title, members, record);
|
return RecipientDetails.forDistributionList(title, members, record);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
|
||||||
import static org.thoughtcrime.securesms.database.RecipientDatabase.InsightsBannerTier;
|
import static org.thoughtcrime.securesms.database.RecipientDatabase.InsightsBannerTier;
|
||||||
|
|
||||||
|
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||||
public class Recipient {
|
public class Recipient {
|
||||||
|
|
||||||
private static final String TAG = Log.tag(Recipient.class);
|
private static final String TAG = Log.tag(Recipient.class);
|
||||||
|
@ -91,7 +92,7 @@ public class Recipient {
|
||||||
private final String email;
|
private final String email;
|
||||||
private final GroupId groupId;
|
private final GroupId groupId;
|
||||||
private final DistributionListId distributionListId;
|
private final DistributionListId distributionListId;
|
||||||
private final List<Recipient> participants;
|
private final List<RecipientId> participantIds;
|
||||||
private final Optional<Long> groupAvatarId;
|
private final Optional<Long> groupAvatarId;
|
||||||
private final boolean isSelf;
|
private final boolean isSelf;
|
||||||
private final boolean blocked;
|
private final boolean blocked;
|
||||||
|
@ -368,7 +369,7 @@ public class Recipient {
|
||||||
this.email = null;
|
this.email = null;
|
||||||
this.groupId = null;
|
this.groupId = null;
|
||||||
this.distributionListId = null;
|
this.distributionListId = null;
|
||||||
this.participants = Collections.emptyList();
|
this.participantIds = Collections.emptyList();
|
||||||
this.groupAvatarId = Optional.empty();
|
this.groupAvatarId = Optional.empty();
|
||||||
this.isSelf = false;
|
this.isSelf = false;
|
||||||
this.blocked = false;
|
this.blocked = false;
|
||||||
|
@ -426,7 +427,7 @@ public class Recipient {
|
||||||
this.email = details.email;
|
this.email = details.email;
|
||||||
this.groupId = details.groupId;
|
this.groupId = details.groupId;
|
||||||
this.distributionListId = details.distributionListId;
|
this.distributionListId = details.distributionListId;
|
||||||
this.participants = details.participants;
|
this.participantIds = details.participantIds;
|
||||||
this.groupAvatarId = details.groupAvatarId;
|
this.groupAvatarId = details.groupAvatarId;
|
||||||
this.isSelf = details.isSelf;
|
this.isSelf = details.isSelf;
|
||||||
this.blocked = details.blocked;
|
this.blocked = details.blocked;
|
||||||
|
@ -488,9 +489,11 @@ public class Recipient {
|
||||||
|
|
||||||
public @Nullable String getGroupName(@NonNull Context context) {
|
public @Nullable String getGroupName(@NonNull Context context) {
|
||||||
if (groupId != null && Util.isEmpty(this.groupName)) {
|
if (groupId != null && Util.isEmpty(this.groupName)) {
|
||||||
List<Recipient> others = participants.stream()
|
RecipientId selfId = Recipient.self().getId();
|
||||||
.filter(r -> !r.isSelf())
|
List<Recipient> others = participantIds.stream()
|
||||||
|
.filter(id -> !id.equals(selfId))
|
||||||
.limit(MAX_MEMBER_NAMES)
|
.limit(MAX_MEMBER_NAMES)
|
||||||
|
.map(Recipient::resolved)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
Map<String, Integer> shortNameCounts = new HashMap<>();
|
Map<String, Integer> shortNameCounts = new HashMap<>();
|
||||||
|
@ -515,7 +518,7 @@ public class Recipient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (participants.stream().anyMatch(Recipient::isSelf)) {
|
if (participantIds.stream().anyMatch(id -> id.equals(selfId))) {
|
||||||
names.add(context.getString(R.string.Recipient_you));
|
names.add(context.getString(R.string.Recipient_you));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,11 +864,12 @@ public class Recipient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isActiveGroup() {
|
public boolean isActiveGroup() {
|
||||||
return Stream.of(getParticipants()).anyMatch(Recipient::isSelf);
|
RecipientId selfId = Recipient.self().getId();
|
||||||
|
return Stream.of(getParticipantIds()).anyMatch(p -> p.equals(selfId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull List<Recipient> getParticipants() {
|
public @NonNull List<RecipientId> getParticipantIds() {
|
||||||
return new ArrayList<>(participants);
|
return new ArrayList<>(participantIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NonNull Drawable getFallbackContactPhotoDrawable(Context context, boolean inverted) {
|
public @NonNull Drawable getFallbackContactPhotoDrawable(Context context, boolean inverted) {
|
||||||
|
@ -1277,7 +1281,7 @@ public class Recipient {
|
||||||
Objects.equals(e164, other.e164) &&
|
Objects.equals(e164, other.e164) &&
|
||||||
Objects.equals(email, other.email) &&
|
Objects.equals(email, other.email) &&
|
||||||
Objects.equals(groupId, other.groupId) &&
|
Objects.equals(groupId, other.groupId) &&
|
||||||
allContentsAreTheSame(participants, other.participants) &&
|
Objects.equals(participantIds, other.participantIds) &&
|
||||||
Objects.equals(groupAvatarId, other.groupAvatarId) &&
|
Objects.equals(groupAvatarId, other.groupAvatarId) &&
|
||||||
messageVibrate == other.messageVibrate &&
|
messageVibrate == other.messageVibrate &&
|
||||||
callVibrate == other.callVibrate &&
|
callVibrate == other.callVibrate &&
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class RecipientDetails {
|
||||||
final VibrateState callVibrateState;
|
final VibrateState callVibrateState;
|
||||||
final boolean blocked;
|
final boolean blocked;
|
||||||
final int expireMessages;
|
final int expireMessages;
|
||||||
final List<Recipient> participants;
|
final List<RecipientId> participantIds;
|
||||||
final ProfileName profileName;
|
final ProfileName profileName;
|
||||||
final Optional<Integer> defaultSubscriptionId;
|
final Optional<Integer> defaultSubscriptionId;
|
||||||
final RegisteredState registered;
|
final RegisteredState registered;
|
||||||
|
@ -96,7 +96,7 @@ public class RecipientDetails {
|
||||||
boolean isSelf,
|
boolean isSelf,
|
||||||
@NonNull RegisteredState registeredState,
|
@NonNull RegisteredState registeredState,
|
||||||
@NonNull RecipientRecord record,
|
@NonNull RecipientRecord record,
|
||||||
@Nullable List<Recipient> participants,
|
@Nullable List<RecipientId> participantIds,
|
||||||
boolean isReleaseChannel)
|
boolean isReleaseChannel)
|
||||||
{
|
{
|
||||||
this.groupAvatarId = groupAvatarId;
|
this.groupAvatarId = groupAvatarId;
|
||||||
|
@ -117,7 +117,7 @@ public class RecipientDetails {
|
||||||
this.callVibrateState = record.getCallVibrateState();
|
this.callVibrateState = record.getCallVibrateState();
|
||||||
this.blocked = record.isBlocked();
|
this.blocked = record.isBlocked();
|
||||||
this.expireMessages = record.getExpireMessages();
|
this.expireMessages = record.getExpireMessages();
|
||||||
this.participants = participants == null ? new LinkedList<>() : participants;
|
this.participantIds = participantIds == null ? new LinkedList<>() : participantIds;
|
||||||
this.profileName = record.getProfileName();
|
this.profileName = record.getProfileName();
|
||||||
this.defaultSubscriptionId = record.getDefaultSubscriptionId();
|
this.defaultSubscriptionId = record.getDefaultSubscriptionId();
|
||||||
this.registered = registeredState;
|
this.registered = registeredState;
|
||||||
|
@ -174,7 +174,7 @@ public class RecipientDetails {
|
||||||
this.callVibrateState = VibrateState.DEFAULT;
|
this.callVibrateState = VibrateState.DEFAULT;
|
||||||
this.blocked = false;
|
this.blocked = false;
|
||||||
this.expireMessages = 0;
|
this.expireMessages = 0;
|
||||||
this.participants = new LinkedList<>();
|
this.participantIds = new LinkedList<>();
|
||||||
this.profileName = ProfileName.EMPTY;
|
this.profileName = ProfileName.EMPTY;
|
||||||
this.insightsBannerTier = InsightsBannerTier.TIER_TWO;
|
this.insightsBannerTier = InsightsBannerTier.TIER_TWO;
|
||||||
this.defaultSubscriptionId = Optional.empty();
|
this.defaultSubscriptionId = Optional.empty();
|
||||||
|
@ -231,7 +231,7 @@ public class RecipientDetails {
|
||||||
return new RecipientDetails(null, settings.getSystemDisplayName(), Optional.empty(), systemContact, isSelf, registeredState, settings, null, isReleaseChannel);
|
return new RecipientDetails(null, settings.getSystemDisplayName(), Optional.empty(), systemContact, isSelf, registeredState, settings, null, isReleaseChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NonNull RecipientDetails forDistributionList(String title, @Nullable List<Recipient> members, @NonNull RecipientRecord record) {
|
public static @NonNull RecipientDetails forDistributionList(String title, @Nullable List<RecipientId> members, @NonNull RecipientRecord record) {
|
||||||
return new RecipientDetails(title, null, Optional.empty(), false, false, record.getRegistered(), record, members, false);
|
return new RecipientDetails(title, null, Optional.empty(), false, false, record.getRegistered(), record, members, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,7 @@ class SafetyNumberBottomSheetRepository {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getGroupMemberships(recipient: Recipient, groups: List<Recipient>): List<Recipient> {
|
private fun getGroupMemberships(recipient: Recipient, groups: List<Recipient>): List<Recipient> {
|
||||||
return groups.filter { it.participants.contains(recipient) }
|
return groups.filter { it.participantIds.contains(recipient.id) }
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ResolvedIdentity(val recipient: Recipient, val identityRecord: Optional<IdentityRecord>)
|
data class ResolvedIdentity(val recipient: Recipient, val identityRecord: Optional<IdentityRecord>)
|
||||||
|
|
|
@ -17,7 +17,6 @@ import org.signal.core.util.ThreadUtil;
|
||||||
import org.signal.core.util.concurrent.SimpleTask;
|
import org.signal.core.util.concurrent.SimpleTask;
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
|
|
||||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey;
|
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey;
|
||||||
import org.thoughtcrime.securesms.conversation.MessageSendType;
|
import org.thoughtcrime.securesms.conversation.MessageSendType;
|
||||||
import org.thoughtcrime.securesms.conversation.colors.ChatColors;
|
import org.thoughtcrime.securesms.conversation.colors.ChatColors;
|
||||||
|
@ -36,7 +35,6 @@ import org.thoughtcrime.securesms.mediasend.v2.text.TextStoryBackgroundColors;
|
||||||
import org.thoughtcrime.securesms.mms.ImageSlide;
|
import org.thoughtcrime.securesms.mms.ImageSlide;
|
||||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||||
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage;
|
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage;
|
||||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
|
||||||
import org.thoughtcrime.securesms.mms.SentMediaQuality;
|
import org.thoughtcrime.securesms.mms.SentMediaQuality;
|
||||||
import org.thoughtcrime.securesms.mms.Slide;
|
import org.thoughtcrime.securesms.mms.Slide;
|
||||||
import org.thoughtcrime.securesms.mms.SlideDeck;
|
import org.thoughtcrime.securesms.mms.SlideDeck;
|
||||||
|
@ -57,6 +55,7 @@ import org.thoughtcrime.securesms.util.Util;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -480,10 +479,7 @@ public final class MultiShareSender {
|
||||||
if (mentions.isEmpty() || !recipient.isPushV2Group() || !recipient.isActiveGroup()) {
|
if (mentions.isEmpty() || !recipient.isPushV2Group() || !recipient.isActiveGroup()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
} else {
|
} else {
|
||||||
Set<RecipientId> validRecipientIds = recipient.getParticipants()
|
Set<RecipientId> validRecipientIds = new HashSet<>(recipient.getParticipantIds());
|
||||||
.stream()
|
|
||||||
.map(Recipient::getId)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
return mentions.stream()
|
return mentions.stream()
|
||||||
.filter(mention -> validRecipientIds.contains(mention.getRecipientId()))
|
.filter(mention -> validRecipientIds.contains(mention.getRecipientId()))
|
||||||
|
|
|
@ -436,8 +436,8 @@ class StoryGroupReplyFragment :
|
||||||
annotations
|
annotations
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
val validRecipientIds: Set<String> = recipient.participants
|
val validRecipientIds: Set<String> = recipient.participantIds
|
||||||
.map { r -> MentionAnnotation.idToMentionAnnotationValue(r.id) }
|
.map { id -> MentionAnnotation.idToMentionAnnotationValue(id) }
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
||||||
annotations
|
annotations
|
||||||
|
|
|
@ -30,7 +30,7 @@ object RecipientDatabaseTestUtils {
|
||||||
groupAvatarId: Optional<Long> = Optional.empty(),
|
groupAvatarId: Optional<Long> = Optional.empty(),
|
||||||
systemContact: Boolean = false,
|
systemContact: Boolean = false,
|
||||||
isSelf: Boolean = false,
|
isSelf: Boolean = false,
|
||||||
participants: List<Recipient> = listOf(),
|
participants: List<RecipientId> = listOf(),
|
||||||
recipientId: RecipientId = RecipientId.from(Random.nextLong()),
|
recipientId: RecipientId = RecipientId.from(Random.nextLong()),
|
||||||
serviceId: ServiceId? = ServiceId.from(UUID.randomUUID()),
|
serviceId: ServiceId? = ServiceId.from(UUID.randomUUID()),
|
||||||
username: String? = null,
|
username: String? = null,
|
||||||
|
|
Ładowanie…
Reference in New Issue