mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-10-09 02:54:14 +00:00
share twonly score with friends
This commit is contained in:
parent
4337db58be
commit
e76eead183
32 changed files with 918 additions and 164 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -60,4 +60,4 @@ fastlane/repo/status/running.json
|
|||
# Widget Preview related
|
||||
.widget_preview/
|
||||
ios/build/
|
||||
APKS/*.apk
|
||||
offline/
|
||||
|
|
@ -8082,6 +8082,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
);
|
||||
}
|
||||
|
||||
@protected
|
||||
TwonlyScoreVisibility dco_decode_twonly_score_visibility(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
return TwonlyScoreVisibility.values[raw as int];
|
||||
}
|
||||
|
||||
@protected
|
||||
int dco_decode_u_16(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
|
|
@ -8122,8 +8128,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
UserConfig dco_decode_user_config(dynamic raw) {
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
final arr = raw as List<dynamic>;
|
||||
if (arr.length != 64)
|
||||
throw Exception('unexpected arr length: expect 64 but see ${arr.length}');
|
||||
if (arr.length != 65)
|
||||
throw Exception('unexpected arr length: expect 65 but see ${arr.length}');
|
||||
return UserConfig(
|
||||
userId: dco_decode_i_64(arr[0]),
|
||||
username: dco_decode_String(arr[1]),
|
||||
|
|
@ -8169,31 +8175,32 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
allowErrorTrackingViaSentry: dco_decode_bool(arr[37]),
|
||||
screenLockEnabled: dco_decode_bool(arr[38]),
|
||||
isCloudBackupEnabled: dco_decode_bool(arr[39]),
|
||||
isUserDiscoveryEnabled: dco_decode_bool(arr[40]),
|
||||
requiredSendImages: dco_decode_i_64(arr[41]),
|
||||
userDiscoveryThreshold: dco_decode_u_8(arr[42]),
|
||||
userDiscoveryRequiresManualApproval: dco_decode_bool(arr[43]),
|
||||
userDiscoverySharePromotion: dco_decode_bool(arr[44]),
|
||||
userDiscoveryInitializationError: dco_decode_bool(arr[45]),
|
||||
askForFriendPromotions: dco_decode_bool(arr[46]),
|
||||
currentPreKeyIndexStart: dco_decode_i_64(arr[47]),
|
||||
currentSignedPreKeyIndexStart: dco_decode_i_64(arr[48]),
|
||||
lastChangeLogHash: dco_decode_opt_list_prim_u_8_strict(arr[49]),
|
||||
hideChangeLog: dco_decode_bool(arr[50]),
|
||||
hideMemoriesBackupPromo: dco_decode_bool(arr[51]),
|
||||
hideWidgetShareExplainer: dco_decode_bool(arr[52]),
|
||||
updateFcmToken: dco_decode_bool(arr[53]),
|
||||
canUseLoginTokenForAuth: dco_decode_bool(arr[54]),
|
||||
twonlySafeBackup: dco_decode_opt_box_autoadd_twonly_safe_backup(arr[55]),
|
||||
isBackupEnabled: dco_decode_bool(arr[56]),
|
||||
twonlyScoreVisibility: dco_decode_twonly_score_visibility(arr[40]),
|
||||
isUserDiscoveryEnabled: dco_decode_bool(arr[41]),
|
||||
requiredSendImages: dco_decode_i_64(arr[42]),
|
||||
userDiscoveryThreshold: dco_decode_u_8(arr[43]),
|
||||
userDiscoveryRequiresManualApproval: dco_decode_bool(arr[44]),
|
||||
userDiscoverySharePromotion: dco_decode_bool(arr[45]),
|
||||
userDiscoveryInitializationError: dco_decode_bool(arr[46]),
|
||||
askForFriendPromotions: dco_decode_bool(arr[47]),
|
||||
currentPreKeyIndexStart: dco_decode_i_64(arr[48]),
|
||||
currentSignedPreKeyIndexStart: dco_decode_i_64(arr[49]),
|
||||
lastChangeLogHash: dco_decode_opt_list_prim_u_8_strict(arr[50]),
|
||||
hideChangeLog: dco_decode_bool(arr[51]),
|
||||
hideMemoriesBackupPromo: dco_decode_bool(arr[52]),
|
||||
hideWidgetShareExplainer: dco_decode_bool(arr[53]),
|
||||
updateFcmToken: dco_decode_bool(arr[54]),
|
||||
canUseLoginTokenForAuth: dco_decode_bool(arr[55]),
|
||||
twonlySafeBackup: dco_decode_opt_box_autoadd_twonly_safe_backup(arr[56]),
|
||||
isBackupEnabled: dco_decode_bool(arr[57]),
|
||||
passwordLessRecovery:
|
||||
dco_decode_opt_box_autoadd_passwordless_recovery_config(arr[57]),
|
||||
fcmToken: dco_decode_opt_String(arr[58]),
|
||||
lastFcmWakeupAt: dco_decode_opt_box_autoadd_i_64(arr[59]),
|
||||
lastServerMessageAt: dco_decode_opt_box_autoadd_i_64(arr[60]),
|
||||
currentSetupPage: dco_decode_opt_String(arr[61]),
|
||||
skipSetupPages: dco_decode_bool(arr[62]),
|
||||
hasZoomed: dco_decode_bool(arr[63]),
|
||||
dco_decode_opt_box_autoadd_passwordless_recovery_config(arr[58]),
|
||||
fcmToken: dco_decode_opt_String(arr[59]),
|
||||
lastFcmWakeupAt: dco_decode_opt_box_autoadd_i_64(arr[60]),
|
||||
lastServerMessageAt: dco_decode_opt_box_autoadd_i_64(arr[61]),
|
||||
currentSetupPage: dco_decode_opt_String(arr[62]),
|
||||
skipSetupPages: dco_decode_bool(arr[63]),
|
||||
hasZoomed: dco_decode_bool(arr[64]),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -9449,6 +9456,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
);
|
||||
}
|
||||
|
||||
@protected
|
||||
TwonlyScoreVisibility sse_decode_twonly_score_visibility(
|
||||
SseDeserializer deserializer,
|
||||
) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
var inner = sse_decode_i_32(deserializer);
|
||||
return TwonlyScoreVisibility.values[inner];
|
||||
}
|
||||
|
||||
@protected
|
||||
int sse_decode_u_16(SseDeserializer deserializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
|
@ -9534,6 +9550,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
var var_allowErrorTrackingViaSentry = sse_decode_bool(deserializer);
|
||||
var var_screenLockEnabled = sse_decode_bool(deserializer);
|
||||
var var_isCloudBackupEnabled = sse_decode_bool(deserializer);
|
||||
var var_twonlyScoreVisibility = sse_decode_twonly_score_visibility(
|
||||
deserializer,
|
||||
);
|
||||
var var_isUserDiscoveryEnabled = sse_decode_bool(deserializer);
|
||||
var var_requiredSendImages = sse_decode_i_64(deserializer);
|
||||
var var_userDiscoveryThreshold = sse_decode_u_8(deserializer);
|
||||
|
|
@ -9606,6 +9625,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
allowErrorTrackingViaSentry: var_allowErrorTrackingViaSentry,
|
||||
screenLockEnabled: var_screenLockEnabled,
|
||||
isCloudBackupEnabled: var_isCloudBackupEnabled,
|
||||
twonlyScoreVisibility: var_twonlyScoreVisibility,
|
||||
isUserDiscoveryEnabled: var_isUserDiscoveryEnabled,
|
||||
requiredSendImages: var_requiredSendImages,
|
||||
userDiscoveryThreshold: var_userDiscoveryThreshold,
|
||||
|
|
@ -10856,6 +10876,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
sse_encode_list_prim_u_8_strict(self.encryptionKey, serializer);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_twonly_score_visibility(
|
||||
TwonlyScoreVisibility self,
|
||||
SseSerializer serializer,
|
||||
) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
sse_encode_i_32(self.index, serializer);
|
||||
}
|
||||
|
||||
@protected
|
||||
void sse_encode_u_16(int self, SseSerializer serializer) {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
|
|
@ -10943,6 +10972,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||
sse_encode_bool(self.allowErrorTrackingViaSentry, serializer);
|
||||
sse_encode_bool(self.screenLockEnabled, serializer);
|
||||
sse_encode_bool(self.isCloudBackupEnabled, serializer);
|
||||
sse_encode_twonly_score_visibility(self.twonlyScoreVisibility, serializer);
|
||||
sse_encode_bool(self.isUserDiscoveryEnabled, serializer);
|
||||
sse_encode_i_64(self.requiredSendImages, serializer);
|
||||
sse_encode_u_8(self.userDiscoveryThreshold, serializer);
|
||||
|
|
|
|||
|
|
@ -396,6 +396,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
@protected
|
||||
TwonlySafeBackup dco_decode_twonly_safe_backup(dynamic raw);
|
||||
|
||||
@protected
|
||||
TwonlyScoreVisibility dco_decode_twonly_score_visibility(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_u_16(dynamic raw);
|
||||
|
||||
|
|
@ -863,6 +866,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
@protected
|
||||
TwonlySafeBackup sse_decode_twonly_safe_backup(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
TwonlyScoreVisibility sse_decode_twonly_score_visibility(
|
||||
SseDeserializer deserializer,
|
||||
);
|
||||
|
||||
@protected
|
||||
int sse_decode_u_16(SseDeserializer deserializer);
|
||||
|
||||
|
|
@ -1454,6 +1462,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
SseSerializer serializer,
|
||||
);
|
||||
|
||||
@protected
|
||||
void sse_encode_twonly_score_visibility(
|
||||
TwonlyScoreVisibility self,
|
||||
SseSerializer serializer,
|
||||
);
|
||||
|
||||
@protected
|
||||
void sse_encode_u_16(int self, SseSerializer serializer);
|
||||
|
||||
|
|
|
|||
|
|
@ -398,6 +398,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
@protected
|
||||
TwonlySafeBackup dco_decode_twonly_safe_backup(dynamic raw);
|
||||
|
||||
@protected
|
||||
TwonlyScoreVisibility dco_decode_twonly_score_visibility(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_u_16(dynamic raw);
|
||||
|
||||
|
|
@ -865,6 +868,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
@protected
|
||||
TwonlySafeBackup sse_decode_twonly_safe_backup(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
TwonlyScoreVisibility sse_decode_twonly_score_visibility(
|
||||
SseDeserializer deserializer,
|
||||
);
|
||||
|
||||
@protected
|
||||
int sse_decode_u_16(SseDeserializer deserializer);
|
||||
|
||||
|
|
@ -1456,6 +1464,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||
SseSerializer serializer,
|
||||
);
|
||||
|
||||
@protected
|
||||
void sse_encode_twonly_score_visibility(
|
||||
TwonlyScoreVisibility self,
|
||||
SseSerializer serializer,
|
||||
);
|
||||
|
||||
@protected
|
||||
void sse_encode_u_16(int self, SseSerializer serializer);
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,12 @@ class TwonlySafeBackup {
|
|||
encryptionKey == other.encryptionKey;
|
||||
}
|
||||
|
||||
enum TwonlyScoreVisibility {
|
||||
nobody,
|
||||
onlyContacts,
|
||||
everyone,
|
||||
}
|
||||
|
||||
class UserConfig {
|
||||
PlatformInt64 userId;
|
||||
String username;
|
||||
|
|
@ -155,6 +161,9 @@ class UserConfig {
|
|||
bool allowErrorTrackingViaSentry;
|
||||
bool screenLockEnabled;
|
||||
bool isCloudBackupEnabled;
|
||||
|
||||
/// Controls which recipients receive the current twonly Score in sender metadata.
|
||||
TwonlyScoreVisibility twonlyScoreVisibility;
|
||||
bool isUserDiscoveryEnabled;
|
||||
PlatformInt64 requiredSendImages;
|
||||
int userDiscoveryThreshold;
|
||||
|
|
@ -229,6 +238,7 @@ class UserConfig {
|
|||
required this.allowErrorTrackingViaSentry,
|
||||
required this.screenLockEnabled,
|
||||
required this.isCloudBackupEnabled,
|
||||
required this.twonlyScoreVisibility,
|
||||
required this.isUserDiscoveryEnabled,
|
||||
required this.requiredSendImages,
|
||||
required this.userDiscoveryThreshold,
|
||||
|
|
@ -297,6 +307,7 @@ class UserConfig {
|
|||
allowErrorTrackingViaSentry.hashCode ^
|
||||
screenLockEnabled.hashCode ^
|
||||
isCloudBackupEnabled.hashCode ^
|
||||
twonlyScoreVisibility.hashCode ^
|
||||
isUserDiscoveryEnabled.hashCode ^
|
||||
requiredSendImages.hashCode ^
|
||||
userDiscoveryThreshold.hashCode ^
|
||||
|
|
@ -371,6 +382,7 @@ class UserConfig {
|
|||
allowErrorTrackingViaSentry == other.allowErrorTrackingViaSentry &&
|
||||
screenLockEnabled == other.screenLockEnabled &&
|
||||
isCloudBackupEnabled == other.isCloudBackupEnabled &&
|
||||
twonlyScoreVisibility == other.twonlyScoreVisibility &&
|
||||
isUserDiscoveryEnabled == other.isUserDiscoveryEnabled &&
|
||||
requiredSendImages == other.requiredSendImages &&
|
||||
userDiscoveryThreshold == other.userDiscoveryThreshold &&
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ class Routes {
|
|||
'/settings/privacy/block_users';
|
||||
static const String settingsPrivacyUserDiscovery =
|
||||
'/settings/privacy/user_discovery';
|
||||
static const String settingsPrivacyPublicProfile =
|
||||
'/settings/privacy/public_profile';
|
||||
static const String settingsNotification = '/settings/notification';
|
||||
static const String settingsStorage = '/settings/storage_data';
|
||||
static const String settingsStorageManage = '/settings/storage_data/manage';
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ class Contacts extends Table {
|
|||
BoolColumn get widgetSharingGranted =>
|
||||
boolean().withDefault(const Constant(false))();
|
||||
|
||||
IntColumn get twonlyScore => integer().nullable()();
|
||||
|
||||
IntColumn get mediaSendCounter => integer().withDefault(const Constant(0))();
|
||||
IntColumn get mediaReceivedCounter =>
|
||||
integer().withDefault(const Constant(0))();
|
||||
|
|
|
|||
|
|
@ -337,6 +337,17 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
),
|
||||
defaultValue: const Constant(false),
|
||||
);
|
||||
static const VerificationMeta _twonlyScoreMeta = const VerificationMeta(
|
||||
'twonlyScore',
|
||||
);
|
||||
@override
|
||||
late final GeneratedColumn<int> twonlyScore = GeneratedColumn<int>(
|
||||
'twonly_score',
|
||||
aliasedName,
|
||||
true,
|
||||
type: DriftSqlType.int,
|
||||
requiredDuringInsert: false,
|
||||
);
|
||||
static const VerificationMeta _mediaSendCounterMeta = const VerificationMeta(
|
||||
'mediaSendCounter',
|
||||
);
|
||||
|
|
@ -388,6 +399,7 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
askForFriendPromotions,
|
||||
widgetSharingAllowed,
|
||||
widgetSharingGranted,
|
||||
twonlyScore,
|
||||
mediaSendCounter,
|
||||
mediaReceivedCounter,
|
||||
];
|
||||
|
|
@ -606,6 +618,15 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('twonly_score')) {
|
||||
context.handle(
|
||||
_twonlyScoreMeta,
|
||||
twonlyScore.isAcceptableOrUnknown(
|
||||
data['twonly_score']!,
|
||||
_twonlyScoreMeta,
|
||||
),
|
||||
);
|
||||
}
|
||||
if (data.containsKey('media_send_counter')) {
|
||||
context.handle(
|
||||
_mediaSendCounterMeta,
|
||||
|
|
@ -739,6 +760,10 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
|||
DriftSqlType.bool,
|
||||
data['${effectivePrefix}widget_sharing_granted'],
|
||||
)!,
|
||||
twonlyScore: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.int,
|
||||
data['${effectivePrefix}twonly_score'],
|
||||
),
|
||||
mediaSendCounter: attachedDatabase.typeMapping.read(
|
||||
DriftSqlType.int,
|
||||
data['${effectivePrefix}media_send_counter'],
|
||||
|
|
@ -788,6 +813,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
final bool? askForFriendPromotions;
|
||||
final bool widgetSharingAllowed;
|
||||
final bool widgetSharingGranted;
|
||||
final int? twonlyScore;
|
||||
final int mediaSendCounter;
|
||||
final int mediaReceivedCounter;
|
||||
const Contact({
|
||||
|
|
@ -817,6 +843,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
this.askForFriendPromotions,
|
||||
required this.widgetSharingAllowed,
|
||||
required this.widgetSharingGranted,
|
||||
this.twonlyScore,
|
||||
required this.mediaSendCounter,
|
||||
required this.mediaReceivedCounter,
|
||||
});
|
||||
|
|
@ -885,6 +912,9 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
}
|
||||
map['widget_sharing_allowed'] = Variable<bool>(widgetSharingAllowed);
|
||||
map['widget_sharing_granted'] = Variable<bool>(widgetSharingGranted);
|
||||
if (!nullToAbsent || twonlyScore != null) {
|
||||
map['twonly_score'] = Variable<int>(twonlyScore);
|
||||
}
|
||||
map['media_send_counter'] = Variable<int>(mediaSendCounter);
|
||||
map['media_received_counter'] = Variable<int>(mediaReceivedCounter);
|
||||
return map;
|
||||
|
|
@ -944,6 +974,9 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
: Value(askForFriendPromotions),
|
||||
widgetSharingAllowed: Value(widgetSharingAllowed),
|
||||
widgetSharingGranted: Value(widgetSharingGranted),
|
||||
twonlyScore: twonlyScore == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(twonlyScore),
|
||||
mediaSendCounter: Value(mediaSendCounter),
|
||||
mediaReceivedCounter: Value(mediaReceivedCounter),
|
||||
);
|
||||
|
|
@ -1011,6 +1044,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
widgetSharingGranted: serializer.fromJson<bool>(
|
||||
json['widgetSharingGranted'],
|
||||
),
|
||||
twonlyScore: serializer.fromJson<int?>(json['twonlyScore']),
|
||||
mediaSendCounter: serializer.fromJson<int>(json['mediaSendCounter']),
|
||||
mediaReceivedCounter: serializer.fromJson<int>(
|
||||
json['mediaReceivedCounter'],
|
||||
|
|
@ -1065,6 +1099,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
),
|
||||
'widgetSharingAllowed': serializer.toJson<bool>(widgetSharingAllowed),
|
||||
'widgetSharingGranted': serializer.toJson<bool>(widgetSharingGranted),
|
||||
'twonlyScore': serializer.toJson<int?>(twonlyScore),
|
||||
'mediaSendCounter': serializer.toJson<int>(mediaSendCounter),
|
||||
'mediaReceivedCounter': serializer.toJson<int>(mediaReceivedCounter),
|
||||
};
|
||||
|
|
@ -1097,6 +1132,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
Value<bool?> askForFriendPromotions = const Value.absent(),
|
||||
bool? widgetSharingAllowed,
|
||||
bool? widgetSharingGranted,
|
||||
Value<int?> twonlyScore = const Value.absent(),
|
||||
int? mediaSendCounter,
|
||||
int? mediaReceivedCounter,
|
||||
}) => Contact(
|
||||
|
|
@ -1145,6 +1181,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
: this.askForFriendPromotions,
|
||||
widgetSharingAllowed: widgetSharingAllowed ?? this.widgetSharingAllowed,
|
||||
widgetSharingGranted: widgetSharingGranted ?? this.widgetSharingGranted,
|
||||
twonlyScore: twonlyScore.present ? twonlyScore.value : this.twonlyScore,
|
||||
mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter,
|
||||
mediaReceivedCounter: mediaReceivedCounter ?? this.mediaReceivedCounter,
|
||||
);
|
||||
|
|
@ -1212,6 +1249,9 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
widgetSharingGranted: data.widgetSharingGranted.present
|
||||
? data.widgetSharingGranted.value
|
||||
: this.widgetSharingGranted,
|
||||
twonlyScore: data.twonlyScore.present
|
||||
? data.twonlyScore.value
|
||||
: this.twonlyScore,
|
||||
mediaSendCounter: data.mediaSendCounter.present
|
||||
? data.mediaSendCounter.value
|
||||
: this.mediaSendCounter,
|
||||
|
|
@ -1252,6 +1292,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
..write('askForFriendPromotions: $askForFriendPromotions, ')
|
||||
..write('widgetSharingAllowed: $widgetSharingAllowed, ')
|
||||
..write('widgetSharingGranted: $widgetSharingGranted, ')
|
||||
..write('twonlyScore: $twonlyScore, ')
|
||||
..write('mediaSendCounter: $mediaSendCounter, ')
|
||||
..write('mediaReceivedCounter: $mediaReceivedCounter')
|
||||
..write(')'))
|
||||
|
|
@ -1286,6 +1327,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
askForFriendPromotions,
|
||||
widgetSharingAllowed,
|
||||
widgetSharingGranted,
|
||||
twonlyScore,
|
||||
mediaSendCounter,
|
||||
mediaReceivedCounter,
|
||||
]);
|
||||
|
|
@ -1333,6 +1375,7 @@ class Contact extends DataClass implements Insertable<Contact> {
|
|||
other.askForFriendPromotions == this.askForFriendPromotions &&
|
||||
other.widgetSharingAllowed == this.widgetSharingAllowed &&
|
||||
other.widgetSharingGranted == this.widgetSharingGranted &&
|
||||
other.twonlyScore == this.twonlyScore &&
|
||||
other.mediaSendCounter == this.mediaSendCounter &&
|
||||
other.mediaReceivedCounter == this.mediaReceivedCounter);
|
||||
}
|
||||
|
|
@ -1364,6 +1407,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
final Value<bool?> askForFriendPromotions;
|
||||
final Value<bool> widgetSharingAllowed;
|
||||
final Value<bool> widgetSharingGranted;
|
||||
final Value<int?> twonlyScore;
|
||||
final Value<int> mediaSendCounter;
|
||||
final Value<int> mediaReceivedCounter;
|
||||
const ContactsCompanion({
|
||||
|
|
@ -1393,6 +1437,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
this.askForFriendPromotions = const Value.absent(),
|
||||
this.widgetSharingAllowed = const Value.absent(),
|
||||
this.widgetSharingGranted = const Value.absent(),
|
||||
this.twonlyScore = const Value.absent(),
|
||||
this.mediaSendCounter = const Value.absent(),
|
||||
this.mediaReceivedCounter = const Value.absent(),
|
||||
});
|
||||
|
|
@ -1423,6 +1468,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
this.askForFriendPromotions = const Value.absent(),
|
||||
this.widgetSharingAllowed = const Value.absent(),
|
||||
this.widgetSharingGranted = const Value.absent(),
|
||||
this.twonlyScore = const Value.absent(),
|
||||
this.mediaSendCounter = const Value.absent(),
|
||||
this.mediaReceivedCounter = const Value.absent(),
|
||||
}) : username = Value(username);
|
||||
|
|
@ -1453,6 +1499,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
Expression<bool>? askForFriendPromotions,
|
||||
Expression<bool>? widgetSharingAllowed,
|
||||
Expression<bool>? widgetSharingGranted,
|
||||
Expression<int>? twonlyScore,
|
||||
Expression<int>? mediaSendCounter,
|
||||
Expression<int>? mediaReceivedCounter,
|
||||
}) {
|
||||
|
|
@ -1497,6 +1544,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
'widget_sharing_allowed': widgetSharingAllowed,
|
||||
if (widgetSharingGranted != null)
|
||||
'widget_sharing_granted': widgetSharingGranted,
|
||||
if (twonlyScore != null) 'twonly_score': twonlyScore,
|
||||
if (mediaSendCounter != null) 'media_send_counter': mediaSendCounter,
|
||||
if (mediaReceivedCounter != null)
|
||||
'media_received_counter': mediaReceivedCounter,
|
||||
|
|
@ -1530,6 +1578,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
Value<bool?>? askForFriendPromotions,
|
||||
Value<bool>? widgetSharingAllowed,
|
||||
Value<bool>? widgetSharingGranted,
|
||||
Value<int?>? twonlyScore,
|
||||
Value<int>? mediaSendCounter,
|
||||
Value<int>? mediaReceivedCounter,
|
||||
}) {
|
||||
|
|
@ -1568,6 +1617,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
askForFriendPromotions ?? this.askForFriendPromotions,
|
||||
widgetSharingAllowed: widgetSharingAllowed ?? this.widgetSharingAllowed,
|
||||
widgetSharingGranted: widgetSharingGranted ?? this.widgetSharingGranted,
|
||||
twonlyScore: twonlyScore ?? this.twonlyScore,
|
||||
mediaSendCounter: mediaSendCounter ?? this.mediaSendCounter,
|
||||
mediaReceivedCounter: mediaReceivedCounter ?? this.mediaReceivedCounter,
|
||||
);
|
||||
|
|
@ -1682,6 +1732,9 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
widgetSharingGranted.value,
|
||||
);
|
||||
}
|
||||
if (twonlyScore.present) {
|
||||
map['twonly_score'] = Variable<int>(twonlyScore.value);
|
||||
}
|
||||
if (mediaSendCounter.present) {
|
||||
map['media_send_counter'] = Variable<int>(mediaSendCounter.value);
|
||||
}
|
||||
|
|
@ -1722,6 +1775,7 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
|||
..write('askForFriendPromotions: $askForFriendPromotions, ')
|
||||
..write('widgetSharingAllowed: $widgetSharingAllowed, ')
|
||||
..write('widgetSharingGranted: $widgetSharingGranted, ')
|
||||
..write('twonlyScore: $twonlyScore, ')
|
||||
..write('mediaSendCounter: $mediaSendCounter, ')
|
||||
..write('mediaReceivedCounter: $mediaReceivedCounter')
|
||||
..write(')'))
|
||||
|
|
@ -15757,6 +15811,7 @@ typedef $$ContactsTableCreateCompanionBuilder =
|
|||
Value<bool?> askForFriendPromotions,
|
||||
Value<bool> widgetSharingAllowed,
|
||||
Value<bool> widgetSharingGranted,
|
||||
Value<int?> twonlyScore,
|
||||
Value<int> mediaSendCounter,
|
||||
Value<int> mediaReceivedCounter,
|
||||
});
|
||||
|
|
@ -15788,6 +15843,7 @@ typedef $$ContactsTableUpdateCompanionBuilder =
|
|||
Value<bool?> askForFriendPromotions,
|
||||
Value<bool> widgetSharingAllowed,
|
||||
Value<bool> widgetSharingGranted,
|
||||
Value<int?> twonlyScore,
|
||||
Value<int> mediaSendCounter,
|
||||
Value<int> mediaReceivedCounter,
|
||||
});
|
||||
|
|
@ -16207,6 +16263,11 @@ class $$ContactsTableFilterComposer
|
|||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<int> get twonlyScore => $composableBuilder(
|
||||
column: $table.twonlyScore,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
);
|
||||
|
||||
ColumnFilters<int> get mediaSendCounter => $composableBuilder(
|
||||
column: $table.mediaSendCounter,
|
||||
builder: (column) => ColumnFilters(column),
|
||||
|
|
@ -16667,6 +16728,11 @@ class $$ContactsTableOrderingComposer
|
|||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<int> get twonlyScore => $composableBuilder(
|
||||
column: $table.twonlyScore,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
);
|
||||
|
||||
ColumnOrderings<int> get mediaSendCounter => $composableBuilder(
|
||||
column: $table.mediaSendCounter,
|
||||
builder: (column) => ColumnOrderings(column),
|
||||
|
|
@ -16804,6 +16870,11 @@ class $$ContactsTableAnnotationComposer
|
|||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumn<int> get twonlyScore => $composableBuilder(
|
||||
column: $table.twonlyScore,
|
||||
builder: (column) => column,
|
||||
);
|
||||
|
||||
GeneratedColumn<int> get mediaSendCounter => $composableBuilder(
|
||||
column: $table.mediaSendCounter,
|
||||
builder: (column) => column,
|
||||
|
|
@ -17198,6 +17269,7 @@ class $$ContactsTableTableManager
|
|||
Value<bool?> askForFriendPromotions = const Value.absent(),
|
||||
Value<bool> widgetSharingAllowed = const Value.absent(),
|
||||
Value<bool> widgetSharingGranted = const Value.absent(),
|
||||
Value<int?> twonlyScore = const Value.absent(),
|
||||
Value<int> mediaSendCounter = const Value.absent(),
|
||||
Value<int> mediaReceivedCounter = const Value.absent(),
|
||||
}) => ContactsCompanion(
|
||||
|
|
@ -17227,6 +17299,7 @@ class $$ContactsTableTableManager
|
|||
askForFriendPromotions: askForFriendPromotions,
|
||||
widgetSharingAllowed: widgetSharingAllowed,
|
||||
widgetSharingGranted: widgetSharingGranted,
|
||||
twonlyScore: twonlyScore,
|
||||
mediaSendCounter: mediaSendCounter,
|
||||
mediaReceivedCounter: mediaReceivedCounter,
|
||||
),
|
||||
|
|
@ -17260,6 +17333,7 @@ class $$ContactsTableTableManager
|
|||
Value<bool?> askForFriendPromotions = const Value.absent(),
|
||||
Value<bool> widgetSharingAllowed = const Value.absent(),
|
||||
Value<bool> widgetSharingGranted = const Value.absent(),
|
||||
Value<int?> twonlyScore = const Value.absent(),
|
||||
Value<int> mediaSendCounter = const Value.absent(),
|
||||
Value<int> mediaReceivedCounter = const Value.absent(),
|
||||
}) => ContactsCompanion.insert(
|
||||
|
|
@ -17289,6 +17363,7 @@ class $$ContactsTableTableManager
|
|||
askForFriendPromotions: askForFriendPromotions,
|
||||
widgetSharingAllowed: widgetSharingAllowed,
|
||||
widgetSharingGranted: widgetSharingGranted,
|
||||
twonlyScore: twonlyScore,
|
||||
mediaSendCounter: mediaSendCounter,
|
||||
mediaReceivedCounter: mediaReceivedCounter,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -658,6 +658,48 @@ abstract class AppLocalizations {
|
|||
/// **'{len} contact(s)'**
|
||||
String settingsPrivacyBlockUsersCount(Object len);
|
||||
|
||||
/// No description provided for @publicProfilePrivacyTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Public Profile'**
|
||||
String get publicProfilePrivacyTitle;
|
||||
|
||||
/// No description provided for @publicProfilePrivacyDescription.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Choose who can see information about your profile.'**
|
||||
String get publicProfilePrivacyDescription;
|
||||
|
||||
/// No description provided for @publicProfileTwonlyScore.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'twonly Score'**
|
||||
String get publicProfileTwonlyScore;
|
||||
|
||||
/// No description provided for @contactTwonlyScoreDescription.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The twonly Score reflects a person\'s activity on twonly. It is calculated from several factors, such as how many photos and videos they send and receive.'**
|
||||
String get contactTwonlyScoreDescription;
|
||||
|
||||
/// No description provided for @privacyVisibilityNobody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Nobody'**
|
||||
String get privacyVisibilityNobody;
|
||||
|
||||
/// No description provided for @privacyVisibilityOnlyContacts.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Only Contacts'**
|
||||
String get privacyVisibilityOnlyContacts;
|
||||
|
||||
/// No description provided for @privacyVisibilityEveryone.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Everyone'**
|
||||
String get privacyVisibilityEveryone;
|
||||
|
||||
/// No description provided for @settingsNotification.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
|
|
@ -302,6 +302,29 @@ class AppLocalizationsAr extends AppLocalizations {
|
|||
return 'جهات الاتصال: $len';
|
||||
}
|
||||
|
||||
@override
|
||||
String get publicProfilePrivacyTitle => 'الملف الشخصي العام';
|
||||
|
||||
@override
|
||||
String get publicProfilePrivacyDescription =>
|
||||
'اختر من يمكنه رؤية معلومات ملفك الشخصي.';
|
||||
|
||||
@override
|
||||
String get publicProfileTwonlyScore => 'نقاط twonly';
|
||||
|
||||
@override
|
||||
String get contactTwonlyScoreDescription =>
|
||||
'تعكس نقاط twonly نشاط الشخص على twonly. ويتم احتسابها استنادًا إلى عدة عوامل، مثل عدد الصور ومقاطع الفيديو التي يرسلها ويستلمها.';
|
||||
|
||||
@override
|
||||
String get privacyVisibilityNobody => 'لا أحد';
|
||||
|
||||
@override
|
||||
String get privacyVisibilityOnlyContacts => 'جهات الاتصال فقط';
|
||||
|
||||
@override
|
||||
String get privacyVisibilityEveryone => 'الجميع';
|
||||
|
||||
@override
|
||||
String get settingsNotification => 'الإشعارات';
|
||||
|
||||
|
|
|
|||
|
|
@ -305,6 +305,29 @@ class AppLocalizationsDe extends AppLocalizations {
|
|||
return '$len Kontakt(e)';
|
||||
}
|
||||
|
||||
@override
|
||||
String get publicProfilePrivacyTitle => 'Öffentliches Profil';
|
||||
|
||||
@override
|
||||
String get publicProfilePrivacyDescription =>
|
||||
'Wähle aus, wer Informationen über dein Profil sehen kann.';
|
||||
|
||||
@override
|
||||
String get publicProfileTwonlyScore => 'twonly Score';
|
||||
|
||||
@override
|
||||
String get contactTwonlyScoreDescription =>
|
||||
'Der twonly Score spiegelt die Aktivität einer Person auf twonly wider. Er wird aus verschiedenen Faktoren berechnet, zum Beispiel daraus, wie viele Fotos und Videos sie sendet und empfängt.';
|
||||
|
||||
@override
|
||||
String get privacyVisibilityNobody => 'Niemand';
|
||||
|
||||
@override
|
||||
String get privacyVisibilityOnlyContacts => 'Nur Kontakte';
|
||||
|
||||
@override
|
||||
String get privacyVisibilityEveryone => 'Alle';
|
||||
|
||||
@override
|
||||
String get settingsNotification => 'Benachrichtigung';
|
||||
|
||||
|
|
|
|||
|
|
@ -302,6 +302,29 @@ class AppLocalizationsEn extends AppLocalizations {
|
|||
return '$len contact(s)';
|
||||
}
|
||||
|
||||
@override
|
||||
String get publicProfilePrivacyTitle => 'Public Profile';
|
||||
|
||||
@override
|
||||
String get publicProfilePrivacyDescription =>
|
||||
'Choose who can see information about your profile.';
|
||||
|
||||
@override
|
||||
String get publicProfileTwonlyScore => 'twonly Score';
|
||||
|
||||
@override
|
||||
String get contactTwonlyScoreDescription =>
|
||||
'The twonly Score reflects a person\'s activity on twonly. It is calculated from several factors, such as how many photos and videos they send and receive.';
|
||||
|
||||
@override
|
||||
String get privacyVisibilityNobody => 'Nobody';
|
||||
|
||||
@override
|
||||
String get privacyVisibilityOnlyContacts => 'Only Contacts';
|
||||
|
||||
@override
|
||||
String get privacyVisibilityEveryone => 'Everyone';
|
||||
|
||||
@override
|
||||
String get settingsNotification => 'Notification';
|
||||
|
||||
|
|
|
|||
|
|
@ -93,6 +93,13 @@
|
|||
"settingsPrivacyBlockUsers": "حظر جهات الاتصال",
|
||||
"settingsPrivacyBlockUsersDesc": "لن تتمكن جهات الاتصال المحظورة من التواصل معك. يمكنك إلغاء حظر أي جهة اتصال في أي وقت.",
|
||||
"settingsPrivacyBlockUsersCount": "جهات الاتصال: {len}",
|
||||
"publicProfilePrivacyTitle": "الملف الشخصي العام",
|
||||
"publicProfilePrivacyDescription": "اختر من يمكنه رؤية معلومات ملفك الشخصي.",
|
||||
"publicProfileTwonlyScore": "نقاط twonly",
|
||||
"contactTwonlyScoreDescription": "تعكس نقاط twonly نشاط الشخص على twonly. ويتم احتسابها استنادًا إلى عدة عوامل، مثل عدد الصور ومقاطع الفيديو التي يرسلها ويستلمها.",
|
||||
"privacyVisibilityNobody": "لا أحد",
|
||||
"privacyVisibilityOnlyContacts": "جهات الاتصال فقط",
|
||||
"privacyVisibilityEveryone": "الجميع",
|
||||
"settingsNotification": "الإشعارات",
|
||||
"settingsNotifyPermission": "أذونات الإشعارات",
|
||||
"settingsNotifyPermissionDesc": "افتح إعدادات النظام للسماح بالإشعارات الفورية.",
|
||||
|
|
|
|||
|
|
@ -102,6 +102,13 @@
|
|||
"settingsPrivacyBlockUsers": "Kontakte blockieren",
|
||||
"settingsPrivacyBlockUsersDesc": "Blockierte Kontakte können nicht mit dir kommunizieren. Du kannst einen blockierten Kontakt jederzeit wieder entsperren.",
|
||||
"settingsPrivacyBlockUsersCount": "{len} Kontakt(e)",
|
||||
"publicProfilePrivacyTitle": "Öffentliches Profil",
|
||||
"publicProfilePrivacyDescription": "Wähle aus, wer Informationen über dein Profil sehen kann.",
|
||||
"publicProfileTwonlyScore": "twonly Score",
|
||||
"contactTwonlyScoreDescription": "Der twonly Score spiegelt die Aktivität einer Person auf twonly wider. Er wird aus verschiedenen Faktoren berechnet, zum Beispiel daraus, wie viele Fotos und Videos sie sendet und empfängt.",
|
||||
"privacyVisibilityNobody": "Niemand",
|
||||
"privacyVisibilityOnlyContacts": "Nur Kontakte",
|
||||
"privacyVisibilityEveryone": "Alle",
|
||||
"settingsNotification": "Benachrichtigung",
|
||||
"settingsNotifyPermission": "Benachrichtigungsberechtigung",
|
||||
"settingsNotifyPermissionDesc": "Systemeinstellungen öffnen, um Push-Benachrichtigungen zu erlauben.",
|
||||
|
|
|
|||
|
|
@ -98,6 +98,13 @@
|
|||
"len": {}
|
||||
}
|
||||
},
|
||||
"publicProfilePrivacyTitle": "Public Profile",
|
||||
"publicProfilePrivacyDescription": "Choose who can see information about your profile.",
|
||||
"publicProfileTwonlyScore": "twonly Score",
|
||||
"contactTwonlyScoreDescription": "The twonly Score reflects a person's activity on twonly. It is calculated from several factors, such as how many photos and videos they send and receive.",
|
||||
"privacyVisibilityNobody": "Nobody",
|
||||
"privacyVisibilityOnlyContacts": "Only Contacts",
|
||||
"privacyVisibilityEveryone": "Everyone",
|
||||
"settingsNotification": "Notification",
|
||||
"settingsNotifyPermission": "Notification permissions",
|
||||
"settingsNotifyPermissionDesc": "Open system settings to allow push notifications.",
|
||||
|
|
|
|||
|
|
@ -1774,6 +1774,7 @@ class EncryptedContent extends $pb.GeneratedMessage {
|
|||
passwordlessRecoveryHeartbeat,
|
||||
$core.bool? widgetSharingAllowed,
|
||||
EncryptedContent_Story? story,
|
||||
$fixnum.Int64? senderTwonlyScore,
|
||||
}) {
|
||||
final result = create();
|
||||
if (groupId != null) result.groupId = groupId;
|
||||
|
|
@ -1814,6 +1815,7 @@ class EncryptedContent extends $pb.GeneratedMessage {
|
|||
if (widgetSharingAllowed != null)
|
||||
result.widgetSharingAllowed = widgetSharingAllowed;
|
||||
if (story != null) result.story = story;
|
||||
if (senderTwonlyScore != null) result.senderTwonlyScore = senderTwonlyScore;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1893,6 +1895,7 @@ class EncryptedContent extends $pb.GeneratedMessage {
|
|||
..aOB(29, _omitFieldNames ? '' : 'widgetSharingAllowed')
|
||||
..aOM<EncryptedContent_Story>(30, _omitFieldNames ? '' : 'story',
|
||||
subBuilder: EncryptedContent_Story.create)
|
||||
..aInt64(31, _omitFieldNames ? '' : 'senderTwonlyScore')
|
||||
..hasRequiredFields = false;
|
||||
|
||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||
|
|
@ -2222,6 +2225,15 @@ class EncryptedContent extends $pb.GeneratedMessage {
|
|||
void clearStory() => $_clearField(30);
|
||||
@$pb.TagNumber(30)
|
||||
EncryptedContent_Story ensureStory() => $_ensure(26);
|
||||
|
||||
@$pb.TagNumber(31)
|
||||
$fixnum.Int64 get senderTwonlyScore => $_getI64(27);
|
||||
@$pb.TagNumber(31)
|
||||
set senderTwonlyScore($fixnum.Int64 value) => $_setInt64(27, value);
|
||||
@$pb.TagNumber(31)
|
||||
$core.bool hasSenderTwonlyScore() => $_has(27);
|
||||
@$pb.TagNumber(31)
|
||||
void clearSenderTwonlyScore() => $_clearField(31);
|
||||
}
|
||||
|
||||
const $core.bool _omitFieldNames =
|
||||
|
|
|
|||
|
|
@ -73,13 +73,22 @@ const EncryptedContent$json = {
|
|||
'10': 'widgetSharingAllowed',
|
||||
'17': true
|
||||
},
|
||||
{
|
||||
'1': 'sender_twonly_score',
|
||||
'3': 31,
|
||||
'4': 1,
|
||||
'5': 3,
|
||||
'9': 6,
|
||||
'10': 'senderTwonlyScore',
|
||||
'17': true
|
||||
},
|
||||
{
|
||||
'1': 'message_update',
|
||||
'3': 5,
|
||||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.MessageUpdate',
|
||||
'9': 6,
|
||||
'9': 7,
|
||||
'10': 'messageUpdate',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -89,7 +98,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.Media',
|
||||
'9': 7,
|
||||
'9': 8,
|
||||
'10': 'media',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -99,7 +108,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.MediaUpdate',
|
||||
'9': 8,
|
||||
'9': 9,
|
||||
'10': 'mediaUpdate',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -109,7 +118,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.ContactUpdate',
|
||||
'9': 9,
|
||||
'9': 10,
|
||||
'10': 'contactUpdate',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -119,7 +128,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.ContactRequest',
|
||||
'9': 10,
|
||||
'9': 11,
|
||||
'10': 'contactRequest',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -129,7 +138,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.FlameSync',
|
||||
'9': 11,
|
||||
'9': 12,
|
||||
'10': 'flameSync',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -139,7 +148,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.Reaction',
|
||||
'9': 12,
|
||||
'9': 13,
|
||||
'10': 'reaction',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -149,7 +158,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.TextMessage',
|
||||
'9': 13,
|
||||
'9': 14,
|
||||
'10': 'textMessage',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -159,7 +168,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.GroupCreate',
|
||||
'9': 14,
|
||||
'9': 15,
|
||||
'10': 'groupCreate',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -169,7 +178,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.GroupJoin',
|
||||
'9': 15,
|
||||
'9': 16,
|
||||
'10': 'groupJoin',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -179,7 +188,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.GroupUpdate',
|
||||
'9': 16,
|
||||
'9': 17,
|
||||
'10': 'groupUpdate',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -189,7 +198,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.ResendGroupPublicKey',
|
||||
'9': 17,
|
||||
'9': 18,
|
||||
'10': 'resendGroupPublicKey',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -199,7 +208,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.ErrorMessages',
|
||||
'9': 18,
|
||||
'9': 19,
|
||||
'10': 'errorMessages',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -209,7 +218,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.AdditionalDataMessage',
|
||||
'9': 19,
|
||||
'9': 20,
|
||||
'10': 'additionalDataMessage',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -219,7 +228,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.TypingIndicator',
|
||||
'9': 20,
|
||||
'9': 21,
|
||||
'10': 'typingIndicator',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -229,7 +238,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.UserDiscoveryRequest',
|
||||
'9': 21,
|
||||
'9': 22,
|
||||
'10': 'userDiscoveryRequest',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -239,7 +248,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.UserDiscoveryUpdate',
|
||||
'9': 22,
|
||||
'9': 23,
|
||||
'10': 'userDiscoveryUpdate',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -249,7 +258,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.KeyVerificationProof',
|
||||
'9': 23,
|
||||
'9': 24,
|
||||
'10': 'keyVerificationProof',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -259,7 +268,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.PasswordLessRecovery',
|
||||
'9': 24,
|
||||
'9': 25,
|
||||
'10': 'passwordlessRecovery',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -269,7 +278,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.PasswordLessRecoveryHeartbeat',
|
||||
'9': 25,
|
||||
'9': 26,
|
||||
'10': 'passwordlessRecoveryHeartbeat',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -279,7 +288,7 @@ const EncryptedContent$json = {
|
|||
'4': 1,
|
||||
'5': 11,
|
||||
'6': '.EncryptedContent.Story',
|
||||
'9': 26,
|
||||
'9': 27,
|
||||
'10': 'story',
|
||||
'17': true
|
||||
},
|
||||
|
|
@ -314,6 +323,7 @@ const EncryptedContent$json = {
|
|||
{'1': '_sender_user_discovery_version'},
|
||||
{'1': '_ask_for_friend_promotions'},
|
||||
{'1': '_widget_sharing_allowed'},
|
||||
{'1': '_sender_twonly_score'},
|
||||
{'1': '_message_update'},
|
||||
{'1': '_media'},
|
||||
{'1': '_media_update'},
|
||||
|
|
@ -894,115 +904,116 @@ final $typed_data.Uint8List encryptedContentDescriptor = $convert.base64Decode(
|
|||
'JfZGlzY292ZXJ5X3ZlcnNpb24YFSABKAxIA1Iac2VuZGVyVXNlckRpc2NvdmVyeVZlcnNpb26I'
|
||||
'AQESPgoZYXNrX2Zvcl9mcmllbmRfcHJvbW90aW9ucxgZIAEoCEgEUhZhc2tGb3JGcmllbmRQcm'
|
||||
'9tb3Rpb25ziAEBEjkKFndpZGdldF9zaGFyaW5nX2FsbG93ZWQYHSABKAhIBVIUd2lkZ2V0U2hh'
|
||||
'cmluZ0FsbG93ZWSIAQESSwoObWVzc2FnZV91cGRhdGUYBSABKAsyHy5FbmNyeXB0ZWRDb250ZW'
|
||||
'50Lk1lc3NhZ2VVcGRhdGVIBlINbWVzc2FnZVVwZGF0ZYgBARIyCgVtZWRpYRgGIAEoCzIXLkVu'
|
||||
'Y3J5cHRlZENvbnRlbnQuTWVkaWFIB1IFbWVkaWGIAQESRQoMbWVkaWFfdXBkYXRlGAcgASgLMh'
|
||||
'0uRW5jcnlwdGVkQ29udGVudC5NZWRpYVVwZGF0ZUgIUgttZWRpYVVwZGF0ZYgBARJLCg5jb250'
|
||||
'YWN0X3VwZGF0ZRgIIAEoCzIfLkVuY3J5cHRlZENvbnRlbnQuQ29udGFjdFVwZGF0ZUgJUg1jb2'
|
||||
'50YWN0VXBkYXRliAEBEk4KD2NvbnRhY3RfcmVxdWVzdBgJIAEoCzIgLkVuY3J5cHRlZENvbnRl'
|
||||
'bnQuQ29udGFjdFJlcXVlc3RIClIOY29udGFjdFJlcXVlc3SIAQESPwoKZmxhbWVfc3luYxgKIA'
|
||||
'EoCzIbLkVuY3J5cHRlZENvbnRlbnQuRmxhbWVTeW5jSAtSCWZsYW1lU3luY4gBARI7CghyZWFj'
|
||||
'dGlvbhgMIAEoCzIaLkVuY3J5cHRlZENvbnRlbnQuUmVhY3Rpb25IDFIIcmVhY3Rpb26IAQESRQ'
|
||||
'oMdGV4dF9tZXNzYWdlGA0gASgLMh0uRW5jcnlwdGVkQ29udGVudC5UZXh0TWVzc2FnZUgNUgt0'
|
||||
'ZXh0TWVzc2FnZYgBARJFCgxncm91cF9jcmVhdGUYDiABKAsyHS5FbmNyeXB0ZWRDb250ZW50Lk'
|
||||
'dyb3VwQ3JlYXRlSA5SC2dyb3VwQ3JlYXRliAEBEj8KCmdyb3VwX2pvaW4YDyABKAsyGy5FbmNy'
|
||||
'eXB0ZWRDb250ZW50Lkdyb3VwSm9pbkgPUglncm91cEpvaW6IAQESRQoMZ3JvdXBfdXBkYXRlGB'
|
||||
'AgASgLMh0uRW5jcnlwdGVkQ29udGVudC5Hcm91cFVwZGF0ZUgQUgtncm91cFVwZGF0ZYgBARJi'
|
||||
'ChdyZXNlbmRfZ3JvdXBfcHVibGljX2tleRgRIAEoCzImLkVuY3J5cHRlZENvbnRlbnQuUmVzZW'
|
||||
'5kR3JvdXBQdWJsaWNLZXlIEVIUcmVzZW5kR3JvdXBQdWJsaWNLZXmIAQESSwoOZXJyb3JfbWVz'
|
||||
'c2FnZXMYEiABKAsyHy5FbmNyeXB0ZWRDb250ZW50LkVycm9yTWVzc2FnZXNIElINZXJyb3JNZX'
|
||||
'NzYWdlc4gBARJkChdhZGRpdGlvbmFsX2RhdGFfbWVzc2FnZRgTIAEoCzInLkVuY3J5cHRlZENv'
|
||||
'bnRlbnQuQWRkaXRpb25hbERhdGFNZXNzYWdlSBNSFWFkZGl0aW9uYWxEYXRhTWVzc2FnZYgBAR'
|
||||
'JRChB0eXBpbmdfaW5kaWNhdG9yGBQgASgLMiEuRW5jcnlwdGVkQ29udGVudC5UeXBpbmdJbmRp'
|
||||
'Y2F0b3JIFFIPdHlwaW5nSW5kaWNhdG9yiAEBEmEKFnVzZXJfZGlzY292ZXJ5X3JlcXVlc3QYFi'
|
||||
'ABKAsyJi5FbmNyeXB0ZWRDb250ZW50LlVzZXJEaXNjb3ZlcnlSZXF1ZXN0SBVSFHVzZXJEaXNj'
|
||||
'b3ZlcnlSZXF1ZXN0iAEBEl4KFXVzZXJfZGlzY292ZXJ5X3VwZGF0ZRgXIAEoCzIlLkVuY3J5cH'
|
||||
'RlZENvbnRlbnQuVXNlckRpc2NvdmVyeVVwZGF0ZUgWUhN1c2VyRGlzY292ZXJ5VXBkYXRliAEB'
|
||||
'EmEKFmtleV92ZXJpZmljYXRpb25fcHJvb2YYGCABKAsyJi5FbmNyeXB0ZWRDb250ZW50LktleV'
|
||||
'ZlcmlmaWNhdGlvblByb29mSBdSFGtleVZlcmlmaWNhdGlvblByb29miAEBEmAKFXBhc3N3b3Jk'
|
||||
'bGVzc19yZWNvdmVyeRgaIAEoCzImLkVuY3J5cHRlZENvbnRlbnQuUGFzc3dvcmRMZXNzUmVjb3'
|
||||
'ZlcnlIGFIUcGFzc3dvcmRsZXNzUmVjb3ZlcnmIAQESfAofcGFzc3dvcmRsZXNzX3JlY292ZXJ5'
|
||||
'X2hlYXJ0YmVhdBgbIAEoCzIvLkVuY3J5cHRlZENvbnRlbnQuUGFzc3dvcmRMZXNzUmVjb3Zlcn'
|
||||
'lIZWFydGJlYXRIGVIdcGFzc3dvcmRsZXNzUmVjb3ZlcnlIZWFydGJlYXSIAQESMgoFc3RvcnkY'
|
||||
'HiABKAsyFy5FbmNyeXB0ZWRDb250ZW50LlN0b3J5SBpSBXN0b3J5iAEBGpYCCg1FcnJvck1lc3'
|
||||
'NhZ2VzEjgKBHR5cGUYASABKA4yJC5FbmNyeXB0ZWRDb250ZW50LkVycm9yTWVzc2FnZXMuVHlw'
|
||||
'ZVIEdHlwZRIsChJyZWxhdGVkX3JlY2VpcHRfaWQYAiABKAlSEHJlbGF0ZWRSZWNlaXB0SWQinA'
|
||||
'EKBFR5cGUSPAo4RVJST1JfUFJPQ0VTU0lOR19NRVNTQUdFX0NSRUFURURfQUNDT1VOVF9SRVFV'
|
||||
'RVNUX0lOU1RFQUQQABIYChRVTktOT1dOX01FU1NBR0VfVFlQRRACEhcKE1NFU1NJT05fT1VUX0'
|
||||
'9GX1NZTkMQAxIjCh9HUk9VUF9OT1RfRk9VTkRfT1JfTk9UX0FfTUVNQkVSEAQahwEKC0dyb3Vw'
|
||||
'Q3JlYXRlEhsKCXN0YXRlX2tleRgDIAEoDFIIc3RhdGVLZXkSKAoQZ3JvdXBfcHVibGljX2tleR'
|
||||
'gEIAEoDFIOZ3JvdXBQdWJsaWNLZXkSIgoKZ3JvdXBfbmFtZRgFIAEoCUgAUglncm91cE5hbWWI'
|
||||
'AQFCDQoLX2dyb3VwX25hbWUaNQoJR3JvdXBKb2luEigKEGdyb3VwX3B1YmxpY19rZXkYASABKA'
|
||||
'xSDmdyb3VwUHVibGljS2V5GhYKFFJlc2VuZEdyb3VwUHVibGljS2V5GsgCCgtHcm91cFVwZGF0'
|
||||
'ZRIqChFncm91cF9hY3Rpb25fdHlwZRgBIAEoCVIPZ3JvdXBBY3Rpb25UeXBlEjMKE2FmZmVjdG'
|
||||
'VkX2NvbnRhY3RfaWQYAiABKANIAFIRYWZmZWN0ZWRDb250YWN0SWSIAQESKQoObmV3X2dyb3Vw'
|
||||
'X25hbWUYAyABKAlIAVIMbmV3R3JvdXBOYW1liAEBElcKJm5ld19kZWxldGVfbWVzc2FnZXNfYW'
|
||||
'Z0ZXJfbWlsbGlzZWNvbmRzGAQgASgDSAJSIm5ld0RlbGV0ZU1lc3NhZ2VzQWZ0ZXJNaWxsaXNl'
|
||||
'Y29uZHOIAQFCFgoUX2FmZmVjdGVkX2NvbnRhY3RfaWRCEQoPX25ld19ncm91cF9uYW1lQikKJ1'
|
||||
'9uZXdfZGVsZXRlX21lc3NhZ2VzX2FmdGVyX21pbGxpc2Vjb25kcxqIAgoLVGV4dE1lc3NhZ2US'
|
||||
'KgoRc2VuZGVyX21lc3NhZ2VfaWQYASABKAlSD3NlbmRlck1lc3NhZ2VJZBISCgR0ZXh0GAIgAS'
|
||||
'gJUgR0ZXh0EhwKCXRpbWVzdGFtcBgDIAEoA1IJdGltZXN0YW1wEi0KEHF1b3RlX21lc3NhZ2Vf'
|
||||
'aWQYBCABKAlIAFIOcXVvdGVNZXNzYWdlSWSIAQESOwoXYWRkaXRpb25hbF9tZXNzYWdlX2RhdG'
|
||||
'EYBSABKAxIAVIVYWRkaXRpb25hbE1lc3NhZ2VEYXRhiAEBQhMKEV9xdW90ZV9tZXNzYWdlX2lk'
|
||||
'QhoKGF9hZGRpdGlvbmFsX21lc3NhZ2VfZGF0YRrmAQoVQWRkaXRpb25hbERhdGFNZXNzYWdlEi'
|
||||
'oKEXNlbmRlcl9tZXNzYWdlX2lkGAEgASgJUg9zZW5kZXJNZXNzYWdlSWQSHAoJdGltZXN0YW1w'
|
||||
'GAIgASgDUgl0aW1lc3RhbXASEgoEdHlwZRgDIAEoCVIEdHlwZRI7ChdhZGRpdGlvbmFsX21lc3'
|
||||
'NhZ2VfZGF0YRgEIAEoDEgAUhVhZGRpdGlvbmFsTWVzc2FnZURhdGGIAQESFgoGaGlkZGVuGAUg'
|
||||
'ASgIUgZoaWRkZW5CGgoYX2FkZGl0aW9uYWxfbWVzc2FnZV9kYXRhGmQKCFJlYWN0aW9uEioKEX'
|
||||
'RhcmdldF9tZXNzYWdlX2lkGAEgASgJUg90YXJnZXRNZXNzYWdlSWQSFAoFZW1vamkYAiABKAlS'
|
||||
'BWVtb2ppEhYKBnJlbW92ZRgDIAEoCFIGcmVtb3ZlGr4CCg1NZXNzYWdlVXBkYXRlEjgKBHR5cG'
|
||||
'UYASABKA4yJC5FbmNyeXB0ZWRDb250ZW50Lk1lc3NhZ2VVcGRhdGUuVHlwZVIEdHlwZRIvChFz'
|
||||
'ZW5kZXJfbWVzc2FnZV9pZBgCIAEoCUgAUg9zZW5kZXJNZXNzYWdlSWSIAQESPQobbXVsdGlwbG'
|
||||
'VfdGFyZ2V0X21lc3NhZ2VfaWRzGAMgAygJUhhtdWx0aXBsZVRhcmdldE1lc3NhZ2VJZHMSFwoE'
|
||||
'dGV4dBgEIAEoCUgBUgR0ZXh0iAEBEhwKCXRpbWVzdGFtcBgFIAEoA1IJdGltZXN0YW1wIi0KBF'
|
||||
'R5cGUSCgoGREVMRVRFEAASDQoJRURJVF9URVhUEAESCgoGT1BFTkVEEAJCFAoSX3NlbmRlcl9t'
|
||||
'ZXNzYWdlX2lkQgcKBV90ZXh0GrsGCgVNZWRpYRIqChFzZW5kZXJfbWVzc2FnZV9pZBgBIAEoCV'
|
||||
'IPc2VuZGVyTWVzc2FnZUlkEjAKBHR5cGUYAiABKA4yHC5FbmNyeXB0ZWRDb250ZW50Lk1lZGlh'
|
||||
'LlR5cGVSBHR5cGUSRgodZGlzcGxheV9saW1pdF9pbl9taWxsaXNlY29uZHMYAyABKANIAFIaZG'
|
||||
'lzcGxheUxpbWl0SW5NaWxsaXNlY29uZHOIAQESNwoXcmVxdWlyZXNfYXV0aGVudGljYXRpb24Y'
|
||||
'BCABKAhSFnJlcXVpcmVzQXV0aGVudGljYXRpb24SHAoJdGltZXN0YW1wGAUgASgDUgl0aW1lc3'
|
||||
'RhbXASLQoQcXVvdGVfbWVzc2FnZV9pZBgGIAEoCUgBUg5xdW90ZU1lc3NhZ2VJZIgBARIqCg5k'
|
||||
'b3dubG9hZF90b2tlbhgHIAEoDEgCUg1kb3dubG9hZFRva2VuiAEBEioKDmVuY3J5cHRpb25fa2'
|
||||
'V5GAggASgMSANSDWVuY3J5cHRpb25LZXmIAQESKgoOZW5jcnlwdGlvbl9tYWMYCSABKAxIBFIN'
|
||||
'ZW5jcnlwdGlvbk1hY4gBARIuChBlbmNyeXB0aW9uX25vbmNlGAogASgMSAVSD2VuY3J5cHRpb2'
|
||||
'5Ob25jZYgBARI7ChdhZGRpdGlvbmFsX21lc3NhZ2VfZGF0YRgLIAEoDEgGUhVhZGRpdGlvbmFs'
|
||||
'TWVzc2FnZURhdGGIAQESJAoLd2lkZ2V0X29ubHkYDCABKAhIB1IKd2lkZ2V0T25seYgBASI+Cg'
|
||||
'RUeXBlEgwKCFJFVVBMT0FEEAASCQoFSU1BR0UQARIJCgVWSURFTxACEgcKA0dJRhADEgkKBUFV'
|
||||
'RElPEARCIAoeX2Rpc3BsYXlfbGltaXRfaW5fbWlsbGlzZWNvbmRzQhMKEV9xdW90ZV9tZXNzYW'
|
||||
'dlX2lkQhEKD19kb3dubG9hZF90b2tlbkIRCg9fZW5jcnlwdGlvbl9rZXlCEQoPX2VuY3J5cHRp'
|
||||
'b25fbWFjQhMKEV9lbmNyeXB0aW9uX25vbmNlQhoKGF9hZGRpdGlvbmFsX21lc3NhZ2VfZGF0YU'
|
||||
'IOCgxfd2lkZ2V0X29ubHkaTgoFU3RvcnkSLQoFbWVkaWEYASABKAsyFy5FbmNyeXB0ZWRDb250'
|
||||
'ZW50Lk1lZGlhUgVtZWRpYRIWCgZub3RpZnkYAiABKAhSBm5vdGlmeRqpAQoLTWVkaWFVcGRhdG'
|
||||
'USNgoEdHlwZRgBIAEoDjIiLkVuY3J5cHRlZENvbnRlbnQuTWVkaWFVcGRhdGUuVHlwZVIEdHlw'
|
||||
'ZRIqChF0YXJnZXRfbWVzc2FnZV9pZBgCIAEoCVIPdGFyZ2V0TWVzc2FnZUlkIjYKBFR5cGUSDA'
|
||||
'oIUkVPUEVORUQQABIKCgZTVE9SRUQQARIUChBERUNSWVBUSU9OX0VSUk9SEAIaeAoOQ29udGFj'
|
||||
'dFJlcXVlc3QSOQoEdHlwZRgBIAEoDjIlLkVuY3J5cHRlZENvbnRlbnQuQ29udGFjdFJlcXVlc3'
|
||||
'QuVHlwZVIEdHlwZSIrCgRUeXBlEgsKB1JFUVVFU1QQABIKCgZSRUpFQ1QQARIKCgZBQ0NFUFQQ'
|
||||
'AhqkAgoNQ29udGFjdFVwZGF0ZRI4CgR0eXBlGAEgASgOMiQuRW5jcnlwdGVkQ29udGVudC5Db2'
|
||||
'50YWN0VXBkYXRlLlR5cGVSBHR5cGUSNwoVYXZhdGFyX3N2Z19jb21wcmVzc2VkGAIgASgMSABS'
|
||||
'E2F2YXRhclN2Z0NvbXByZXNzZWSIAQESHwoIdXNlcm5hbWUYAyABKAlIAVIIdXNlcm5hbWWIAQ'
|
||||
'ESJgoMZGlzcGxheV9uYW1lGAQgASgJSAJSC2Rpc3BsYXlOYW1liAEBIh8KBFR5cGUSCwoHUkVR'
|
||||
'VUVTVBAAEgoKBlVQREFURRABQhgKFl9hdmF0YXJfc3ZnX2NvbXByZXNzZWRCCwoJX3VzZXJuYW'
|
||||
'1lQg8KDV9kaXNwbGF5X25hbWUarwEKCUZsYW1lU3luYxIjCg1mbGFtZV9jb3VudGVyGAEgASgD'
|
||||
'UgxmbGFtZUNvdW50ZXISOQoZbGFzdF9mbGFtZV9jb3VudGVyX2NoYW5nZRgCIAEoA1IWbGFzdE'
|
||||
'ZsYW1lQ291bnRlckNoYW5nZRIfCgtiZXN0X2ZyaWVuZBgDIAEoCFIKYmVzdEZyaWVuZBIhCgxm'
|
||||
'b3JjZV91cGRhdGUYBCABKAhSC2ZvcmNlVXBkYXRlGk0KD1R5cGluZ0luZGljYXRvchIbCglpc1'
|
||||
'90eXBpbmcYASABKAhSCGlzVHlwaW5nEh0KCmNyZWF0ZWRfYXQYAiABKANSCWNyZWF0ZWRBdBo/'
|
||||
'ChRVc2VyRGlzY292ZXJ5UmVxdWVzdBInCg9jdXJyZW50X3ZlcnNpb24YASABKAxSDmN1cnJlbn'
|
||||
'RWZXJzaW9uGjEKE1VzZXJEaXNjb3ZlcnlVcGRhdGUSGgoIbWVzc2FnZXMYASADKAxSCG1lc3Nh'
|
||||
'Z2VzGj0KFEtleVZlcmlmaWNhdGlvblByb29mEiUKDmNhbGN1bGF0ZWRfbWFjGAEgASgMUg1jYW'
|
||||
'xjdWxhdGVkTWFjGpsBChRQYXNzd29yZExlc3NSZWNvdmVyeRI1ChNyZWNvdmVyeVNlY3JldFNo'
|
||||
'YXJlGAEgASgMSABSE3JlY292ZXJ5U2VjcmV0U2hhcmWIAQESFgoGZGVsZXRlGAIgASgIUgZkZW'
|
||||
'xldGUSHAoJdGhyZXNob2xkGAMgASgDUgl0aHJlc2hvbGRCFgoUX3JlY292ZXJ5U2VjcmV0U2hh'
|
||||
'cmUaMwodUGFzc3dvcmRMZXNzUmVjb3ZlcnlIZWFydGJlYXQSEgoEaGFzaBgBIAEoDFIEaGFzaE'
|
||||
'ILCglfZ3JvdXBfaWRCEQoPX2lzX2RpcmVjdF9jaGF0QhkKF19zZW5kZXJfcHJvZmlsZV9jb3Vu'
|
||||
'dGVyQiAKHl9zZW5kZXJfdXNlcl9kaXNjb3ZlcnlfdmVyc2lvbkIcChpfYXNrX2Zvcl9mcmllbm'
|
||||
'RfcHJvbW90aW9uc0IZChdfd2lkZ2V0X3NoYXJpbmdfYWxsb3dlZEIRCg9fbWVzc2FnZV91cGRh'
|
||||
'dGVCCAoGX21lZGlhQg8KDV9tZWRpYV91cGRhdGVCEQoPX2NvbnRhY3RfdXBkYXRlQhIKEF9jb2'
|
||||
'50YWN0X3JlcXVlc3RCDQoLX2ZsYW1lX3N5bmNCCwoJX3JlYWN0aW9uQg8KDV90ZXh0X21lc3Nh'
|
||||
'Z2VCDwoNX2dyb3VwX2NyZWF0ZUINCgtfZ3JvdXBfam9pbkIPCg1fZ3JvdXBfdXBkYXRlQhoKGF'
|
||||
'9yZXNlbmRfZ3JvdXBfcHVibGljX2tleUIRCg9fZXJyb3JfbWVzc2FnZXNCGgoYX2FkZGl0aW9u'
|
||||
'YWxfZGF0YV9tZXNzYWdlQhMKEV90eXBpbmdfaW5kaWNhdG9yQhkKF191c2VyX2Rpc2NvdmVyeV'
|
||||
'9yZXF1ZXN0QhgKFl91c2VyX2Rpc2NvdmVyeV91cGRhdGVCGQoXX2tleV92ZXJpZmljYXRpb25f'
|
||||
'cHJvb2ZCGAoWX3Bhc3N3b3JkbGVzc19yZWNvdmVyeUIiCiBfcGFzc3dvcmRsZXNzX3JlY292ZX'
|
||||
'J5X2hlYXJ0YmVhdEIICgZfc3RvcnlKBAgcEB0=');
|
||||
'cmluZ0FsbG93ZWSIAQESMwoTc2VuZGVyX3R3b25seV9zY29yZRgfIAEoA0gGUhFzZW5kZXJUd2'
|
||||
'9ubHlTY29yZYgBARJLCg5tZXNzYWdlX3VwZGF0ZRgFIAEoCzIfLkVuY3J5cHRlZENvbnRlbnQu'
|
||||
'TWVzc2FnZVVwZGF0ZUgHUg1tZXNzYWdlVXBkYXRliAEBEjIKBW1lZGlhGAYgASgLMhcuRW5jcn'
|
||||
'lwdGVkQ29udGVudC5NZWRpYUgIUgVtZWRpYYgBARJFCgxtZWRpYV91cGRhdGUYByABKAsyHS5F'
|
||||
'bmNyeXB0ZWRDb250ZW50Lk1lZGlhVXBkYXRlSAlSC21lZGlhVXBkYXRliAEBEksKDmNvbnRhY3'
|
||||
'RfdXBkYXRlGAggASgLMh8uRW5jcnlwdGVkQ29udGVudC5Db250YWN0VXBkYXRlSApSDWNvbnRh'
|
||||
'Y3RVcGRhdGWIAQESTgoPY29udGFjdF9yZXF1ZXN0GAkgASgLMiAuRW5jcnlwdGVkQ29udGVudC'
|
||||
'5Db250YWN0UmVxdWVzdEgLUg5jb250YWN0UmVxdWVzdIgBARI/CgpmbGFtZV9zeW5jGAogASgL'
|
||||
'MhsuRW5jcnlwdGVkQ29udGVudC5GbGFtZVN5bmNIDFIJZmxhbWVTeW5jiAEBEjsKCHJlYWN0aW'
|
||||
'9uGAwgASgLMhouRW5jcnlwdGVkQ29udGVudC5SZWFjdGlvbkgNUghyZWFjdGlvbogBARJFCgx0'
|
||||
'ZXh0X21lc3NhZ2UYDSABKAsyHS5FbmNyeXB0ZWRDb250ZW50LlRleHRNZXNzYWdlSA5SC3RleH'
|
||||
'RNZXNzYWdliAEBEkUKDGdyb3VwX2NyZWF0ZRgOIAEoCzIdLkVuY3J5cHRlZENvbnRlbnQuR3Jv'
|
||||
'dXBDcmVhdGVID1ILZ3JvdXBDcmVhdGWIAQESPwoKZ3JvdXBfam9pbhgPIAEoCzIbLkVuY3J5cH'
|
||||
'RlZENvbnRlbnQuR3JvdXBKb2luSBBSCWdyb3VwSm9pbogBARJFCgxncm91cF91cGRhdGUYECAB'
|
||||
'KAsyHS5FbmNyeXB0ZWRDb250ZW50Lkdyb3VwVXBkYXRlSBFSC2dyb3VwVXBkYXRliAEBEmIKF3'
|
||||
'Jlc2VuZF9ncm91cF9wdWJsaWNfa2V5GBEgASgLMiYuRW5jcnlwdGVkQ29udGVudC5SZXNlbmRH'
|
||||
'cm91cFB1YmxpY0tleUgSUhRyZXNlbmRHcm91cFB1YmxpY0tleYgBARJLCg5lcnJvcl9tZXNzYW'
|
||||
'dlcxgSIAEoCzIfLkVuY3J5cHRlZENvbnRlbnQuRXJyb3JNZXNzYWdlc0gTUg1lcnJvck1lc3Nh'
|
||||
'Z2VziAEBEmQKF2FkZGl0aW9uYWxfZGF0YV9tZXNzYWdlGBMgASgLMicuRW5jcnlwdGVkQ29udG'
|
||||
'VudC5BZGRpdGlvbmFsRGF0YU1lc3NhZ2VIFFIVYWRkaXRpb25hbERhdGFNZXNzYWdliAEBElEK'
|
||||
'EHR5cGluZ19pbmRpY2F0b3IYFCABKAsyIS5FbmNyeXB0ZWRDb250ZW50LlR5cGluZ0luZGljYX'
|
||||
'RvckgVUg90eXBpbmdJbmRpY2F0b3KIAQESYQoWdXNlcl9kaXNjb3ZlcnlfcmVxdWVzdBgWIAEo'
|
||||
'CzImLkVuY3J5cHRlZENvbnRlbnQuVXNlckRpc2NvdmVyeVJlcXVlc3RIFlIUdXNlckRpc2Nvdm'
|
||||
'VyeVJlcXVlc3SIAQESXgoVdXNlcl9kaXNjb3ZlcnlfdXBkYXRlGBcgASgLMiUuRW5jcnlwdGVk'
|
||||
'Q29udGVudC5Vc2VyRGlzY292ZXJ5VXBkYXRlSBdSE3VzZXJEaXNjb3ZlcnlVcGRhdGWIAQESYQ'
|
||||
'oWa2V5X3ZlcmlmaWNhdGlvbl9wcm9vZhgYIAEoCzImLkVuY3J5cHRlZENvbnRlbnQuS2V5VmVy'
|
||||
'aWZpY2F0aW9uUHJvb2ZIGFIUa2V5VmVyaWZpY2F0aW9uUHJvb2aIAQESYAoVcGFzc3dvcmRsZX'
|
||||
'NzX3JlY292ZXJ5GBogASgLMiYuRW5jcnlwdGVkQ29udGVudC5QYXNzd29yZExlc3NSZWNvdmVy'
|
||||
'eUgZUhRwYXNzd29yZGxlc3NSZWNvdmVyeYgBARJ8Ch9wYXNzd29yZGxlc3NfcmVjb3ZlcnlfaG'
|
||||
'VhcnRiZWF0GBsgASgLMi8uRW5jcnlwdGVkQ29udGVudC5QYXNzd29yZExlc3NSZWNvdmVyeUhl'
|
||||
'YXJ0YmVhdEgaUh1wYXNzd29yZGxlc3NSZWNvdmVyeUhlYXJ0YmVhdIgBARIyCgVzdG9yeRgeIA'
|
||||
'EoCzIXLkVuY3J5cHRlZENvbnRlbnQuU3RvcnlIG1IFc3RvcnmIAQEalgIKDUVycm9yTWVzc2Fn'
|
||||
'ZXMSOAoEdHlwZRgBIAEoDjIkLkVuY3J5cHRlZENvbnRlbnQuRXJyb3JNZXNzYWdlcy5UeXBlUg'
|
||||
'R0eXBlEiwKEnJlbGF0ZWRfcmVjZWlwdF9pZBgCIAEoCVIQcmVsYXRlZFJlY2VpcHRJZCKcAQoE'
|
||||
'VHlwZRI8CjhFUlJPUl9QUk9DRVNTSU5HX01FU1NBR0VfQ1JFQVRFRF9BQ0NPVU5UX1JFUVVFU1'
|
||||
'RfSU5TVEVBRBAAEhgKFFVOS05PV05fTUVTU0FHRV9UWVBFEAISFwoTU0VTU0lPTl9PVVRfT0Zf'
|
||||
'U1lOQxADEiMKH0dST1VQX05PVF9GT1VORF9PUl9OT1RfQV9NRU1CRVIQBBqHAQoLR3JvdXBDcm'
|
||||
'VhdGUSGwoJc3RhdGVfa2V5GAMgASgMUghzdGF0ZUtleRIoChBncm91cF9wdWJsaWNfa2V5GAQg'
|
||||
'ASgMUg5ncm91cFB1YmxpY0tleRIiCgpncm91cF9uYW1lGAUgASgJSABSCWdyb3VwTmFtZYgBAU'
|
||||
'INCgtfZ3JvdXBfbmFtZRo1CglHcm91cEpvaW4SKAoQZ3JvdXBfcHVibGljX2tleRgBIAEoDFIO'
|
||||
'Z3JvdXBQdWJsaWNLZXkaFgoUUmVzZW5kR3JvdXBQdWJsaWNLZXkayAIKC0dyb3VwVXBkYXRlEi'
|
||||
'oKEWdyb3VwX2FjdGlvbl90eXBlGAEgASgJUg9ncm91cEFjdGlvblR5cGUSMwoTYWZmZWN0ZWRf'
|
||||
'Y29udGFjdF9pZBgCIAEoA0gAUhFhZmZlY3RlZENvbnRhY3RJZIgBARIpCg5uZXdfZ3JvdXBfbm'
|
||||
'FtZRgDIAEoCUgBUgxuZXdHcm91cE5hbWWIAQESVwombmV3X2RlbGV0ZV9tZXNzYWdlc19hZnRl'
|
||||
'cl9taWxsaXNlY29uZHMYBCABKANIAlIibmV3RGVsZXRlTWVzc2FnZXNBZnRlck1pbGxpc2Vjb2'
|
||||
'5kc4gBAUIWChRfYWZmZWN0ZWRfY29udGFjdF9pZEIRCg9fbmV3X2dyb3VwX25hbWVCKQonX25l'
|
||||
'd19kZWxldGVfbWVzc2FnZXNfYWZ0ZXJfbWlsbGlzZWNvbmRzGogCCgtUZXh0TWVzc2FnZRIqCh'
|
||||
'FzZW5kZXJfbWVzc2FnZV9pZBgBIAEoCVIPc2VuZGVyTWVzc2FnZUlkEhIKBHRleHQYAiABKAlS'
|
||||
'BHRleHQSHAoJdGltZXN0YW1wGAMgASgDUgl0aW1lc3RhbXASLQoQcXVvdGVfbWVzc2FnZV9pZB'
|
||||
'gEIAEoCUgAUg5xdW90ZU1lc3NhZ2VJZIgBARI7ChdhZGRpdGlvbmFsX21lc3NhZ2VfZGF0YRgF'
|
||||
'IAEoDEgBUhVhZGRpdGlvbmFsTWVzc2FnZURhdGGIAQFCEwoRX3F1b3RlX21lc3NhZ2VfaWRCGg'
|
||||
'oYX2FkZGl0aW9uYWxfbWVzc2FnZV9kYXRhGuYBChVBZGRpdGlvbmFsRGF0YU1lc3NhZ2USKgoR'
|
||||
'c2VuZGVyX21lc3NhZ2VfaWQYASABKAlSD3NlbmRlck1lc3NhZ2VJZBIcCgl0aW1lc3RhbXAYAi'
|
||||
'ABKANSCXRpbWVzdGFtcBISCgR0eXBlGAMgASgJUgR0eXBlEjsKF2FkZGl0aW9uYWxfbWVzc2Fn'
|
||||
'ZV9kYXRhGAQgASgMSABSFWFkZGl0aW9uYWxNZXNzYWdlRGF0YYgBARIWCgZoaWRkZW4YBSABKA'
|
||||
'hSBmhpZGRlbkIaChhfYWRkaXRpb25hbF9tZXNzYWdlX2RhdGEaZAoIUmVhY3Rpb24SKgoRdGFy'
|
||||
'Z2V0X21lc3NhZ2VfaWQYASABKAlSD3RhcmdldE1lc3NhZ2VJZBIUCgVlbW9qaRgCIAEoCVIFZW'
|
||||
'1vamkSFgoGcmVtb3ZlGAMgASgIUgZyZW1vdmUavgIKDU1lc3NhZ2VVcGRhdGUSOAoEdHlwZRgB'
|
||||
'IAEoDjIkLkVuY3J5cHRlZENvbnRlbnQuTWVzc2FnZVVwZGF0ZS5UeXBlUgR0eXBlEi8KEXNlbm'
|
||||
'Rlcl9tZXNzYWdlX2lkGAIgASgJSABSD3NlbmRlck1lc3NhZ2VJZIgBARI9ChttdWx0aXBsZV90'
|
||||
'YXJnZXRfbWVzc2FnZV9pZHMYAyADKAlSGG11bHRpcGxlVGFyZ2V0TWVzc2FnZUlkcxIXCgR0ZX'
|
||||
'h0GAQgASgJSAFSBHRleHSIAQESHAoJdGltZXN0YW1wGAUgASgDUgl0aW1lc3RhbXAiLQoEVHlw'
|
||||
'ZRIKCgZERUxFVEUQABINCglFRElUX1RFWFQQARIKCgZPUEVORUQQAkIUChJfc2VuZGVyX21lc3'
|
||||
'NhZ2VfaWRCBwoFX3RleHQauwYKBU1lZGlhEioKEXNlbmRlcl9tZXNzYWdlX2lkGAEgASgJUg9z'
|
||||
'ZW5kZXJNZXNzYWdlSWQSMAoEdHlwZRgCIAEoDjIcLkVuY3J5cHRlZENvbnRlbnQuTWVkaWEuVH'
|
||||
'lwZVIEdHlwZRJGCh1kaXNwbGF5X2xpbWl0X2luX21pbGxpc2Vjb25kcxgDIAEoA0gAUhpkaXNw'
|
||||
'bGF5TGltaXRJbk1pbGxpc2Vjb25kc4gBARI3ChdyZXF1aXJlc19hdXRoZW50aWNhdGlvbhgEIA'
|
||||
'EoCFIWcmVxdWlyZXNBdXRoZW50aWNhdGlvbhIcCgl0aW1lc3RhbXAYBSABKANSCXRpbWVzdGFt'
|
||||
'cBItChBxdW90ZV9tZXNzYWdlX2lkGAYgASgJSAFSDnF1b3RlTWVzc2FnZUlkiAEBEioKDmRvd2'
|
||||
'5sb2FkX3Rva2VuGAcgASgMSAJSDWRvd25sb2FkVG9rZW6IAQESKgoOZW5jcnlwdGlvbl9rZXkY'
|
||||
'CCABKAxIA1INZW5jcnlwdGlvbktleYgBARIqCg5lbmNyeXB0aW9uX21hYxgJIAEoDEgEUg1lbm'
|
||||
'NyeXB0aW9uTWFjiAEBEi4KEGVuY3J5cHRpb25fbm9uY2UYCiABKAxIBVIPZW5jcnlwdGlvbk5v'
|
||||
'bmNliAEBEjsKF2FkZGl0aW9uYWxfbWVzc2FnZV9kYXRhGAsgASgMSAZSFWFkZGl0aW9uYWxNZX'
|
||||
'NzYWdlRGF0YYgBARIkCgt3aWRnZXRfb25seRgMIAEoCEgHUgp3aWRnZXRPbmx5iAEBIj4KBFR5'
|
||||
'cGUSDAoIUkVVUExPQUQQABIJCgVJTUFHRRABEgkKBVZJREVPEAISBwoDR0lGEAMSCQoFQVVESU'
|
||||
'8QBEIgCh5fZGlzcGxheV9saW1pdF9pbl9taWxsaXNlY29uZHNCEwoRX3F1b3RlX21lc3NhZ2Vf'
|
||||
'aWRCEQoPX2Rvd25sb2FkX3Rva2VuQhEKD19lbmNyeXB0aW9uX2tleUIRCg9fZW5jcnlwdGlvbl'
|
||||
'9tYWNCEwoRX2VuY3J5cHRpb25fbm9uY2VCGgoYX2FkZGl0aW9uYWxfbWVzc2FnZV9kYXRhQg4K'
|
||||
'DF93aWRnZXRfb25seRpOCgVTdG9yeRItCgVtZWRpYRgBIAEoCzIXLkVuY3J5cHRlZENvbnRlbn'
|
||||
'QuTWVkaWFSBW1lZGlhEhYKBm5vdGlmeRgCIAEoCFIGbm90aWZ5GqkBCgtNZWRpYVVwZGF0ZRI2'
|
||||
'CgR0eXBlGAEgASgOMiIuRW5jcnlwdGVkQ29udGVudC5NZWRpYVVwZGF0ZS5UeXBlUgR0eXBlEi'
|
||||
'oKEXRhcmdldF9tZXNzYWdlX2lkGAIgASgJUg90YXJnZXRNZXNzYWdlSWQiNgoEVHlwZRIMCghS'
|
||||
'RU9QRU5FRBAAEgoKBlNUT1JFRBABEhQKEERFQ1JZUFRJT05fRVJST1IQAhp4Cg5Db250YWN0Um'
|
||||
'VxdWVzdBI5CgR0eXBlGAEgASgOMiUuRW5jcnlwdGVkQ29udGVudC5Db250YWN0UmVxdWVzdC5U'
|
||||
'eXBlUgR0eXBlIisKBFR5cGUSCwoHUkVRVUVTVBAAEgoKBlJFSkVDVBABEgoKBkFDQ0VQVBACGq'
|
||||
'QCCg1Db250YWN0VXBkYXRlEjgKBHR5cGUYASABKA4yJC5FbmNyeXB0ZWRDb250ZW50LkNvbnRh'
|
||||
'Y3RVcGRhdGUuVHlwZVIEdHlwZRI3ChVhdmF0YXJfc3ZnX2NvbXByZXNzZWQYAiABKAxIAFITYX'
|
||||
'ZhdGFyU3ZnQ29tcHJlc3NlZIgBARIfCgh1c2VybmFtZRgDIAEoCUgBUgh1c2VybmFtZYgBARIm'
|
||||
'CgxkaXNwbGF5X25hbWUYBCABKAlIAlILZGlzcGxheU5hbWWIAQEiHwoEVHlwZRILCgdSRVFVRV'
|
||||
'NUEAASCgoGVVBEQVRFEAFCGAoWX2F2YXRhcl9zdmdfY29tcHJlc3NlZEILCglfdXNlcm5hbWVC'
|
||||
'DwoNX2Rpc3BsYXlfbmFtZRqvAQoJRmxhbWVTeW5jEiMKDWZsYW1lX2NvdW50ZXIYASABKANSDG'
|
||||
'ZsYW1lQ291bnRlchI5ChlsYXN0X2ZsYW1lX2NvdW50ZXJfY2hhbmdlGAIgASgDUhZsYXN0Rmxh'
|
||||
'bWVDb3VudGVyQ2hhbmdlEh8KC2Jlc3RfZnJpZW5kGAMgASgIUgpiZXN0RnJpZW5kEiEKDGZvcm'
|
||||
'NlX3VwZGF0ZRgEIAEoCFILZm9yY2VVcGRhdGUaTQoPVHlwaW5nSW5kaWNhdG9yEhsKCWlzX3R5'
|
||||
'cGluZxgBIAEoCFIIaXNUeXBpbmcSHQoKY3JlYXRlZF9hdBgCIAEoA1IJY3JlYXRlZEF0Gj8KFF'
|
||||
'VzZXJEaXNjb3ZlcnlSZXF1ZXN0EicKD2N1cnJlbnRfdmVyc2lvbhgBIAEoDFIOY3VycmVudFZl'
|
||||
'cnNpb24aMQoTVXNlckRpc2NvdmVyeVVwZGF0ZRIaCghtZXNzYWdlcxgBIAMoDFIIbWVzc2FnZX'
|
||||
'MaPQoUS2V5VmVyaWZpY2F0aW9uUHJvb2YSJQoOY2FsY3VsYXRlZF9tYWMYASABKAxSDWNhbGN1'
|
||||
'bGF0ZWRNYWMamwEKFFBhc3N3b3JkTGVzc1JlY292ZXJ5EjUKE3JlY292ZXJ5U2VjcmV0U2hhcm'
|
||||
'UYASABKAxIAFITcmVjb3ZlcnlTZWNyZXRTaGFyZYgBARIWCgZkZWxldGUYAiABKAhSBmRlbGV0'
|
||||
'ZRIcCgl0aHJlc2hvbGQYAyABKANSCXRocmVzaG9sZEIWChRfcmVjb3ZlcnlTZWNyZXRTaGFyZR'
|
||||
'ozCh1QYXNzd29yZExlc3NSZWNvdmVyeUhlYXJ0YmVhdBISCgRoYXNoGAEgASgMUgRoYXNoQgsK'
|
||||
'CV9ncm91cF9pZEIRCg9faXNfZGlyZWN0X2NoYXRCGQoXX3NlbmRlcl9wcm9maWxlX2NvdW50ZX'
|
||||
'JCIAoeX3NlbmRlcl91c2VyX2Rpc2NvdmVyeV92ZXJzaW9uQhwKGl9hc2tfZm9yX2ZyaWVuZF9w'
|
||||
'cm9tb3Rpb25zQhkKF193aWRnZXRfc2hhcmluZ19hbGxvd2VkQhYKFF9zZW5kZXJfdHdvbmx5X3'
|
||||
'Njb3JlQhEKD19tZXNzYWdlX3VwZGF0ZUIICgZfbWVkaWFCDwoNX21lZGlhX3VwZGF0ZUIRCg9f'
|
||||
'Y29udGFjdF91cGRhdGVCEgoQX2NvbnRhY3RfcmVxdWVzdEINCgtfZmxhbWVfc3luY0ILCglfcm'
|
||||
'VhY3Rpb25CDwoNX3RleHRfbWVzc2FnZUIPCg1fZ3JvdXBfY3JlYXRlQg0KC19ncm91cF9qb2lu'
|
||||
'Qg8KDV9ncm91cF91cGRhdGVCGgoYX3Jlc2VuZF9ncm91cF9wdWJsaWNfa2V5QhEKD19lcnJvcl'
|
||||
'9tZXNzYWdlc0IaChhfYWRkaXRpb25hbF9kYXRhX21lc3NhZ2VCEwoRX3R5cGluZ19pbmRpY2F0'
|
||||
'b3JCGQoXX3VzZXJfZGlzY292ZXJ5X3JlcXVlc3RCGAoWX3VzZXJfZGlzY292ZXJ5X3VwZGF0ZU'
|
||||
'IZChdfa2V5X3ZlcmlmaWNhdGlvbl9wcm9vZkIYChZfcGFzc3dvcmRsZXNzX3JlY292ZXJ5QiIK'
|
||||
'IF9wYXNzd29yZGxlc3NfcmVjb3ZlcnlfaGVhcnRiZWF0QggKBl9zdG9yeUoECBwQHQ==');
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import 'package:twonly/src/visual/views/settings/help/news.view.dart';
|
|||
import 'package:twonly/src/visual/views/settings/notification.view.dart';
|
||||
import 'package:twonly/src/visual/views/settings/privacy.view.dart';
|
||||
import 'package:twonly/src/visual/views/settings/privacy/block_users.view.dart';
|
||||
import 'package:twonly/src/visual/views/settings/privacy/public_profile.view.dart';
|
||||
import 'package:twonly/src/visual/views/settings/privacy/user_discovery.view.dart';
|
||||
import 'package:twonly/src/visual/views/settings/profile/modify_avatar.view.dart';
|
||||
import 'package:twonly/src/visual/views/settings/profile/profile.view.dart';
|
||||
|
|
@ -241,6 +242,10 @@ final routerProvider = GoRouter(
|
|||
path: 'user_discovery',
|
||||
builder: (context, state) => const UserDiscoverySettingsView(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'public_profile',
|
||||
builder: (context, state) => const PublicProfilePrivacyView(),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import 'package:twonly/src/visual/components/select_chat_deletion_time.comp.dart
|
|||
import 'package:twonly/src/visual/components/snackbar.dart';
|
||||
import 'package:twonly/src/visual/components/verification_badge.comp.dart';
|
||||
import 'package:twonly/src/visual/elements/better_list_title.element.dart';
|
||||
import 'package:twonly/src/visual/elements/my_chip.element.dart';
|
||||
import 'package:twonly/src/visual/views/contact/contact_components/mutual_groups_expansion_tile.comp.dart';
|
||||
import 'package:twonly/src/visual/views/contact/contact_components/restore_flame.comp.dart';
|
||||
import 'package:twonly/src/visual/views/contact/contact_components/verification_expansion_tile.comp.dart';
|
||||
|
|
@ -225,6 +226,39 @@ class _ContactViewState extends State<ContactView> {
|
|||
),
|
||||
if (getContactDisplayName(contact) != contact.username)
|
||||
Center(child: Text('(${contact.username})')),
|
||||
if (contact.twonlyScore != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Center(
|
||||
child: IntrinsicWidth(
|
||||
child: MyChip(
|
||||
label: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const FaIcon(FontAwesomeIcons.trophy, size: 14),
|
||||
const SizedBox(width: 7),
|
||||
Text('${contact.twonlyScore}'),
|
||||
],
|
||||
),
|
||||
onTap: () => showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text(context.lang.publicProfileTwonlyScore),
|
||||
content: Text(
|
||||
context.lang.contactTwonlyScoreDescription,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text(context.lang.ok),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 50),
|
||||
BetterListTile(
|
||||
icon: FontAwesomeIcons.solidComments,
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ class _PrivacyViewState extends State<PrivacyView> {
|
|||
),
|
||||
body: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: Text(context.lang.publicProfilePrivacyTitle),
|
||||
onTap: () => context.push(Routes.settingsPrivacyPublicProfile),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(context.lang.settingsPrivacyBlockUsers),
|
||||
subtitle: StreamBuilder(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:twonly/core/user_config.dart';
|
||||
import 'package:twonly/locator.dart';
|
||||
import 'package:twonly/src/services/user.service.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
||||
class PublicProfilePrivacyView extends StatefulWidget {
|
||||
const PublicProfilePrivacyView({super.key});
|
||||
|
||||
@override
|
||||
State<PublicProfilePrivacyView> createState() =>
|
||||
_PublicProfilePrivacyViewState();
|
||||
}
|
||||
|
||||
class _PublicProfilePrivacyViewState extends State<PublicProfilePrivacyView> {
|
||||
Future<void> _setTwonlyScoreVisibility(
|
||||
TwonlyScoreVisibility visibility,
|
||||
) async {
|
||||
await UserService.update((user) {
|
||||
user.twonlyScoreVisibility = visibility;
|
||||
});
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
|
||||
String _visibilityLabel(TwonlyScoreVisibility visibility) {
|
||||
return switch (visibility) {
|
||||
TwonlyScoreVisibility.nobody => context.lang.privacyVisibilityNobody,
|
||||
TwonlyScoreVisibility.onlyContacts =>
|
||||
context.lang.privacyVisibilityOnlyContacts,
|
||||
TwonlyScoreVisibility.everyone => context.lang.privacyVisibilityEveryone,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(context.lang.publicProfilePrivacyTitle)),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Text(
|
||||
context.lang.publicProfilePrivacyDescription,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: context.color.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
ListTile(
|
||||
title: Text(context.lang.publicProfileTwonlyScore),
|
||||
trailing: DropdownButtonHideUnderline(
|
||||
child: DropdownButton<TwonlyScoreVisibility>(
|
||||
value: userService.currentUser.twonlyScoreVisibility,
|
||||
items: TwonlyScoreVisibility.values
|
||||
.map(
|
||||
(visibility) => DropdownMenuItem(
|
||||
value: visibility,
|
||||
child: Text(_visibilityLabel(visibility)),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: (visibility) {
|
||||
if (visibility != null) {
|
||||
_setTwonlyScoreVisibility(visibility);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE contacts SET twonly_score = ? WHERE user_id = ?",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "1b8401b1ec6cbb52dfc4ce32b2bf73900eec826b2ca2029a05a0125024ee071d"
|
||||
}
|
||||
|
|
@ -321,6 +321,17 @@
|
|||
"name": "widget_sharing_granted"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "twonly_score",
|
||||
"ordinal": 29,
|
||||
"type_info": "Integer",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "contacts",
|
||||
"name": "twonly_score"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
|
|
@ -355,7 +366,8 @@
|
|||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "c618a305e1355fcefa5c8420544779b5fe4f003a16ba01ee2834f028fabf213f"
|
||||
|
|
|
|||
|
|
@ -794,6 +794,8 @@ async fn handle_encrypted_inner(
|
|||
return contact::handle_contact_request(ctx, t, from_user_id, request).await;
|
||||
}
|
||||
|
||||
Contact::update_twonly_score(t, from_user_id, content.sender_twonly_score).await?;
|
||||
|
||||
if let Some(update) = content.contact_update {
|
||||
return contact::handle_contact_update(
|
||||
ctx,
|
||||
|
|
@ -970,6 +972,57 @@ async fn handle_encrypted_inner(
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn incoming_twonly_score_is_stored_and_missing_score_clears_it() -> Result<()> {
|
||||
let directory = tempfile::tempdir()?;
|
||||
let ctx = Context::init_for_testing(
|
||||
directory.path().join("database"),
|
||||
directory.path().join("data"),
|
||||
)
|
||||
.await?;
|
||||
let database = ctx.app_db.read().await.clone();
|
||||
sqlx::query("INSERT INTO contacts(user_id, username) VALUES (7, 'alice')")
|
||||
.execute(&database.pool)
|
||||
.await?;
|
||||
|
||||
let mut transaction = database.pool.begin().await?;
|
||||
handle_encrypted_inner(
|
||||
&ctx,
|
||||
&mut transaction,
|
||||
7,
|
||||
"score-present",
|
||||
proto::EncryptedContent {
|
||||
sender_twonly_score: Some(23),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
transaction.commit().await?;
|
||||
let score: Option<i64> =
|
||||
sqlx::query_scalar("SELECT twonly_score FROM contacts WHERE user_id = 7")
|
||||
.fetch_one(&database.pool)
|
||||
.await?;
|
||||
assert_eq!(score, Some(23));
|
||||
|
||||
let mut transaction = database.pool.begin().await?;
|
||||
handle_encrypted_inner(
|
||||
&ctx,
|
||||
&mut transaction,
|
||||
7,
|
||||
"score-missing",
|
||||
proto::EncryptedContent::default(),
|
||||
)
|
||||
.await?;
|
||||
transaction.commit().await?;
|
||||
let score: Option<i64> =
|
||||
sqlx::query_scalar("SELECT twonly_score FROM contacts WHERE user_id = 7")
|
||||
.fetch_one(&database.pool)
|
||||
.await?;
|
||||
assert_eq!(score, None);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn copies_of_one_receipt_share_a_lock_until_the_last_one_goes() {
|
||||
let receipt_id = "in-flight-registry-test";
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use crate::api::messages::incoming::messages;
|
|||
use crate::api::proto::client as proto;
|
||||
use crate::context::Context;
|
||||
use crate::error::Result;
|
||||
use crate::user_config::UserConfig;
|
||||
use crate::user_config::{TwonlyScoreVisibility, UserConfig};
|
||||
use prost::Message as _;
|
||||
use sqlx::{Sqlite, Transaction};
|
||||
use std::sync::Arc;
|
||||
|
|
@ -66,6 +66,31 @@ pub(crate) async fn decorate_content(
|
|||
.unwrap_or(0)
|
||||
!= 0,
|
||||
);
|
||||
let share_twonly_score = match config.twonly_score_visibility {
|
||||
TwonlyScoreVisibility::Nobody => false,
|
||||
TwonlyScoreVisibility::OnlyContacts => {
|
||||
sqlx::query_scalar!(
|
||||
"SELECT accepted FROM contacts WHERE user_id = ?",
|
||||
contact_id,
|
||||
)
|
||||
.fetch_optional(&mut **t)
|
||||
.await?
|
||||
.unwrap_or(0)
|
||||
!= 0
|
||||
}
|
||||
TwonlyScoreVisibility::Everyone => true,
|
||||
};
|
||||
content.sender_twonly_score = if share_twonly_score {
|
||||
Some(
|
||||
sqlx::query_scalar::<_, i64>(
|
||||
"SELECT COALESCE(SUM(total_media_counter), 0) FROM groups",
|
||||
)
|
||||
.fetch_one(&mut **t)
|
||||
.await?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if config.ask_for_friend_promotions {
|
||||
let accepted = sqlx::query_scalar!("SELECT COUNT(*) FROM contacts WHERE accepted = 1")
|
||||
.fetch_one(&mut **t)
|
||||
|
|
@ -203,3 +228,73 @@ pub async fn send_c2c_message_to_contact(
|
|||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn twonly_score_respects_recipient_visibility() -> Result<()> {
|
||||
let directory = tempfile::tempdir()?;
|
||||
let ctx = Context::init_for_testing(
|
||||
directory.path().join("database"),
|
||||
directory.path().join("data"),
|
||||
)
|
||||
.await?;
|
||||
UserConfig::save_json(
|
||||
&ctx,
|
||||
r#"{"userId":42,"username":"ben","displayName":"Ben"}"#,
|
||||
)?;
|
||||
|
||||
let database = ctx.app_db.read().await.clone();
|
||||
sqlx::query("INSERT INTO contacts(user_id, username) VALUES (7, 'anna')")
|
||||
.execute(&database.pool)
|
||||
.await?;
|
||||
sqlx::query(
|
||||
"INSERT INTO groups(group_id, group_name, total_media_counter) VALUES ('a', 'A', 4), ('b', 'B', 7)",
|
||||
)
|
||||
.execute(&database.pool)
|
||||
.await?;
|
||||
|
||||
let mut content = proto::EncryptedContent::default();
|
||||
let mut transaction = database.pool.begin().await?;
|
||||
decorate_content(&ctx, &mut transaction, 7, &mut content, false).await?;
|
||||
transaction.rollback().await?;
|
||||
assert_eq!(content.sender_twonly_score, Some(11));
|
||||
|
||||
UserConfig::update(&ctx, |config| {
|
||||
config.twonly_score_visibility = TwonlyScoreVisibility::OnlyContacts;
|
||||
})?;
|
||||
let mut hidden_content = proto::EncryptedContent {
|
||||
sender_twonly_score: Some(999),
|
||||
..Default::default()
|
||||
};
|
||||
let mut transaction = database.pool.begin().await?;
|
||||
decorate_content(&ctx, &mut transaction, 7, &mut hidden_content, false).await?;
|
||||
transaction.rollback().await?;
|
||||
assert_eq!(hidden_content.sender_twonly_score, None);
|
||||
|
||||
sqlx::query("UPDATE contacts SET accepted = 1 WHERE user_id = 7")
|
||||
.execute(&database.pool)
|
||||
.await?;
|
||||
let mut contact_content = proto::EncryptedContent::default();
|
||||
let mut transaction = database.pool.begin().await?;
|
||||
decorate_content(&ctx, &mut transaction, 7, &mut contact_content, false).await?;
|
||||
transaction.rollback().await?;
|
||||
assert_eq!(contact_content.sender_twonly_score, Some(11));
|
||||
|
||||
UserConfig::update(&ctx, |config| {
|
||||
config.twonly_score_visibility = TwonlyScoreVisibility::Nobody;
|
||||
})?;
|
||||
let mut nobody_content = proto::EncryptedContent {
|
||||
sender_twonly_score: Some(999),
|
||||
..Default::default()
|
||||
};
|
||||
let mut transaction = database.pool.begin().await?;
|
||||
decorate_content(&ctx, &mut transaction, 7, &mut nobody_content, false).await?;
|
||||
transaction.rollback().await?;
|
||||
assert_eq!(nobody_content.sender_twonly_score, None);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ message EncryptedContent {
|
|||
optional bool ask_for_friend_promotions = 25;
|
||||
reserved 28;
|
||||
optional bool widget_sharing_allowed = 29;
|
||||
// Sum of all exchanged media, omitted when profile sharing is disabled.
|
||||
optional int64 sender_twonly_score = 31;
|
||||
|
||||
optional MessageUpdate message_update = 5;
|
||||
optional Media media = 6;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
-- A contact's latest publicly shared twonly Score. NULL means that the
|
||||
-- contact does not currently share it.
|
||||
ALTER TABLE contacts ADD COLUMN twonly_score INTEGER;
|
||||
|
|
@ -16,7 +16,7 @@ mod legacy_import;
|
|||
pub mod tables;
|
||||
|
||||
pub const APP_DATABASE_FILE: &str = "app_db.sqlite";
|
||||
pub const APP_SCHEMA_VERSION: i64 = 13;
|
||||
pub const APP_SCHEMA_VERSION: i64 = 14;
|
||||
|
||||
/// User-owned application tables in the current Rust schema. Rust-only outbox
|
||||
/// tables are deliberately absent because they are reconstructed locally.
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ pub struct Contact {
|
|||
pub media_received_counter: i64,
|
||||
pub widget_sharing_allowed: i64,
|
||||
pub widget_sharing_granted: i64,
|
||||
pub twonly_score: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(bon::Builder)]
|
||||
|
|
@ -206,6 +207,21 @@ impl Contact {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn update_twonly_score(
|
||||
t: &mut Transaction<'_, Sqlite>,
|
||||
user_id: i64,
|
||||
score: Option<i64>,
|
||||
) -> Result<()> {
|
||||
sqlx::query!(
|
||||
"UPDATE contacts SET twonly_score = ? WHERE user_id = ?",
|
||||
score,
|
||||
user_id,
|
||||
)
|
||||
.execute(&mut **t)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn is_user_discovery_allowed(
|
||||
context: &Context,
|
||||
t: &mut Transaction<'_, Sqlite>,
|
||||
|
|
|
|||
|
|
@ -7830,6 +7830,19 @@ impl SseDecode for crate::user_config::TwonlySafeBackup {
|
|||
}
|
||||
}
|
||||
|
||||
impl SseDecode for crate::user_config::TwonlyScoreVisibility {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
let mut inner = <i32>::sse_decode(deserializer);
|
||||
return match inner {
|
||||
0 => crate::user_config::TwonlyScoreVisibility::Nobody,
|
||||
1 => crate::user_config::TwonlyScoreVisibility::OnlyContacts,
|
||||
2 => crate::user_config::TwonlyScoreVisibility::Everyone,
|
||||
_ => unreachable!("Invalid variant for TwonlyScoreVisibility: {}", inner),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl SseDecode for u16 {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||
|
|
@ -7918,6 +7931,8 @@ impl SseDecode for crate::user_config::UserConfig {
|
|||
let mut var_allowErrorTrackingViaSentry = <bool>::sse_decode(deserializer);
|
||||
let mut var_screenLockEnabled = <bool>::sse_decode(deserializer);
|
||||
let mut var_isCloudBackupEnabled = <bool>::sse_decode(deserializer);
|
||||
let mut var_twonlyScoreVisibility =
|
||||
<crate::user_config::TwonlyScoreVisibility>::sse_decode(deserializer);
|
||||
let mut var_isUserDiscoveryEnabled = <bool>::sse_decode(deserializer);
|
||||
let mut var_requiredSendImages = <i64>::sse_decode(deserializer);
|
||||
let mut var_userDiscoveryThreshold = <u8>::sse_decode(deserializer);
|
||||
|
|
@ -7986,6 +8001,7 @@ impl SseDecode for crate::user_config::UserConfig {
|
|||
allow_error_tracking_via_sentry: var_allowErrorTrackingViaSentry,
|
||||
screen_lock_enabled: var_screenLockEnabled,
|
||||
is_cloud_backup_enabled: var_isCloudBackupEnabled,
|
||||
twonly_score_visibility: var_twonlyScoreVisibility,
|
||||
is_user_discovery_enabled: var_isUserDiscoveryEnabled,
|
||||
required_send_images: var_requiredSendImages,
|
||||
user_discovery_threshold: var_userDiscoveryThreshold,
|
||||
|
|
@ -9202,6 +9218,28 @@ impl flutter_rust_bridge::IntoIntoDart<crate::user_config::TwonlySafeBackup>
|
|||
}
|
||||
}
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
impl flutter_rust_bridge::IntoDart for crate::user_config::TwonlyScoreVisibility {
|
||||
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
||||
match self {
|
||||
Self::Nobody => 0.into_dart(),
|
||||
Self::OnlyContacts => 1.into_dart(),
|
||||
Self::Everyone => 2.into_dart(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
|
||||
for crate::user_config::TwonlyScoreVisibility
|
||||
{
|
||||
}
|
||||
impl flutter_rust_bridge::IntoIntoDart<crate::user_config::TwonlyScoreVisibility>
|
||||
for crate::user_config::TwonlyScoreVisibility
|
||||
{
|
||||
fn into_into_dart(self) -> crate::user_config::TwonlyScoreVisibility {
|
||||
self
|
||||
}
|
||||
}
|
||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||
impl flutter_rust_bridge::IntoDart for crate::user_config::UserConfig {
|
||||
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
|
||||
[
|
||||
|
|
@ -9261,6 +9299,7 @@ impl flutter_rust_bridge::IntoDart for crate::user_config::UserConfig {
|
|||
.into_dart(),
|
||||
self.screen_lock_enabled.into_into_dart().into_dart(),
|
||||
self.is_cloud_backup_enabled.into_into_dart().into_dart(),
|
||||
self.twonly_score_visibility.into_into_dart().into_dart(),
|
||||
self.is_user_discovery_enabled.into_into_dart().into_dart(),
|
||||
self.required_send_images.into_into_dart().into_dart(),
|
||||
self.user_discovery_threshold.into_into_dart().into_dart(),
|
||||
|
|
@ -10344,6 +10383,23 @@ impl SseEncode for crate::user_config::TwonlySafeBackup {
|
|||
}
|
||||
}
|
||||
|
||||
impl SseEncode for crate::user_config::TwonlyScoreVisibility {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
<i32>::sse_encode(
|
||||
match self {
|
||||
crate::user_config::TwonlyScoreVisibility::Nobody => 0,
|
||||
crate::user_config::TwonlyScoreVisibility::OnlyContacts => 1,
|
||||
crate::user_config::TwonlyScoreVisibility::Everyone => 2,
|
||||
_ => {
|
||||
unimplemented!("");
|
||||
}
|
||||
},
|
||||
serializer,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl SseEncode for u16 {
|
||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||
|
|
@ -10445,6 +10501,10 @@ impl SseEncode for crate::user_config::UserConfig {
|
|||
<bool>::sse_encode(self.allow_error_tracking_via_sentry, serializer);
|
||||
<bool>::sse_encode(self.screen_lock_enabled, serializer);
|
||||
<bool>::sse_encode(self.is_cloud_backup_enabled, serializer);
|
||||
<crate::user_config::TwonlyScoreVisibility>::sse_encode(
|
||||
self.twonly_score_visibility,
|
||||
serializer,
|
||||
);
|
||||
<bool>::sse_encode(self.is_user_discovery_enabled, serializer);
|
||||
<i64>::sse_encode(self.required_send_images, serializer);
|
||||
<u8>::sse_encode(self.user_discovery_threshold, serializer);
|
||||
|
|
|
|||
|
|
@ -166,6 +166,41 @@ pub enum ThemeMode {
|
|||
Dark,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Serialize, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum TwonlyScoreVisibility {
|
||||
Nobody,
|
||||
OnlyContacts,
|
||||
#[default]
|
||||
Everyone,
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for TwonlyScoreVisibility {
|
||||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let value = serde_json::Value::deserialize(deserializer)?;
|
||||
match value {
|
||||
serde_json::Value::String(value) => match value.as_str() {
|
||||
"nobody" => Ok(Self::Nobody),
|
||||
"onlyContacts" => Ok(Self::OnlyContacts),
|
||||
"everyone" => Ok(Self::Everyone),
|
||||
_ => Err(serde::de::Error::custom(format!(
|
||||
"unknown twonly Score visibility: {value}"
|
||||
))),
|
||||
},
|
||||
// Migrate the boolean setting used by the first version of this
|
||||
// feature without changing an existing privacy choice.
|
||||
serde_json::Value::Bool(true) => Ok(Self::Everyone),
|
||||
serde_json::Value::Bool(false) => Ok(Self::Nobody),
|
||||
_ => Err(serde::de::Error::custom(
|
||||
"twonly Score visibility must be a visibility name",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[flutter_rust_bridge::frb(non_final)]
|
||||
|
|
@ -288,6 +323,11 @@ pub struct UserConfig {
|
|||
#[frb(non_final)]
|
||||
pub is_cloud_backup_enabled: bool,
|
||||
|
||||
/// Controls which recipients receive the current twonly Score in sender metadata.
|
||||
#[serde(default, alias = "shareTwonlyScore")]
|
||||
#[frb(non_final)]
|
||||
pub twonly_score_visibility: TwonlyScoreVisibility,
|
||||
|
||||
#[serde(default)]
|
||||
#[frb(non_final)]
|
||||
pub is_user_discovery_enabled: bool,
|
||||
|
|
@ -480,7 +520,9 @@ impl UserConfig {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{merge_changed_fields, UserConfig, MIN_USER_DISCOVERY_THRESHOLD};
|
||||
use super::{
|
||||
merge_changed_fields, TwonlyScoreVisibility, UserConfig, MIN_USER_DISCOVERY_THRESHOLD,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn parses_only_rust_fields_and_applies_defaults() {
|
||||
|
|
@ -503,10 +545,45 @@ mod tests {
|
|||
);
|
||||
|
||||
assert!(config.can_use_login_token_for_auth);
|
||||
assert_eq!(
|
||||
config.twonly_score_visibility,
|
||||
TwonlyScoreVisibility::Everyone
|
||||
);
|
||||
assert!(!config.is_user_discovery_enabled);
|
||||
assert_eq!(config.last_server_message_at, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn migrates_legacy_twonly_score_boolean() {
|
||||
let hidden: UserConfig = serde_json::from_str(
|
||||
r#"{
|
||||
"userId": 42,
|
||||
"username": "alice",
|
||||
"displayName": "Alice",
|
||||
"shareTwonlyScore": false
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
hidden.twonly_score_visibility,
|
||||
TwonlyScoreVisibility::Nobody
|
||||
);
|
||||
|
||||
let shared: UserConfig = serde_json::from_str(
|
||||
r#"{
|
||||
"userId": 42,
|
||||
"username": "alice",
|
||||
"displayName": "Alice",
|
||||
"shareTwonlyScore": true
|
||||
}"#,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
shared.twonly_score_visibility,
|
||||
TwonlyScoreVisibility::Everyone
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn normalizes_legacy_user_discovery_threshold() {
|
||||
let mut config: UserConfig = serde_json::from_str(
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ UserConfig testUserConfig({
|
|||
allowErrorTrackingViaSentry: false,
|
||||
screenLockEnabled: false,
|
||||
isCloudBackupEnabled: false,
|
||||
twonlyScoreVisibility: TwonlyScoreVisibility.everyone,
|
||||
isUserDiscoveryEnabled: false,
|
||||
requiredSendImages: 4,
|
||||
userDiscoveryThreshold: 3,
|
||||
|
|
|
|||
Loading…
Reference in a new issue