Add support for syncing default reactions.

fork-5.53.8
Greyson Parrelli 2021-09-22 10:42:13 -04:00 zatwierdzone przez Alex Hart
rodzic 2281e83607
commit 7267d77dcb
8 zmienionych plików z 77 dodań i 6 usunięć

Wyświetl plik

@ -8,6 +8,7 @@ import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.components.emoji.EmojiUtil;
import org.thoughtcrime.securesms.util.Util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -68,16 +69,39 @@ public class EmojiValues extends SignalStoreValues {
return getString(PREFIX + canonical, emoji);
}
/**
* Returns a list usable emoji that the user has selected as their defaults. If any stored reactions are unreadable, it will provide a default.
* For raw access to the unfiltered list of reactions, see {@link #getRawReactions()}.
*/
public @NonNull List<String> getReactions() {
List<String> raw = getRawReactions();
List<String> out = new ArrayList<>(DEFAULT_REACTIONS_LIST.size());
for (int i = 0; i < DEFAULT_REACTIONS_LIST.size(); i++) {
if (raw.size() > i && EmojiUtil.isEmoji(raw.get(i))) {
out.add(raw.get(i));
} else {
out.add(DEFAULT_REACTIONS_LIST.get(i));
}
}
return out;
}
/**
* A raw list of the default reactions the user has selected. It will be empty if there hasn't been any custom ones set. It may contain unrenderable emoji.
* This is primarily here for syncing to storage service. You probably want {@link #getReactions()} for everything else.
*/
public @NonNull List<String> getRawReactions() {
String list = getString(REACTIONS_LIST, "");
if (TextUtils.isEmpty(list)) {
return DEFAULT_REACTIONS_LIST;
return Collections.emptyList();
} else {
return Arrays.asList(list.split(","));
}
}
public void setReactions(List<String> reactions) {
public void setReactions(@NonNull List<String> reactions) {
putString(REACTIONS_LIST, Util.join(reactions, ","));
}

Wyświetl plik

@ -88,9 +88,10 @@ public class ApplicationMigrations {
static final int CHANGE_NUMBER_SYNC = 44;
static final int CHANGE_NUMBER_CAPABILITY = 45;
static final int CHANGE_NUMBER_CAPABILITY_2 = 46;
static final int DEFAULT_REACTIONS_SYNC = 47;
}
public static final int CURRENT_VERSION = 46;
public static final int CURRENT_VERSION = 47;
/**
* This *must* be called after the {@link JobManager} has been instantiated, but *before* the call
@ -384,6 +385,10 @@ public class ApplicationMigrations {
jobs.put(Version.CHANGE_NUMBER_CAPABILITY_2, new AttributesMigrationJob());
}
if (lastSeenVersion < Version.DEFAULT_REACTIONS_SYNC) {
jobs.put(Version.DEFAULT_REACTIONS_SYNC, new StorageServiceMigrationJob());
}
return jobs;
}

Wyświetl plik

@ -3,12 +3,14 @@ package org.thoughtcrime.securesms.migrations;
import androidx.annotation.NonNull;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobs.MultiDeviceKeysUpdateJob;
import org.thoughtcrime.securesms.jobs.StorageSyncJob;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
/**
@ -40,6 +42,13 @@ public class StorageServiceMigrationJob extends MigrationJob {
@Override
public void performMigration() {
if (TextSecurePreferences.getLocalUuid(context) == null) {
Log.w(TAG, "Self not yet available.");
return;
}
DatabaseFactory.getRecipientDatabase(context).markNeedsSync(Recipient.self().getId());
JobManager jobManager = ApplicationDependencies.getJobManager();
if (TextSecurePreferences.isMultiDevice(context)) {

Wyświetl plik

@ -2,8 +2,13 @@ package org.thoughtcrime.securesms.reactions.edit
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import org.signal.core.util.concurrent.SignalExecutors
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.keyvalue.EmojiValues
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.storage.StorageSyncHelper
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil
import org.thoughtcrime.securesms.util.livedata.Store
@ -37,6 +42,11 @@ class EditReactionsViewModel : ViewModel() {
fun save() {
emojiValues.reactions = store.state.reactions
SignalExecutors.BOUNDED.execute {
DatabaseFactory.getRecipientDatabase(ApplicationDependencies.getApplication()).markNeedsSync(Recipient.self().id)
StorageSyncHelper.scheduleSyncForDataChange()
}
}
companion object {

Wyświetl plik

@ -98,8 +98,9 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
int universalExpireTimer = remote.getUniversalExpireTimer();
boolean primarySendsSms = local.isPrimarySendsSms();
String e164 = local.getE164();
boolean matchesRemote = doParamsMatch(remote, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164);
boolean matchesLocal = doParamsMatch(local, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164);
List<String> defaultReactions = remote.getDefaultReactions().size() > 0 ? remote.getDefaultReactions() : local.getDefaultReactions();
boolean matchesRemote = doParamsMatch(remote, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions);
boolean matchesLocal = doParamsMatch(local, unknownFields, givenName, familyName, avatarUrlPath, profileKey, noteToSelfArchived, noteToSelfForcedUnread, readReceipts, typingIndicators, sealedSenderIndicators, linkPreviews, phoneNumberSharingMode, unlisted, pinnedConversations, preferContactAvatars, payments, universalExpireTimer, primarySendsSms, e164, defaultReactions);
if (matchesRemote) {
return remote;
@ -127,6 +128,7 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
.setUniversalExpireTimer(universalExpireTimer)
.setPrimarySendsSms(primarySendsSms)
.setE164(e164)
.setDefaultReactions(defaultReactions)
.build();
}
}
@ -165,7 +167,8 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
SignalAccountRecord.Payments payments,
int universalExpireTimer,
boolean primarySendsSms,
String e164)
String e164,
@NonNull List <String> defaultReactions)
{
return Arrays.equals(contact.serializeUnknownFields(), unknownFields) &&
Objects.equals(contact.getGivenName().or(""), givenName) &&
@ -173,6 +176,7 @@ public class AccountRecordProcessor extends DefaultStorageRecordProcessor<Signal
Objects.equals(contact.getAvatarUrlPath().or(""), avatarUrlPath) &&
Objects.equals(contact.getPayments(), payments) &&
Objects.equals(contact.getE164(), e164) &&
Objects.equals(contact.getDefaultReactions(), defaultReactions) &&
Arrays.equals(contact.getProfileKey().orNull(), profileKey) &&
contact.isNoteToSelfArchived() == noteToSelfArchived &&
contact.isNoteToSelfForcedUnread() == noteToSelfForcedUnread &&

Wyświetl plik

@ -130,6 +130,7 @@ public final class StorageSyncHelper {
.setPrimarySendsSms(Util.isDefaultSmsProvider(context))
.setUniversalExpireTimer(SignalStore.settings().getUniversalExpireTimer())
.setE164(TextSecurePreferences.getLocalNumber(context))
.setDefaultReactions(SignalStore.emojiValues().getReactions())
.build();
return SignalStorageRecord.forAccount(account);
@ -152,6 +153,7 @@ public final class StorageSyncHelper {
SignalStore.settings().setPreferSystemContactPhotos(update.getNew().isPreferContactAvatars());
SignalStore.paymentsValues().setEnabledAndEntropy(update.getNew().getPayments().isEnabled(), Entropy.fromBytes(update.getNew().getPayments().getEntropy().orNull()));
SignalStore.settings().setUniversalExpireTimer(update.getNew().getUniversalExpireTimer());
SignalStore.emojiValues().setReactions(update.getNew().getDefaultReactions());
if (fetchProfile && update.getNew().getAvatarUrlPath().isPresent()) {
ApplicationDependencies.getJobManager().add(new RetrieveProfileAvatarJob(self, update.getNew().getAvatarUrlPath().get()));

Wyświetl plik

@ -32,6 +32,7 @@ public final class SignalAccountRecord implements SignalRecord {
private final Optional<byte[]> profileKey;
private final List<PinnedConversation> pinnedConversations;
private final Payments payments;
private final List<String> defaultReactions;
public SignalAccountRecord(StorageId id, AccountRecord proto) {
this.id = id;
@ -44,6 +45,7 @@ public final class SignalAccountRecord implements SignalRecord {
this.avatarUrlPath = OptionalUtil.absentIfEmpty(proto.getAvatarUrlPath());
this.pinnedConversations = new ArrayList<>(proto.getPinnedConversationsCount());
this.payments = new Payments(proto.getPayments().getEnabled(), OptionalUtil.absentIfEmpty(proto.getPayments().getEntropy()));
this.defaultReactions = new ArrayList<>(proto.getPreferredReactionEmojiList());
for (AccountRecord.PinnedConversation conversation : proto.getPinnedConversationsList()) {
pinnedConversations.add(PinnedConversation.fromRemote(conversation));
@ -142,6 +144,10 @@ public final class SignalAccountRecord implements SignalRecord {
diff.add("E164");
}
if (!Objects.equals(this.getDefaultReactions(), that.getDefaultReactions())) {
diff.add("DefaultReactions");
}
if (!Objects.equals(this.hasUnknownFields(), that.hasUnknownFields())) {
diff.add("UnknownFields");
}
@ -232,6 +238,10 @@ public final class SignalAccountRecord implements SignalRecord {
return proto.getE164();
}
public List<String> getDefaultReactions() {
return defaultReactions;
}
AccountRecord toProto() {
return proto;
}
@ -501,6 +511,12 @@ public final class SignalAccountRecord implements SignalRecord {
return this;
}
public Builder setDefaultReactions(List<String> defaultReactions) {
builder.clearPreferredReactionEmoji();
builder.addAllPreferredReactionEmoji(defaultReactions);
return this;
}
public SignalAccountRecord build() {
AccountRecord proto = builder.build();

Wyświetl plik

@ -147,4 +147,5 @@ message AccountRecord {
uint32 universalExpireTimer = 17;
bool primarySendsSms = 18;
string e164 = 19;
repeated string preferredReactionEmoji = 20;
}