kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add support for syncing default reactions.
rodzic
2281e83607
commit
7267d77dcb
|
@ -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, ","));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -147,4 +147,5 @@ message AccountRecord {
|
|||
uint32 universalExpireTimer = 17;
|
||||
bool primarySendsSms = 18;
|
||||
string e164 = 19;
|
||||
repeated string preferredReactionEmoji = 20;
|
||||
}
|
Ładowanie…
Reference in New Issue