mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 09:28:41 +00:00
fix #289
This commit is contained in:
parent
07d36c133c
commit
8d45c8e9ce
24 changed files with 588 additions and 181 deletions
|
|
@ -229,7 +229,7 @@ func getPushNotificationText(pushNotification: PushNotification) -> (String, Str
|
||||||
.reactionToText: "hat mit {{content}} auf deinen Text reagiert.",
|
.reactionToText: "hat mit {{content}} auf deinen Text reagiert.",
|
||||||
.reactionToImage: "hat mit {{content}} auf dein Bild reagiert.",
|
.reactionToImage: "hat mit {{content}} auf dein Bild reagiert.",
|
||||||
.response: "hat dir{inGroup} geantwortet.",
|
.response: "hat dir{inGroup} geantwortet.",
|
||||||
.addedToGroup: "hat dich zu \"{{content}}\" hinzugefügt."
|
.addedToGroup: "hat dich zu \"{{content}}\" hinzugefügt.",
|
||||||
]
|
]
|
||||||
} else { // Default to English
|
} else { // Default to English
|
||||||
pushNotificationText = [
|
pushNotificationText = [
|
||||||
|
|
@ -247,7 +247,7 @@ func getPushNotificationText(pushNotification: PushNotification) -> (String, Str
|
||||||
.reactionToText: "has reacted with {{content}} to your text.",
|
.reactionToText: "has reacted with {{content}} to your text.",
|
||||||
.reactionToImage: "has reacted with {{content}} to your image.",
|
.reactionToImage: "has reacted with {{content}} to your image.",
|
||||||
.response: "has responded{inGroup}.",
|
.response: "has responded{inGroup}.",
|
||||||
.addedToGroup: "has added you to \"{{content}}\""
|
.addedToGroup: "has added you to \"{{content}}\"",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,9 +257,10 @@ func getPushNotificationText(pushNotification: PushNotification) -> (String, Str
|
||||||
content.replace("{{content}}", with: pushNotification.additionalContent)
|
content.replace("{{content}}", with: pushNotification.additionalContent)
|
||||||
content.replace("{inGroup}", with: " in {inGroup}")
|
content.replace("{inGroup}", with: " in {inGroup}")
|
||||||
content.replace("{inGroup}", with: pushNotification.additionalContent)
|
content.replace("{inGroup}", with: pushNotification.additionalContent)
|
||||||
|
} else {
|
||||||
|
content.replace("{inGroup}", with: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the corresponding message or an empty string if not found
|
// Return the corresponding message or an empty string if not found
|
||||||
return (content, title)
|
return (content, title)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,10 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
||||||
return entry != null;
|
return entry != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> deleteGroup(String groupId) async {
|
||||||
|
await (delete(groups)..where((t) => t.groupId.equals(groupId))).go();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> updateGroup(
|
Future<void> updateGroup(
|
||||||
String groupId,
|
String groupId,
|
||||||
GroupsCompanion updates,
|
GroupsCompanion updates,
|
||||||
|
|
@ -42,7 +46,8 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
||||||
..where(
|
..where(
|
||||||
(t) =>
|
(t) =>
|
||||||
t.groupId.equals(groupId) &
|
t.groupId.equals(groupId) &
|
||||||
t.memberState.equals(MemberState.leftGroup.name).not(),
|
(t.memberState.equals(MemberState.leftGroup.name).not() |
|
||||||
|
t.memberState.isNull()),
|
||||||
))
|
))
|
||||||
.get();
|
.get();
|
||||||
}
|
}
|
||||||
|
|
@ -131,8 +136,9 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
||||||
|
|
||||||
Future<Group?> _insertGroup(GroupsCompanion group) async {
|
Future<Group?> _insertGroup(GroupsCompanion group) async {
|
||||||
try {
|
try {
|
||||||
final rowId = await into(groups).insert(group);
|
await into(groups).insert(group);
|
||||||
return await (select(groups)..where((t) => t.rowId.equals(rowId)))
|
return await (select(groups)
|
||||||
|
..where((t) => t.groupId.equals(group.groupId.value)))
|
||||||
.getSingle();
|
.getSingle();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log.error('Could not insert group: $e');
|
Log.error('Could not insert group: $e');
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ enum GroupActionType {
|
||||||
promoteToAdmin,
|
promoteToAdmin,
|
||||||
demoteToMember,
|
demoteToMember,
|
||||||
updatedGroupName,
|
updatedGroupName,
|
||||||
|
changeDisplayMaxTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
@DataClassName('GroupHistory')
|
@DataClassName('GroupHistory')
|
||||||
|
|
@ -94,6 +95,8 @@ class GroupHistories extends Table {
|
||||||
TextColumn get oldGroupName => text().nullable()();
|
TextColumn get oldGroupName => text().nullable()();
|
||||||
TextColumn get newGroupName => text().nullable()();
|
TextColumn get newGroupName => text().nullable()();
|
||||||
|
|
||||||
|
IntColumn get newDeleteMessagesAfterMilliseconds => integer().nullable()();
|
||||||
|
|
||||||
TextColumn get type => textEnum<GroupActionType>()();
|
TextColumn get type => textEnum<GroupActionType>()();
|
||||||
|
|
||||||
DateTimeColumn get actionAt => dateTime().withDefault(currentDateAndTime)();
|
DateTimeColumn get actionAt => dateTime().withDefault(currentDateAndTime)();
|
||||||
|
|
|
||||||
|
|
@ -7038,6 +7038,13 @@ class $GroupHistoriesTable extends GroupHistories
|
||||||
late final GeneratedColumn<String> newGroupName = GeneratedColumn<String>(
|
late final GeneratedColumn<String> newGroupName = GeneratedColumn<String>(
|
||||||
'new_group_name', aliasedName, true,
|
'new_group_name', aliasedName, true,
|
||||||
type: DriftSqlType.string, requiredDuringInsert: false);
|
type: DriftSqlType.string, requiredDuringInsert: false);
|
||||||
|
static const VerificationMeta _newDeleteMessagesAfterMillisecondsMeta =
|
||||||
|
const VerificationMeta('newDeleteMessagesAfterMilliseconds');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<int> newDeleteMessagesAfterMilliseconds =
|
||||||
|
GeneratedColumn<int>(
|
||||||
|
'new_delete_messages_after_milliseconds', aliasedName, true,
|
||||||
|
type: DriftSqlType.int, requiredDuringInsert: false);
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumnWithTypeConverter<GroupActionType, String> type =
|
late final GeneratedColumnWithTypeConverter<GroupActionType, String> type =
|
||||||
GeneratedColumn<String>('type', aliasedName, false,
|
GeneratedColumn<String>('type', aliasedName, false,
|
||||||
|
|
@ -7059,6 +7066,7 @@ class $GroupHistoriesTable extends GroupHistories
|
||||||
affectedContactId,
|
affectedContactId,
|
||||||
oldGroupName,
|
oldGroupName,
|
||||||
newGroupName,
|
newGroupName,
|
||||||
|
newDeleteMessagesAfterMilliseconds,
|
||||||
type,
|
type,
|
||||||
actionAt
|
actionAt
|
||||||
];
|
];
|
||||||
|
|
@ -7108,6 +7116,13 @@ class $GroupHistoriesTable extends GroupHistories
|
||||||
newGroupName.isAcceptableOrUnknown(
|
newGroupName.isAcceptableOrUnknown(
|
||||||
data['new_group_name']!, _newGroupNameMeta));
|
data['new_group_name']!, _newGroupNameMeta));
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('new_delete_messages_after_milliseconds')) {
|
||||||
|
context.handle(
|
||||||
|
_newDeleteMessagesAfterMillisecondsMeta,
|
||||||
|
newDeleteMessagesAfterMilliseconds.isAcceptableOrUnknown(
|
||||||
|
data['new_delete_messages_after_milliseconds']!,
|
||||||
|
_newDeleteMessagesAfterMillisecondsMeta));
|
||||||
|
}
|
||||||
if (data.containsKey('action_at')) {
|
if (data.containsKey('action_at')) {
|
||||||
context.handle(_actionAtMeta,
|
context.handle(_actionAtMeta,
|
||||||
actionAt.isAcceptableOrUnknown(data['action_at']!, _actionAtMeta));
|
actionAt.isAcceptableOrUnknown(data['action_at']!, _actionAtMeta));
|
||||||
|
|
@ -7133,6 +7148,9 @@ class $GroupHistoriesTable extends GroupHistories
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}old_group_name']),
|
.read(DriftSqlType.string, data['${effectivePrefix}old_group_name']),
|
||||||
newGroupName: attachedDatabase.typeMapping
|
newGroupName: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}new_group_name']),
|
.read(DriftSqlType.string, data['${effectivePrefix}new_group_name']),
|
||||||
|
newDeleteMessagesAfterMilliseconds: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.int,
|
||||||
|
data['${effectivePrefix}new_delete_messages_after_milliseconds']),
|
||||||
type: $GroupHistoriesTable.$convertertype.fromSql(attachedDatabase
|
type: $GroupHistoriesTable.$convertertype.fromSql(attachedDatabase
|
||||||
.typeMapping
|
.typeMapping
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}type'])!),
|
.read(DriftSqlType.string, data['${effectivePrefix}type'])!),
|
||||||
|
|
@ -7157,6 +7175,7 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
final int? affectedContactId;
|
final int? affectedContactId;
|
||||||
final String? oldGroupName;
|
final String? oldGroupName;
|
||||||
final String? newGroupName;
|
final String? newGroupName;
|
||||||
|
final int? newDeleteMessagesAfterMilliseconds;
|
||||||
final GroupActionType type;
|
final GroupActionType type;
|
||||||
final DateTime actionAt;
|
final DateTime actionAt;
|
||||||
const GroupHistory(
|
const GroupHistory(
|
||||||
|
|
@ -7166,6 +7185,7 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
this.affectedContactId,
|
this.affectedContactId,
|
||||||
this.oldGroupName,
|
this.oldGroupName,
|
||||||
this.newGroupName,
|
this.newGroupName,
|
||||||
|
this.newDeleteMessagesAfterMilliseconds,
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.actionAt});
|
required this.actionAt});
|
||||||
@override
|
@override
|
||||||
|
|
@ -7185,6 +7205,10 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
if (!nullToAbsent || newGroupName != null) {
|
if (!nullToAbsent || newGroupName != null) {
|
||||||
map['new_group_name'] = Variable<String>(newGroupName);
|
map['new_group_name'] = Variable<String>(newGroupName);
|
||||||
}
|
}
|
||||||
|
if (!nullToAbsent || newDeleteMessagesAfterMilliseconds != null) {
|
||||||
|
map['new_delete_messages_after_milliseconds'] =
|
||||||
|
Variable<int>(newDeleteMessagesAfterMilliseconds);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
map['type'] =
|
map['type'] =
|
||||||
Variable<String>($GroupHistoriesTable.$convertertype.toSql(type));
|
Variable<String>($GroupHistoriesTable.$convertertype.toSql(type));
|
||||||
|
|
@ -7209,6 +7233,10 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
newGroupName: newGroupName == null && nullToAbsent
|
newGroupName: newGroupName == null && nullToAbsent
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(newGroupName),
|
: Value(newGroupName),
|
||||||
|
newDeleteMessagesAfterMilliseconds:
|
||||||
|
newDeleteMessagesAfterMilliseconds == null && nullToAbsent
|
||||||
|
? const Value.absent()
|
||||||
|
: Value(newDeleteMessagesAfterMilliseconds),
|
||||||
type: Value(type),
|
type: Value(type),
|
||||||
actionAt: Value(actionAt),
|
actionAt: Value(actionAt),
|
||||||
);
|
);
|
||||||
|
|
@ -7224,6 +7252,8 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
affectedContactId: serializer.fromJson<int?>(json['affectedContactId']),
|
affectedContactId: serializer.fromJson<int?>(json['affectedContactId']),
|
||||||
oldGroupName: serializer.fromJson<String?>(json['oldGroupName']),
|
oldGroupName: serializer.fromJson<String?>(json['oldGroupName']),
|
||||||
newGroupName: serializer.fromJson<String?>(json['newGroupName']),
|
newGroupName: serializer.fromJson<String?>(json['newGroupName']),
|
||||||
|
newDeleteMessagesAfterMilliseconds:
|
||||||
|
serializer.fromJson<int?>(json['newDeleteMessagesAfterMilliseconds']),
|
||||||
type: $GroupHistoriesTable.$convertertype
|
type: $GroupHistoriesTable.$convertertype
|
||||||
.fromJson(serializer.fromJson<String>(json['type'])),
|
.fromJson(serializer.fromJson<String>(json['type'])),
|
||||||
actionAt: serializer.fromJson<DateTime>(json['actionAt']),
|
actionAt: serializer.fromJson<DateTime>(json['actionAt']),
|
||||||
|
|
@ -7239,6 +7269,8 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
'affectedContactId': serializer.toJson<int?>(affectedContactId),
|
'affectedContactId': serializer.toJson<int?>(affectedContactId),
|
||||||
'oldGroupName': serializer.toJson<String?>(oldGroupName),
|
'oldGroupName': serializer.toJson<String?>(oldGroupName),
|
||||||
'newGroupName': serializer.toJson<String?>(newGroupName),
|
'newGroupName': serializer.toJson<String?>(newGroupName),
|
||||||
|
'newDeleteMessagesAfterMilliseconds':
|
||||||
|
serializer.toJson<int?>(newDeleteMessagesAfterMilliseconds),
|
||||||
'type': serializer
|
'type': serializer
|
||||||
.toJson<String>($GroupHistoriesTable.$convertertype.toJson(type)),
|
.toJson<String>($GroupHistoriesTable.$convertertype.toJson(type)),
|
||||||
'actionAt': serializer.toJson<DateTime>(actionAt),
|
'actionAt': serializer.toJson<DateTime>(actionAt),
|
||||||
|
|
@ -7252,6 +7284,7 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
Value<int?> affectedContactId = const Value.absent(),
|
Value<int?> affectedContactId = const Value.absent(),
|
||||||
Value<String?> oldGroupName = const Value.absent(),
|
Value<String?> oldGroupName = const Value.absent(),
|
||||||
Value<String?> newGroupName = const Value.absent(),
|
Value<String?> newGroupName = const Value.absent(),
|
||||||
|
Value<int?> newDeleteMessagesAfterMilliseconds = const Value.absent(),
|
||||||
GroupActionType? type,
|
GroupActionType? type,
|
||||||
DateTime? actionAt}) =>
|
DateTime? actionAt}) =>
|
||||||
GroupHistory(
|
GroupHistory(
|
||||||
|
|
@ -7265,6 +7298,10 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
oldGroupName.present ? oldGroupName.value : this.oldGroupName,
|
oldGroupName.present ? oldGroupName.value : this.oldGroupName,
|
||||||
newGroupName:
|
newGroupName:
|
||||||
newGroupName.present ? newGroupName.value : this.newGroupName,
|
newGroupName.present ? newGroupName.value : this.newGroupName,
|
||||||
|
newDeleteMessagesAfterMilliseconds:
|
||||||
|
newDeleteMessagesAfterMilliseconds.present
|
||||||
|
? newDeleteMessagesAfterMilliseconds.value
|
||||||
|
: this.newDeleteMessagesAfterMilliseconds,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
actionAt: actionAt ?? this.actionAt,
|
actionAt: actionAt ?? this.actionAt,
|
||||||
);
|
);
|
||||||
|
|
@ -7284,6 +7321,10 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
newGroupName: data.newGroupName.present
|
newGroupName: data.newGroupName.present
|
||||||
? data.newGroupName.value
|
? data.newGroupName.value
|
||||||
: this.newGroupName,
|
: this.newGroupName,
|
||||||
|
newDeleteMessagesAfterMilliseconds:
|
||||||
|
data.newDeleteMessagesAfterMilliseconds.present
|
||||||
|
? data.newDeleteMessagesAfterMilliseconds.value
|
||||||
|
: this.newDeleteMessagesAfterMilliseconds,
|
||||||
type: data.type.present ? data.type.value : this.type,
|
type: data.type.present ? data.type.value : this.type,
|
||||||
actionAt: data.actionAt.present ? data.actionAt.value : this.actionAt,
|
actionAt: data.actionAt.present ? data.actionAt.value : this.actionAt,
|
||||||
);
|
);
|
||||||
|
|
@ -7298,6 +7339,8 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
..write('affectedContactId: $affectedContactId, ')
|
..write('affectedContactId: $affectedContactId, ')
|
||||||
..write('oldGroupName: $oldGroupName, ')
|
..write('oldGroupName: $oldGroupName, ')
|
||||||
..write('newGroupName: $newGroupName, ')
|
..write('newGroupName: $newGroupName, ')
|
||||||
|
..write(
|
||||||
|
'newDeleteMessagesAfterMilliseconds: $newDeleteMessagesAfterMilliseconds, ')
|
||||||
..write('type: $type, ')
|
..write('type: $type, ')
|
||||||
..write('actionAt: $actionAt')
|
..write('actionAt: $actionAt')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
|
|
@ -7305,8 +7348,16 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(groupHistoryId, groupId, contactId,
|
int get hashCode => Object.hash(
|
||||||
affectedContactId, oldGroupName, newGroupName, type, actionAt);
|
groupHistoryId,
|
||||||
|
groupId,
|
||||||
|
contactId,
|
||||||
|
affectedContactId,
|
||||||
|
oldGroupName,
|
||||||
|
newGroupName,
|
||||||
|
newDeleteMessagesAfterMilliseconds,
|
||||||
|
type,
|
||||||
|
actionAt);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
|
|
@ -7317,6 +7368,8 @@ class GroupHistory extends DataClass implements Insertable<GroupHistory> {
|
||||||
other.affectedContactId == this.affectedContactId &&
|
other.affectedContactId == this.affectedContactId &&
|
||||||
other.oldGroupName == this.oldGroupName &&
|
other.oldGroupName == this.oldGroupName &&
|
||||||
other.newGroupName == this.newGroupName &&
|
other.newGroupName == this.newGroupName &&
|
||||||
|
other.newDeleteMessagesAfterMilliseconds ==
|
||||||
|
this.newDeleteMessagesAfterMilliseconds &&
|
||||||
other.type == this.type &&
|
other.type == this.type &&
|
||||||
other.actionAt == this.actionAt);
|
other.actionAt == this.actionAt);
|
||||||
}
|
}
|
||||||
|
|
@ -7328,6 +7381,7 @@ class GroupHistoriesCompanion extends UpdateCompanion<GroupHistory> {
|
||||||
final Value<int?> affectedContactId;
|
final Value<int?> affectedContactId;
|
||||||
final Value<String?> oldGroupName;
|
final Value<String?> oldGroupName;
|
||||||
final Value<String?> newGroupName;
|
final Value<String?> newGroupName;
|
||||||
|
final Value<int?> newDeleteMessagesAfterMilliseconds;
|
||||||
final Value<GroupActionType> type;
|
final Value<GroupActionType> type;
|
||||||
final Value<DateTime> actionAt;
|
final Value<DateTime> actionAt;
|
||||||
final Value<int> rowid;
|
final Value<int> rowid;
|
||||||
|
|
@ -7338,6 +7392,7 @@ class GroupHistoriesCompanion extends UpdateCompanion<GroupHistory> {
|
||||||
this.affectedContactId = const Value.absent(),
|
this.affectedContactId = const Value.absent(),
|
||||||
this.oldGroupName = const Value.absent(),
|
this.oldGroupName = const Value.absent(),
|
||||||
this.newGroupName = const Value.absent(),
|
this.newGroupName = const Value.absent(),
|
||||||
|
this.newDeleteMessagesAfterMilliseconds = const Value.absent(),
|
||||||
this.type = const Value.absent(),
|
this.type = const Value.absent(),
|
||||||
this.actionAt = const Value.absent(),
|
this.actionAt = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
|
|
@ -7349,6 +7404,7 @@ class GroupHistoriesCompanion extends UpdateCompanion<GroupHistory> {
|
||||||
this.affectedContactId = const Value.absent(),
|
this.affectedContactId = const Value.absent(),
|
||||||
this.oldGroupName = const Value.absent(),
|
this.oldGroupName = const Value.absent(),
|
||||||
this.newGroupName = const Value.absent(),
|
this.newGroupName = const Value.absent(),
|
||||||
|
this.newDeleteMessagesAfterMilliseconds = const Value.absent(),
|
||||||
required GroupActionType type,
|
required GroupActionType type,
|
||||||
this.actionAt = const Value.absent(),
|
this.actionAt = const Value.absent(),
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
|
|
@ -7362,6 +7418,7 @@ class GroupHistoriesCompanion extends UpdateCompanion<GroupHistory> {
|
||||||
Expression<int>? affectedContactId,
|
Expression<int>? affectedContactId,
|
||||||
Expression<String>? oldGroupName,
|
Expression<String>? oldGroupName,
|
||||||
Expression<String>? newGroupName,
|
Expression<String>? newGroupName,
|
||||||
|
Expression<int>? newDeleteMessagesAfterMilliseconds,
|
||||||
Expression<String>? type,
|
Expression<String>? type,
|
||||||
Expression<DateTime>? actionAt,
|
Expression<DateTime>? actionAt,
|
||||||
Expression<int>? rowid,
|
Expression<int>? rowid,
|
||||||
|
|
@ -7373,6 +7430,9 @@ class GroupHistoriesCompanion extends UpdateCompanion<GroupHistory> {
|
||||||
if (affectedContactId != null) 'affected_contact_id': affectedContactId,
|
if (affectedContactId != null) 'affected_contact_id': affectedContactId,
|
||||||
if (oldGroupName != null) 'old_group_name': oldGroupName,
|
if (oldGroupName != null) 'old_group_name': oldGroupName,
|
||||||
if (newGroupName != null) 'new_group_name': newGroupName,
|
if (newGroupName != null) 'new_group_name': newGroupName,
|
||||||
|
if (newDeleteMessagesAfterMilliseconds != null)
|
||||||
|
'new_delete_messages_after_milliseconds':
|
||||||
|
newDeleteMessagesAfterMilliseconds,
|
||||||
if (type != null) 'type': type,
|
if (type != null) 'type': type,
|
||||||
if (actionAt != null) 'action_at': actionAt,
|
if (actionAt != null) 'action_at': actionAt,
|
||||||
if (rowid != null) 'rowid': rowid,
|
if (rowid != null) 'rowid': rowid,
|
||||||
|
|
@ -7386,6 +7446,7 @@ class GroupHistoriesCompanion extends UpdateCompanion<GroupHistory> {
|
||||||
Value<int?>? affectedContactId,
|
Value<int?>? affectedContactId,
|
||||||
Value<String?>? oldGroupName,
|
Value<String?>? oldGroupName,
|
||||||
Value<String?>? newGroupName,
|
Value<String?>? newGroupName,
|
||||||
|
Value<int?>? newDeleteMessagesAfterMilliseconds,
|
||||||
Value<GroupActionType>? type,
|
Value<GroupActionType>? type,
|
||||||
Value<DateTime>? actionAt,
|
Value<DateTime>? actionAt,
|
||||||
Value<int>? rowid}) {
|
Value<int>? rowid}) {
|
||||||
|
|
@ -7396,6 +7457,8 @@ class GroupHistoriesCompanion extends UpdateCompanion<GroupHistory> {
|
||||||
affectedContactId: affectedContactId ?? this.affectedContactId,
|
affectedContactId: affectedContactId ?? this.affectedContactId,
|
||||||
oldGroupName: oldGroupName ?? this.oldGroupName,
|
oldGroupName: oldGroupName ?? this.oldGroupName,
|
||||||
newGroupName: newGroupName ?? this.newGroupName,
|
newGroupName: newGroupName ?? this.newGroupName,
|
||||||
|
newDeleteMessagesAfterMilliseconds: newDeleteMessagesAfterMilliseconds ??
|
||||||
|
this.newDeleteMessagesAfterMilliseconds,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
actionAt: actionAt ?? this.actionAt,
|
actionAt: actionAt ?? this.actionAt,
|
||||||
rowid: rowid ?? this.rowid,
|
rowid: rowid ?? this.rowid,
|
||||||
|
|
@ -7423,6 +7486,10 @@ class GroupHistoriesCompanion extends UpdateCompanion<GroupHistory> {
|
||||||
if (newGroupName.present) {
|
if (newGroupName.present) {
|
||||||
map['new_group_name'] = Variable<String>(newGroupName.value);
|
map['new_group_name'] = Variable<String>(newGroupName.value);
|
||||||
}
|
}
|
||||||
|
if (newDeleteMessagesAfterMilliseconds.present) {
|
||||||
|
map['new_delete_messages_after_milliseconds'] =
|
||||||
|
Variable<int>(newDeleteMessagesAfterMilliseconds.value);
|
||||||
|
}
|
||||||
if (type.present) {
|
if (type.present) {
|
||||||
map['type'] = Variable<String>(
|
map['type'] = Variable<String>(
|
||||||
$GroupHistoriesTable.$convertertype.toSql(type.value));
|
$GroupHistoriesTable.$convertertype.toSql(type.value));
|
||||||
|
|
@ -7445,6 +7512,8 @@ class GroupHistoriesCompanion extends UpdateCompanion<GroupHistory> {
|
||||||
..write('affectedContactId: $affectedContactId, ')
|
..write('affectedContactId: $affectedContactId, ')
|
||||||
..write('oldGroupName: $oldGroupName, ')
|
..write('oldGroupName: $oldGroupName, ')
|
||||||
..write('newGroupName: $newGroupName, ')
|
..write('newGroupName: $newGroupName, ')
|
||||||
|
..write(
|
||||||
|
'newDeleteMessagesAfterMilliseconds: $newDeleteMessagesAfterMilliseconds, ')
|
||||||
..write('type: $type, ')
|
..write('type: $type, ')
|
||||||
..write('actionAt: $actionAt, ')
|
..write('actionAt: $actionAt, ')
|
||||||
..write('rowid: $rowid')
|
..write('rowid: $rowid')
|
||||||
|
|
@ -13359,6 +13428,7 @@ typedef $$GroupHistoriesTableCreateCompanionBuilder = GroupHistoriesCompanion
|
||||||
Value<int?> affectedContactId,
|
Value<int?> affectedContactId,
|
||||||
Value<String?> oldGroupName,
|
Value<String?> oldGroupName,
|
||||||
Value<String?> newGroupName,
|
Value<String?> newGroupName,
|
||||||
|
Value<int?> newDeleteMessagesAfterMilliseconds,
|
||||||
required GroupActionType type,
|
required GroupActionType type,
|
||||||
Value<DateTime> actionAt,
|
Value<DateTime> actionAt,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
|
|
@ -13371,6 +13441,7 @@ typedef $$GroupHistoriesTableUpdateCompanionBuilder = GroupHistoriesCompanion
|
||||||
Value<int?> affectedContactId,
|
Value<int?> affectedContactId,
|
||||||
Value<String?> oldGroupName,
|
Value<String?> oldGroupName,
|
||||||
Value<String?> newGroupName,
|
Value<String?> newGroupName,
|
||||||
|
Value<int?> newDeleteMessagesAfterMilliseconds,
|
||||||
Value<GroupActionType> type,
|
Value<GroupActionType> type,
|
||||||
Value<DateTime> actionAt,
|
Value<DateTime> actionAt,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
|
|
@ -13445,6 +13516,11 @@ class $$GroupHistoriesTableFilterComposer
|
||||||
ColumnFilters<String> get newGroupName => $composableBuilder(
|
ColumnFilters<String> get newGroupName => $composableBuilder(
|
||||||
column: $table.newGroupName, builder: (column) => ColumnFilters(column));
|
column: $table.newGroupName, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
ColumnFilters<int> get newDeleteMessagesAfterMilliseconds =>
|
||||||
|
$composableBuilder(
|
||||||
|
column: $table.newDeleteMessagesAfterMilliseconds,
|
||||||
|
builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnWithTypeConverterFilters<GroupActionType, GroupActionType, String>
|
ColumnWithTypeConverterFilters<GroupActionType, GroupActionType, String>
|
||||||
get type => $composableBuilder(
|
get type => $composableBuilder(
|
||||||
column: $table.type,
|
column: $table.type,
|
||||||
|
|
@ -13535,6 +13611,11 @@ class $$GroupHistoriesTableOrderingComposer
|
||||||
column: $table.newGroupName,
|
column: $table.newGroupName,
|
||||||
builder: (column) => ColumnOrderings(column));
|
builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
ColumnOrderings<int> get newDeleteMessagesAfterMilliseconds =>
|
||||||
|
$composableBuilder(
|
||||||
|
column: $table.newDeleteMessagesAfterMilliseconds,
|
||||||
|
builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<String> get type => $composableBuilder(
|
ColumnOrderings<String> get type => $composableBuilder(
|
||||||
column: $table.type, builder: (column) => ColumnOrderings(column));
|
column: $table.type, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
|
@ -13620,6 +13701,11 @@ class $$GroupHistoriesTableAnnotationComposer
|
||||||
GeneratedColumn<String> get newGroupName => $composableBuilder(
|
GeneratedColumn<String> get newGroupName => $composableBuilder(
|
||||||
column: $table.newGroupName, builder: (column) => column);
|
column: $table.newGroupName, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<int> get newDeleteMessagesAfterMilliseconds =>
|
||||||
|
$composableBuilder(
|
||||||
|
column: $table.newDeleteMessagesAfterMilliseconds,
|
||||||
|
builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumnWithTypeConverter<GroupActionType, String> get type =>
|
GeneratedColumnWithTypeConverter<GroupActionType, String> get type =>
|
||||||
$composableBuilder(column: $table.type, builder: (column) => column);
|
$composableBuilder(column: $table.type, builder: (column) => column);
|
||||||
|
|
||||||
|
|
@ -13717,6 +13803,8 @@ class $$GroupHistoriesTableTableManager extends RootTableManager<
|
||||||
Value<int?> affectedContactId = const Value.absent(),
|
Value<int?> affectedContactId = const Value.absent(),
|
||||||
Value<String?> oldGroupName = const Value.absent(),
|
Value<String?> oldGroupName = const Value.absent(),
|
||||||
Value<String?> newGroupName = const Value.absent(),
|
Value<String?> newGroupName = const Value.absent(),
|
||||||
|
Value<int?> newDeleteMessagesAfterMilliseconds =
|
||||||
|
const Value.absent(),
|
||||||
Value<GroupActionType> type = const Value.absent(),
|
Value<GroupActionType> type = const Value.absent(),
|
||||||
Value<DateTime> actionAt = const Value.absent(),
|
Value<DateTime> actionAt = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
|
|
@ -13728,6 +13816,8 @@ class $$GroupHistoriesTableTableManager extends RootTableManager<
|
||||||
affectedContactId: affectedContactId,
|
affectedContactId: affectedContactId,
|
||||||
oldGroupName: oldGroupName,
|
oldGroupName: oldGroupName,
|
||||||
newGroupName: newGroupName,
|
newGroupName: newGroupName,
|
||||||
|
newDeleteMessagesAfterMilliseconds:
|
||||||
|
newDeleteMessagesAfterMilliseconds,
|
||||||
type: type,
|
type: type,
|
||||||
actionAt: actionAt,
|
actionAt: actionAt,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
|
|
@ -13739,6 +13829,8 @@ class $$GroupHistoriesTableTableManager extends RootTableManager<
|
||||||
Value<int?> affectedContactId = const Value.absent(),
|
Value<int?> affectedContactId = const Value.absent(),
|
||||||
Value<String?> oldGroupName = const Value.absent(),
|
Value<String?> oldGroupName = const Value.absent(),
|
||||||
Value<String?> newGroupName = const Value.absent(),
|
Value<String?> newGroupName = const Value.absent(),
|
||||||
|
Value<int?> newDeleteMessagesAfterMilliseconds =
|
||||||
|
const Value.absent(),
|
||||||
required GroupActionType type,
|
required GroupActionType type,
|
||||||
Value<DateTime> actionAt = const Value.absent(),
|
Value<DateTime> actionAt = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
|
|
@ -13750,6 +13842,8 @@ class $$GroupHistoriesTableTableManager extends RootTableManager<
|
||||||
affectedContactId: affectedContactId,
|
affectedContactId: affectedContactId,
|
||||||
oldGroupName: oldGroupName,
|
oldGroupName: oldGroupName,
|
||||||
newGroupName: newGroupName,
|
newGroupName: newGroupName,
|
||||||
|
newDeleteMessagesAfterMilliseconds:
|
||||||
|
newDeleteMessagesAfterMilliseconds,
|
||||||
type: type,
|
type: type,
|
||||||
actionAt: actionAt,
|
actionAt: actionAt,
|
||||||
rowid: rowid,
|
rowid: rowid,
|
||||||
|
|
|
||||||
|
|
@ -804,5 +804,7 @@
|
||||||
"leaveGroupSelectOtherAdminBody": "Um die Gruppe zu verlassen, musst du zuerst einen neuen Administrator auswählen.",
|
"leaveGroupSelectOtherAdminBody": "Um die Gruppe zu verlassen, musst du zuerst einen neuen Administrator auswählen.",
|
||||||
"leaveGroupSureTitle": "Gruppe verlassen",
|
"leaveGroupSureTitle": "Gruppe verlassen",
|
||||||
"leaveGroupSureBody": "Willst du die Gruppe wirklich verlassen?",
|
"leaveGroupSureBody": "Willst du die Gruppe wirklich verlassen?",
|
||||||
"leaveGroupSureOkBtn": "Gruppe verlassen"
|
"leaveGroupSureOkBtn": "Gruppe verlassen",
|
||||||
|
"changeDisplayMaxTime": "{username} hat das Zeitlimit für verschwindende Nachrichten auf {time}.",
|
||||||
|
"youChangedDisplayMaxTime": "Du hat das Zeitlimit für verschwindende Nachrichten auf {time}."
|
||||||
}
|
}
|
||||||
|
|
@ -582,5 +582,7 @@
|
||||||
"leaveGroupSelectOtherAdminBody": "To leave the group, you must first select a new administrator.",
|
"leaveGroupSelectOtherAdminBody": "To leave the group, you must first select a new administrator.",
|
||||||
"leaveGroupSureTitle": "Leave group",
|
"leaveGroupSureTitle": "Leave group",
|
||||||
"leaveGroupSureBody": "Do you really want to leave the group?",
|
"leaveGroupSureBody": "Do you really want to leave the group?",
|
||||||
"leaveGroupSureOkBtn": "Leave group"
|
"leaveGroupSureOkBtn": "Leave group",
|
||||||
|
"changeDisplayMaxTime": "{username} has set the time limit for disappearing messages to {time}.",
|
||||||
|
"youChangedDisplayMaxTime": "You have set the time limit for disappearing messages to {time}."
|
||||||
}
|
}
|
||||||
|
|
@ -2599,6 +2599,18 @@ abstract class AppLocalizations {
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
/// **'Leave group'**
|
/// **'Leave group'**
|
||||||
String get leaveGroupSureOkBtn;
|
String get leaveGroupSureOkBtn;
|
||||||
|
|
||||||
|
/// No description provided for @changeDisplayMaxTime.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'{username} has set the time limit for disappearing messages to {time}.'**
|
||||||
|
String changeDisplayMaxTime(Object time, Object username);
|
||||||
|
|
||||||
|
/// No description provided for @youChangedDisplayMaxTime.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'You have set the time limit for disappearing messages to {time}.'**
|
||||||
|
String youChangedDisplayMaxTime(Object time);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AppLocalizationsDelegate
|
class _AppLocalizationsDelegate
|
||||||
|
|
|
||||||
|
|
@ -1421,4 +1421,14 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get leaveGroupSureOkBtn => 'Gruppe verlassen';
|
String get leaveGroupSureOkBtn => 'Gruppe verlassen';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String changeDisplayMaxTime(Object time, Object username) {
|
||||||
|
return '$username hat das Zeitlimit für verschwindende Nachrichten auf $time.';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String youChangedDisplayMaxTime(Object time) {
|
||||||
|
return 'Du hat das Zeitlimit für verschwindende Nachrichten auf $time.';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1411,4 +1411,14 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get leaveGroupSureOkBtn => 'Leave group';
|
String get leaveGroupSureOkBtn => 'Leave group';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String changeDisplayMaxTime(Object time, Object username) {
|
||||||
|
return '$username has set the time limit for disappearing messages to $time.';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String youChangedDisplayMaxTime(Object time) {
|
||||||
|
return 'You have set the time limit for disappearing messages to $time.';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -415,6 +415,7 @@ class EncryptedContent_GroupUpdate extends $pb.GeneratedMessage {
|
||||||
$core.String? groupActionType,
|
$core.String? groupActionType,
|
||||||
$fixnum.Int64? affectedContactId,
|
$fixnum.Int64? affectedContactId,
|
||||||
$core.String? newGroupName,
|
$core.String? newGroupName,
|
||||||
|
$fixnum.Int64? newDeleteMessagesAfterMilliseconds,
|
||||||
}) {
|
}) {
|
||||||
final $result = create();
|
final $result = create();
|
||||||
if (groupActionType != null) {
|
if (groupActionType != null) {
|
||||||
|
|
@ -426,6 +427,9 @@ class EncryptedContent_GroupUpdate extends $pb.GeneratedMessage {
|
||||||
if (newGroupName != null) {
|
if (newGroupName != null) {
|
||||||
$result.newGroupName = newGroupName;
|
$result.newGroupName = newGroupName;
|
||||||
}
|
}
|
||||||
|
if (newDeleteMessagesAfterMilliseconds != null) {
|
||||||
|
$result.newDeleteMessagesAfterMilliseconds = newDeleteMessagesAfterMilliseconds;
|
||||||
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
EncryptedContent_GroupUpdate._() : super();
|
EncryptedContent_GroupUpdate._() : super();
|
||||||
|
|
@ -436,6 +440,7 @@ class EncryptedContent_GroupUpdate extends $pb.GeneratedMessage {
|
||||||
..aOS(1, _omitFieldNames ? '' : 'groupActionType', protoName: 'groupActionType')
|
..aOS(1, _omitFieldNames ? '' : 'groupActionType', protoName: 'groupActionType')
|
||||||
..aInt64(2, _omitFieldNames ? '' : 'affectedContactId', protoName: 'affectedContactId')
|
..aInt64(2, _omitFieldNames ? '' : 'affectedContactId', protoName: 'affectedContactId')
|
||||||
..aOS(3, _omitFieldNames ? '' : 'newGroupName', protoName: 'newGroupName')
|
..aOS(3, _omitFieldNames ? '' : 'newGroupName', protoName: 'newGroupName')
|
||||||
|
..aInt64(4, _omitFieldNames ? '' : 'newDeleteMessagesAfterMilliseconds', protoName: 'newDeleteMessagesAfterMilliseconds')
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -486,6 +491,15 @@ class EncryptedContent_GroupUpdate extends $pb.GeneratedMessage {
|
||||||
$core.bool hasNewGroupName() => $_has(2);
|
$core.bool hasNewGroupName() => $_has(2);
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
void clearNewGroupName() => clearField(3);
|
void clearNewGroupName() => clearField(3);
|
||||||
|
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$fixnum.Int64 get newDeleteMessagesAfterMilliseconds => $_getI64(3);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
set newDeleteMessagesAfterMilliseconds($fixnum.Int64 v) { $_setInt64(3, v); }
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
$core.bool hasNewDeleteMessagesAfterMilliseconds() => $_has(3);
|
||||||
|
@$pb.TagNumber(4)
|
||||||
|
void clearNewDeleteMessagesAfterMilliseconds() => clearField(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
class EncryptedContent_TextMessage extends $pb.GeneratedMessage {
|
class EncryptedContent_TextMessage extends $pb.GeneratedMessage {
|
||||||
|
|
|
||||||
|
|
@ -170,10 +170,12 @@ const EncryptedContent_GroupUpdate$json = {
|
||||||
{'1': 'groupActionType', '3': 1, '4': 1, '5': 9, '10': 'groupActionType'},
|
{'1': 'groupActionType', '3': 1, '4': 1, '5': 9, '10': 'groupActionType'},
|
||||||
{'1': 'affectedContactId', '3': 2, '4': 1, '5': 3, '9': 0, '10': 'affectedContactId', '17': true},
|
{'1': 'affectedContactId', '3': 2, '4': 1, '5': 3, '9': 0, '10': 'affectedContactId', '17': true},
|
||||||
{'1': 'newGroupName', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'newGroupName', '17': true},
|
{'1': 'newGroupName', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'newGroupName', '17': true},
|
||||||
|
{'1': 'newDeleteMessagesAfterMilliseconds', '3': 4, '4': 1, '5': 3, '9': 2, '10': 'newDeleteMessagesAfterMilliseconds', '17': true},
|
||||||
],
|
],
|
||||||
'8': [
|
'8': [
|
||||||
{'1': '_affectedContactId'},
|
{'1': '_affectedContactId'},
|
||||||
{'1': '_newGroupName'},
|
{'1': '_newGroupName'},
|
||||||
|
{'1': '_newDeleteMessagesAfterMilliseconds'},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -389,53 +391,55 @@ final $typed_data.Uint8List encryptedContentDescriptor = $convert.base64Decode(
|
||||||
'dGVkQ29udGVudC5SZXNlbmRHcm91cFB1YmxpY0tleUgPUhRyZXNlbmRHcm91cFB1YmxpY0tleY'
|
'dGVkQ29udGVudC5SZXNlbmRHcm91cFB1YmxpY0tleUgPUhRyZXNlbmRHcm91cFB1YmxpY0tleY'
|
||||||
'gBARpRCgtHcm91cENyZWF0ZRIaCghzdGF0ZUtleRgDIAEoDFIIc3RhdGVLZXkSJgoOZ3JvdXBQ'
|
'gBARpRCgtHcm91cENyZWF0ZRIaCghzdGF0ZUtleRgDIAEoDFIIc3RhdGVLZXkSJgoOZ3JvdXBQ'
|
||||||
'dWJsaWNLZXkYBCABKAxSDmdyb3VwUHVibGljS2V5GjMKCUdyb3VwSm9pbhImCg5ncm91cFB1Ym'
|
'dWJsaWNLZXkYBCABKAxSDmdyb3VwUHVibGljS2V5GjMKCUdyb3VwSm9pbhImCg5ncm91cFB1Ym'
|
||||||
'xpY0tleRgBIAEoDFIOZ3JvdXBQdWJsaWNLZXkaFgoUUmVzZW5kR3JvdXBQdWJsaWNLZXkaugEK'
|
'xpY0tleRgBIAEoDFIOZ3JvdXBQdWJsaWNLZXkaFgoUUmVzZW5kR3JvdXBQdWJsaWNLZXkatgIK'
|
||||||
'C0dyb3VwVXBkYXRlEigKD2dyb3VwQWN0aW9uVHlwZRgBIAEoCVIPZ3JvdXBBY3Rpb25UeXBlEj'
|
'C0dyb3VwVXBkYXRlEigKD2dyb3VwQWN0aW9uVHlwZRgBIAEoCVIPZ3JvdXBBY3Rpb25UeXBlEj'
|
||||||
'EKEWFmZmVjdGVkQ29udGFjdElkGAIgASgDSABSEWFmZmVjdGVkQ29udGFjdElkiAEBEicKDG5l'
|
'EKEWFmZmVjdGVkQ29udGFjdElkGAIgASgDSABSEWFmZmVjdGVkQ29udGFjdElkiAEBEicKDG5l'
|
||||||
'd0dyb3VwTmFtZRgDIAEoCUgBUgxuZXdHcm91cE5hbWWIAQFCFAoSX2FmZmVjdGVkQ29udGFjdE'
|
'd0dyb3VwTmFtZRgDIAEoCUgBUgxuZXdHcm91cE5hbWWIAQESUwoibmV3RGVsZXRlTWVzc2FnZX'
|
||||||
'lkQg8KDV9uZXdHcm91cE5hbWUaqQEKC1RleHRNZXNzYWdlEigKD3NlbmRlck1lc3NhZ2VJZBgB'
|
'NBZnRlck1pbGxpc2Vjb25kcxgEIAEoA0gCUiJuZXdEZWxldGVNZXNzYWdlc0FmdGVyTWlsbGlz'
|
||||||
'IAEoCVIPc2VuZGVyTWVzc2FnZUlkEhIKBHRleHQYAiABKAlSBHRleHQSHAoJdGltZXN0YW1wGA'
|
'ZWNvbmRziAEBQhQKEl9hZmZlY3RlZENvbnRhY3RJZEIPCg1fbmV3R3JvdXBOYW1lQiUKI19uZX'
|
||||||
'MgASgDUgl0aW1lc3RhbXASKwoOcXVvdGVNZXNzYWdlSWQYBCABKAlIAFIOcXVvdGVNZXNzYWdl'
|
'dEZWxldGVNZXNzYWdlc0FmdGVyTWlsbGlzZWNvbmRzGqkBCgtUZXh0TWVzc2FnZRIoCg9zZW5k'
|
||||||
'SWSIAQFCEQoPX3F1b3RlTWVzc2FnZUlkGmIKCFJlYWN0aW9uEigKD3RhcmdldE1lc3NhZ2VJZB'
|
'ZXJNZXNzYWdlSWQYASABKAlSD3NlbmRlck1lc3NhZ2VJZBISCgR0ZXh0GAIgASgJUgR0ZXh0Eh'
|
||||||
'gBIAEoCVIPdGFyZ2V0TWVzc2FnZUlkEhQKBWVtb2ppGAIgASgJUgVlbW9qaRIWCgZyZW1vdmUY'
|
'wKCXRpbWVzdGFtcBgDIAEoA1IJdGltZXN0YW1wEisKDnF1b3RlTWVzc2FnZUlkGAQgASgJSABS'
|
||||||
'AyABKAhSBnJlbW92ZRq3AgoNTWVzc2FnZVVwZGF0ZRI4CgR0eXBlGAEgASgOMiQuRW5jcnlwdG'
|
'DnF1b3RlTWVzc2FnZUlkiAEBQhEKD19xdW90ZU1lc3NhZ2VJZBpiCghSZWFjdGlvbhIoCg90YX'
|
||||||
'VkQ29udGVudC5NZXNzYWdlVXBkYXRlLlR5cGVSBHR5cGUSLQoPc2VuZGVyTWVzc2FnZUlkGAIg'
|
'JnZXRNZXNzYWdlSWQYASABKAlSD3RhcmdldE1lc3NhZ2VJZBIUCgVlbW9qaRgCIAEoCVIFZW1v'
|
||||||
'ASgJSABSD3NlbmRlck1lc3NhZ2VJZIgBARI6ChhtdWx0aXBsZVRhcmdldE1lc3NhZ2VJZHMYAy'
|
'amkSFgoGcmVtb3ZlGAMgASgIUgZyZW1vdmUatwIKDU1lc3NhZ2VVcGRhdGUSOAoEdHlwZRgBIA'
|
||||||
'ADKAlSGG11bHRpcGxlVGFyZ2V0TWVzc2FnZUlkcxIXCgR0ZXh0GAQgASgJSAFSBHRleHSIAQES'
|
'EoDjIkLkVuY3J5cHRlZENvbnRlbnQuTWVzc2FnZVVwZGF0ZS5UeXBlUgR0eXBlEi0KD3NlbmRl'
|
||||||
'HAoJdGltZXN0YW1wGAUgASgDUgl0aW1lc3RhbXAiLQoEVHlwZRIKCgZERUxFVEUQABINCglFRE'
|
'ck1lc3NhZ2VJZBgCIAEoCUgAUg9zZW5kZXJNZXNzYWdlSWSIAQESOgoYbXVsdGlwbGVUYXJnZX'
|
||||||
'lUX1RFWFQQARIKCgZPUEVORUQQAkISChBfc2VuZGVyTWVzc2FnZUlkQgcKBV90ZXh0GowFCgVN'
|
'RNZXNzYWdlSWRzGAMgAygJUhhtdWx0aXBsZVRhcmdldE1lc3NhZ2VJZHMSFwoEdGV4dBgEIAEo'
|
||||||
'ZWRpYRIoCg9zZW5kZXJNZXNzYWdlSWQYASABKAlSD3NlbmRlck1lc3NhZ2VJZBIwCgR0eXBlGA'
|
'CUgBUgR0ZXh0iAEBEhwKCXRpbWVzdGFtcBgFIAEoA1IJdGltZXN0YW1wIi0KBFR5cGUSCgoGRE'
|
||||||
'IgASgOMhwuRW5jcnlwdGVkQ29udGVudC5NZWRpYS5UeXBlUgR0eXBlEkMKGmRpc3BsYXlMaW1p'
|
'VMRVRFEAASDQoJRURJVF9URVhUEAESCgoGT1BFTkVEEAJCEgoQX3NlbmRlck1lc3NhZ2VJZEIH'
|
||||||
'dEluTWlsbGlzZWNvbmRzGAMgASgDSABSGmRpc3BsYXlMaW1pdEluTWlsbGlzZWNvbmRziAEBEj'
|
'CgVfdGV4dBqMBQoFTWVkaWESKAoPc2VuZGVyTWVzc2FnZUlkGAEgASgJUg9zZW5kZXJNZXNzYW'
|
||||||
'YKFnJlcXVpcmVzQXV0aGVudGljYXRpb24YBCABKAhSFnJlcXVpcmVzQXV0aGVudGljYXRpb24S'
|
'dlSWQSMAoEdHlwZRgCIAEoDjIcLkVuY3J5cHRlZENvbnRlbnQuTWVkaWEuVHlwZVIEdHlwZRJD'
|
||||||
'HAoJdGltZXN0YW1wGAUgASgDUgl0aW1lc3RhbXASKwoOcXVvdGVNZXNzYWdlSWQYBiABKAlIAV'
|
'ChpkaXNwbGF5TGltaXRJbk1pbGxpc2Vjb25kcxgDIAEoA0gAUhpkaXNwbGF5TGltaXRJbk1pbG'
|
||||||
'IOcXVvdGVNZXNzYWdlSWSIAQESKQoNZG93bmxvYWRUb2tlbhgHIAEoDEgCUg1kb3dubG9hZFRv'
|
'xpc2Vjb25kc4gBARI2ChZyZXF1aXJlc0F1dGhlbnRpY2F0aW9uGAQgASgIUhZyZXF1aXJlc0F1'
|
||||||
'a2VuiAEBEikKDWVuY3J5cHRpb25LZXkYCCABKAxIA1INZW5jcnlwdGlvbktleYgBARIpCg1lbm'
|
'dGhlbnRpY2F0aW9uEhwKCXRpbWVzdGFtcBgFIAEoA1IJdGltZXN0YW1wEisKDnF1b3RlTWVzc2'
|
||||||
'NyeXB0aW9uTWFjGAkgASgMSARSDWVuY3J5cHRpb25NYWOIAQESLQoPZW5jcnlwdGlvbk5vbmNl'
|
'FnZUlkGAYgASgJSAFSDnF1b3RlTWVzc2FnZUlkiAEBEikKDWRvd25sb2FkVG9rZW4YByABKAxI'
|
||||||
'GAogASgMSAVSD2VuY3J5cHRpb25Ob25jZYgBASIzCgRUeXBlEgwKCFJFVVBMT0FEEAASCQoFSU'
|
'AlINZG93bmxvYWRUb2tlbogBARIpCg1lbmNyeXB0aW9uS2V5GAggASgMSANSDWVuY3J5cHRpb2'
|
||||||
'1BR0UQARIJCgVWSURFTxACEgcKA0dJRhADQh0KG19kaXNwbGF5TGltaXRJbk1pbGxpc2Vjb25k'
|
'5LZXmIAQESKQoNZW5jcnlwdGlvbk1hYxgJIAEoDEgEUg1lbmNyeXB0aW9uTWFjiAEBEi0KD2Vu'
|
||||||
'c0IRCg9fcXVvdGVNZXNzYWdlSWRCEAoOX2Rvd25sb2FkVG9rZW5CEAoOX2VuY3J5cHRpb25LZX'
|
'Y3J5cHRpb25Ob25jZRgKIAEoDEgFUg9lbmNyeXB0aW9uTm9uY2WIAQEiMwoEVHlwZRIMCghSRV'
|
||||||
'lCEAoOX2VuY3J5cHRpb25NYWNCEgoQX2VuY3J5cHRpb25Ob25jZRqnAQoLTWVkaWFVcGRhdGUS'
|
'VQTE9BRBAAEgkKBUlNQUdFEAESCQoFVklERU8QAhIHCgNHSUYQA0IdChtfZGlzcGxheUxpbWl0'
|
||||||
'NgoEdHlwZRgBIAEoDjIiLkVuY3J5cHRlZENvbnRlbnQuTWVkaWFVcGRhdGUuVHlwZVIEdHlwZR'
|
'SW5NaWxsaXNlY29uZHNCEQoPX3F1b3RlTWVzc2FnZUlkQhAKDl9kb3dubG9hZFRva2VuQhAKDl'
|
||||||
'IoCg90YXJnZXRNZXNzYWdlSWQYAiABKAlSD3RhcmdldE1lc3NhZ2VJZCI2CgRUeXBlEgwKCFJF'
|
'9lbmNyeXB0aW9uS2V5QhAKDl9lbmNyeXB0aW9uTWFjQhIKEF9lbmNyeXB0aW9uTm9uY2UapwEK'
|
||||||
'T1BFTkVEEAASCgoGU1RPUkVEEAESFAoQREVDUllQVElPTl9FUlJPUhACGngKDkNvbnRhY3RSZX'
|
'C01lZGlhVXBkYXRlEjYKBHR5cGUYASABKA4yIi5FbmNyeXB0ZWRDb250ZW50Lk1lZGlhVXBkYX'
|
||||||
'F1ZXN0EjkKBHR5cGUYASABKA4yJS5FbmNyeXB0ZWRDb250ZW50LkNvbnRhY3RSZXF1ZXN0LlR5'
|
'RlLlR5cGVSBHR5cGUSKAoPdGFyZ2V0TWVzc2FnZUlkGAIgASgJUg90YXJnZXRNZXNzYWdlSWQi'
|
||||||
'cGVSBHR5cGUiKwoEVHlwZRILCgdSRVFVRVNUEAASCgoGUkVKRUNUEAESCgoGQUNDRVBUEAIang'
|
'NgoEVHlwZRIMCghSRU9QRU5FRBAAEgoKBlNUT1JFRBABEhQKEERFQ1JZUFRJT05fRVJST1IQAh'
|
||||||
'IKDUNvbnRhY3RVcGRhdGUSOAoEdHlwZRgBIAEoDjIkLkVuY3J5cHRlZENvbnRlbnQuQ29udGFj'
|
'p4Cg5Db250YWN0UmVxdWVzdBI5CgR0eXBlGAEgASgOMiUuRW5jcnlwdGVkQ29udGVudC5Db250'
|
||||||
'dFVwZGF0ZS5UeXBlUgR0eXBlEjUKE2F2YXRhclN2Z0NvbXByZXNzZWQYAiABKAxIAFITYXZhdG'
|
'YWN0UmVxdWVzdC5UeXBlUgR0eXBlIisKBFR5cGUSCwoHUkVRVUVTVBAAEgoKBlJFSkVDVBABEg'
|
||||||
'FyU3ZnQ29tcHJlc3NlZIgBARIfCgh1c2VybmFtZRgDIAEoCUgBUgh1c2VybmFtZYgBARIlCgtk'
|
'oKBkFDQ0VQVBACGp4CCg1Db250YWN0VXBkYXRlEjgKBHR5cGUYASABKA4yJC5FbmNyeXB0ZWRD'
|
||||||
'aXNwbGF5TmFtZRgEIAEoCUgCUgtkaXNwbGF5TmFtZYgBASIfCgRUeXBlEgsKB1JFUVVFU1QQAB'
|
'b250ZW50LkNvbnRhY3RVcGRhdGUuVHlwZVIEdHlwZRI1ChNhdmF0YXJTdmdDb21wcmVzc2VkGA'
|
||||||
'IKCgZVUERBVEUQAUIWChRfYXZhdGFyU3ZnQ29tcHJlc3NlZEILCglfdXNlcm5hbWVCDgoMX2Rp'
|
'IgASgMSABSE2F2YXRhclN2Z0NvbXByZXNzZWSIAQESHwoIdXNlcm5hbWUYAyABKAlIAVIIdXNl'
|
||||||
'c3BsYXlOYW1lGtUBCghQdXNoS2V5cxIzCgR0eXBlGAEgASgOMh8uRW5jcnlwdGVkQ29udGVudC'
|
'cm5hbWWIAQESJQoLZGlzcGxheU5hbWUYBCABKAlIAlILZGlzcGxheU5hbWWIAQEiHwoEVHlwZR'
|
||||||
'5QdXNoS2V5cy5UeXBlUgR0eXBlEhkKBWtleUlkGAIgASgDSABSBWtleUlkiAEBEhUKA2tleRgD'
|
'ILCgdSRVFVRVNUEAASCgoGVVBEQVRFEAFCFgoUX2F2YXRhclN2Z0NvbXByZXNzZWRCCwoJX3Vz'
|
||||||
'IAEoDEgBUgNrZXmIAQESIQoJY3JlYXRlZEF0GAQgASgDSAJSCWNyZWF0ZWRBdIgBASIfCgRUeX'
|
'ZXJuYW1lQg4KDF9kaXNwbGF5TmFtZRrVAQoIUHVzaEtleXMSMwoEdHlwZRgBIAEoDjIfLkVuY3'
|
||||||
'BlEgsKB1JFUVVFU1QQABIKCgZVUERBVEUQAUIICgZfa2V5SWRCBgoEX2tleUIMCgpfY3JlYXRl'
|
'J5cHRlZENvbnRlbnQuUHVzaEtleXMuVHlwZVIEdHlwZRIZCgVrZXlJZBgCIAEoA0gAUgVrZXlJ'
|
||||||
'ZEF0GocBCglGbGFtZVN5bmMSIgoMZmxhbWVDb3VudGVyGAEgASgDUgxmbGFtZUNvdW50ZXISNg'
|
'ZIgBARIVCgNrZXkYAyABKAxIAVIDa2V5iAEBEiEKCWNyZWF0ZWRBdBgEIAEoA0gCUgljcmVhdG'
|
||||||
'oWbGFzdEZsYW1lQ291bnRlckNoYW5nZRgCIAEoA1IWbGFzdEZsYW1lQ291bnRlckNoYW5nZRIe'
|
'VkQXSIAQEiHwoEVHlwZRILCgdSRVFVRVNUEAASCgoGVVBEQVRFEAFCCAoGX2tleUlkQgYKBF9r'
|
||||||
'CgpiZXN0RnJpZW5kGAMgASgIUgpiZXN0RnJpZW5kQgoKCF9ncm91cElkQg8KDV9pc0RpcmVjdE'
|
'ZXlCDAoKX2NyZWF0ZWRBdBqHAQoJRmxhbWVTeW5jEiIKDGZsYW1lQ291bnRlchgBIAEoA1IMZm'
|
||||||
'NoYXRCFwoVX3NlbmRlclByb2ZpbGVDb3VudGVyQhAKDl9tZXNzYWdlVXBkYXRlQggKBl9tZWRp'
|
'xhbWVDb3VudGVyEjYKFmxhc3RGbGFtZUNvdW50ZXJDaGFuZ2UYAiABKANSFmxhc3RGbGFtZUNv'
|
||||||
'YUIOCgxfbWVkaWFVcGRhdGVCEAoOX2NvbnRhY3RVcGRhdGVCEQoPX2NvbnRhY3RSZXF1ZXN0Qg'
|
'dW50ZXJDaGFuZ2USHgoKYmVzdEZyaWVuZBgDIAEoCFIKYmVzdEZyaWVuZEIKCghfZ3JvdXBJZE'
|
||||||
'wKCl9mbGFtZVN5bmNCCwoJX3B1c2hLZXlzQgsKCV9yZWFjdGlvbkIOCgxfdGV4dE1lc3NhZ2VC'
|
'IPCg1faXNEaXJlY3RDaGF0QhcKFV9zZW5kZXJQcm9maWxlQ291bnRlckIQCg5fbWVzc2FnZVVw'
|
||||||
'DgoMX2dyb3VwQ3JlYXRlQgwKCl9ncm91cEpvaW5CDgoMX2dyb3VwVXBkYXRlQhcKFV9yZXNlbm'
|
'ZGF0ZUIICgZfbWVkaWFCDgoMX21lZGlhVXBkYXRlQhAKDl9jb250YWN0VXBkYXRlQhEKD19jb2'
|
||||||
'RHcm91cFB1YmxpY0tleQ==');
|
'50YWN0UmVxdWVzdEIMCgpfZmxhbWVTeW5jQgsKCV9wdXNoS2V5c0ILCglfcmVhY3Rpb25CDgoM'
|
||||||
|
'X3RleHRNZXNzYWdlQg4KDF9ncm91cENyZWF0ZUIMCgpfZ3JvdXBKb2luQg4KDF9ncm91cFVwZG'
|
||||||
|
'F0ZUIXChVfcmVzZW5kR3JvdXBQdWJsaWNLZXk=');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@ message EncryptedContent {
|
||||||
string groupActionType = 1; // GroupActionType.name
|
string groupActionType = 1; // GroupActionType.name
|
||||||
optional int64 affectedContactId = 2;
|
optional int64 affectedContactId = 2;
|
||||||
optional string newGroupName = 3;
|
optional string newGroupName = 3;
|
||||||
|
optional int64 newDeleteMessagesAfterMilliseconds = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message TextMessage {
|
message TextMessage {
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,16 @@ Future<void> handleGroupUpdate(
|
||||||
contactId: Value(fromUserId),
|
contactId: Value(fromUserId),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
case GroupActionType.changeDisplayMaxTime:
|
||||||
|
await twonlyDB.groupsDao.insertGroupAction(
|
||||||
|
GroupHistoriesCompanion(
|
||||||
|
groupId: Value(groupId),
|
||||||
|
type: Value(actionType),
|
||||||
|
newDeleteMessagesAfterMilliseconds:
|
||||||
|
Value(update.newDeleteMessagesAfterMilliseconds.toInt()),
|
||||||
|
contactId: Value(fromUserId),
|
||||||
|
),
|
||||||
|
);
|
||||||
case GroupActionType.removedMember:
|
case GroupActionType.removedMember:
|
||||||
case GroupActionType.addMember:
|
case GroupActionType.addMember:
|
||||||
case GroupActionType.leftGroup:
|
case GroupActionType.leftGroup:
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ Future<void> enableTwonlySafe(String password) async {
|
||||||
unawaited(performTwonlySafeBackup(force: true));
|
unawaited(performTwonlySafeBackup(force: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> disableTwonlySafe() async {
|
Future<void> removeTwonlySafeFromServer() async {
|
||||||
final serverUrl = await getTwonlySafeBackupUrl();
|
final serverUrl = await getTwonlySafeBackupUrl();
|
||||||
if (serverUrl != null) {
|
if (serverUrl != null) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -40,10 +40,6 @@ Future<void> disableTwonlySafe() async {
|
||||||
Log.error('Could not connect to the server.');
|
Log.error('Could not connect to the server.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await updateUserdata((user) {
|
|
||||||
user.twonlySafeBackup = null;
|
|
||||||
return user;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<(Uint8List, Uint8List)> getMasterKey(
|
Future<(Uint8List, Uint8List)> getMasterKey(
|
||||||
|
|
|
||||||
|
|
@ -26,61 +26,63 @@ class EmojiPickerBottom extends StatelessWidget {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Column(
|
child: SafeArea(
|
||||||
children: [
|
child: Column(
|
||||||
Container(
|
children: [
|
||||||
margin: const EdgeInsets.all(30),
|
Container(
|
||||||
decoration: BoxDecoration(
|
margin: const EdgeInsets.all(30),
|
||||||
borderRadius: BorderRadius.circular(32),
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey,
|
borderRadius: BorderRadius.circular(32),
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
height: 3,
|
||||||
|
width: 60,
|
||||||
),
|
),
|
||||||
height: 3,
|
Expanded(
|
||||||
width: 60,
|
child: EmojiPicker(
|
||||||
),
|
onEmojiSelected: (category, emoji) {
|
||||||
Expanded(
|
Navigator.pop(
|
||||||
child: EmojiPicker(
|
context,
|
||||||
onEmojiSelected: (category, emoji) {
|
EmojiLayerData(
|
||||||
Navigator.pop(
|
text: emoji.emoji,
|
||||||
context,
|
),
|
||||||
EmojiLayerData(
|
);
|
||||||
text: emoji.emoji,
|
},
|
||||||
|
// textEditingController: _textFieldController,
|
||||||
|
config: Config(
|
||||||
|
height: 400,
|
||||||
|
locale: Localizations.localeOf(context),
|
||||||
|
viewOrderConfig: const ViewOrderConfig(
|
||||||
|
top: EmojiPickerItem.searchBar,
|
||||||
|
// middle: EmojiPickerItem.emojiView,
|
||||||
|
bottom: EmojiPickerItem.categoryBar,
|
||||||
|
),
|
||||||
|
emojiTextStyle:
|
||||||
|
TextStyle(fontSize: 24 * (Platform.isIOS ? 1.2 : 1)),
|
||||||
|
emojiViewConfig: EmojiViewConfig(
|
||||||
|
backgroundColor: context.color.surfaceContainer,
|
||||||
|
),
|
||||||
|
searchViewConfig: SearchViewConfig(
|
||||||
|
backgroundColor: context.color.surfaceContainer,
|
||||||
|
buttonIconColor: Colors.white,
|
||||||
|
),
|
||||||
|
categoryViewConfig: CategoryViewConfig(
|
||||||
|
backgroundColor: context.color.surfaceContainer,
|
||||||
|
dividerColor: Colors.white,
|
||||||
|
indicatorColor: context.color.primary,
|
||||||
|
iconColorSelected: context.color.primary,
|
||||||
|
iconColor: context.color.secondary,
|
||||||
|
),
|
||||||
|
bottomActionBarConfig: BottomActionBarConfig(
|
||||||
|
backgroundColor: context.color.surfaceContainer,
|
||||||
|
buttonColor: context.color.surfaceContainer,
|
||||||
|
buttonIconColor: context.color.secondary,
|
||||||
),
|
),
|
||||||
);
|
|
||||||
},
|
|
||||||
// textEditingController: _textFieldController,
|
|
||||||
config: Config(
|
|
||||||
height: 400,
|
|
||||||
locale: Localizations.localeOf(context),
|
|
||||||
viewOrderConfig: const ViewOrderConfig(
|
|
||||||
top: EmojiPickerItem.searchBar,
|
|
||||||
// middle: EmojiPickerItem.emojiView,
|
|
||||||
bottom: EmojiPickerItem.categoryBar,
|
|
||||||
),
|
|
||||||
emojiTextStyle:
|
|
||||||
TextStyle(fontSize: 24 * (Platform.isIOS ? 1.2 : 1)),
|
|
||||||
emojiViewConfig: EmojiViewConfig(
|
|
||||||
backgroundColor: context.color.surfaceContainer,
|
|
||||||
),
|
|
||||||
searchViewConfig: SearchViewConfig(
|
|
||||||
backgroundColor: context.color.surfaceContainer,
|
|
||||||
buttonIconColor: Colors.white,
|
|
||||||
),
|
|
||||||
categoryViewConfig: CategoryViewConfig(
|
|
||||||
backgroundColor: context.color.surfaceContainer,
|
|
||||||
dividerColor: Colors.white,
|
|
||||||
indicatorColor: context.color.primary,
|
|
||||||
iconColorSelected: context.color.primary,
|
|
||||||
iconColor: context.color.secondary,
|
|
||||||
),
|
|
||||||
bottomActionBarConfig: BottomActionBarConfig(
|
|
||||||
backgroundColor: context.color.surfaceContainer,
|
|
||||||
buttonColor: context.color.surfaceContainer,
|
|
||||||
buttonIconColor: context.color.secondary,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,6 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
|
||||||
groupActionsSub?.cancel();
|
groupActionsSub?.cancel();
|
||||||
lastOpenedMessageByContactSub?.cancel();
|
lastOpenedMessageByContactSub?.cancel();
|
||||||
tutorial?.cancel();
|
tutorial?.cancel();
|
||||||
textFieldFocus.dispose();
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ class _AllReactionsViewState extends State<AllReactionsView> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (mounted) Navigator.pop(context);
|
// if (mounted) Navigator.pop(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,15 @@ class _ChatGroupActionState extends State<ChatGroupAction> {
|
||||||
final maker = (contact == null) ? '' : getContactDisplayName(contact!);
|
final maker = (contact == null) ? '' : getContactDisplayName(contact!);
|
||||||
|
|
||||||
switch (widget.action.type) {
|
switch (widget.action.type) {
|
||||||
|
case GroupActionType.changeDisplayMaxTime:
|
||||||
|
final time = formatDuration(
|
||||||
|
context,
|
||||||
|
(widget.action.newDeleteMessagesAfterMilliseconds ?? 0 / 1000) as int,
|
||||||
|
);
|
||||||
|
text = (contact == null)
|
||||||
|
? context.lang.youChangedDisplayMaxTime(time)
|
||||||
|
: context.lang.changeDisplayMaxTime(maker, time);
|
||||||
|
icon = FontAwesomeIcons.pencil;
|
||||||
case GroupActionType.updatedGroupName:
|
case GroupActionType.updatedGroupName:
|
||||||
text = (contact == null)
|
text = (contact == null)
|
||||||
? context.lang.youChangedGroupName(widget.action.newGroupName!)
|
? context.lang.youChangedGroupName(widget.action.newGroupName!)
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
bool imageSaved = false;
|
bool imageSaved = false;
|
||||||
bool imageSaving = false;
|
bool imageSaving = false;
|
||||||
bool displayTwonlyPresent = true;
|
bool displayTwonlyPresent = true;
|
||||||
|
final emojiKey = GlobalKey<EmojiFloatWidgetState>();
|
||||||
|
|
||||||
StreamSubscription<MediaFile?>? downloadStateListener;
|
StreamSubscription<MediaFile?>? downloadStateListener;
|
||||||
|
|
||||||
|
|
@ -634,6 +635,7 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
mediaViewerDistanceFromBottom: mediaViewerDistanceFromBottom,
|
mediaViewerDistanceFromBottom: mediaViewerDistanceFromBottom,
|
||||||
groupId: widget.group.groupId,
|
groupId: widget.group.groupId,
|
||||||
messageId: currentMessage!.messageId,
|
messageId: currentMessage!.messageId,
|
||||||
|
emojiKey: emojiKey,
|
||||||
hide: () {
|
hide: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
showShortReactions = false;
|
showShortReactions = false;
|
||||||
|
|
@ -641,6 +643,9 @@ class _MediaViewerViewState extends State<MediaViewerView> {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
Positioned.fill(
|
||||||
|
child: EmojiFloatWidget(key: emojiKey),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,46 @@
|
||||||
// ignore_for_file: avoid_dynamic_calls
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart';
|
import 'package:twonly/src/model/protobuf/client/generated/messages.pb.dart';
|
||||||
import 'package:twonly/src/services/api/messages.dart';
|
import 'package:twonly/src/services/api/messages.dart';
|
||||||
|
import 'package:twonly/src/views/chats/media_viewer_components/reaction_buttons.component.dart';
|
||||||
import 'package:twonly/src/views/components/animate_icon.dart';
|
import 'package:twonly/src/views/components/animate_icon.dart';
|
||||||
|
|
||||||
|
Offset getGlobalOffset(GlobalKey targetKey) {
|
||||||
|
final ctx = targetKey.currentContext;
|
||||||
|
if (ctx == null) {
|
||||||
|
return Offset.zero;
|
||||||
|
}
|
||||||
|
final renderObject = ctx.findRenderObject();
|
||||||
|
if (renderObject is RenderBox) {
|
||||||
|
return renderObject.localToGlobal(
|
||||||
|
Offset(renderObject.size.width / 2, renderObject.size.height / 2),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Offset.zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> sendReaction(
|
||||||
|
String groupId,
|
||||||
|
String messageId,
|
||||||
|
String emoji,
|
||||||
|
) async {
|
||||||
|
await twonlyDB.reactionsDao.updateMyReaction(
|
||||||
|
messageId,
|
||||||
|
emoji,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
await sendCipherTextToGroup(
|
||||||
|
groupId,
|
||||||
|
EncryptedContent(
|
||||||
|
reaction: EncryptedContent_Reaction(
|
||||||
|
targetMessageId: messageId,
|
||||||
|
emoji: emoji,
|
||||||
|
remove: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
class EmojiReactionWidget extends StatefulWidget {
|
class EmojiReactionWidget extends StatefulWidget {
|
||||||
const EmojiReactionWidget({
|
const EmojiReactionWidget({
|
||||||
required this.messageId,
|
required this.messageId,
|
||||||
|
|
@ -13,74 +48,46 @@ class EmojiReactionWidget extends StatefulWidget {
|
||||||
required this.hide,
|
required this.hide,
|
||||||
required this.show,
|
required this.show,
|
||||||
required this.emoji,
|
required this.emoji,
|
||||||
|
required this.emojiKey,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
final String messageId;
|
final String messageId;
|
||||||
final String groupId;
|
final String groupId;
|
||||||
final Function hide;
|
final void Function() hide;
|
||||||
final bool show;
|
final bool show;
|
||||||
final String emoji;
|
final String emoji;
|
||||||
|
final GlobalKey<EmojiFloatWidgetState> emojiKey;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<EmojiReactionWidget> createState() => _EmojiReactionWidgetState();
|
State<EmojiReactionWidget> createState() => _EmojiReactionWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _EmojiReactionWidgetState extends State<EmojiReactionWidget> {
|
class _EmojiReactionWidgetState extends State<EmojiReactionWidget> {
|
||||||
int selectedShortReaction = -1;
|
final GlobalKey _targetKey = GlobalKey();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AnimatedSize(
|
return AnimatedSize(
|
||||||
|
key: _targetKey,
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(milliseconds: 200),
|
||||||
curve: Curves.linearToEaseOut,
|
curve: Curves.linearToEaseOut,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await twonlyDB.reactionsDao
|
await sendReaction(widget.groupId, widget.messageId, widget.emoji);
|
||||||
.updateMyReaction(widget.messageId, widget.emoji, false);
|
widget.emojiKey.currentState?.spawn(
|
||||||
|
getGlobalOffset(_targetKey),
|
||||||
await sendCipherTextToGroup(
|
widget.emoji,
|
||||||
widget.groupId,
|
|
||||||
EncryptedContent(
|
|
||||||
reaction: EncryptedContent_Reaction(
|
|
||||||
targetMessageId: widget.messageId,
|
|
||||||
emoji: widget.emoji,
|
|
||||||
remove: false,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
widget.hide();
|
||||||
setState(() {
|
|
||||||
selectedShortReaction = 0; // Assuming index is 0 for this example
|
|
||||||
});
|
|
||||||
Future.delayed(const Duration(milliseconds: 300), () {
|
|
||||||
if (mounted) {
|
|
||||||
setState(() {
|
|
||||||
widget.hide();
|
|
||||||
selectedShortReaction = -1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
child: (selectedShortReaction ==
|
child: SizedBox(
|
||||||
0) // Assuming index is 0 for this example
|
width: widget.show ? 40 : 10,
|
||||||
? EmojiAnimationFlying(
|
child: Center(
|
||||||
emoji: widget.emoji,
|
child: EmojiAnimation(
|
||||||
duration: const Duration(milliseconds: 300),
|
emoji: widget.emoji,
|
||||||
startPosition: 0,
|
),
|
||||||
size: (widget.show) ? 40 : 10,
|
),
|
||||||
)
|
),
|
||||||
: AnimatedOpacity(
|
|
||||||
opacity: (selectedShortReaction == -1) ? 1 : 0, // Fade in/out
|
|
||||||
duration: const Duration(milliseconds: 150),
|
|
||||||
child: SizedBox(
|
|
||||||
width: widget.show ? 40 : 10,
|
|
||||||
child: Center(
|
|
||||||
child: EmojiAnimation(
|
|
||||||
emoji: widget.emoji,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,12 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:math';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
import 'package:twonly/src/views/camera/image_editor/data/layer.dart';
|
||||||
|
import 'package:twonly/src/views/camera/image_editor/modules/all_emojis.dart';
|
||||||
import 'package:twonly/src/views/chats/media_viewer_components/emoji_reactions_row.component.dart';
|
import 'package:twonly/src/views/chats/media_viewer_components/emoji_reactions_row.component.dart';
|
||||||
import 'package:twonly/src/views/components/animate_icon.dart';
|
import 'package:twonly/src/views/components/animate_icon.dart';
|
||||||
|
|
||||||
|
|
@ -11,6 +17,7 @@ class ReactionButtons extends StatefulWidget {
|
||||||
required this.mediaViewerDistanceFromBottom,
|
required this.mediaViewerDistanceFromBottom,
|
||||||
required this.messageId,
|
required this.messageId,
|
||||||
required this.groupId,
|
required this.groupId,
|
||||||
|
required this.emojiKey,
|
||||||
required this.hide,
|
required this.hide,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
@ -18,6 +25,7 @@ class ReactionButtons extends StatefulWidget {
|
||||||
final double mediaViewerDistanceFromBottom;
|
final double mediaViewerDistanceFromBottom;
|
||||||
final bool show;
|
final bool show;
|
||||||
final bool textInputFocused;
|
final bool textInputFocused;
|
||||||
|
final GlobalKey<EmojiFloatWidgetState> emojiKey;
|
||||||
final String messageId;
|
final String messageId;
|
||||||
final String groupId;
|
final String groupId;
|
||||||
final void Function() hide;
|
final void Function() hide;
|
||||||
|
|
@ -28,6 +36,7 @@ class ReactionButtons extends StatefulWidget {
|
||||||
|
|
||||||
class _ReactionButtonsState extends State<ReactionButtons> {
|
class _ReactionButtonsState extends State<ReactionButtons> {
|
||||||
int selectedShortReaction = -1;
|
int selectedShortReaction = -1;
|
||||||
|
final GlobalKey _keyEmojiPicker = GlobalKey();
|
||||||
|
|
||||||
List<String> selectedEmojis =
|
List<String> selectedEmojis =
|
||||||
EmojiAnimation.animatedIcons.keys.toList().sublist(0, 6);
|
EmojiAnimation.animatedIcons.keys.toList().sublist(0, 6);
|
||||||
|
|
@ -82,6 +91,7 @@ class _ReactionButtonsState extends State<ReactionButtons> {
|
||||||
hide: widget.hide,
|
hide: widget.hide,
|
||||||
show: widget.show,
|
show: widget.show,
|
||||||
emoji: emoji as String,
|
emoji: emoji as String,
|
||||||
|
emojiKey: widget.emojiKey,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
|
|
@ -90,17 +100,53 @@ class _ReactionButtonsState extends State<ReactionButtons> {
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
children: firstRowEmojis
|
children: [
|
||||||
.map(
|
...firstRowEmojis.map(
|
||||||
(emoji) => EmojiReactionWidget(
|
(emoji) => EmojiReactionWidget(
|
||||||
messageId: widget.messageId,
|
messageId: widget.messageId,
|
||||||
groupId: widget.groupId,
|
groupId: widget.groupId,
|
||||||
hide: widget.hide,
|
hide: widget.hide,
|
||||||
show: widget.show,
|
show: widget.show,
|
||||||
emoji: emoji,
|
emoji: emoji,
|
||||||
|
emojiKey: widget.emojiKey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
key: _keyEmojiPicker,
|
||||||
|
onTap: () async {
|
||||||
|
// ignore: inference_failure_on_function_invocation
|
||||||
|
final layer = await showModalBottomSheet(
|
||||||
|
context: context,
|
||||||
|
backgroundColor: context.color.surface,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return const EmojiPickerBottom();
|
||||||
|
},
|
||||||
|
) as EmojiLayerData?;
|
||||||
|
if (layer == null) return;
|
||||||
|
await sendReaction(
|
||||||
|
widget.groupId,
|
||||||
|
widget.messageId,
|
||||||
|
layer.text,
|
||||||
|
);
|
||||||
|
widget.emojiKey.currentState?.spawn(
|
||||||
|
getGlobalOffset(_keyEmojiPicker),
|
||||||
|
layer.text,
|
||||||
|
);
|
||||||
|
widget.hide();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: context.color.surfaceContainer.withAlpha(100),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
)
|
padding: const EdgeInsets.all(8),
|
||||||
.toList(),
|
child: const FaIcon(
|
||||||
|
FontAwesomeIcons.ellipsisVertical,
|
||||||
|
size: 24,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
@ -109,3 +155,164 @@ class _ReactionButtonsState extends State<ReactionButtons> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EmojiFloatWidget extends StatefulWidget {
|
||||||
|
const EmojiFloatWidget({
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
@override
|
||||||
|
EmojiFloatWidgetState createState() => EmojiFloatWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class EmojiFloatWidgetState extends State<EmojiFloatWidget>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
|
final List<_Particle> _particles = [];
|
||||||
|
late final Ticker _ticker;
|
||||||
|
final Random _rnd = Random();
|
||||||
|
Duration _lastTick = Duration.zero;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_ticker = createTicker(_tick)..start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _tick(Duration elapsed) {
|
||||||
|
final dt = (_lastTick == Duration.zero)
|
||||||
|
? 0.016
|
||||||
|
: (elapsed - _lastTick).inMicroseconds / 1e6;
|
||||||
|
_lastTick = elapsed;
|
||||||
|
|
||||||
|
for (final p in List<_Particle>.from(_particles)) {
|
||||||
|
p.update(dt);
|
||||||
|
if (p.isDead) _particles.remove(p);
|
||||||
|
}
|
||||||
|
if (mounted) setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_ticker.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Call this to spawn the emoji animation from a global screen position.
|
||||||
|
void spawn(Offset globalPosition, String emoji) {
|
||||||
|
final box = context.findRenderObject() as RenderBox?;
|
||||||
|
if (box == null) return;
|
||||||
|
final local = box.globalToLocal(globalPosition);
|
||||||
|
const spawnCount = 10;
|
||||||
|
final life = const Duration(milliseconds: 2000).inMilliseconds / 1000.0;
|
||||||
|
|
||||||
|
for (var i = 0; i < spawnCount; i++) {
|
||||||
|
final dx = (_rnd.nextDouble() - 0.5) * 220;
|
||||||
|
final vx = dx;
|
||||||
|
final vy = -(100 + _rnd.nextDouble() * 80);
|
||||||
|
final rot = (_rnd.nextDouble() - 0.5) * 2;
|
||||||
|
final scale = 0.9 + _rnd.nextDouble() * 0.6;
|
||||||
|
|
||||||
|
_particles.add(
|
||||||
|
_Particle(
|
||||||
|
emoji: emoji,
|
||||||
|
x: local.dx,
|
||||||
|
y: local.dy,
|
||||||
|
vx: vx,
|
||||||
|
vy: vy,
|
||||||
|
rotation: rot,
|
||||||
|
lifetime: life,
|
||||||
|
scale: scale,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return IgnorePointer(
|
||||||
|
child: CustomPaint(
|
||||||
|
painter: _ParticlePainter(List<_Particle>.from(_particles)),
|
||||||
|
size: Size.infinite,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _Particle {
|
||||||
|
_Particle({
|
||||||
|
required this.emoji,
|
||||||
|
required this.x,
|
||||||
|
required this.y,
|
||||||
|
required this.vx,
|
||||||
|
required this.vy,
|
||||||
|
required this.rotation,
|
||||||
|
required this.lifetime,
|
||||||
|
required this.scale,
|
||||||
|
});
|
||||||
|
final String emoji;
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
double vx;
|
||||||
|
double vy;
|
||||||
|
double rotation;
|
||||||
|
double age = 0;
|
||||||
|
final double lifetime;
|
||||||
|
final double scale;
|
||||||
|
bool get isDead => age >= lifetime;
|
||||||
|
|
||||||
|
void update(double dt) {
|
||||||
|
age += dt;
|
||||||
|
// vertical-only motion emphasis: mild gravity slows ascent then gently pulls down
|
||||||
|
vy += 100 * dt; // gravity (positive = down)
|
||||||
|
// slight horizontal drag to reduce sideways drift
|
||||||
|
vx *= 1 - 3.0 * dt;
|
||||||
|
// integrate position
|
||||||
|
x += vx * dt;
|
||||||
|
y += vy * dt;
|
||||||
|
// slow rotation decay
|
||||||
|
rotation *= 1 - 1.5 * dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
double get progress => (age / lifetime).clamp(0.0, 1.0);
|
||||||
|
|
||||||
|
// opacity falls from 1 -> 0 as particle ages
|
||||||
|
double get opacity => (1.0 - progress).clamp(0.0, 1.0);
|
||||||
|
|
||||||
|
// scale can gently grow then shrink; here we slightly increase early
|
||||||
|
double get currentScale {
|
||||||
|
final p = progress;
|
||||||
|
if (p < 0.5) return scale * (1.0 + 0.3 * (p / 0.5));
|
||||||
|
return scale * (1.3 - 0.3 * ((p - 0.5) / 0.5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ParticlePainter extends CustomPainter {
|
||||||
|
_ParticlePainter(this.particles);
|
||||||
|
final List<_Particle> particles;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
final textPainter = TextPainter(textDirection: TextDirection.ltr);
|
||||||
|
for (final p in particles) {
|
||||||
|
final tp = TextSpan(
|
||||||
|
text: p.emoji,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 24 * p.currentScale,
|
||||||
|
color: Colors.black.withValues(alpha: p.opacity),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
textPainter
|
||||||
|
..text = tp
|
||||||
|
..layout();
|
||||||
|
canvas
|
||||||
|
..save()
|
||||||
|
..translate(p.x - textPainter.width / 2, p.y - textPainter.height / 2)
|
||||||
|
..rotate(p.rotation);
|
||||||
|
textPainter.paint(canvas, Offset.zero);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(covariant _ParticlePainter old) => true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,10 +72,16 @@ class _AvatarIconState extends State<AvatarIcon> {
|
||||||
_globalUserDataCallBackId = 'avatar_${getRandomString(10)}';
|
_globalUserDataCallBackId = 'avatar_${getRandomString(10)}';
|
||||||
globalUserDataChangedCallBack[_globalUserDataCallBackId!] = () {
|
globalUserDataChangedCallBack[_globalUserDataCallBackId!] = () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_avatarSVGs = [gUser.avatarSvg!];
|
if (gUser.avatarSvg != null) {
|
||||||
|
_avatarSVGs = [gUser.avatarSvg!];
|
||||||
|
} else {
|
||||||
|
_avatarSVGs = [];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
_avatarSVGs.add(gUser.avatarSvg!);
|
if (gUser.avatarSvg != null) {
|
||||||
|
_avatarSVGs = [gUser.avatarSvg!];
|
||||||
|
}
|
||||||
} else if (widget.contactId != null) {
|
} else if (widget.contactId != null) {
|
||||||
contactStream = twonlyDB.contactsDao
|
contactStream = twonlyDB.contactsDao
|
||||||
.watchContact(widget.contactId!)
|
.watchContact(widget.contactId!)
|
||||||
|
|
|
||||||
|
|
@ -82,13 +82,14 @@ class GroupContextMenu extends StatelessWidget {
|
||||||
context.lang.groupContextMenuDeleteGroup,
|
context.lang.groupContextMenuDeleteGroup,
|
||||||
);
|
);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
await twonlyDB.messagesDao.deleteMessagesByGroupId(group.groupId);
|
// await twonlyDB.messagesDao.deleteMessagesByGroupId(group.groupId);
|
||||||
await twonlyDB.groupsDao.updateGroup(
|
await twonlyDB.groupsDao.deleteGroup(group.groupId);
|
||||||
group.groupId,
|
// await twonlyDB.groupsDao.updateGroup(
|
||||||
const GroupsCompanion(
|
// group.groupId,
|
||||||
deletedContent: Value(true),
|
// const GroupsCompanion(
|
||||||
),
|
// deletedContent: Value(true),
|
||||||
);
|
// ),
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/model/protobuf/api/websocket/error.pb.dart';
|
import 'package:twonly/src/model/protobuf/api/websocket/error.pb.dart';
|
||||||
import 'package:twonly/src/services/api/messages.dart';
|
import 'package:twonly/src/services/api/messages.dart';
|
||||||
|
import 'package:twonly/src/services/twonly_safe/common.twonly_safe.dart';
|
||||||
|
import 'package:twonly/src/services/twonly_safe/create_backup.twonly_safe.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/utils/storage.dart';
|
import 'package:twonly/src/utils/storage.dart';
|
||||||
import 'package:twonly/src/views/components/better_list_title.dart';
|
import 'package:twonly/src/views/components/better_list_title.dart';
|
||||||
|
|
@ -59,6 +61,10 @@ class _ProfileViewState extends State<ProfileView> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// as the username has changes, remove the old from the server and then upload it again.
|
||||||
|
await removeTwonlySafeFromServer();
|
||||||
|
unawaited(performTwonlySafeBackup(force: true));
|
||||||
|
|
||||||
await updateUserdata((user) {
|
await updateUserdata((user) {
|
||||||
user
|
user
|
||||||
..username = username
|
..username = username
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue