mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 22:08:40 +00:00
display last reaction and compress avatarsvgs
This commit is contained in:
parent
3d5fc3e807
commit
350fb899e1
33 changed files with 604 additions and 297 deletions
|
|
@ -4,6 +4,7 @@ import 'package:twonly/src/database/tables/contacts.table.dart';
|
||||||
import 'package:twonly/src/database/twonly.db.dart';
|
import 'package:twonly/src/database/twonly.db.dart';
|
||||||
import 'package:twonly/src/database/twonly_database_old.dart' as old;
|
import 'package:twonly/src/database/twonly_database_old.dart' as old;
|
||||||
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
|
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
|
||||||
|
import 'package:twonly/src/utils/log.dart';
|
||||||
|
|
||||||
part 'contacts.dao.g.dart';
|
part 'contacts.dao.g.dart';
|
||||||
|
|
||||||
|
|
@ -14,10 +15,20 @@ class ContactsDao extends DatabaseAccessor<TwonlyDB> with _$ContactsDaoMixin {
|
||||||
// ignore: matching_super_parameters
|
// ignore: matching_super_parameters
|
||||||
ContactsDao(super.db);
|
ContactsDao(super.db);
|
||||||
|
|
||||||
Future<int> insertContact(ContactsCompanion contact) async {
|
Future<int?> insertContact(ContactsCompanion contact) async {
|
||||||
try {
|
try {
|
||||||
return await into(contacts).insert(contact);
|
return await into(contacts).insert(contact);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
Log.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<int> insertOnConflictUpdate(ContactsCompanion contact) async {
|
||||||
|
try {
|
||||||
|
return await into(contacts).insertOnConflictUpdate(contact);
|
||||||
|
} catch (e) {
|
||||||
|
Log.error(e);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -62,10 +73,12 @@ class ContactsDao extends DatabaseAccessor<TwonlyDB> with _$ContactsDaoMixin {
|
||||||
Stream<List<Contact>> watchNotAcceptedContacts() {
|
Stream<List<Contact>> watchNotAcceptedContacts() {
|
||||||
return (select(contacts)
|
return (select(contacts)
|
||||||
..where(
|
..where(
|
||||||
(t) => t.accepted.equals(false) & t.blocked.equals(false),
|
(t) =>
|
||||||
|
t.accepted.equals(false) &
|
||||||
|
t.blocked.equals(false) &
|
||||||
|
t.deletedByUser.equals(false),
|
||||||
))
|
))
|
||||||
.watch();
|
.watch();
|
||||||
// return (select(contacts)).watch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<Contact?> watchContact(int userid) {
|
Stream<Contact?> watchContact(int userid) {
|
||||||
|
|
@ -74,7 +87,7 @@ class ContactsDao extends DatabaseAccessor<TwonlyDB> with _$ContactsDaoMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Contact>> getAllNotBlockedContacts() {
|
Future<List<Contact>> getAllNotBlockedContacts() {
|
||||||
return (select(contacts)..where((t) => t.blocked.equals(false))).get();
|
return select(contacts).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<int?> watchContactsBlocked() {
|
Stream<int?> watchContactsBlocked() {
|
||||||
|
|
@ -89,7 +102,9 @@ class ContactsDao extends DatabaseAccessor<TwonlyDB> with _$ContactsDaoMixin {
|
||||||
final count = contacts.requested.count(distinct: true);
|
final count = contacts.requested.count(distinct: true);
|
||||||
final query = selectOnly(contacts)
|
final query = selectOnly(contacts)
|
||||||
..where(
|
..where(
|
||||||
contacts.requested.equals(true) & contacts.accepted.equals(true).not(),
|
contacts.requested.equals(true) &
|
||||||
|
contacts.accepted.equals(false) &
|
||||||
|
contacts.blocked.equals(false),
|
||||||
)
|
)
|
||||||
..addColumns([count]);
|
..addColumns([count]);
|
||||||
return query.map((row) => row.read(count)).watchSingle();
|
return query.map((row) => row.read(count)).watchSingle();
|
||||||
|
|
@ -113,7 +128,7 @@ String getContactDisplayName(Contact user) {
|
||||||
} else if (user.displayName != null) {
|
} else if (user.displayName != null) {
|
||||||
name = user.displayName!;
|
name = user.displayName!;
|
||||||
}
|
}
|
||||||
if (user.deleted) {
|
if (user.accountDeleted) {
|
||||||
name = applyStrikethrough(name);
|
name = applyStrikethrough(name);
|
||||||
}
|
}
|
||||||
if (name.length > 12) {
|
if (name.length > 12) {
|
||||||
|
|
|
||||||
|
|
@ -81,13 +81,13 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Contact>> getGroupContact(String groupId) async {
|
Future<List<Contact>> getGroupContact(String groupId) async {
|
||||||
final query = select(contacts).join([
|
final query = (select(contacts).join([
|
||||||
leftOuterJoin(
|
leftOuterJoin(
|
||||||
groupMembers,
|
groupMembers,
|
||||||
groupMembers.contactId.equalsExp(contacts.userId) &
|
groupMembers.contactId.equalsExp(contacts.userId),
|
||||||
groupMembers.groupId.equals(groupId),
|
|
||||||
),
|
),
|
||||||
]);
|
])
|
||||||
|
..where(groupMembers.groupId.equals(groupId)));
|
||||||
return query.map((row) => row.readTable(contacts)).get();
|
return query.map((row) => row.readTable(contacts)).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,7 +101,10 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
Stream<List<Group>> watchGroupsForChatList() {
|
Stream<List<Group>> watchGroupsForChatList() {
|
||||||
return (select(groups)..where((t) => t.archived.equals(false))).watch();
|
return (select(groups)
|
||||||
|
..where((t) => t.archived.equals(false))
|
||||||
|
..orderBy([(t) => OrderingTerm.desc(t.lastMessageExchange)]))
|
||||||
|
.watch();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Group?> getGroup(String groupId) {
|
Future<Group?> getGroup(String groupId) {
|
||||||
|
|
@ -117,7 +120,7 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
||||||
u.lastMessageReceived.isNotNull() &
|
u.lastMessageReceived.isNotNull() &
|
||||||
u.lastMessageSend.isNotNull(),
|
u.lastMessageSend.isNotNull(),
|
||||||
))
|
))
|
||||||
.watchSingle()
|
.watchSingleOrNull()
|
||||||
.asyncMap(getFlameCounterFromGroup);
|
.asyncMap(getFlameCounterFromGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,14 +129,14 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Group?> getDirectChat(int userId) async {
|
Future<Group?> getDirectChat(int userId) async {
|
||||||
final query = (select(groups).join([
|
final query =
|
||||||
|
((select(groups)..where((t) => t.isDirectChat.equals(true))).join([
|
||||||
leftOuterJoin(
|
leftOuterJoin(
|
||||||
groupMembers,
|
groupMembers,
|
||||||
groupMembers.groupId.equalsExp(groups.groupId) &
|
groupMembers.groupId.equalsExp(groups.groupId),
|
||||||
groupMembers.contactId.equals(userId),
|
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
..where(groups.isDirectChat.equals(true)));
|
..where(groupMembers.contactId.equals(userId)));
|
||||||
|
|
||||||
return query.map((row) => row.readTable(groups)).getSingleOrNull();
|
return query.map((row) => row.readTable(groups)).getSingleOrNull();
|
||||||
}
|
}
|
||||||
|
|
@ -208,9 +211,23 @@ class GroupsDao extends DatabaseAccessor<TwonlyDB> with _$GroupsDaoMixin {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> increaseLastMessageExchange(
|
||||||
|
String groupId,
|
||||||
|
DateTime newLastMessage,
|
||||||
|
) async {
|
||||||
|
await (update(groups)
|
||||||
|
..where(
|
||||||
|
(t) =>
|
||||||
|
t.groupId.equals(groupId) &
|
||||||
|
(t.lastMessageExchange.isSmallerThanValue(newLastMessage)),
|
||||||
|
))
|
||||||
|
.write(GroupsCompanion(lastMessageExchange: Value(newLastMessage)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getFlameCounterFromGroup(Group group) {
|
int getFlameCounterFromGroup(Group? group) {
|
||||||
|
if (group == null) return 0;
|
||||||
if (group.lastMessageSend == null || group.lastMessageReceived == null) {
|
if (group.lastMessageSend == null || group.lastMessageReceived == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,10 @@ class MessagesDao extends DatabaseAccessor<TwonlyDB> with _$MessagesDaoMixin {
|
||||||
|
|
||||||
Stream<List<Message>> watchMessageNotOpened(String groupId) {
|
Stream<List<Message>> watchMessageNotOpened(String groupId) {
|
||||||
return (select(messages)
|
return (select(messages)
|
||||||
..where((t) => t.openedAt.isNull() & t.groupId.equals(groupId))
|
..where((t) =>
|
||||||
|
t.openedAt.isNull() &
|
||||||
|
t.groupId.equals(groupId) &
|
||||||
|
t.isDeletedFromSender.equals(false))
|
||||||
..orderBy([(t) => OrderingTerm.desc(t.createdAt)]))
|
..orderBy([(t) => OrderingTerm.desc(t.createdAt)]))
|
||||||
.watch();
|
.watch();
|
||||||
}
|
}
|
||||||
|
|
@ -182,7 +185,8 @@ class MessagesDao extends DatabaseAccessor<TwonlyDB> with _$MessagesDaoMixin {
|
||||||
Log.error('Message does not exists or contact is not owner.');
|
Log.error('Message does not exists or contact is not owner.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (msg.mediaId != null) {
|
if (msg.mediaId != null && contactId != null) {
|
||||||
|
// contactId -> When a image is send to multiple and one message is delete the image should be still available...
|
||||||
await (delete(mediaFiles)..where((t) => t.mediaId.equals(msg.mediaId!)))
|
await (delete(mediaFiles)..where((t) => t.mediaId.equals(msg.mediaId!)))
|
||||||
.go();
|
.go();
|
||||||
|
|
||||||
|
|
@ -326,8 +330,8 @@ class MessagesDao extends DatabaseAccessor<TwonlyDB> with _$MessagesDaoMixin {
|
||||||
Future<void> updateMessageId(
|
Future<void> updateMessageId(
|
||||||
String messageId,
|
String messageId,
|
||||||
MessagesCompanion updatedValues,
|
MessagesCompanion updatedValues,
|
||||||
) {
|
) async {
|
||||||
return (update(messages)..where((c) => c.messageId.equals(messageId)))
|
await (update(messages)..where((c) => c.messageId.equals(messageId)))
|
||||||
.write(updatedValues);
|
.write(updatedValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,24 @@ class ReactionsDao extends DatabaseAccessor<TwonlyDB> with _$ReactionsDaoMixin {
|
||||||
.watch();
|
.watch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream<Reaction?> watchLastReactions(String groupId) {
|
||||||
|
final query = (select(reactions)
|
||||||
|
..orderBy([(t) => OrderingTerm.desc(t.createdAt)]))
|
||||||
|
.join(
|
||||||
|
[
|
||||||
|
innerJoin(
|
||||||
|
messages,
|
||||||
|
messages.messageId.equalsExp(reactions.messageId),
|
||||||
|
useColumns: false,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
..where(messages.groupId.equals(groupId))
|
||||||
|
// ..orderBy([(t) => OrderingTerm.asc(t.createdAt)]))
|
||||||
|
..limit(1);
|
||||||
|
return query.map((row) => row.readTable(reactions)).watchSingleOrNull();
|
||||||
|
}
|
||||||
|
|
||||||
Stream<List<(Reaction, Contact?)>> watchReactionWithContacts(
|
Stream<List<(Reaction, Contact?)>> watchReactionWithContacts(
|
||||||
String messageId,
|
String messageId,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,19 @@ class Contacts extends Table {
|
||||||
TextColumn get username => text()();
|
TextColumn get username => text()();
|
||||||
TextColumn get displayName => text().nullable()();
|
TextColumn get displayName => text().nullable()();
|
||||||
TextColumn get nickName => text().nullable()();
|
TextColumn get nickName => text().nullable()();
|
||||||
TextColumn get avatarSvg => text().nullable()();
|
BlobColumn get avatarSvgCompressed => blob().nullable()();
|
||||||
|
|
||||||
IntColumn get senderProfileCounter =>
|
IntColumn get senderProfileCounter =>
|
||||||
integer().withDefault(const Constant(0))();
|
integer().withDefault(const Constant(0))();
|
||||||
|
|
||||||
BoolColumn get accepted => boolean().withDefault(const Constant(false))();
|
BoolColumn get accepted => boolean().withDefault(const Constant(false))();
|
||||||
|
BoolColumn get deletedByUser =>
|
||||||
|
boolean().withDefault(const Constant(false))();
|
||||||
BoolColumn get requested => boolean().withDefault(const Constant(false))();
|
BoolColumn get requested => boolean().withDefault(const Constant(false))();
|
||||||
BoolColumn get blocked => boolean().withDefault(const Constant(false))();
|
BoolColumn get blocked => boolean().withDefault(const Constant(false))();
|
||||||
BoolColumn get verified => boolean().withDefault(const Constant(false))();
|
BoolColumn get verified => boolean().withDefault(const Constant(false))();
|
||||||
BoolColumn get deleted => boolean().withDefault(const Constant(false))();
|
BoolColumn get accountDeleted =>
|
||||||
|
boolean().withDefault(const Constant(false))();
|
||||||
|
|
||||||
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,12 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
late final GeneratedColumn<String> nickName = GeneratedColumn<String>(
|
late final GeneratedColumn<String> nickName = GeneratedColumn<String>(
|
||||||
'nick_name', aliasedName, true,
|
'nick_name', aliasedName, true,
|
||||||
type: DriftSqlType.string, requiredDuringInsert: false);
|
type: DriftSqlType.string, requiredDuringInsert: false);
|
||||||
static const VerificationMeta _avatarSvgMeta =
|
static const VerificationMeta _avatarSvgCompressedMeta =
|
||||||
const VerificationMeta('avatarSvg');
|
const VerificationMeta('avatarSvgCompressed');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<String> avatarSvg = GeneratedColumn<String>(
|
late final GeneratedColumn<Uint8List> avatarSvgCompressed =
|
||||||
'avatar_svg', aliasedName, true,
|
GeneratedColumn<Uint8List>('avatar_svg_compressed', aliasedName, true,
|
||||||
type: DriftSqlType.string, requiredDuringInsert: false);
|
type: DriftSqlType.blob, requiredDuringInsert: false);
|
||||||
static const VerificationMeta _senderProfileCounterMeta =
|
static const VerificationMeta _senderProfileCounterMeta =
|
||||||
const VerificationMeta('senderProfileCounter');
|
const VerificationMeta('senderProfileCounter');
|
||||||
@override
|
@override
|
||||||
|
|
@ -55,6 +55,16 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
defaultConstraints:
|
defaultConstraints:
|
||||||
GeneratedColumn.constraintIsAlways('CHECK ("accepted" IN (0, 1))'),
|
GeneratedColumn.constraintIsAlways('CHECK ("accepted" IN (0, 1))'),
|
||||||
defaultValue: const Constant(false));
|
defaultValue: const Constant(false));
|
||||||
|
static const VerificationMeta _deletedByUserMeta =
|
||||||
|
const VerificationMeta('deletedByUser');
|
||||||
|
@override
|
||||||
|
late final GeneratedColumn<bool> deletedByUser = GeneratedColumn<bool>(
|
||||||
|
'deleted_by_user', aliasedName, false,
|
||||||
|
type: DriftSqlType.bool,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("deleted_by_user" IN (0, 1))'),
|
||||||
|
defaultValue: const Constant(false));
|
||||||
static const VerificationMeta _requestedMeta =
|
static const VerificationMeta _requestedMeta =
|
||||||
const VerificationMeta('requested');
|
const VerificationMeta('requested');
|
||||||
@override
|
@override
|
||||||
|
|
@ -85,15 +95,15 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
defaultConstraints:
|
defaultConstraints:
|
||||||
GeneratedColumn.constraintIsAlways('CHECK ("verified" IN (0, 1))'),
|
GeneratedColumn.constraintIsAlways('CHECK ("verified" IN (0, 1))'),
|
||||||
defaultValue: const Constant(false));
|
defaultValue: const Constant(false));
|
||||||
static const VerificationMeta _deletedMeta =
|
static const VerificationMeta _accountDeletedMeta =
|
||||||
const VerificationMeta('deleted');
|
const VerificationMeta('accountDeleted');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> deleted = GeneratedColumn<bool>(
|
late final GeneratedColumn<bool> accountDeleted = GeneratedColumn<bool>(
|
||||||
'deleted', aliasedName, false,
|
'account_deleted', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints:
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
GeneratedColumn.constraintIsAlways('CHECK ("deleted" IN (0, 1))'),
|
'CHECK ("account_deleted" IN (0, 1))'),
|
||||||
defaultValue: const Constant(false));
|
defaultValue: const Constant(false));
|
||||||
static const VerificationMeta _createdAtMeta =
|
static const VerificationMeta _createdAtMeta =
|
||||||
const VerificationMeta('createdAt');
|
const VerificationMeta('createdAt');
|
||||||
|
|
@ -109,13 +119,14 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
username,
|
username,
|
||||||
displayName,
|
displayName,
|
||||||
nickName,
|
nickName,
|
||||||
avatarSvg,
|
avatarSvgCompressed,
|
||||||
senderProfileCounter,
|
senderProfileCounter,
|
||||||
accepted,
|
accepted,
|
||||||
|
deletedByUser,
|
||||||
requested,
|
requested,
|
||||||
blocked,
|
blocked,
|
||||||
verified,
|
verified,
|
||||||
deleted,
|
accountDeleted,
|
||||||
createdAt
|
createdAt
|
||||||
];
|
];
|
||||||
@override
|
@override
|
||||||
|
|
@ -148,9 +159,11 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
context.handle(_nickNameMeta,
|
context.handle(_nickNameMeta,
|
||||||
nickName.isAcceptableOrUnknown(data['nick_name']!, _nickNameMeta));
|
nickName.isAcceptableOrUnknown(data['nick_name']!, _nickNameMeta));
|
||||||
}
|
}
|
||||||
if (data.containsKey('avatar_svg')) {
|
if (data.containsKey('avatar_svg_compressed')) {
|
||||||
context.handle(_avatarSvgMeta,
|
context.handle(
|
||||||
avatarSvg.isAcceptableOrUnknown(data['avatar_svg']!, _avatarSvgMeta));
|
_avatarSvgCompressedMeta,
|
||||||
|
avatarSvgCompressed.isAcceptableOrUnknown(
|
||||||
|
data['avatar_svg_compressed']!, _avatarSvgCompressedMeta));
|
||||||
}
|
}
|
||||||
if (data.containsKey('sender_profile_counter')) {
|
if (data.containsKey('sender_profile_counter')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
|
|
@ -162,6 +175,12 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
context.handle(_acceptedMeta,
|
context.handle(_acceptedMeta,
|
||||||
accepted.isAcceptableOrUnknown(data['accepted']!, _acceptedMeta));
|
accepted.isAcceptableOrUnknown(data['accepted']!, _acceptedMeta));
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('deleted_by_user')) {
|
||||||
|
context.handle(
|
||||||
|
_deletedByUserMeta,
|
||||||
|
deletedByUser.isAcceptableOrUnknown(
|
||||||
|
data['deleted_by_user']!, _deletedByUserMeta));
|
||||||
|
}
|
||||||
if (data.containsKey('requested')) {
|
if (data.containsKey('requested')) {
|
||||||
context.handle(_requestedMeta,
|
context.handle(_requestedMeta,
|
||||||
requested.isAcceptableOrUnknown(data['requested']!, _requestedMeta));
|
requested.isAcceptableOrUnknown(data['requested']!, _requestedMeta));
|
||||||
|
|
@ -174,9 +193,11 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
context.handle(_verifiedMeta,
|
context.handle(_verifiedMeta,
|
||||||
verified.isAcceptableOrUnknown(data['verified']!, _verifiedMeta));
|
verified.isAcceptableOrUnknown(data['verified']!, _verifiedMeta));
|
||||||
}
|
}
|
||||||
if (data.containsKey('deleted')) {
|
if (data.containsKey('account_deleted')) {
|
||||||
context.handle(_deletedMeta,
|
context.handle(
|
||||||
deleted.isAcceptableOrUnknown(data['deleted']!, _deletedMeta));
|
_accountDeletedMeta,
|
||||||
|
accountDeleted.isAcceptableOrUnknown(
|
||||||
|
data['account_deleted']!, _accountDeletedMeta));
|
||||||
}
|
}
|
||||||
if (data.containsKey('created_at')) {
|
if (data.containsKey('created_at')) {
|
||||||
context.handle(_createdAtMeta,
|
context.handle(_createdAtMeta,
|
||||||
|
|
@ -199,20 +220,22 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> {
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}display_name']),
|
.read(DriftSqlType.string, data['${effectivePrefix}display_name']),
|
||||||
nickName: attachedDatabase.typeMapping
|
nickName: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}nick_name']),
|
.read(DriftSqlType.string, data['${effectivePrefix}nick_name']),
|
||||||
avatarSvg: attachedDatabase.typeMapping
|
avatarSvgCompressed: attachedDatabase.typeMapping.read(
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}avatar_svg']),
|
DriftSqlType.blob, data['${effectivePrefix}avatar_svg_compressed']),
|
||||||
senderProfileCounter: attachedDatabase.typeMapping.read(
|
senderProfileCounter: attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.int, data['${effectivePrefix}sender_profile_counter'])!,
|
DriftSqlType.int, data['${effectivePrefix}sender_profile_counter'])!,
|
||||||
accepted: attachedDatabase.typeMapping
|
accepted: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.bool, data['${effectivePrefix}accepted'])!,
|
.read(DriftSqlType.bool, data['${effectivePrefix}accepted'])!,
|
||||||
|
deletedByUser: attachedDatabase.typeMapping
|
||||||
|
.read(DriftSqlType.bool, data['${effectivePrefix}deleted_by_user'])!,
|
||||||
requested: attachedDatabase.typeMapping
|
requested: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.bool, data['${effectivePrefix}requested'])!,
|
.read(DriftSqlType.bool, data['${effectivePrefix}requested'])!,
|
||||||
blocked: attachedDatabase.typeMapping
|
blocked: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.bool, data['${effectivePrefix}blocked'])!,
|
.read(DriftSqlType.bool, data['${effectivePrefix}blocked'])!,
|
||||||
verified: attachedDatabase.typeMapping
|
verified: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.bool, data['${effectivePrefix}verified'])!,
|
.read(DriftSqlType.bool, data['${effectivePrefix}verified'])!,
|
||||||
deleted: attachedDatabase.typeMapping
|
accountDeleted: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.bool, data['${effectivePrefix}deleted'])!,
|
.read(DriftSqlType.bool, data['${effectivePrefix}account_deleted'])!,
|
||||||
createdAt: attachedDatabase.typeMapping
|
createdAt: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
|
.read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!,
|
||||||
);
|
);
|
||||||
|
|
@ -229,26 +252,28 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
final String username;
|
final String username;
|
||||||
final String? displayName;
|
final String? displayName;
|
||||||
final String? nickName;
|
final String? nickName;
|
||||||
final String? avatarSvg;
|
final Uint8List? avatarSvgCompressed;
|
||||||
final int senderProfileCounter;
|
final int senderProfileCounter;
|
||||||
final bool accepted;
|
final bool accepted;
|
||||||
|
final bool deletedByUser;
|
||||||
final bool requested;
|
final bool requested;
|
||||||
final bool blocked;
|
final bool blocked;
|
||||||
final bool verified;
|
final bool verified;
|
||||||
final bool deleted;
|
final bool accountDeleted;
|
||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
const Contact(
|
const Contact(
|
||||||
{required this.userId,
|
{required this.userId,
|
||||||
required this.username,
|
required this.username,
|
||||||
this.displayName,
|
this.displayName,
|
||||||
this.nickName,
|
this.nickName,
|
||||||
this.avatarSvg,
|
this.avatarSvgCompressed,
|
||||||
required this.senderProfileCounter,
|
required this.senderProfileCounter,
|
||||||
required this.accepted,
|
required this.accepted,
|
||||||
|
required this.deletedByUser,
|
||||||
required this.requested,
|
required this.requested,
|
||||||
required this.blocked,
|
required this.blocked,
|
||||||
required this.verified,
|
required this.verified,
|
||||||
required this.deleted,
|
required this.accountDeleted,
|
||||||
required this.createdAt});
|
required this.createdAt});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
|
|
@ -261,15 +286,16 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
if (!nullToAbsent || nickName != null) {
|
if (!nullToAbsent || nickName != null) {
|
||||||
map['nick_name'] = Variable<String>(nickName);
|
map['nick_name'] = Variable<String>(nickName);
|
||||||
}
|
}
|
||||||
if (!nullToAbsent || avatarSvg != null) {
|
if (!nullToAbsent || avatarSvgCompressed != null) {
|
||||||
map['avatar_svg'] = Variable<String>(avatarSvg);
|
map['avatar_svg_compressed'] = Variable<Uint8List>(avatarSvgCompressed);
|
||||||
}
|
}
|
||||||
map['sender_profile_counter'] = Variable<int>(senderProfileCounter);
|
map['sender_profile_counter'] = Variable<int>(senderProfileCounter);
|
||||||
map['accepted'] = Variable<bool>(accepted);
|
map['accepted'] = Variable<bool>(accepted);
|
||||||
|
map['deleted_by_user'] = Variable<bool>(deletedByUser);
|
||||||
map['requested'] = Variable<bool>(requested);
|
map['requested'] = Variable<bool>(requested);
|
||||||
map['blocked'] = Variable<bool>(blocked);
|
map['blocked'] = Variable<bool>(blocked);
|
||||||
map['verified'] = Variable<bool>(verified);
|
map['verified'] = Variable<bool>(verified);
|
||||||
map['deleted'] = Variable<bool>(deleted);
|
map['account_deleted'] = Variable<bool>(accountDeleted);
|
||||||
map['created_at'] = Variable<DateTime>(createdAt);
|
map['created_at'] = Variable<DateTime>(createdAt);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
@ -284,15 +310,16 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
nickName: nickName == null && nullToAbsent
|
nickName: nickName == null && nullToAbsent
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(nickName),
|
: Value(nickName),
|
||||||
avatarSvg: avatarSvg == null && nullToAbsent
|
avatarSvgCompressed: avatarSvgCompressed == null && nullToAbsent
|
||||||
? const Value.absent()
|
? const Value.absent()
|
||||||
: Value(avatarSvg),
|
: Value(avatarSvgCompressed),
|
||||||
senderProfileCounter: Value(senderProfileCounter),
|
senderProfileCounter: Value(senderProfileCounter),
|
||||||
accepted: Value(accepted),
|
accepted: Value(accepted),
|
||||||
|
deletedByUser: Value(deletedByUser),
|
||||||
requested: Value(requested),
|
requested: Value(requested),
|
||||||
blocked: Value(blocked),
|
blocked: Value(blocked),
|
||||||
verified: Value(verified),
|
verified: Value(verified),
|
||||||
deleted: Value(deleted),
|
accountDeleted: Value(accountDeleted),
|
||||||
createdAt: Value(createdAt),
|
createdAt: Value(createdAt),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -305,14 +332,16 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
username: serializer.fromJson<String>(json['username']),
|
username: serializer.fromJson<String>(json['username']),
|
||||||
displayName: serializer.fromJson<String?>(json['displayName']),
|
displayName: serializer.fromJson<String?>(json['displayName']),
|
||||||
nickName: serializer.fromJson<String?>(json['nickName']),
|
nickName: serializer.fromJson<String?>(json['nickName']),
|
||||||
avatarSvg: serializer.fromJson<String?>(json['avatarSvg']),
|
avatarSvgCompressed:
|
||||||
|
serializer.fromJson<Uint8List?>(json['avatarSvgCompressed']),
|
||||||
senderProfileCounter:
|
senderProfileCounter:
|
||||||
serializer.fromJson<int>(json['senderProfileCounter']),
|
serializer.fromJson<int>(json['senderProfileCounter']),
|
||||||
accepted: serializer.fromJson<bool>(json['accepted']),
|
accepted: serializer.fromJson<bool>(json['accepted']),
|
||||||
|
deletedByUser: serializer.fromJson<bool>(json['deletedByUser']),
|
||||||
requested: serializer.fromJson<bool>(json['requested']),
|
requested: serializer.fromJson<bool>(json['requested']),
|
||||||
blocked: serializer.fromJson<bool>(json['blocked']),
|
blocked: serializer.fromJson<bool>(json['blocked']),
|
||||||
verified: serializer.fromJson<bool>(json['verified']),
|
verified: serializer.fromJson<bool>(json['verified']),
|
||||||
deleted: serializer.fromJson<bool>(json['deleted']),
|
accountDeleted: serializer.fromJson<bool>(json['accountDeleted']),
|
||||||
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -324,13 +353,14 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
'username': serializer.toJson<String>(username),
|
'username': serializer.toJson<String>(username),
|
||||||
'displayName': serializer.toJson<String?>(displayName),
|
'displayName': serializer.toJson<String?>(displayName),
|
||||||
'nickName': serializer.toJson<String?>(nickName),
|
'nickName': serializer.toJson<String?>(nickName),
|
||||||
'avatarSvg': serializer.toJson<String?>(avatarSvg),
|
'avatarSvgCompressed': serializer.toJson<Uint8List?>(avatarSvgCompressed),
|
||||||
'senderProfileCounter': serializer.toJson<int>(senderProfileCounter),
|
'senderProfileCounter': serializer.toJson<int>(senderProfileCounter),
|
||||||
'accepted': serializer.toJson<bool>(accepted),
|
'accepted': serializer.toJson<bool>(accepted),
|
||||||
|
'deletedByUser': serializer.toJson<bool>(deletedByUser),
|
||||||
'requested': serializer.toJson<bool>(requested),
|
'requested': serializer.toJson<bool>(requested),
|
||||||
'blocked': serializer.toJson<bool>(blocked),
|
'blocked': serializer.toJson<bool>(blocked),
|
||||||
'verified': serializer.toJson<bool>(verified),
|
'verified': serializer.toJson<bool>(verified),
|
||||||
'deleted': serializer.toJson<bool>(deleted),
|
'accountDeleted': serializer.toJson<bool>(accountDeleted),
|
||||||
'createdAt': serializer.toJson<DateTime>(createdAt),
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -340,26 +370,30 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
String? username,
|
String? username,
|
||||||
Value<String?> displayName = const Value.absent(),
|
Value<String?> displayName = const Value.absent(),
|
||||||
Value<String?> nickName = const Value.absent(),
|
Value<String?> nickName = const Value.absent(),
|
||||||
Value<String?> avatarSvg = const Value.absent(),
|
Value<Uint8List?> avatarSvgCompressed = const Value.absent(),
|
||||||
int? senderProfileCounter,
|
int? senderProfileCounter,
|
||||||
bool? accepted,
|
bool? accepted,
|
||||||
|
bool? deletedByUser,
|
||||||
bool? requested,
|
bool? requested,
|
||||||
bool? blocked,
|
bool? blocked,
|
||||||
bool? verified,
|
bool? verified,
|
||||||
bool? deleted,
|
bool? accountDeleted,
|
||||||
DateTime? createdAt}) =>
|
DateTime? createdAt}) =>
|
||||||
Contact(
|
Contact(
|
||||||
userId: userId ?? this.userId,
|
userId: userId ?? this.userId,
|
||||||
username: username ?? this.username,
|
username: username ?? this.username,
|
||||||
displayName: displayName.present ? displayName.value : this.displayName,
|
displayName: displayName.present ? displayName.value : this.displayName,
|
||||||
nickName: nickName.present ? nickName.value : this.nickName,
|
nickName: nickName.present ? nickName.value : this.nickName,
|
||||||
avatarSvg: avatarSvg.present ? avatarSvg.value : this.avatarSvg,
|
avatarSvgCompressed: avatarSvgCompressed.present
|
||||||
|
? avatarSvgCompressed.value
|
||||||
|
: this.avatarSvgCompressed,
|
||||||
senderProfileCounter: senderProfileCounter ?? this.senderProfileCounter,
|
senderProfileCounter: senderProfileCounter ?? this.senderProfileCounter,
|
||||||
accepted: accepted ?? this.accepted,
|
accepted: accepted ?? this.accepted,
|
||||||
|
deletedByUser: deletedByUser ?? this.deletedByUser,
|
||||||
requested: requested ?? this.requested,
|
requested: requested ?? this.requested,
|
||||||
blocked: blocked ?? this.blocked,
|
blocked: blocked ?? this.blocked,
|
||||||
verified: verified ?? this.verified,
|
verified: verified ?? this.verified,
|
||||||
deleted: deleted ?? this.deleted,
|
accountDeleted: accountDeleted ?? this.accountDeleted,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
);
|
);
|
||||||
Contact copyWithCompanion(ContactsCompanion data) {
|
Contact copyWithCompanion(ContactsCompanion data) {
|
||||||
|
|
@ -369,15 +403,22 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
displayName:
|
displayName:
|
||||||
data.displayName.present ? data.displayName.value : this.displayName,
|
data.displayName.present ? data.displayName.value : this.displayName,
|
||||||
nickName: data.nickName.present ? data.nickName.value : this.nickName,
|
nickName: data.nickName.present ? data.nickName.value : this.nickName,
|
||||||
avatarSvg: data.avatarSvg.present ? data.avatarSvg.value : this.avatarSvg,
|
avatarSvgCompressed: data.avatarSvgCompressed.present
|
||||||
|
? data.avatarSvgCompressed.value
|
||||||
|
: this.avatarSvgCompressed,
|
||||||
senderProfileCounter: data.senderProfileCounter.present
|
senderProfileCounter: data.senderProfileCounter.present
|
||||||
? data.senderProfileCounter.value
|
? data.senderProfileCounter.value
|
||||||
: this.senderProfileCounter,
|
: this.senderProfileCounter,
|
||||||
accepted: data.accepted.present ? data.accepted.value : this.accepted,
|
accepted: data.accepted.present ? data.accepted.value : this.accepted,
|
||||||
|
deletedByUser: data.deletedByUser.present
|
||||||
|
? data.deletedByUser.value
|
||||||
|
: this.deletedByUser,
|
||||||
requested: data.requested.present ? data.requested.value : this.requested,
|
requested: data.requested.present ? data.requested.value : this.requested,
|
||||||
blocked: data.blocked.present ? data.blocked.value : this.blocked,
|
blocked: data.blocked.present ? data.blocked.value : this.blocked,
|
||||||
verified: data.verified.present ? data.verified.value : this.verified,
|
verified: data.verified.present ? data.verified.value : this.verified,
|
||||||
deleted: data.deleted.present ? data.deleted.value : this.deleted,
|
accountDeleted: data.accountDeleted.present
|
||||||
|
? data.accountDeleted.value
|
||||||
|
: this.accountDeleted,
|
||||||
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -389,13 +430,14 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
..write('username: $username, ')
|
..write('username: $username, ')
|
||||||
..write('displayName: $displayName, ')
|
..write('displayName: $displayName, ')
|
||||||
..write('nickName: $nickName, ')
|
..write('nickName: $nickName, ')
|
||||||
..write('avatarSvg: $avatarSvg, ')
|
..write('avatarSvgCompressed: $avatarSvgCompressed, ')
|
||||||
..write('senderProfileCounter: $senderProfileCounter, ')
|
..write('senderProfileCounter: $senderProfileCounter, ')
|
||||||
..write('accepted: $accepted, ')
|
..write('accepted: $accepted, ')
|
||||||
|
..write('deletedByUser: $deletedByUser, ')
|
||||||
..write('requested: $requested, ')
|
..write('requested: $requested, ')
|
||||||
..write('blocked: $blocked, ')
|
..write('blocked: $blocked, ')
|
||||||
..write('verified: $verified, ')
|
..write('verified: $verified, ')
|
||||||
..write('deleted: $deleted, ')
|
..write('accountDeleted: $accountDeleted, ')
|
||||||
..write('createdAt: $createdAt')
|
..write('createdAt: $createdAt')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
|
|
@ -407,13 +449,14 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
username,
|
username,
|
||||||
displayName,
|
displayName,
|
||||||
nickName,
|
nickName,
|
||||||
avatarSvg,
|
$driftBlobEquality.hash(avatarSvgCompressed),
|
||||||
senderProfileCounter,
|
senderProfileCounter,
|
||||||
accepted,
|
accepted,
|
||||||
|
deletedByUser,
|
||||||
requested,
|
requested,
|
||||||
blocked,
|
blocked,
|
||||||
verified,
|
verified,
|
||||||
deleted,
|
accountDeleted,
|
||||||
createdAt);
|
createdAt);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
|
|
@ -423,13 +466,15 @@ class Contact extends DataClass implements Insertable<Contact> {
|
||||||
other.username == this.username &&
|
other.username == this.username &&
|
||||||
other.displayName == this.displayName &&
|
other.displayName == this.displayName &&
|
||||||
other.nickName == this.nickName &&
|
other.nickName == this.nickName &&
|
||||||
other.avatarSvg == this.avatarSvg &&
|
$driftBlobEquality.equals(
|
||||||
|
other.avatarSvgCompressed, this.avatarSvgCompressed) &&
|
||||||
other.senderProfileCounter == this.senderProfileCounter &&
|
other.senderProfileCounter == this.senderProfileCounter &&
|
||||||
other.accepted == this.accepted &&
|
other.accepted == this.accepted &&
|
||||||
|
other.deletedByUser == this.deletedByUser &&
|
||||||
other.requested == this.requested &&
|
other.requested == this.requested &&
|
||||||
other.blocked == this.blocked &&
|
other.blocked == this.blocked &&
|
||||||
other.verified == this.verified &&
|
other.verified == this.verified &&
|
||||||
other.deleted == this.deleted &&
|
other.accountDeleted == this.accountDeleted &&
|
||||||
other.createdAt == this.createdAt);
|
other.createdAt == this.createdAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -438,26 +483,28 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
final Value<String> username;
|
final Value<String> username;
|
||||||
final Value<String?> displayName;
|
final Value<String?> displayName;
|
||||||
final Value<String?> nickName;
|
final Value<String?> nickName;
|
||||||
final Value<String?> avatarSvg;
|
final Value<Uint8List?> avatarSvgCompressed;
|
||||||
final Value<int> senderProfileCounter;
|
final Value<int> senderProfileCounter;
|
||||||
final Value<bool> accepted;
|
final Value<bool> accepted;
|
||||||
|
final Value<bool> deletedByUser;
|
||||||
final Value<bool> requested;
|
final Value<bool> requested;
|
||||||
final Value<bool> blocked;
|
final Value<bool> blocked;
|
||||||
final Value<bool> verified;
|
final Value<bool> verified;
|
||||||
final Value<bool> deleted;
|
final Value<bool> accountDeleted;
|
||||||
final Value<DateTime> createdAt;
|
final Value<DateTime> createdAt;
|
||||||
const ContactsCompanion({
|
const ContactsCompanion({
|
||||||
this.userId = const Value.absent(),
|
this.userId = const Value.absent(),
|
||||||
this.username = const Value.absent(),
|
this.username = const Value.absent(),
|
||||||
this.displayName = const Value.absent(),
|
this.displayName = const Value.absent(),
|
||||||
this.nickName = const Value.absent(),
|
this.nickName = const Value.absent(),
|
||||||
this.avatarSvg = const Value.absent(),
|
this.avatarSvgCompressed = const Value.absent(),
|
||||||
this.senderProfileCounter = const Value.absent(),
|
this.senderProfileCounter = const Value.absent(),
|
||||||
this.accepted = const Value.absent(),
|
this.accepted = const Value.absent(),
|
||||||
|
this.deletedByUser = const Value.absent(),
|
||||||
this.requested = const Value.absent(),
|
this.requested = const Value.absent(),
|
||||||
this.blocked = const Value.absent(),
|
this.blocked = const Value.absent(),
|
||||||
this.verified = const Value.absent(),
|
this.verified = const Value.absent(),
|
||||||
this.deleted = const Value.absent(),
|
this.accountDeleted = const Value.absent(),
|
||||||
this.createdAt = const Value.absent(),
|
this.createdAt = const Value.absent(),
|
||||||
});
|
});
|
||||||
ContactsCompanion.insert({
|
ContactsCompanion.insert({
|
||||||
|
|
@ -465,13 +512,14 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
required String username,
|
required String username,
|
||||||
this.displayName = const Value.absent(),
|
this.displayName = const Value.absent(),
|
||||||
this.nickName = const Value.absent(),
|
this.nickName = const Value.absent(),
|
||||||
this.avatarSvg = const Value.absent(),
|
this.avatarSvgCompressed = const Value.absent(),
|
||||||
this.senderProfileCounter = const Value.absent(),
|
this.senderProfileCounter = const Value.absent(),
|
||||||
this.accepted = const Value.absent(),
|
this.accepted = const Value.absent(),
|
||||||
|
this.deletedByUser = const Value.absent(),
|
||||||
this.requested = const Value.absent(),
|
this.requested = const Value.absent(),
|
||||||
this.blocked = const Value.absent(),
|
this.blocked = const Value.absent(),
|
||||||
this.verified = const Value.absent(),
|
this.verified = const Value.absent(),
|
||||||
this.deleted = const Value.absent(),
|
this.accountDeleted = const Value.absent(),
|
||||||
this.createdAt = const Value.absent(),
|
this.createdAt = const Value.absent(),
|
||||||
}) : username = Value(username);
|
}) : username = Value(username);
|
||||||
static Insertable<Contact> custom({
|
static Insertable<Contact> custom({
|
||||||
|
|
@ -479,13 +527,14 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
Expression<String>? username,
|
Expression<String>? username,
|
||||||
Expression<String>? displayName,
|
Expression<String>? displayName,
|
||||||
Expression<String>? nickName,
|
Expression<String>? nickName,
|
||||||
Expression<String>? avatarSvg,
|
Expression<Uint8List>? avatarSvgCompressed,
|
||||||
Expression<int>? senderProfileCounter,
|
Expression<int>? senderProfileCounter,
|
||||||
Expression<bool>? accepted,
|
Expression<bool>? accepted,
|
||||||
|
Expression<bool>? deletedByUser,
|
||||||
Expression<bool>? requested,
|
Expression<bool>? requested,
|
||||||
Expression<bool>? blocked,
|
Expression<bool>? blocked,
|
||||||
Expression<bool>? verified,
|
Expression<bool>? verified,
|
||||||
Expression<bool>? deleted,
|
Expression<bool>? accountDeleted,
|
||||||
Expression<DateTime>? createdAt,
|
Expression<DateTime>? createdAt,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
|
|
@ -493,14 +542,16 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
if (username != null) 'username': username,
|
if (username != null) 'username': username,
|
||||||
if (displayName != null) 'display_name': displayName,
|
if (displayName != null) 'display_name': displayName,
|
||||||
if (nickName != null) 'nick_name': nickName,
|
if (nickName != null) 'nick_name': nickName,
|
||||||
if (avatarSvg != null) 'avatar_svg': avatarSvg,
|
if (avatarSvgCompressed != null)
|
||||||
|
'avatar_svg_compressed': avatarSvgCompressed,
|
||||||
if (senderProfileCounter != null)
|
if (senderProfileCounter != null)
|
||||||
'sender_profile_counter': senderProfileCounter,
|
'sender_profile_counter': senderProfileCounter,
|
||||||
if (accepted != null) 'accepted': accepted,
|
if (accepted != null) 'accepted': accepted,
|
||||||
|
if (deletedByUser != null) 'deleted_by_user': deletedByUser,
|
||||||
if (requested != null) 'requested': requested,
|
if (requested != null) 'requested': requested,
|
||||||
if (blocked != null) 'blocked': blocked,
|
if (blocked != null) 'blocked': blocked,
|
||||||
if (verified != null) 'verified': verified,
|
if (verified != null) 'verified': verified,
|
||||||
if (deleted != null) 'deleted': deleted,
|
if (accountDeleted != null) 'account_deleted': accountDeleted,
|
||||||
if (createdAt != null) 'created_at': createdAt,
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -510,26 +561,28 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
Value<String>? username,
|
Value<String>? username,
|
||||||
Value<String?>? displayName,
|
Value<String?>? displayName,
|
||||||
Value<String?>? nickName,
|
Value<String?>? nickName,
|
||||||
Value<String?>? avatarSvg,
|
Value<Uint8List?>? avatarSvgCompressed,
|
||||||
Value<int>? senderProfileCounter,
|
Value<int>? senderProfileCounter,
|
||||||
Value<bool>? accepted,
|
Value<bool>? accepted,
|
||||||
|
Value<bool>? deletedByUser,
|
||||||
Value<bool>? requested,
|
Value<bool>? requested,
|
||||||
Value<bool>? blocked,
|
Value<bool>? blocked,
|
||||||
Value<bool>? verified,
|
Value<bool>? verified,
|
||||||
Value<bool>? deleted,
|
Value<bool>? accountDeleted,
|
||||||
Value<DateTime>? createdAt}) {
|
Value<DateTime>? createdAt}) {
|
||||||
return ContactsCompanion(
|
return ContactsCompanion(
|
||||||
userId: userId ?? this.userId,
|
userId: userId ?? this.userId,
|
||||||
username: username ?? this.username,
|
username: username ?? this.username,
|
||||||
displayName: displayName ?? this.displayName,
|
displayName: displayName ?? this.displayName,
|
||||||
nickName: nickName ?? this.nickName,
|
nickName: nickName ?? this.nickName,
|
||||||
avatarSvg: avatarSvg ?? this.avatarSvg,
|
avatarSvgCompressed: avatarSvgCompressed ?? this.avatarSvgCompressed,
|
||||||
senderProfileCounter: senderProfileCounter ?? this.senderProfileCounter,
|
senderProfileCounter: senderProfileCounter ?? this.senderProfileCounter,
|
||||||
accepted: accepted ?? this.accepted,
|
accepted: accepted ?? this.accepted,
|
||||||
|
deletedByUser: deletedByUser ?? this.deletedByUser,
|
||||||
requested: requested ?? this.requested,
|
requested: requested ?? this.requested,
|
||||||
blocked: blocked ?? this.blocked,
|
blocked: blocked ?? this.blocked,
|
||||||
verified: verified ?? this.verified,
|
verified: verified ?? this.verified,
|
||||||
deleted: deleted ?? this.deleted,
|
accountDeleted: accountDeleted ?? this.accountDeleted,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -549,8 +602,9 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
if (nickName.present) {
|
if (nickName.present) {
|
||||||
map['nick_name'] = Variable<String>(nickName.value);
|
map['nick_name'] = Variable<String>(nickName.value);
|
||||||
}
|
}
|
||||||
if (avatarSvg.present) {
|
if (avatarSvgCompressed.present) {
|
||||||
map['avatar_svg'] = Variable<String>(avatarSvg.value);
|
map['avatar_svg_compressed'] =
|
||||||
|
Variable<Uint8List>(avatarSvgCompressed.value);
|
||||||
}
|
}
|
||||||
if (senderProfileCounter.present) {
|
if (senderProfileCounter.present) {
|
||||||
map['sender_profile_counter'] = Variable<int>(senderProfileCounter.value);
|
map['sender_profile_counter'] = Variable<int>(senderProfileCounter.value);
|
||||||
|
|
@ -558,6 +612,9 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
if (accepted.present) {
|
if (accepted.present) {
|
||||||
map['accepted'] = Variable<bool>(accepted.value);
|
map['accepted'] = Variable<bool>(accepted.value);
|
||||||
}
|
}
|
||||||
|
if (deletedByUser.present) {
|
||||||
|
map['deleted_by_user'] = Variable<bool>(deletedByUser.value);
|
||||||
|
}
|
||||||
if (requested.present) {
|
if (requested.present) {
|
||||||
map['requested'] = Variable<bool>(requested.value);
|
map['requested'] = Variable<bool>(requested.value);
|
||||||
}
|
}
|
||||||
|
|
@ -567,8 +624,8 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
if (verified.present) {
|
if (verified.present) {
|
||||||
map['verified'] = Variable<bool>(verified.value);
|
map['verified'] = Variable<bool>(verified.value);
|
||||||
}
|
}
|
||||||
if (deleted.present) {
|
if (accountDeleted.present) {
|
||||||
map['deleted'] = Variable<bool>(deleted.value);
|
map['account_deleted'] = Variable<bool>(accountDeleted.value);
|
||||||
}
|
}
|
||||||
if (createdAt.present) {
|
if (createdAt.present) {
|
||||||
map['created_at'] = Variable<DateTime>(createdAt.value);
|
map['created_at'] = Variable<DateTime>(createdAt.value);
|
||||||
|
|
@ -583,13 +640,14 @@ class ContactsCompanion extends UpdateCompanion<Contact> {
|
||||||
..write('username: $username, ')
|
..write('username: $username, ')
|
||||||
..write('displayName: $displayName, ')
|
..write('displayName: $displayName, ')
|
||||||
..write('nickName: $nickName, ')
|
..write('nickName: $nickName, ')
|
||||||
..write('avatarSvg: $avatarSvg, ')
|
..write('avatarSvgCompressed: $avatarSvgCompressed, ')
|
||||||
..write('senderProfileCounter: $senderProfileCounter, ')
|
..write('senderProfileCounter: $senderProfileCounter, ')
|
||||||
..write('accepted: $accepted, ')
|
..write('accepted: $accepted, ')
|
||||||
|
..write('deletedByUser: $deletedByUser, ')
|
||||||
..write('requested: $requested, ')
|
..write('requested: $requested, ')
|
||||||
..write('blocked: $blocked, ')
|
..write('blocked: $blocked, ')
|
||||||
..write('verified: $verified, ')
|
..write('verified: $verified, ')
|
||||||
..write('deleted: $deleted, ')
|
..write('accountDeleted: $accountDeleted, ')
|
||||||
..write('createdAt: $createdAt')
|
..write('createdAt: $createdAt')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
|
|
@ -6533,13 +6591,14 @@ typedef $$ContactsTableCreateCompanionBuilder = ContactsCompanion Function({
|
||||||
required String username,
|
required String username,
|
||||||
Value<String?> displayName,
|
Value<String?> displayName,
|
||||||
Value<String?> nickName,
|
Value<String?> nickName,
|
||||||
Value<String?> avatarSvg,
|
Value<Uint8List?> avatarSvgCompressed,
|
||||||
Value<int> senderProfileCounter,
|
Value<int> senderProfileCounter,
|
||||||
Value<bool> accepted,
|
Value<bool> accepted,
|
||||||
|
Value<bool> deletedByUser,
|
||||||
Value<bool> requested,
|
Value<bool> requested,
|
||||||
Value<bool> blocked,
|
Value<bool> blocked,
|
||||||
Value<bool> verified,
|
Value<bool> verified,
|
||||||
Value<bool> deleted,
|
Value<bool> accountDeleted,
|
||||||
Value<DateTime> createdAt,
|
Value<DateTime> createdAt,
|
||||||
});
|
});
|
||||||
typedef $$ContactsTableUpdateCompanionBuilder = ContactsCompanion Function({
|
typedef $$ContactsTableUpdateCompanionBuilder = ContactsCompanion Function({
|
||||||
|
|
@ -6547,13 +6606,14 @@ typedef $$ContactsTableUpdateCompanionBuilder = ContactsCompanion Function({
|
||||||
Value<String> username,
|
Value<String> username,
|
||||||
Value<String?> displayName,
|
Value<String?> displayName,
|
||||||
Value<String?> nickName,
|
Value<String?> nickName,
|
||||||
Value<String?> avatarSvg,
|
Value<Uint8List?> avatarSvgCompressed,
|
||||||
Value<int> senderProfileCounter,
|
Value<int> senderProfileCounter,
|
||||||
Value<bool> accepted,
|
Value<bool> accepted,
|
||||||
|
Value<bool> deletedByUser,
|
||||||
Value<bool> requested,
|
Value<bool> requested,
|
||||||
Value<bool> blocked,
|
Value<bool> blocked,
|
||||||
Value<bool> verified,
|
Value<bool> verified,
|
||||||
Value<bool> deleted,
|
Value<bool> accountDeleted,
|
||||||
Value<DateTime> createdAt,
|
Value<DateTime> createdAt,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -6684,8 +6744,9 @@ class $$ContactsTableFilterComposer
|
||||||
ColumnFilters<String> get nickName => $composableBuilder(
|
ColumnFilters<String> get nickName => $composableBuilder(
|
||||||
column: $table.nickName, builder: (column) => ColumnFilters(column));
|
column: $table.nickName, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<String> get avatarSvg => $composableBuilder(
|
ColumnFilters<Uint8List> get avatarSvgCompressed => $composableBuilder(
|
||||||
column: $table.avatarSvg, builder: (column) => ColumnFilters(column));
|
column: $table.avatarSvgCompressed,
|
||||||
|
builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<int> get senderProfileCounter => $composableBuilder(
|
ColumnFilters<int> get senderProfileCounter => $composableBuilder(
|
||||||
column: $table.senderProfileCounter,
|
column: $table.senderProfileCounter,
|
||||||
|
|
@ -6694,6 +6755,9 @@ class $$ContactsTableFilterComposer
|
||||||
ColumnFilters<bool> get accepted => $composableBuilder(
|
ColumnFilters<bool> get accepted => $composableBuilder(
|
||||||
column: $table.accepted, builder: (column) => ColumnFilters(column));
|
column: $table.accepted, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
ColumnFilters<bool> get deletedByUser => $composableBuilder(
|
||||||
|
column: $table.deletedByUser, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<bool> get requested => $composableBuilder(
|
ColumnFilters<bool> get requested => $composableBuilder(
|
||||||
column: $table.requested, builder: (column) => ColumnFilters(column));
|
column: $table.requested, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
|
|
@ -6703,8 +6767,9 @@ class $$ContactsTableFilterComposer
|
||||||
ColumnFilters<bool> get verified => $composableBuilder(
|
ColumnFilters<bool> get verified => $composableBuilder(
|
||||||
column: $table.verified, builder: (column) => ColumnFilters(column));
|
column: $table.verified, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<bool> get deleted => $composableBuilder(
|
ColumnFilters<bool> get accountDeleted => $composableBuilder(
|
||||||
column: $table.deleted, builder: (column) => ColumnFilters(column));
|
column: $table.accountDeleted,
|
||||||
|
builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
ColumnFilters<DateTime> get createdAt => $composableBuilder(
|
||||||
column: $table.createdAt, builder: (column) => ColumnFilters(column));
|
column: $table.createdAt, builder: (column) => ColumnFilters(column));
|
||||||
|
|
@ -6861,8 +6926,9 @@ class $$ContactsTableOrderingComposer
|
||||||
ColumnOrderings<String> get nickName => $composableBuilder(
|
ColumnOrderings<String> get nickName => $composableBuilder(
|
||||||
column: $table.nickName, builder: (column) => ColumnOrderings(column));
|
column: $table.nickName, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<String> get avatarSvg => $composableBuilder(
|
ColumnOrderings<Uint8List> get avatarSvgCompressed => $composableBuilder(
|
||||||
column: $table.avatarSvg, builder: (column) => ColumnOrderings(column));
|
column: $table.avatarSvgCompressed,
|
||||||
|
builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<int> get senderProfileCounter => $composableBuilder(
|
ColumnOrderings<int> get senderProfileCounter => $composableBuilder(
|
||||||
column: $table.senderProfileCounter,
|
column: $table.senderProfileCounter,
|
||||||
|
|
@ -6871,6 +6937,10 @@ class $$ContactsTableOrderingComposer
|
||||||
ColumnOrderings<bool> get accepted => $composableBuilder(
|
ColumnOrderings<bool> get accepted => $composableBuilder(
|
||||||
column: $table.accepted, builder: (column) => ColumnOrderings(column));
|
column: $table.accepted, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
ColumnOrderings<bool> get deletedByUser => $composableBuilder(
|
||||||
|
column: $table.deletedByUser,
|
||||||
|
builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<bool> get requested => $composableBuilder(
|
ColumnOrderings<bool> get requested => $composableBuilder(
|
||||||
column: $table.requested, builder: (column) => ColumnOrderings(column));
|
column: $table.requested, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
|
|
@ -6880,8 +6950,9 @@ class $$ContactsTableOrderingComposer
|
||||||
ColumnOrderings<bool> get verified => $composableBuilder(
|
ColumnOrderings<bool> get verified => $composableBuilder(
|
||||||
column: $table.verified, builder: (column) => ColumnOrderings(column));
|
column: $table.verified, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<bool> get deleted => $composableBuilder(
|
ColumnOrderings<bool> get accountDeleted => $composableBuilder(
|
||||||
column: $table.deleted, builder: (column) => ColumnOrderings(column));
|
column: $table.accountDeleted,
|
||||||
|
builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
ColumnOrderings<DateTime> get createdAt => $composableBuilder(
|
||||||
column: $table.createdAt, builder: (column) => ColumnOrderings(column));
|
column: $table.createdAt, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
@ -6908,8 +6979,8 @@ class $$ContactsTableAnnotationComposer
|
||||||
GeneratedColumn<String> get nickName =>
|
GeneratedColumn<String> get nickName =>
|
||||||
$composableBuilder(column: $table.nickName, builder: (column) => column);
|
$composableBuilder(column: $table.nickName, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumn<String> get avatarSvg =>
|
GeneratedColumn<Uint8List> get avatarSvgCompressed => $composableBuilder(
|
||||||
$composableBuilder(column: $table.avatarSvg, builder: (column) => column);
|
column: $table.avatarSvgCompressed, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumn<int> get senderProfileCounter => $composableBuilder(
|
GeneratedColumn<int> get senderProfileCounter => $composableBuilder(
|
||||||
column: $table.senderProfileCounter, builder: (column) => column);
|
column: $table.senderProfileCounter, builder: (column) => column);
|
||||||
|
|
@ -6917,6 +6988,9 @@ class $$ContactsTableAnnotationComposer
|
||||||
GeneratedColumn<bool> get accepted =>
|
GeneratedColumn<bool> get accepted =>
|
||||||
$composableBuilder(column: $table.accepted, builder: (column) => column);
|
$composableBuilder(column: $table.accepted, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<bool> get deletedByUser => $composableBuilder(
|
||||||
|
column: $table.deletedByUser, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumn<bool> get requested =>
|
GeneratedColumn<bool> get requested =>
|
||||||
$composableBuilder(column: $table.requested, builder: (column) => column);
|
$composableBuilder(column: $table.requested, builder: (column) => column);
|
||||||
|
|
||||||
|
|
@ -6926,8 +7000,8 @@ class $$ContactsTableAnnotationComposer
|
||||||
GeneratedColumn<bool> get verified =>
|
GeneratedColumn<bool> get verified =>
|
||||||
$composableBuilder(column: $table.verified, builder: (column) => column);
|
$composableBuilder(column: $table.verified, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumn<bool> get deleted =>
|
GeneratedColumn<bool> get accountDeleted => $composableBuilder(
|
||||||
$composableBuilder(column: $table.deleted, builder: (column) => column);
|
column: $table.accountDeleted, builder: (column) => column);
|
||||||
|
|
||||||
GeneratedColumn<DateTime> get createdAt =>
|
GeneratedColumn<DateTime> get createdAt =>
|
||||||
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
$composableBuilder(column: $table.createdAt, builder: (column) => column);
|
||||||
|
|
@ -7097,13 +7171,14 @@ class $$ContactsTableTableManager extends RootTableManager<
|
||||||
Value<String> username = const Value.absent(),
|
Value<String> username = const Value.absent(),
|
||||||
Value<String?> displayName = const Value.absent(),
|
Value<String?> displayName = const Value.absent(),
|
||||||
Value<String?> nickName = const Value.absent(),
|
Value<String?> nickName = const Value.absent(),
|
||||||
Value<String?> avatarSvg = const Value.absent(),
|
Value<Uint8List?> avatarSvgCompressed = const Value.absent(),
|
||||||
Value<int> senderProfileCounter = const Value.absent(),
|
Value<int> senderProfileCounter = const Value.absent(),
|
||||||
Value<bool> accepted = const Value.absent(),
|
Value<bool> accepted = const Value.absent(),
|
||||||
|
Value<bool> deletedByUser = const Value.absent(),
|
||||||
Value<bool> requested = const Value.absent(),
|
Value<bool> requested = const Value.absent(),
|
||||||
Value<bool> blocked = const Value.absent(),
|
Value<bool> blocked = const Value.absent(),
|
||||||
Value<bool> verified = const Value.absent(),
|
Value<bool> verified = const Value.absent(),
|
||||||
Value<bool> deleted = const Value.absent(),
|
Value<bool> accountDeleted = const Value.absent(),
|
||||||
Value<DateTime> createdAt = const Value.absent(),
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
}) =>
|
}) =>
|
||||||
ContactsCompanion(
|
ContactsCompanion(
|
||||||
|
|
@ -7111,13 +7186,14 @@ class $$ContactsTableTableManager extends RootTableManager<
|
||||||
username: username,
|
username: username,
|
||||||
displayName: displayName,
|
displayName: displayName,
|
||||||
nickName: nickName,
|
nickName: nickName,
|
||||||
avatarSvg: avatarSvg,
|
avatarSvgCompressed: avatarSvgCompressed,
|
||||||
senderProfileCounter: senderProfileCounter,
|
senderProfileCounter: senderProfileCounter,
|
||||||
accepted: accepted,
|
accepted: accepted,
|
||||||
|
deletedByUser: deletedByUser,
|
||||||
requested: requested,
|
requested: requested,
|
||||||
blocked: blocked,
|
blocked: blocked,
|
||||||
verified: verified,
|
verified: verified,
|
||||||
deleted: deleted,
|
accountDeleted: accountDeleted,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
),
|
),
|
||||||
createCompanionCallback: ({
|
createCompanionCallback: ({
|
||||||
|
|
@ -7125,13 +7201,14 @@ class $$ContactsTableTableManager extends RootTableManager<
|
||||||
required String username,
|
required String username,
|
||||||
Value<String?> displayName = const Value.absent(),
|
Value<String?> displayName = const Value.absent(),
|
||||||
Value<String?> nickName = const Value.absent(),
|
Value<String?> nickName = const Value.absent(),
|
||||||
Value<String?> avatarSvg = const Value.absent(),
|
Value<Uint8List?> avatarSvgCompressed = const Value.absent(),
|
||||||
Value<int> senderProfileCounter = const Value.absent(),
|
Value<int> senderProfileCounter = const Value.absent(),
|
||||||
Value<bool> accepted = const Value.absent(),
|
Value<bool> accepted = const Value.absent(),
|
||||||
|
Value<bool> deletedByUser = const Value.absent(),
|
||||||
Value<bool> requested = const Value.absent(),
|
Value<bool> requested = const Value.absent(),
|
||||||
Value<bool> blocked = const Value.absent(),
|
Value<bool> blocked = const Value.absent(),
|
||||||
Value<bool> verified = const Value.absent(),
|
Value<bool> verified = const Value.absent(),
|
||||||
Value<bool> deleted = const Value.absent(),
|
Value<bool> accountDeleted = const Value.absent(),
|
||||||
Value<DateTime> createdAt = const Value.absent(),
|
Value<DateTime> createdAt = const Value.absent(),
|
||||||
}) =>
|
}) =>
|
||||||
ContactsCompanion.insert(
|
ContactsCompanion.insert(
|
||||||
|
|
@ -7139,13 +7216,14 @@ class $$ContactsTableTableManager extends RootTableManager<
|
||||||
username: username,
|
username: username,
|
||||||
displayName: displayName,
|
displayName: displayName,
|
||||||
nickName: nickName,
|
nickName: nickName,
|
||||||
avatarSvg: avatarSvg,
|
avatarSvgCompressed: avatarSvgCompressed,
|
||||||
senderProfileCounter: senderProfileCounter,
|
senderProfileCounter: senderProfileCounter,
|
||||||
accepted: accepted,
|
accepted: accepted,
|
||||||
|
deletedByUser: deletedByUser,
|
||||||
requested: requested,
|
requested: requested,
|
||||||
blocked: blocked,
|
blocked: blocked,
|
||||||
verified: verified,
|
verified: verified,
|
||||||
deleted: deleted,
|
accountDeleted: accountDeleted,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
),
|
),
|
||||||
withReferenceMapper: (p0) => p0
|
withReferenceMapper: (p0) => p0
|
||||||
|
|
|
||||||
|
|
@ -346,6 +346,7 @@
|
||||||
"tabToRemoveEmoji": "Tippen um zu entfernen",
|
"tabToRemoveEmoji": "Tippen um zu entfernen",
|
||||||
"quotedMessageWasDeleted": "Die zitierte Nachricht wurde gelöscht.",
|
"quotedMessageWasDeleted": "Die zitierte Nachricht wurde gelöscht.",
|
||||||
"messageWasDeleted": "Nachricht wurde gelöscht.",
|
"messageWasDeleted": "Nachricht wurde gelöscht.",
|
||||||
|
"messageWasDeletedShort": "Gelöscht",
|
||||||
"sent": "Versendet",
|
"sent": "Versendet",
|
||||||
"sentTo": "Zugestellt an",
|
"sentTo": "Zugestellt an",
|
||||||
"received": "Empfangen",
|
"received": "Empfangen",
|
||||||
|
|
|
||||||
|
|
@ -502,6 +502,7 @@
|
||||||
"tabToRemoveEmoji": "Tab to remove",
|
"tabToRemoveEmoji": "Tab to remove",
|
||||||
"quotedMessageWasDeleted": "The quoted message has been deleted.",
|
"quotedMessageWasDeleted": "The quoted message has been deleted.",
|
||||||
"messageWasDeleted": "Message has been deleted.",
|
"messageWasDeleted": "Message has been deleted.",
|
||||||
|
"messageWasDeletedShort": "Deleted",
|
||||||
"sent": "Delivered",
|
"sent": "Delivered",
|
||||||
"sentTo": "Delivered to",
|
"sentTo": "Delivered to",
|
||||||
"received": "Received",
|
"received": "Received",
|
||||||
|
|
|
||||||
|
|
@ -2114,6 +2114,12 @@ abstract class AppLocalizations {
|
||||||
/// **'Message has been deleted.'**
|
/// **'Message has been deleted.'**
|
||||||
String get messageWasDeleted;
|
String get messageWasDeleted;
|
||||||
|
|
||||||
|
/// No description provided for @messageWasDeletedShort.
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Deleted'**
|
||||||
|
String get messageWasDeletedShort;
|
||||||
|
|
||||||
/// No description provided for @sent.
|
/// No description provided for @sent.
|
||||||
///
|
///
|
||||||
/// In en, this message translates to:
|
/// In en, this message translates to:
|
||||||
|
|
|
||||||
|
|
@ -1123,6 +1123,9 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get messageWasDeleted => 'Nachricht wurde gelöscht.';
|
String get messageWasDeleted => 'Nachricht wurde gelöscht.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get messageWasDeletedShort => 'Gelöscht';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get sent => 'Versendet';
|
String get sent => 'Versendet';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1116,6 +1116,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||||
@override
|
@override
|
||||||
String get messageWasDeleted => 'Message has been deleted.';
|
String get messageWasDeleted => 'Message has been deleted.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get messageWasDeletedShort => 'Deleted';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get sent => 'Delivered';
|
String get sent => 'Delivered';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -777,15 +777,15 @@ class EncryptedContent_ContactRequest extends $pb.GeneratedMessage {
|
||||||
class EncryptedContent_ContactUpdate extends $pb.GeneratedMessage {
|
class EncryptedContent_ContactUpdate extends $pb.GeneratedMessage {
|
||||||
factory EncryptedContent_ContactUpdate({
|
factory EncryptedContent_ContactUpdate({
|
||||||
EncryptedContent_ContactUpdate_Type? type,
|
EncryptedContent_ContactUpdate_Type? type,
|
||||||
$core.String? avatarSvg,
|
$core.List<$core.int>? avatarSvgCompressed,
|
||||||
$core.String? displayName,
|
$core.String? displayName,
|
||||||
}) {
|
}) {
|
||||||
final $result = create();
|
final $result = create();
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
$result.type = type;
|
$result.type = type;
|
||||||
}
|
}
|
||||||
if (avatarSvg != null) {
|
if (avatarSvgCompressed != null) {
|
||||||
$result.avatarSvg = avatarSvg;
|
$result.avatarSvgCompressed = avatarSvgCompressed;
|
||||||
}
|
}
|
||||||
if (displayName != null) {
|
if (displayName != null) {
|
||||||
$result.displayName = displayName;
|
$result.displayName = displayName;
|
||||||
|
|
@ -798,7 +798,7 @@ class EncryptedContent_ContactUpdate extends $pb.GeneratedMessage {
|
||||||
|
|
||||||
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'EncryptedContent.ContactUpdate', createEmptyInstance: create)
|
static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'EncryptedContent.ContactUpdate', createEmptyInstance: create)
|
||||||
..e<EncryptedContent_ContactUpdate_Type>(1, _omitFieldNames ? '' : 'type', $pb.PbFieldType.OE, defaultOrMaker: EncryptedContent_ContactUpdate_Type.REQUEST, valueOf: EncryptedContent_ContactUpdate_Type.valueOf, enumValues: EncryptedContent_ContactUpdate_Type.values)
|
..e<EncryptedContent_ContactUpdate_Type>(1, _omitFieldNames ? '' : 'type', $pb.PbFieldType.OE, defaultOrMaker: EncryptedContent_ContactUpdate_Type.REQUEST, valueOf: EncryptedContent_ContactUpdate_Type.valueOf, enumValues: EncryptedContent_ContactUpdate_Type.values)
|
||||||
..aOS(2, _omitFieldNames ? '' : 'avatarSvg', protoName: 'avatarSvg')
|
..a<$core.List<$core.int>>(2, _omitFieldNames ? '' : 'avatarSvgCompressed', $pb.PbFieldType.OY, protoName: 'avatarSvgCompressed')
|
||||||
..aOS(3, _omitFieldNames ? '' : 'displayName', protoName: 'displayName')
|
..aOS(3, _omitFieldNames ? '' : 'displayName', protoName: 'displayName')
|
||||||
..hasRequiredFields = false
|
..hasRequiredFields = false
|
||||||
;
|
;
|
||||||
|
|
@ -834,13 +834,13 @@ class EncryptedContent_ContactUpdate extends $pb.GeneratedMessage {
|
||||||
void clearType() => clearField(1);
|
void clearType() => clearField(1);
|
||||||
|
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
$core.String get avatarSvg => $_getSZ(1);
|
$core.List<$core.int> get avatarSvgCompressed => $_getN(1);
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
set avatarSvg($core.String v) { $_setString(1, v); }
|
set avatarSvgCompressed($core.List<$core.int> v) { $_setBytes(1, v); }
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
$core.bool hasAvatarSvg() => $_has(1);
|
$core.bool hasAvatarSvgCompressed() => $_has(1);
|
||||||
@$pb.TagNumber(2)
|
@$pb.TagNumber(2)
|
||||||
void clearAvatarSvg() => clearField(2);
|
void clearAvatarSvgCompressed() => clearField(2);
|
||||||
|
|
||||||
@$pb.TagNumber(3)
|
@$pb.TagNumber(3)
|
||||||
$core.String get displayName => $_getSZ(2);
|
$core.String get displayName => $_getSZ(2);
|
||||||
|
|
|
||||||
|
|
@ -260,12 +260,12 @@ const EncryptedContent_ContactUpdate$json = {
|
||||||
'1': 'ContactUpdate',
|
'1': 'ContactUpdate',
|
||||||
'2': [
|
'2': [
|
||||||
{'1': 'type', '3': 1, '4': 1, '5': 14, '6': '.EncryptedContent.ContactUpdate.Type', '10': 'type'},
|
{'1': 'type', '3': 1, '4': 1, '5': 14, '6': '.EncryptedContent.ContactUpdate.Type', '10': 'type'},
|
||||||
{'1': 'avatarSvg', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'avatarSvg', '17': true},
|
{'1': 'avatarSvgCompressed', '3': 2, '4': 1, '5': 12, '9': 0, '10': 'avatarSvgCompressed', '17': true},
|
||||||
{'1': 'displayName', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'displayName', '17': true},
|
{'1': 'displayName', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'displayName', '17': true},
|
||||||
],
|
],
|
||||||
'4': [EncryptedContent_ContactUpdate_Type$json],
|
'4': [EncryptedContent_ContactUpdate_Type$json],
|
||||||
'8': [
|
'8': [
|
||||||
{'1': '_avatarSvg'},
|
{'1': '_avatarSvgCompressed'},
|
||||||
{'1': '_displayName'},
|
{'1': '_displayName'},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
@ -358,19 +358,20 @@ final $typed_data.Uint8List encryptedContentDescriptor = $convert.base64Decode(
|
||||||
'ZXRNZXNzYWdlSWQYAiABKAlSD3RhcmdldE1lc3NhZ2VJZCI2CgRUeXBlEgwKCFJFT1BFTkVEEA'
|
'ZXRNZXNzYWdlSWQYAiABKAlSD3RhcmdldE1lc3NhZ2VJZCI2CgRUeXBlEgwKCFJFT1BFTkVEEA'
|
||||||
'ASCgoGU1RPUkVEEAESFAoQREVDUllQVElPTl9FUlJPUhACGngKDkNvbnRhY3RSZXF1ZXN0EjkK'
|
'ASCgoGU1RPUkVEEAESFAoQREVDUllQVElPTl9FUlJPUhACGngKDkNvbnRhY3RSZXF1ZXN0EjkK'
|
||||||
'BHR5cGUYASABKA4yJS5FbmNyeXB0ZWRDb250ZW50LkNvbnRhY3RSZXF1ZXN0LlR5cGVSBHR5cG'
|
'BHR5cGUYASABKA4yJS5FbmNyeXB0ZWRDb250ZW50LkNvbnRhY3RSZXF1ZXN0LlR5cGVSBHR5cG'
|
||||||
'UiKwoEVHlwZRILCgdSRVFVRVNUEAASCgoGUkVKRUNUEAESCgoGQUNDRVBUEAIa0gEKDUNvbnRh'
|
'UiKwoEVHlwZRILCgdSRVFVRVNUEAASCgoGUkVKRUNUEAESCgoGQUNDRVBUEAIa8AEKDUNvbnRh'
|
||||||
'Y3RVcGRhdGUSOAoEdHlwZRgBIAEoDjIkLkVuY3J5cHRlZENvbnRlbnQuQ29udGFjdFVwZGF0ZS'
|
'Y3RVcGRhdGUSOAoEdHlwZRgBIAEoDjIkLkVuY3J5cHRlZENvbnRlbnQuQ29udGFjdFVwZGF0ZS'
|
||||||
'5UeXBlUgR0eXBlEiEKCWF2YXRhclN2ZxgCIAEoCUgAUglhdmF0YXJTdmeIAQESJQoLZGlzcGxh'
|
'5UeXBlUgR0eXBlEjUKE2F2YXRhclN2Z0NvbXByZXNzZWQYAiABKAxIAFITYXZhdGFyU3ZnQ29t'
|
||||||
'eU5hbWUYAyABKAlIAVILZGlzcGxheU5hbWWIAQEiHwoEVHlwZRILCgdSRVFVRVNUEAASCgoGVV'
|
'cHJlc3NlZIgBARIlCgtkaXNwbGF5TmFtZRgDIAEoCUgBUgtkaXNwbGF5TmFtZYgBASIfCgRUeX'
|
||||||
'BEQVRFEAFCDAoKX2F2YXRhclN2Z0IOCgxfZGlzcGxheU5hbWUa1QEKCFB1c2hLZXlzEjMKBHR5'
|
'BlEgsKB1JFUVVFU1QQABIKCgZVUERBVEUQAUIWChRfYXZhdGFyU3ZnQ29tcHJlc3NlZEIOCgxf'
|
||||||
'cGUYASABKA4yHy5FbmNyeXB0ZWRDb250ZW50LlB1c2hLZXlzLlR5cGVSBHR5cGUSGQoFa2V5SW'
|
'ZGlzcGxheU5hbWUa1QEKCFB1c2hLZXlzEjMKBHR5cGUYASABKA4yHy5FbmNyeXB0ZWRDb250ZW'
|
||||||
'QYAiABKANIAFIFa2V5SWSIAQESFQoDa2V5GAMgASgMSAFSA2tleYgBARIhCgljcmVhdGVkQXQY'
|
'50LlB1c2hLZXlzLlR5cGVSBHR5cGUSGQoFa2V5SWQYAiABKANIAFIFa2V5SWSIAQESFQoDa2V5'
|
||||||
'BCABKANIAlIJY3JlYXRlZEF0iAEBIh8KBFR5cGUSCwoHUkVRVUVTVBAAEgoKBlVQREFURRABQg'
|
'GAMgASgMSAFSA2tleYgBARIhCgljcmVhdGVkQXQYBCABKANIAlIJY3JlYXRlZEF0iAEBIh8KBF'
|
||||||
'gKBl9rZXlJZEIGCgRfa2V5QgwKCl9jcmVhdGVkQXQahwEKCUZsYW1lU3luYxIiCgxmbGFtZUNv'
|
'R5cGUSCwoHUkVRVUVTVBAAEgoKBlVQREFURRABQggKBl9rZXlJZEIGCgRfa2V5QgwKCl9jcmVh'
|
||||||
'dW50ZXIYASABKANSDGZsYW1lQ291bnRlchI2ChZsYXN0RmxhbWVDb3VudGVyQ2hhbmdlGAIgAS'
|
'dGVkQXQahwEKCUZsYW1lU3luYxIiCgxmbGFtZUNvdW50ZXIYASABKANSDGZsYW1lQ291bnRlch'
|
||||||
'gDUhZsYXN0RmxhbWVDb3VudGVyQ2hhbmdlEh4KCmJlc3RGcmllbmQYAyABKAhSCmJlc3RGcmll'
|
'I2ChZsYXN0RmxhbWVDb3VudGVyQ2hhbmdlGAIgASgDUhZsYXN0RmxhbWVDb3VudGVyQ2hhbmdl'
|
||||||
'bmRCCgoIX2dyb3VwSWRCDwoNX2lzRGlyZWN0Q2hhdEIXChVfc2VuZGVyUHJvZmlsZUNvdW50ZX'
|
'Eh4KCmJlc3RGcmllbmQYAyABKAhSCmJlc3RGcmllbmRCCgoIX2dyb3VwSWRCDwoNX2lzRGlyZW'
|
||||||
'JCEAoOX21lc3NhZ2VVcGRhdGVCCAoGX21lZGlhQg4KDF9tZWRpYVVwZGF0ZUIQCg5fY29udGFj'
|
'N0Q2hhdEIXChVfc2VuZGVyUHJvZmlsZUNvdW50ZXJCEAoOX21lc3NhZ2VVcGRhdGVCCAoGX21l'
|
||||||
'dFVwZGF0ZUIRCg9fY29udGFjdFJlcXVlc3RCDAoKX2ZsYW1lU3luY0ILCglfcHVzaEtleXNCCw'
|
'ZGlhQg4KDF9tZWRpYVVwZGF0ZUIQCg5fY29udGFjdFVwZGF0ZUIRCg9fY29udGFjdFJlcXVlc3'
|
||||||
'oJX3JlYWN0aW9uQg4KDF90ZXh0TWVzc2FnZQ==');
|
'RCDAoKX2ZsYW1lU3luY0ILCglfcHVzaEtleXNCCwoJX3JlYWN0aW9uQg4KDF90ZXh0TWVzc2Fn'
|
||||||
|
'ZQ==');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,7 @@ message EncryptedContent {
|
||||||
}
|
}
|
||||||
|
|
||||||
Type type = 1;
|
Type type = 1;
|
||||||
optional string avatarSvg = 2;
|
optional bytes avatarSvgCompressed = 2;
|
||||||
optional string displayName = 3;
|
optional string displayName = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -339,7 +339,7 @@ class ApiService {
|
||||||
await twonlyDB.contactsDao.updateContact(
|
await twonlyDB.contactsDao.updateContact(
|
||||||
contactId,
|
contactId,
|
||||||
ContactsCompanion(
|
ContactsCompanion(
|
||||||
deleted: const Value(true),
|
accountDeleted: const Value(true),
|
||||||
username: Value('${contact.username} (${contact.userId})'),
|
username: Value('${contact.username} (${contact.userId})'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ Future<void> insertMediaFileInMessagesTable(
|
||||||
type: const Value(MessageType.media),
|
type: const Value(MessageType.media),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
await twonlyDB.groupsDao
|
||||||
|
.increaseLastMessageExchange(groupId, DateTime.now());
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
// de-archive contact when sending a new message
|
// de-archive contact when sending a new message
|
||||||
await twonlyDB.groupsDao.updateGroup(
|
await twonlyDB.groupsDao.updateGroup(
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:fixnum/fixnum.dart';
|
import 'package:fixnum/fixnum.dart';
|
||||||
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
|
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
|
||||||
|
|
@ -116,7 +118,7 @@ Future<(Uint8List, Uint8List?)?> tryToSendCompleteMessage({
|
||||||
await twonlyDB.receiptsDao.deleteReceipt(receiptId);
|
await twonlyDB.receiptsDao.deleteReceipt(receiptId);
|
||||||
await twonlyDB.contactsDao.updateContact(
|
await twonlyDB.contactsDao.updateContact(
|
||||||
receipt.contactId,
|
receipt.contactId,
|
||||||
const ContactsCompanion(deleted: Value(true)),
|
const ContactsCompanion(accountDeleted: Value(true)),
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -195,6 +197,8 @@ Future<void> sendCipherTextToGroup(
|
||||||
) async {
|
) async {
|
||||||
final groupMembers = await twonlyDB.groupsDao.getGroupMembers(groupId);
|
final groupMembers = await twonlyDB.groupsDao.getGroupMembers(groupId);
|
||||||
|
|
||||||
|
await twonlyDB.groupsDao.increaseLastMessageExchange(groupId, DateTime.now());
|
||||||
|
|
||||||
encryptedContent.groupId = groupId;
|
encryptedContent.groupId = groupId;
|
||||||
|
|
||||||
for (final groupMember in groupMembers) {
|
for (final groupMember in groupMembers) {
|
||||||
|
|
@ -280,7 +284,7 @@ Future<void> notifyContactsAboutProfileChange({int? onlyToContact}) async {
|
||||||
final encryptedContent = pb.EncryptedContent(
|
final encryptedContent = pb.EncryptedContent(
|
||||||
contactUpdate: pb.EncryptedContent_ContactUpdate(
|
contactUpdate: pb.EncryptedContent_ContactUpdate(
|
||||||
type: pb.EncryptedContent_ContactUpdate_Type.UPDATE,
|
type: pb.EncryptedContent_ContactUpdate_Type.UPDATE,
|
||||||
avatarSvg: user.avatarSvg,
|
avatarSvgCompressed: gzip.encode(utf8.encode(user.avatarSvg!)),
|
||||||
displayName: user.displayName,
|
displayName: user.displayName,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:drift/drift.dart';
|
||||||
import 'package:hashlib/random.dart';
|
import 'package:hashlib/random.dart';
|
||||||
import 'package:mutex/mutex.dart';
|
import 'package:mutex/mutex.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
|
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||||
import 'package:twonly/src/database/twonly.db.dart' hide Message;
|
import 'package:twonly/src/database/twonly.db.dart' hide Message;
|
||||||
import 'package:twonly/src/model/protobuf/api/websocket/client_to_server.pb.dart'
|
import 'package:twonly/src/model/protobuf/api/websocket/client_to_server.pb.dart'
|
||||||
as client;
|
as client;
|
||||||
|
|
@ -20,6 +21,7 @@ import 'package:twonly/src/services/api/server_messages/reaction.server_message.
|
||||||
import 'package:twonly/src/services/api/server_messages/text_message.server_messages.dart';
|
import 'package:twonly/src/services/api/server_messages/text_message.server_messages.dart';
|
||||||
import 'package:twonly/src/services/signal/encryption.signal.dart';
|
import 'package:twonly/src/services/signal/encryption.signal.dart';
|
||||||
import 'package:twonly/src/utils/log.dart';
|
import 'package:twonly/src/utils/log.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
final lockHandleServerMessage = Mutex();
|
final lockHandleServerMessage = Mutex();
|
||||||
|
|
||||||
|
|
@ -28,19 +30,19 @@ Future<void> handleServerMessage(server.ServerToClient msg) async {
|
||||||
final ok = client.Response_Ok()..none = true;
|
final ok = client.Response_Ok()..none = true;
|
||||||
var response = client.Response()..ok = ok;
|
var response = client.Response()..ok = ok;
|
||||||
|
|
||||||
try {
|
// try {
|
||||||
if (msg.v0.hasRequestNewPreKeys()) {
|
if (msg.v0.hasRequestNewPreKeys()) {
|
||||||
response = await handleRequestNewPreKey();
|
response = await handleRequestNewPreKey();
|
||||||
} else if (msg.v0.hasNewMessage()) {
|
} else if (msg.v0.hasNewMessage()) {
|
||||||
final body = Uint8List.fromList(msg.v0.newMessage.body);
|
final body = Uint8List.fromList(msg.v0.newMessage.body);
|
||||||
final fromUserId = msg.v0.newMessage.fromUserId.toInt();
|
final fromUserId = msg.v0.newMessage.fromUserId.toInt();
|
||||||
await handleNewMessage(fromUserId, body);
|
await handleNewMessage(fromUserId, body);
|
||||||
} else {
|
} else {
|
||||||
Log.error('Unknown server message: $msg');
|
Log.error('Unknown server message: $msg');
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
Log.error(e);
|
|
||||||
}
|
}
|
||||||
|
// } catch (e) {
|
||||||
|
// Log.error(e);
|
||||||
|
// }
|
||||||
|
|
||||||
final v0 = client.V0()
|
final v0 = client.V0()
|
||||||
..seq = msg.v0.seq
|
..seq = msg.v0.seq
|
||||||
|
|
@ -93,6 +95,21 @@ Future<void> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
final encryptedContentRaw =
|
final encryptedContentRaw =
|
||||||
Uint8List.fromList(message.encryptedContent);
|
Uint8List.fromList(message.encryptedContent);
|
||||||
|
|
||||||
|
if (await twonlyDB.contactsDao
|
||||||
|
.getContactByUserId(fromUserId)
|
||||||
|
.getSingleOrNull() ==
|
||||||
|
null) {
|
||||||
|
/// In case the user does not exists, just create a dummy user which was deleted by the user, so the message
|
||||||
|
/// can be inserted into the receipts database
|
||||||
|
await twonlyDB.contactsDao.insertContact(
|
||||||
|
ContactsCompanion(
|
||||||
|
userId: Value(fromUserId),
|
||||||
|
deletedByUser: const Value(true),
|
||||||
|
username: const Value('[deleted]'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
final responsePlaintextContent = await handleEncryptedMessage(
|
final responsePlaintextContent = await handleEncryptedMessage(
|
||||||
fromUserId,
|
fromUserId,
|
||||||
encryptedContentRaw,
|
encryptedContentRaw,
|
||||||
|
|
@ -108,6 +125,7 @@ Future<void> handleNewMessage(int fromUserId, Uint8List body) async {
|
||||||
} else {
|
} else {
|
||||||
response = Message()..type = Message_Type.SENDER_DELIVERY_RECEIPT;
|
response = Message()..type = Message_Type.SENDER_DELIVERY_RECEIPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
await twonlyDB.receiptsDao.insertReceipt(
|
await twonlyDB.receiptsDao.insertReceipt(
|
||||||
ReceiptsCompanion(
|
ReceiptsCompanion(
|
||||||
receiptId: Value(receiptId),
|
receiptId: Value(receiptId),
|
||||||
|
|
@ -189,8 +207,29 @@ Future<PlaintextContent?> handleEncryptedMessage(
|
||||||
|
|
||||||
/// Verify that the user is (still) in that group...
|
/// Verify that the user is (still) in that group...
|
||||||
if (!await twonlyDB.groupsDao.isContactInGroup(fromUserId, content.groupId)) {
|
if (!await twonlyDB.groupsDao.isContactInGroup(fromUserId, content.groupId)) {
|
||||||
Log.error('User $fromUserId tried to access group ${content.groupId}.');
|
if (getUUIDforDirectChat(gUser.userId, fromUserId) == content.groupId) {
|
||||||
return null;
|
final contact = await twonlyDB.contactsDao
|
||||||
|
.getContactByUserId(fromUserId)
|
||||||
|
.getSingleOrNull();
|
||||||
|
if (contact == null || contact.deletedByUser) {
|
||||||
|
Log.error(
|
||||||
|
'User tries to send message to direct chat while the user does not exists !',
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Log.info(
|
||||||
|
'Creating new DirectChat between two users',
|
||||||
|
);
|
||||||
|
await twonlyDB.groupsDao.createNewDirectChat(
|
||||||
|
fromUserId,
|
||||||
|
GroupsCompanion(
|
||||||
|
groupName: Value(getContactDisplayName(contact)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Log.error('User $fromUserId tried to access group ${content.groupId}.');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content.hasTextMessage()) {
|
if (content.hasTextMessage()) {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
|
import 'package:twonly/src/database/daos/contacts.dao.dart';
|
||||||
import 'package:twonly/src/database/twonly.db.dart' hide Message;
|
import 'package:twonly/src/database/twonly.db.dart' hide Message;
|
||||||
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';
|
||||||
|
|
@ -25,11 +26,12 @@ Future<void> handleContactRequest(
|
||||||
if (username.isSuccess) {
|
if (username.isSuccess) {
|
||||||
// ignore: avoid_dynamic_calls
|
// ignore: avoid_dynamic_calls
|
||||||
final name = username.value.userdata.username as Uint8List;
|
final name = username.value.userdata.username as Uint8List;
|
||||||
await twonlyDB.contactsDao.insertContact(
|
await twonlyDB.contactsDao.insertOnConflictUpdate(
|
||||||
ContactsCompanion(
|
ContactsCompanion(
|
||||||
username: Value(utf8.decode(name)),
|
username: Value(utf8.decode(name)),
|
||||||
userId: Value(fromUserId),
|
userId: Value(fromUserId),
|
||||||
requested: const Value(true),
|
requested: const Value(true),
|
||||||
|
deletedByUser: const Value(false),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -43,9 +45,25 @@ Future<void> handleContactRequest(
|
||||||
accepted: Value(true),
|
accepted: Value(true),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
final contact = await twonlyDB.contactsDao
|
||||||
|
.getContactByUserId(fromUserId)
|
||||||
|
.getSingleOrNull();
|
||||||
|
await twonlyDB.groupsDao.createNewDirectChat(
|
||||||
|
fromUserId,
|
||||||
|
GroupsCompanion(
|
||||||
|
groupName: Value(getContactDisplayName(contact!)),
|
||||||
|
),
|
||||||
|
);
|
||||||
case EncryptedContent_ContactRequest_Type.REJECT:
|
case EncryptedContent_ContactRequest_Type.REJECT:
|
||||||
Log.info('Got a contact reject from $fromUserId');
|
Log.info('Got a contact reject from $fromUserId');
|
||||||
await twonlyDB.contactsDao.deleteContactByUserId(fromUserId);
|
await twonlyDB.contactsDao.updateContact(
|
||||||
|
fromUserId,
|
||||||
|
const ContactsCompanion(
|
||||||
|
accepted: Value(false),
|
||||||
|
requested: Value(false),
|
||||||
|
deletedByUser: Value(true),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,13 +79,14 @@ Future<void> handleContactUpdate(
|
||||||
|
|
||||||
case EncryptedContent_ContactUpdate_Type.UPDATE:
|
case EncryptedContent_ContactUpdate_Type.UPDATE:
|
||||||
Log.info('Got a contact update $fromUserId');
|
Log.info('Got a contact update $fromUserId');
|
||||||
if (contactUpdate.hasAvatarSvg() &&
|
if (contactUpdate.hasAvatarSvgCompressed() &&
|
||||||
contactUpdate.hasDisplayName() &&
|
contactUpdate.hasDisplayName() &&
|
||||||
senderProfileCounter != null) {
|
senderProfileCounter != null) {
|
||||||
await twonlyDB.contactsDao.updateContact(
|
await twonlyDB.contactsDao.updateContact(
|
||||||
fromUserId,
|
fromUserId,
|
||||||
ContactsCompanion(
|
ContactsCompanion(
|
||||||
avatarSvg: Value(contactUpdate.avatarSvg),
|
avatarSvgCompressed:
|
||||||
|
Value(Uint8List.fromList(contactUpdate.avatarSvgCompressed)),
|
||||||
displayName: Value(contactUpdate.displayName),
|
displayName: Value(contactUpdate.displayName),
|
||||||
senderProfileCounter: Value(senderProfileCounter),
|
senderProfileCounter: Value(senderProfileCounter),
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,8 @@ Future<void> handleMedia(
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
|
await twonlyDB.groupsDao
|
||||||
|
.increaseLastMessageExchange(groupId, fromTimestamp(media.timestamp));
|
||||||
Log.info('Inserted a new media message with ID: ${message.messageId}');
|
Log.info('Inserted a new media message with ID: ${message.messageId}');
|
||||||
await twonlyDB.groupsDao.incFlameCounter(
|
await twonlyDB.groupsDao.incFlameCounter(
|
||||||
message.groupId,
|
message.groupId,
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,10 @@ Future<void> handleTextMessage(
|
||||||
ackByServer: Value(DateTime.now()),
|
ackByServer: Value(DateTime.now()),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
await twonlyDB.groupsDao.increaseLastMessageExchange(
|
||||||
|
groupId,
|
||||||
|
fromTimestamp(textMessage.timestamp),
|
||||||
|
);
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
Log.info('Inserted a new text message with ID: ${message.messageId}');
|
Log.info('Inserted a new text message with ID: ${message.messageId}');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import 'package:twonly/src/model/protobuf/api/websocket/server_to_client.pb.dart
|
||||||
import 'package:twonly/src/model/protobuf/client/generated/messages.pbserver.dart'
|
import 'package:twonly/src/model/protobuf/client/generated/messages.pbserver.dart'
|
||||||
hide Message;
|
hide Message;
|
||||||
import 'package:twonly/src/services/api/messages.dart';
|
import 'package:twonly/src/services/api/messages.dart';
|
||||||
import 'package:twonly/src/services/signal/session.signal.dart';
|
|
||||||
|
|
||||||
class Result<T, E> {
|
class Result<T, E> {
|
||||||
Result.error(this.error) : value = null;
|
Result.error(this.error) : value = null;
|
||||||
|
|
@ -57,7 +56,7 @@ ClientToServer createClientToServerFromApplicationData(
|
||||||
return ClientToServer()..v0 = v0;
|
return ClientToServer()..v0 = v0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> rejectAndDeleteContact(int contactId) async {
|
Future<void> rejectAndHideContact(int contactId) async {
|
||||||
await sendCipherText(
|
await sendCipherText(
|
||||||
contactId,
|
contactId,
|
||||||
EncryptedContent(
|
EncryptedContent(
|
||||||
|
|
@ -66,9 +65,14 @@ Future<void> rejectAndDeleteContact(int contactId) async {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
await twonlyDB.signalDao.deleteAllByContactId(contactId);
|
await twonlyDB.contactsDao.updateContact(
|
||||||
await deleteSessionWithTarget(contactId);
|
contactId,
|
||||||
await twonlyDB.contactsDao.deleteContactByUserId(contactId);
|
const ContactsCompanion(
|
||||||
|
accepted: Value(false),
|
||||||
|
requested: Value(false),
|
||||||
|
deletedByUser: Value(true),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> handleMediaError(MediaFile media) async {
|
Future<void> handleMediaError(MediaFile media) async {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ Future<void> createThumbnailsForImage(
|
||||||
) async {
|
) async {
|
||||||
final fileExtension = sourceFile.path.split('.').last.toLowerCase();
|
final fileExtension = sourceFile.path.split('.').last.toLowerCase();
|
||||||
if (fileExtension != 'png') {
|
if (fileExtension != 'png') {
|
||||||
Log.error('Could not create thumbnail for image. $fileExtension != .png');
|
Log.error('Could not create thumbnail for image. $fileExtension != png');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
final StreamController<NotificationResponse> selectNotificationStream =
|
final StreamController<NotificationResponse> selectNotificationStream =
|
||||||
StreamController<NotificationResponse>.broadcast();
|
StreamController<NotificationResponse>.broadcast();
|
||||||
|
|
@ -61,10 +62,11 @@ Future<void> createPushAvatars() async {
|
||||||
final contacts = await twonlyDB.contactsDao.getAllNotBlockedContacts();
|
final contacts = await twonlyDB.contactsDao.getAllNotBlockedContacts();
|
||||||
|
|
||||||
for (final contact in contacts) {
|
for (final contact in contacts) {
|
||||||
if (contact.avatarSvg == null) return;
|
if (contact.avatarSvgCompressed == null) return;
|
||||||
|
|
||||||
final pictureInfo =
|
final avatarSvg = getAvatarSvg(contact.avatarSvgCompressed!);
|
||||||
await vg.loadPicture(SvgStringLoader(contact.avatarSvg!), null);
|
|
||||||
|
final pictureInfo = await vg.loadPicture(SvgStringLoader(avatarSvg), null);
|
||||||
|
|
||||||
final image = await pictureInfo.picture.toImage(300, 300);
|
final image = await pictureInfo.picture.toImage(300, 300);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
@ -372,3 +374,8 @@ String friendlyDateTime(
|
||||||
|
|
||||||
return '$timePart $datePart';
|
return '$timePart $datePart';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getAvatarSvg(Uint8List avatarSvgCompressed) {
|
||||||
|
final raw = gzip.decode(avatarSvgCompressed);
|
||||||
|
return utf8.decode(raw);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import 'package:twonly/src/services/api/utils.dart';
|
||||||
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
|
import 'package:twonly/src/services/notifications/pushkeys.notifications.dart';
|
||||||
import 'package:twonly/src/services/signal/session.signal.dart';
|
import 'package:twonly/src/services/signal/session.signal.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/views/components/alert_dialog.dart';
|
import 'package:twonly/src/views/components/alert_dialog.dart';
|
||||||
import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
import 'package:twonly/src/views/components/avatar_icon.component.dart';
|
||||||
import 'package:twonly/src/views/components/headline.dart';
|
import 'package:twonly/src/views/components/headline.dart';
|
||||||
|
|
@ -49,8 +48,7 @@ class _SearchUsernameView extends State<AddNewUserView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _addNewUser(BuildContext context) async {
|
Future<void> _addNewUser(BuildContext context) async {
|
||||||
final user = await getUser();
|
if (gUser.username == searchUserName.text) {
|
||||||
if (user == null || user.username == searchUserName.text || !mounted) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,11 +82,13 @@ class _SearchUsernameView extends State<AddNewUserView> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final added = await twonlyDB.contactsDao.insertContact(
|
final added = await twonlyDB.contactsDao.insertOnConflictUpdate(
|
||||||
ContactsCompanion(
|
ContactsCompanion(
|
||||||
username: Value(searchUserName.text),
|
username: Value(searchUserName.text),
|
||||||
userId: Value(userdata.userId.toInt()),
|
userId: Value(userdata.userId.toInt()),
|
||||||
requested: const Value(false),
|
requested: const Value(false),
|
||||||
|
blocked: const Value(false),
|
||||||
|
deletedByUser: const Value(false),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -223,18 +223,26 @@ class ContactsListView extends StatelessWidget {
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: const Icon(Icons.close, color: Colors.red),
|
icon: const Icon(Icons.close, color: Colors.red),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await rejectAndDeleteContact(contact.userId);
|
await rejectAndHideContact(contact.userId);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.check, color: Colors.green),
|
icon: const Icon(Icons.check, color: Colors.green),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
const update = ContactsCompanion(
|
await twonlyDB.contactsDao.updateContact(
|
||||||
accepted: Value(true),
|
contact.userId,
|
||||||
requested: Value(false),
|
const ContactsCompanion(
|
||||||
|
accepted: Value(true),
|
||||||
|
requested: Value(false),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await twonlyDB.groupsDao.createNewDirectChat(
|
||||||
|
contact.userId,
|
||||||
|
GroupsCompanion(
|
||||||
|
groupName: Value(getContactDisplayName(contact)),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
await twonlyDB.contactsDao.updateContact(contact.userId, update);
|
|
||||||
await sendCipherText(
|
await sendCipherText(
|
||||||
contact.userId,
|
contact.userId,
|
||||||
EncryptedContent(
|
EncryptedContent(
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ class _ChatListViewState extends State<ChatListView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initAsync() async {
|
Future<void> initAsync() async {
|
||||||
final stream = twonlyDB.groupsDao.watchGroups();
|
final stream = twonlyDB.groupsDao.watchGroupsForChatList();
|
||||||
_contactsSub = stream.listen((groups) {
|
_contactsSub = stream.listen((groups) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_groupsNotPinned = groups.where((x) => !x.pinned).toList();
|
_groupsNotPinned = groups.where((x) => !x.pinned).toList();
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,9 @@ class _UserListItem extends State<GroupListItem> {
|
||||||
late StreamSubscription<List<Message>> messagesNotOpenedStream;
|
late StreamSubscription<List<Message>> messagesNotOpenedStream;
|
||||||
|
|
||||||
Message? lastMessage;
|
Message? lastMessage;
|
||||||
|
Reaction? lastReaction;
|
||||||
late StreamSubscription<Message?> lastMessageStream;
|
late StreamSubscription<Message?> lastMessageStream;
|
||||||
|
late StreamSubscription<Reaction?> lastReactionStream;
|
||||||
late StreamSubscription<List<MediaFile>> lastMediaFilesStream;
|
late StreamSubscription<List<MediaFile>> lastMediaFilesStream;
|
||||||
|
|
||||||
List<Message> previewMessages = [];
|
List<Message> previewMessages = [];
|
||||||
|
|
@ -54,6 +56,7 @@ class _UserListItem extends State<GroupListItem> {
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
messagesNotOpenedStream.cancel();
|
messagesNotOpenedStream.cancel();
|
||||||
|
lastReactionStream.cancel();
|
||||||
lastMessageStream.cancel();
|
lastMessageStream.cancel();
|
||||||
lastMediaFilesStream.cancel();
|
lastMediaFilesStream.cancel();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|
@ -68,6 +71,17 @@ class _UserListItem extends State<GroupListItem> {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
lastReactionStream = twonlyDB.reactionsDao
|
||||||
|
.watchLastReactions(widget.group.groupId)
|
||||||
|
.listen((update) {
|
||||||
|
setState(() {
|
||||||
|
lastReaction = update;
|
||||||
|
});
|
||||||
|
// protectUpdateState.protect(() async {
|
||||||
|
// await updateState(lastMessage, update, messagesNotOpened);
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
|
||||||
messagesNotOpenedStream = twonlyDB.messagesDao
|
messagesNotOpenedStream = twonlyDB.messagesDao
|
||||||
.watchMessageNotOpened(widget.group.groupId)
|
.watchMessageNotOpened(widget.group.groupId)
|
||||||
.listen((update) {
|
.listen((update) {
|
||||||
|
|
@ -141,9 +155,7 @@ class _UserListItem extends State<GroupListItem> {
|
||||||
|
|
||||||
lastMessage = newLastMessage;
|
lastMessage = newLastMessage;
|
||||||
messagesNotOpened = newMessagesNotOpened;
|
messagesNotOpened = newMessagesNotOpened;
|
||||||
setState(() {
|
if (mounted) setState(() {});
|
||||||
// sets lastMessages, messagesNotOpened and currentMessage
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> onTap() async {
|
Future<void> onTap() async {
|
||||||
|
|
@ -217,7 +229,11 @@ class _UserListItem extends State<GroupListItem> {
|
||||||
? Text(context.lang.chatsTapToSend)
|
? Text(context.lang.chatsTapToSend)
|
||||||
: Row(
|
: Row(
|
||||||
children: [
|
children: [
|
||||||
MessageSendStateIcon(previewMessages, previewMediaFiles),
|
MessageSendStateIcon(
|
||||||
|
previewMessages,
|
||||||
|
previewMediaFiles,
|
||||||
|
lastReaction: lastReaction,
|
||||||
|
),
|
||||||
const Text('•'),
|
const Text('•'),
|
||||||
const SizedBox(width: 5),
|
const SizedBox(width: 5),
|
||||||
if (currentMessage != null)
|
if (currentMessage != null)
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ class _ChatListEntryState extends State<ChatListEntry> {
|
||||||
Message? nextMessage,
|
Message? nextMessage,
|
||||||
bool hasReactions,
|
bool hasReactions,
|
||||||
) {
|
) {
|
||||||
var bottom = 30.0;
|
var bottom = 20.0;
|
||||||
var top = 0.0;
|
var top = 0.0;
|
||||||
|
|
||||||
var topLeft = 12.0;
|
var topLeft = 12.0;
|
||||||
|
|
@ -189,7 +189,7 @@ class _ChatListEntryState extends State<ChatListEntry> {
|
||||||
|
|
||||||
if (nextMessage != null) {
|
if (nextMessage != null) {
|
||||||
if (message.senderId == nextMessage.senderId) {
|
if (message.senderId == nextMessage.senderId) {
|
||||||
bottom = 10;
|
bottom = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,7 +203,7 @@ class _ChatListEntryState extends State<ChatListEntry> {
|
||||||
|
|
||||||
final combinesWidthNext = combineTextMessageWithNext(message, nextMessage);
|
final combinesWidthNext = combineTextMessageWithNext(message, nextMessage);
|
||||||
if (combinesWidthNext) {
|
if (combinesWidthNext) {
|
||||||
bottom = 1;
|
bottom = 0;
|
||||||
bottomLeft = 5.0;
|
bottomLeft = 5.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:twonly/src/database/tables/mediafiles.table.dart';
|
import 'package:twonly/src/database/tables/mediafiles.table.dart';
|
||||||
import 'package:twonly/src/database/tables/messages.table.dart';
|
import 'package:twonly/src/database/tables/messages.table.dart';
|
||||||
import 'package:twonly/src/database/twonly.db.dart';
|
import 'package:twonly/src/database/twonly.db.dart';
|
||||||
|
import 'package:twonly/src/utils/log.dart';
|
||||||
import 'package:twonly/src/utils/misc.dart';
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
import 'package:twonly/src/views/components/animate_icon.dart';
|
import 'package:twonly/src/views/components/animate_icon.dart';
|
||||||
|
|
||||||
|
|
@ -44,10 +45,12 @@ class MessageSendStateIcon extends StatefulWidget {
|
||||||
this.mediaFiles, {
|
this.mediaFiles, {
|
||||||
super.key,
|
super.key,
|
||||||
this.canBeReopened = false,
|
this.canBeReopened = false,
|
||||||
|
this.lastReaction,
|
||||||
this.mainAxisAlignment = MainAxisAlignment.end,
|
this.mainAxisAlignment = MainAxisAlignment.end,
|
||||||
});
|
});
|
||||||
final List<Message> messages;
|
final List<Message> messages;
|
||||||
final List<MediaFile> mediaFiles;
|
final List<MediaFile> mediaFiles;
|
||||||
|
final Reaction? lastReaction;
|
||||||
final MainAxisAlignment mainAxisAlignment;
|
final MainAxisAlignment mainAxisAlignment;
|
||||||
final bool canBeReopened;
|
final bool canBeReopened;
|
||||||
|
|
||||||
|
|
@ -125,8 +128,8 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
|
||||||
case MessageSendState.received:
|
case MessageSendState.received:
|
||||||
icon = Icon(Icons.square_rounded, size: 14, color: color);
|
icon = Icon(Icons.square_rounded, size: 14, color: color);
|
||||||
text = context.lang.messageSendState_Received;
|
text = context.lang.messageSendState_Received;
|
||||||
if (message.type == MessageType.media) {
|
if (message.type == MessageType.media && mediaFile != null) {
|
||||||
if (mediaFile!.downloadState == DownloadState.pending) {
|
if (mediaFile.downloadState == DownloadState.pending) {
|
||||||
text = context.lang.messageSendState_TapToLoad;
|
text = context.lang.messageSendState_TapToLoad;
|
||||||
}
|
}
|
||||||
if (mediaFile.downloadState == DownloadState.downloading) {
|
if (mediaFile.downloadState == DownloadState.downloading) {
|
||||||
|
|
@ -170,6 +173,11 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.isDeletedFromSender) {
|
||||||
|
icon = FaIcon(FontAwesomeIcons.trash, size: 10, color: color);
|
||||||
|
text = context.lang.messageWasDeletedShort;
|
||||||
|
}
|
||||||
|
|
||||||
if (hasLoader) {
|
if (hasLoader) {
|
||||||
icons = [icon];
|
icons = [icon];
|
||||||
break;
|
break;
|
||||||
|
|
@ -182,6 +190,41 @@ class _MessageSendStateIconState extends State<MessageSendStateIcon> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (widget.lastReaction != null &&
|
||||||
|
!widget.messages.any((t) => t.openedAt == null)) {
|
||||||
|
/// No messages are still open, so check if the reaction is the last message received.
|
||||||
|
|
||||||
|
if (!widget.messages
|
||||||
|
.any((m) => m.createdAt.isAfter(widget.lastReaction!.createdAt))) {
|
||||||
|
if (EmojiAnimation.animatedIcons
|
||||||
|
.containsKey(widget.lastReaction!.emoji)) {
|
||||||
|
icons = [
|
||||||
|
SizedBox(
|
||||||
|
height: 18,
|
||||||
|
child: EmojiAnimation(emoji: widget.lastReaction!.emoji),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
icons = [
|
||||||
|
SizedBox(
|
||||||
|
height: 18,
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
widget.lastReaction!.emoji,
|
||||||
|
style: const TextStyle(fontSize: 18),
|
||||||
|
strutStyle: const StrutStyle(
|
||||||
|
forceStrutHeight: true,
|
||||||
|
height: 1.6,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// Log.info("DISPLAY REACTION");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (icons.isEmpty) return Container();
|
if (icons.isEmpty) return Container();
|
||||||
|
|
||||||
var icon = icons[0];
|
var icon = icons[0];
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/database/twonly.db.dart';
|
import 'package:twonly/src/database/twonly.db.dart';
|
||||||
import 'package:twonly/src/model/json/userdata.dart';
|
import 'package:twonly/src/model/json/userdata.dart';
|
||||||
import 'package:twonly/src/utils/log.dart';
|
import 'package:twonly/src/utils/log.dart';
|
||||||
|
import 'package:twonly/src/utils/misc.dart';
|
||||||
|
|
||||||
class AvatarIcon extends StatefulWidget {
|
class AvatarIcon extends StatefulWidget {
|
||||||
const AvatarIcon({
|
const AvatarIcon({
|
||||||
|
|
@ -38,21 +39,21 @@ class _AvatarIconState extends State<AvatarIcon> {
|
||||||
final contacts =
|
final contacts =
|
||||||
await twonlyDB.groupsDao.getGroupContact(widget.group!.groupId);
|
await twonlyDB.groupsDao.getGroupContact(widget.group!.groupId);
|
||||||
if (contacts.length == 1) {
|
if (contacts.length == 1) {
|
||||||
if (contacts.first.avatarSvg != null) {
|
if (contacts.first.avatarSvgCompressed != null) {
|
||||||
avatarSVGs.add(contacts.first.avatarSvg!);
|
avatarSVGs.add(getAvatarSvg(contacts.first.avatarSvgCompressed!));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (final contact in contacts) {
|
for (final contact in contacts) {
|
||||||
if (contact.avatarSvg != null) {
|
if (contact.avatarSvgCompressed != null) {
|
||||||
avatarSVGs.add(contact.avatarSvg!);
|
avatarSVGs.add(getAvatarSvg(contact.avatarSvgCompressed!));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// avatarSvg = group!.avatarSvg;
|
// avatarSvg = group!.avatarSvg;
|
||||||
} else if (widget.userData?.avatarSvg != null) {
|
} else if (widget.userData?.avatarSvg != null) {
|
||||||
avatarSVGs.add(widget.userData!.avatarSvg!);
|
avatarSVGs.add(widget.userData!.avatarSvg!);
|
||||||
} else if (widget.contact?.avatarSvg != null) {
|
} else if (widget.contact?.avatarSvgCompressed != null) {
|
||||||
avatarSVGs.add(widget.contact!.avatarSvg!);
|
avatarSVGs.add(getAvatarSvg(widget.contact!.avatarSvgCompressed!));
|
||||||
}
|
}
|
||||||
if (mounted) setState(() {});
|
if (mounted) setState(() {});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class _ContactViewState extends State<ContactView> {
|
||||||
);
|
);
|
||||||
if (remove) {
|
if (remove) {
|
||||||
// trigger deletion for the other user...
|
// trigger deletion for the other user...
|
||||||
await rejectAndDeleteContact(contact.userId);
|
await rejectAndHideContact(contact.userId);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
Navigator.popUntil(context, (route) => route.isFirst);
|
Navigator.popUntil(context, (route) => route.isFirst);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
@ -39,134 +40,139 @@ class _DatabaseMigrationViewState extends State<DatabaseMigrationView> {
|
||||||
final oldMessages = await oldDatabase.messages.select().get();
|
final oldMessages = await oldDatabase.messages.select().get();
|
||||||
|
|
||||||
for (final oldContact in oldContacts) {
|
for (final oldContact in oldContacts) {
|
||||||
|
if (oldContact.deleted) continue;
|
||||||
|
Uint8List? avatarSvg;
|
||||||
|
if (oldContact.avatarSvg != null) {
|
||||||
|
avatarSvg =
|
||||||
|
Uint8List.fromList(gzip.encode(utf8.encode(oldContact.avatarSvg!)));
|
||||||
|
}
|
||||||
await twonlyDB.contactsDao.insertContact(
|
await twonlyDB.contactsDao.insertContact(
|
||||||
ContactsCompanion(
|
ContactsCompanion(
|
||||||
userId: Value(oldContact.userId),
|
userId: Value(oldContact.userId),
|
||||||
username: Value(oldContact.username),
|
username: Value(oldContact.username),
|
||||||
displayName: Value(oldContact.displayName),
|
displayName: Value(oldContact.displayName),
|
||||||
nickName: Value(oldContact.nickName),
|
nickName: Value(oldContact.nickName),
|
||||||
avatarSvg: Value(oldContact.avatarSvg),
|
avatarSvgCompressed: Value(avatarSvg),
|
||||||
senderProfileCounter: const Value(0),
|
senderProfileCounter: const Value(0),
|
||||||
accepted: Value(oldContact.accepted),
|
accepted: Value(oldContact.accepted),
|
||||||
requested: Value(oldContact.requested),
|
requested: Value(oldContact.requested),
|
||||||
blocked: Value(oldContact.blocked),
|
blocked: Value(oldContact.blocked),
|
||||||
verified: Value(oldContact.verified),
|
verified: Value(oldContact.verified),
|
||||||
deleted: Value(oldContact.deleted),
|
|
||||||
createdAt: Value(oldContact.createdAt),
|
createdAt: Value(oldContact.createdAt),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
setState(() {
|
setState(() {
|
||||||
_contactsMigrated += 1;
|
_contactsMigrated += 1;
|
||||||
});
|
});
|
||||||
if (!oldContact.deleted) {
|
final group = await twonlyDB.groupsDao.createNewDirectChat(
|
||||||
final group = await twonlyDB.groupsDao.createNewDirectChat(
|
oldContact.userId,
|
||||||
oldContact.userId,
|
GroupsCompanion(
|
||||||
GroupsCompanion(
|
pinned: Value(oldContact.pinned),
|
||||||
pinned: Value(oldContact.pinned),
|
archived: Value(oldContact.archived),
|
||||||
archived: Value(oldContact.archived),
|
groupName: Value(getContactDisplayNameOld(oldContact)),
|
||||||
groupName: Value(getContactDisplayNameOld(oldContact)),
|
totalMediaCounter: Value(oldContact.totalMediaCounter),
|
||||||
totalMediaCounter: Value(oldContact.totalMediaCounter),
|
alsoBestFriend: Value(oldContact.alsoBestFriend),
|
||||||
alsoBestFriend: Value(oldContact.alsoBestFriend),
|
createdAt: Value(oldContact.createdAt),
|
||||||
createdAt: Value(oldContact.createdAt),
|
lastFlameCounterChange: Value(oldContact.lastFlameCounterChange),
|
||||||
lastFlameCounterChange: Value(oldContact.lastFlameCounterChange),
|
lastFlameSync: Value(oldContact.lastFlameSync),
|
||||||
lastFlameSync: Value(oldContact.lastFlameSync),
|
lastMessageExchange: Value(oldContact.lastMessageExchange),
|
||||||
lastMessageExchange: Value(oldContact.lastMessageExchange),
|
lastMessageReceived: Value(oldContact.lastMessageReceived),
|
||||||
lastMessageReceived: Value(oldContact.lastMessageReceived),
|
lastMessageSend: Value(oldContact.lastMessageSend),
|
||||||
lastMessageSend: Value(oldContact.lastMessageSend),
|
flameCounter: Value(oldContact.flameCounter),
|
||||||
flameCounter: Value(oldContact.flameCounter),
|
),
|
||||||
|
);
|
||||||
|
if (group == null) continue;
|
||||||
|
for (final oldMessage in oldMessages) {
|
||||||
|
if (oldMessage.mediaUploadId == null &&
|
||||||
|
oldMessage.mediaDownloadId == null) {
|
||||||
|
/// only interested in media files...
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (oldMessage.contactId != oldContact.userId) continue;
|
||||||
|
if (!oldMessage.mediaStored) continue;
|
||||||
|
|
||||||
|
var storedMediaPath =
|
||||||
|
join((await getApplicationSupportDirectory()).path, 'media');
|
||||||
|
if (oldMessage.mediaDownloadId != null) {
|
||||||
|
storedMediaPath =
|
||||||
|
'${join(storedMediaPath, 'received')}/${oldMessage.mediaDownloadId}';
|
||||||
|
} else {
|
||||||
|
storedMediaPath =
|
||||||
|
'${join(storedMediaPath, 'send')}/${oldMessage.mediaDownloadId}';
|
||||||
|
}
|
||||||
|
|
||||||
|
var type = MediaType.image;
|
||||||
|
if (File('$storedMediaPath.mp4').existsSync()) {
|
||||||
|
type = MediaType.video;
|
||||||
|
storedMediaPath = '$storedMediaPath.mp4';
|
||||||
|
} else if (File('$storedMediaPath.png').existsSync()) {
|
||||||
|
type = MediaType.image;
|
||||||
|
storedMediaPath = '$storedMediaPath.png';
|
||||||
|
} else if (File('$storedMediaPath.webp').existsSync()) {
|
||||||
|
type = MediaType.image;
|
||||||
|
storedMediaPath = '$storedMediaPath.webp';
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final uniqueId = Value(
|
||||||
|
getUUIDforDirectChat(
|
||||||
|
oldMessage.messageOtherId ?? oldMessage.messageId,
|
||||||
|
oldMessage.contactId ^ gUser.userId,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (group == null) continue;
|
|
||||||
for (final oldMessage in oldMessages) {
|
|
||||||
if (oldMessage.mediaUploadId == null &&
|
|
||||||
oldMessage.mediaDownloadId == null) {
|
|
||||||
/// only interested in media files...
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (oldMessage.contactId != oldContact.userId) continue;
|
|
||||||
if (!oldMessage.mediaStored) continue;
|
|
||||||
|
|
||||||
var storedMediaPath =
|
final mediaFile = await twonlyDB.mediaFilesDao.insertMedia(
|
||||||
join((await getApplicationSupportDirectory()).path, 'media');
|
MediaFilesCompanion(
|
||||||
if (oldMessage.mediaDownloadId != null) {
|
mediaId: uniqueId,
|
||||||
storedMediaPath =
|
stored: const Value(true),
|
||||||
'${join(storedMediaPath, 'received')}/${oldMessage.mediaDownloadId}';
|
type: Value(type),
|
||||||
} else {
|
createdAt: Value(oldMessage.sendAt),
|
||||||
storedMediaPath =
|
),
|
||||||
'${join(storedMediaPath, 'send')}/${oldMessage.mediaDownloadId}';
|
);
|
||||||
}
|
if (mediaFile == null) continue;
|
||||||
|
|
||||||
var type = MediaType.image;
|
final message = await twonlyDB.messagesDao.insertMessage(
|
||||||
if (File('$storedMediaPath.mp4').existsSync()) {
|
MessagesCompanion(
|
||||||
type = MediaType.video;
|
messageId: uniqueId,
|
||||||
storedMediaPath = '$storedMediaPath.mp4';
|
groupId: Value(group.groupId),
|
||||||
} else if (File('$storedMediaPath.png').existsSync()) {
|
mediaId: uniqueId,
|
||||||
type = MediaType.image;
|
type: const Value(MessageType.media),
|
||||||
storedMediaPath = '$storedMediaPath.png';
|
),
|
||||||
} else if (File('$storedMediaPath.webp').existsSync()) {
|
);
|
||||||
type = MediaType.image;
|
if (message == null) continue;
|
||||||
storedMediaPath = '$storedMediaPath.webp';
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
final uniqueId = Value(
|
final mediaService = await MediaFileService.fromMedia(mediaFile);
|
||||||
getUUIDforDirectChat(
|
File(storedMediaPath).copySync(mediaService.storedPath.path);
|
||||||
oldMessage.messageOtherId ?? oldMessage.messageId,
|
setState(() {
|
||||||
oldMessage.contactId ^ gUser.userId,
|
_storedMediaFiles += 1;
|
||||||
),
|
});
|
||||||
);
|
|
||||||
|
|
||||||
final mediaFile = await twonlyDB.mediaFilesDao.insertMedia(
|
|
||||||
MediaFilesCompanion(
|
|
||||||
mediaId: uniqueId,
|
|
||||||
stored: const Value(true),
|
|
||||||
type: Value(type),
|
|
||||||
createdAt: Value(oldMessage.sendAt),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if (mediaFile == null) continue;
|
|
||||||
|
|
||||||
final message = await twonlyDB.messagesDao.insertMessage(
|
|
||||||
MessagesCompanion(
|
|
||||||
messageId: uniqueId,
|
|
||||||
groupId: Value(group.groupId),
|
|
||||||
mediaId: uniqueId,
|
|
||||||
type: const Value(MessageType.media),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if (message == null) continue;
|
|
||||||
|
|
||||||
final mediaService = await MediaFileService.fromMedia(mediaFile);
|
|
||||||
File(storedMediaPath).copySync(mediaService.storedPath.path);
|
|
||||||
setState(() {
|
|
||||||
_storedMediaFiles += 1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final memoriesPath = Directory(
|
final memoriesPath = Directory(
|
||||||
join((await getApplicationSupportDirectory()).path, 'media', 'memories'),
|
join((await getApplicationSupportDirectory()).path, 'media', 'memories'),
|
||||||
);
|
);
|
||||||
final files = memoriesPath.listSync();
|
if (memoriesPath.existsSync()) {
|
||||||
for (final file in files) {
|
final files = memoriesPath.listSync();
|
||||||
if (file.path.contains('thumbnail')) continue;
|
for (final file in files) {
|
||||||
final type =
|
if (file.path.contains('thumbnail')) continue;
|
||||||
file.path.contains('mp4') ? MediaType.video : MediaType.image;
|
final type =
|
||||||
final stat = FileStat.statSync(file.path);
|
file.path.contains('mp4') ? MediaType.video : MediaType.image;
|
||||||
final mediaFile = await twonlyDB.mediaFilesDao.insertMedia(
|
final stat = FileStat.statSync(file.path);
|
||||||
MediaFilesCompanion(
|
final mediaFile = await twonlyDB.mediaFilesDao.insertMedia(
|
||||||
type: Value(type),
|
MediaFilesCompanion(
|
||||||
createdAt: Value(stat.modified),
|
type: Value(type),
|
||||||
stored: const Value(true),
|
createdAt: Value(stat.modified),
|
||||||
),
|
stored: const Value(true),
|
||||||
);
|
),
|
||||||
final mediaService = await MediaFileService.fromMedia(mediaFile!);
|
);
|
||||||
File(file.path).copySync(mediaService.storedPath.path);
|
final mediaService = await MediaFileService.fromMedia(mediaFile!);
|
||||||
setState(() {
|
File(file.path).copySync(mediaService.storedPath.path);
|
||||||
_storedMediaFiles += 1;
|
setState(() {
|
||||||
});
|
_storedMediaFiles += 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final oldContactPreKeys =
|
final oldContactPreKeys =
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue