diff --git a/lib/src/database/daos/messages.dao.dart b/lib/src/database/daos/messages.dao.dart index 5314944..4e45db6 100644 --- a/lib/src/database/daos/messages.dao.dart +++ b/lib/src/database/daos/messages.dao.dart @@ -122,7 +122,7 @@ class MessagesDao extends DatabaseAccessor with _$MessagesDaoMixin { (m.mediaStored.equals(true) & m.isDeletedFromSender.equals(true) | m.mediaStored.equals(false)) & - (m.openedAt.isSmallerThanValue(deletionTime) | + (m.openedByAll.isSmallerThanValue(deletionTime) | (m.isDeletedFromSender.equals(true) & m.createdAt.isSmallerThanValue(deletionTime))), )) @@ -271,12 +271,17 @@ class MessagesDao extends DatabaseAccessor with _$MessagesDaoMixin { ), ); // Directly show as message opened as soon as one person has opened it - // if (await haveAllMembers(messageId, MessageActionType.openedAt)) { + final openedByAll = + await haveAllMembers(messageId, MessageActionType.openedAt) + ? DateTime.now() + : null; await twonlyDB.messagesDao.updateMessageId( messageId, - MessagesCompanion(openedAt: Value(DateTime.now())), + MessagesCompanion( + openedAt: Value(DateTime.now()), + openedByAll: Value(openedByAll), + ), ); - // } } Future handleMessageAckByServer( @@ -292,13 +297,10 @@ class MessagesDao extends DatabaseAccessor with _$MessagesDaoMixin { actionAt: Value(timestamp), ), ); - // if (await haveAllMembers(messageId, MessageActionType.ackByServerAt)) { - /// always update the state, so it will be shown as soon as one member gets the message await twonlyDB.messagesDao.updateMessageId( messageId, MessagesCompanion(ackByServer: Value(DateTime.now())), ); - // } } Future haveAllMembers( diff --git a/lib/src/database/tables/messages.table.dart b/lib/src/database/tables/messages.table.dart index 5a9aa3f..7d0f20c 100644 --- a/lib/src/database/tables/messages.table.dart +++ b/lib/src/database/tables/messages.table.dart @@ -32,6 +32,7 @@ class Messages extends Table { boolean().withDefault(const Constant(false))(); DateTimeColumn get openedAt => dateTime().nullable()(); + DateTimeColumn get openedByAll => dateTime().nullable()(); DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); DateTimeColumn get modifiedAt => dateTime().nullable()(); DateTimeColumn get ackByUser => dateTime().nullable()(); diff --git a/lib/src/database/twonly.db.g.dart b/lib/src/database/twonly.db.g.dart index 9e58333..2e07136 100644 --- a/lib/src/database/twonly.db.g.dart +++ b/lib/src/database/twonly.db.g.dart @@ -2699,6 +2699,12 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> { late final GeneratedColumn openedAt = GeneratedColumn( 'opened_at', aliasedName, true, type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _openedByAllMeta = + const VerificationMeta('openedByAll'); + @override + late final GeneratedColumn openedByAll = GeneratedColumn( + 'opened_by_all', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); static const VerificationMeta _createdAtMeta = const VerificationMeta('createdAt'); @override @@ -2738,6 +2744,7 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> { quotesMessageId, isDeletedFromSender, openedAt, + openedByAll, createdAt, modifiedAt, ackByUser, @@ -2805,6 +2812,12 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> { context.handle(_openedAtMeta, openedAt.isAcceptableOrUnknown(data['opened_at']!, _openedAtMeta)); } + if (data.containsKey('opened_by_all')) { + context.handle( + _openedByAllMeta, + openedByAll.isAcceptableOrUnknown( + data['opened_by_all']!, _openedByAllMeta)); + } if (data.containsKey('created_at')) { context.handle(_createdAtMeta, createdAt.isAcceptableOrUnknown(data['created_at']!, _createdAtMeta)); @@ -2858,6 +2871,8 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> { DriftSqlType.bool, data['${effectivePrefix}is_deleted_from_sender'])!, openedAt: attachedDatabase.typeMapping .read(DriftSqlType.dateTime, data['${effectivePrefix}opened_at']), + openedByAll: attachedDatabase.typeMapping + .read(DriftSqlType.dateTime, data['${effectivePrefix}opened_by_all']), createdAt: attachedDatabase.typeMapping .read(DriftSqlType.dateTime, data['${effectivePrefix}created_at'])!, modifiedAt: attachedDatabase.typeMapping @@ -2890,6 +2905,7 @@ class Message extends DataClass implements Insertable { final String? quotesMessageId; final bool isDeletedFromSender; final DateTime? openedAt; + final DateTime? openedByAll; final DateTime createdAt; final DateTime? modifiedAt; final DateTime? ackByUser; @@ -2906,6 +2922,7 @@ class Message extends DataClass implements Insertable { this.quotesMessageId, required this.isDeletedFromSender, this.openedAt, + this.openedByAll, required this.createdAt, this.modifiedAt, this.ackByUser, @@ -2938,6 +2955,9 @@ class Message extends DataClass implements Insertable { if (!nullToAbsent || openedAt != null) { map['opened_at'] = Variable(openedAt); } + if (!nullToAbsent || openedByAll != null) { + map['opened_by_all'] = Variable(openedByAll); + } map['created_at'] = Variable(createdAt); if (!nullToAbsent || modifiedAt != null) { map['modified_at'] = Variable(modifiedAt); @@ -2976,6 +2996,9 @@ class Message extends DataClass implements Insertable { openedAt: openedAt == null && nullToAbsent ? const Value.absent() : Value(openedAt), + openedByAll: openedByAll == null && nullToAbsent + ? const Value.absent() + : Value(openedByAll), createdAt: Value(createdAt), modifiedAt: modifiedAt == null && nullToAbsent ? const Value.absent() @@ -3006,6 +3029,7 @@ class Message extends DataClass implements Insertable { isDeletedFromSender: serializer.fromJson(json['isDeletedFromSender']), openedAt: serializer.fromJson(json['openedAt']), + openedByAll: serializer.fromJson(json['openedByAll']), createdAt: serializer.fromJson(json['createdAt']), modifiedAt: serializer.fromJson(json['modifiedAt']), ackByUser: serializer.fromJson(json['ackByUser']), @@ -3028,6 +3052,7 @@ class Message extends DataClass implements Insertable { 'quotesMessageId': serializer.toJson(quotesMessageId), 'isDeletedFromSender': serializer.toJson(isDeletedFromSender), 'openedAt': serializer.toJson(openedAt), + 'openedByAll': serializer.toJson(openedByAll), 'createdAt': serializer.toJson(createdAt), 'modifiedAt': serializer.toJson(modifiedAt), 'ackByUser': serializer.toJson(ackByUser), @@ -3047,6 +3072,7 @@ class Message extends DataClass implements Insertable { Value quotesMessageId = const Value.absent(), bool? isDeletedFromSender, Value openedAt = const Value.absent(), + Value openedByAll = const Value.absent(), DateTime? createdAt, Value modifiedAt = const Value.absent(), Value ackByUser = const Value.absent(), @@ -3066,6 +3092,7 @@ class Message extends DataClass implements Insertable { : this.quotesMessageId, isDeletedFromSender: isDeletedFromSender ?? this.isDeletedFromSender, openedAt: openedAt.present ? openedAt.value : this.openedAt, + openedByAll: openedByAll.present ? openedByAll.value : this.openedByAll, createdAt: createdAt ?? this.createdAt, modifiedAt: modifiedAt.present ? modifiedAt.value : this.modifiedAt, ackByUser: ackByUser.present ? ackByUser.value : this.ackByUser, @@ -3091,6 +3118,8 @@ class Message extends DataClass implements Insertable { ? data.isDeletedFromSender.value : this.isDeletedFromSender, openedAt: data.openedAt.present ? data.openedAt.value : this.openedAt, + openedByAll: + data.openedByAll.present ? data.openedByAll.value : this.openedByAll, createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, modifiedAt: data.modifiedAt.present ? data.modifiedAt.value : this.modifiedAt, @@ -3114,6 +3143,7 @@ class Message extends DataClass implements Insertable { ..write('quotesMessageId: $quotesMessageId, ') ..write('isDeletedFromSender: $isDeletedFromSender, ') ..write('openedAt: $openedAt, ') + ..write('openedByAll: $openedByAll, ') ..write('createdAt: $createdAt, ') ..write('modifiedAt: $modifiedAt, ') ..write('ackByUser: $ackByUser, ') @@ -3135,6 +3165,7 @@ class Message extends DataClass implements Insertable { quotesMessageId, isDeletedFromSender, openedAt, + openedByAll, createdAt, modifiedAt, ackByUser, @@ -3154,6 +3185,7 @@ class Message extends DataClass implements Insertable { other.quotesMessageId == this.quotesMessageId && other.isDeletedFromSender == this.isDeletedFromSender && other.openedAt == this.openedAt && + other.openedByAll == this.openedByAll && other.createdAt == this.createdAt && other.modifiedAt == this.modifiedAt && other.ackByUser == this.ackByUser && @@ -3172,6 +3204,7 @@ class MessagesCompanion extends UpdateCompanion { final Value quotesMessageId; final Value isDeletedFromSender; final Value openedAt; + final Value openedByAll; final Value createdAt; final Value modifiedAt; final Value ackByUser; @@ -3189,6 +3222,7 @@ class MessagesCompanion extends UpdateCompanion { this.quotesMessageId = const Value.absent(), this.isDeletedFromSender = const Value.absent(), this.openedAt = const Value.absent(), + this.openedByAll = const Value.absent(), this.createdAt = const Value.absent(), this.modifiedAt = const Value.absent(), this.ackByUser = const Value.absent(), @@ -3207,6 +3241,7 @@ class MessagesCompanion extends UpdateCompanion { this.quotesMessageId = const Value.absent(), this.isDeletedFromSender = const Value.absent(), this.openedAt = const Value.absent(), + this.openedByAll = const Value.absent(), this.createdAt = const Value.absent(), this.modifiedAt = const Value.absent(), this.ackByUser = const Value.absent(), @@ -3227,6 +3262,7 @@ class MessagesCompanion extends UpdateCompanion { Expression? quotesMessageId, Expression? isDeletedFromSender, Expression? openedAt, + Expression? openedByAll, Expression? createdAt, Expression? modifiedAt, Expression? ackByUser, @@ -3246,6 +3282,7 @@ class MessagesCompanion extends UpdateCompanion { if (isDeletedFromSender != null) 'is_deleted_from_sender': isDeletedFromSender, if (openedAt != null) 'opened_at': openedAt, + if (openedByAll != null) 'opened_by_all': openedByAll, if (createdAt != null) 'created_at': createdAt, if (modifiedAt != null) 'modified_at': modifiedAt, if (ackByUser != null) 'ack_by_user': ackByUser, @@ -3266,6 +3303,7 @@ class MessagesCompanion extends UpdateCompanion { Value? quotesMessageId, Value? isDeletedFromSender, Value? openedAt, + Value? openedByAll, Value? createdAt, Value? modifiedAt, Value? ackByUser, @@ -3283,6 +3321,7 @@ class MessagesCompanion extends UpdateCompanion { quotesMessageId: quotesMessageId ?? this.quotesMessageId, isDeletedFromSender: isDeletedFromSender ?? this.isDeletedFromSender, openedAt: openedAt ?? this.openedAt, + openedByAll: openedByAll ?? this.openedByAll, createdAt: createdAt ?? this.createdAt, modifiedAt: modifiedAt ?? this.modifiedAt, ackByUser: ackByUser ?? this.ackByUser, @@ -3328,6 +3367,9 @@ class MessagesCompanion extends UpdateCompanion { if (openedAt.present) { map['opened_at'] = Variable(openedAt.value); } + if (openedByAll.present) { + map['opened_by_all'] = Variable(openedByAll.value); + } if (createdAt.present) { map['created_at'] = Variable(createdAt.value); } @@ -3360,6 +3402,7 @@ class MessagesCompanion extends UpdateCompanion { ..write('quotesMessageId: $quotesMessageId, ') ..write('isDeletedFromSender: $isDeletedFromSender, ') ..write('openedAt: $openedAt, ') + ..write('openedByAll: $openedByAll, ') ..write('createdAt: $createdAt, ') ..write('modifiedAt: $modifiedAt, ') ..write('ackByUser: $ackByUser, ') @@ -9419,6 +9462,7 @@ typedef $$MessagesTableCreateCompanionBuilder = MessagesCompanion Function({ Value quotesMessageId, Value isDeletedFromSender, Value openedAt, + Value openedByAll, Value createdAt, Value modifiedAt, Value ackByUser, @@ -9437,6 +9481,7 @@ typedef $$MessagesTableUpdateCompanionBuilder = MessagesCompanion Function({ Value quotesMessageId, Value isDeletedFromSender, Value openedAt, + Value openedByAll, Value createdAt, Value modifiedAt, Value ackByUser, @@ -9596,6 +9641,9 @@ class $$MessagesTableFilterComposer ColumnFilters get openedAt => $composableBuilder( column: $table.openedAt, builder: (column) => ColumnFilters(column)); + ColumnFilters get openedByAll => $composableBuilder( + column: $table.openedByAll, builder: (column) => ColumnFilters(column)); + ColumnFilters get createdAt => $composableBuilder( column: $table.createdAt, builder: (column) => ColumnFilters(column)); @@ -9789,6 +9837,9 @@ class $$MessagesTableOrderingComposer ColumnOrderings get openedAt => $composableBuilder( column: $table.openedAt, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get openedByAll => $composableBuilder( + column: $table.openedByAll, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get createdAt => $composableBuilder( column: $table.createdAt, builder: (column) => ColumnOrderings(column)); @@ -9895,6 +9946,9 @@ class $$MessagesTableAnnotationComposer GeneratedColumn get openedAt => $composableBuilder(column: $table.openedAt, builder: (column) => column); + GeneratedColumn get openedByAll => $composableBuilder( + column: $table.openedByAll, builder: (column) => column); + GeneratedColumn get createdAt => $composableBuilder(column: $table.createdAt, builder: (column) => column); @@ -10093,6 +10147,7 @@ class $$MessagesTableTableManager extends RootTableManager< Value quotesMessageId = const Value.absent(), Value isDeletedFromSender = const Value.absent(), Value openedAt = const Value.absent(), + Value openedByAll = const Value.absent(), Value createdAt = const Value.absent(), Value modifiedAt = const Value.absent(), Value ackByUser = const Value.absent(), @@ -10111,6 +10166,7 @@ class $$MessagesTableTableManager extends RootTableManager< quotesMessageId: quotesMessageId, isDeletedFromSender: isDeletedFromSender, openedAt: openedAt, + openedByAll: openedByAll, createdAt: createdAt, modifiedAt: modifiedAt, ackByUser: ackByUser, @@ -10129,6 +10185,7 @@ class $$MessagesTableTableManager extends RootTableManager< Value quotesMessageId = const Value.absent(), Value isDeletedFromSender = const Value.absent(), Value openedAt = const Value.absent(), + Value openedByAll = const Value.absent(), Value createdAt = const Value.absent(), Value modifiedAt = const Value.absent(), Value ackByUser = const Value.absent(), @@ -10147,6 +10204,7 @@ class $$MessagesTableTableManager extends RootTableManager< quotesMessageId: quotesMessageId, isDeletedFromSender: isDeletedFromSender, openedAt: openedAt, + openedByAll: openedByAll, createdAt: createdAt, modifiedAt: modifiedAt, ackByUser: ackByUser, diff --git a/lib/src/services/api/messages.dart b/lib/src/services/api/messages.dart index 4b72807..8a7497e 100644 --- a/lib/src/services/api/messages.dart +++ b/lib/src/services/api/messages.dart @@ -274,7 +274,10 @@ Future notifyContactAboutOpeningMessage( for (final messageId in messageOtherIds) { await twonlyDB.messagesDao.updateMessageId( messageId, - MessagesCompanion(openedAt: Value(actionAt)), + MessagesCompanion( + openedAt: Value(actionAt), + openedByAll: Value(actionAt), + ), ); } await updateLastMessageId(contactId, biggestMessageId); diff --git a/lib/src/views/chats/chat_messages.view.dart b/lib/src/views/chats/chat_messages.view.dart index 64e5a44..1e47905 100644 --- a/lib/src/views/chats/chat_messages.view.dart +++ b/lib/src/views/chats/chat_messages.view.dart @@ -385,7 +385,6 @@ class _ChatMessagesViewState extends State { alignment: WrapAlignment.center, children: messages[i].lastOpenedPosition!.map((w) { return AvatarIcon( - key: GlobalKey(), contactId: w.userId, fontSize: 12, ); diff --git a/lib/src/views/chats/chat_messages_components/chat_text_entry.dart b/lib/src/views/chats/chat_messages_components/chat_text_entry.dart index c22df9f..7d7d3fb 100644 --- a/lib/src/views/chats/chat_messages_components/chat_text_entry.dart +++ b/lib/src/views/chats/chat_messages_components/chat_text_entry.dart @@ -47,13 +47,16 @@ class ChatTextEntry extends StatelessWidget { var displayTime = !combineTextMessageWithNext(message, nextMessage); var displayUserName = ''; - if (message.senderId != null && - prevMessage != null && - userIdToContact != null) { - if (!combineTextMessageWithNext(prevMessage!, message)) { - if (userIdToContact![message.senderId] != null) { - displayUserName = - getContactDisplayName(userIdToContact![message.senderId]!); + if (message.senderId != null && userIdToContact != null) { + if (prevMessage == null) { + displayUserName = + getContactDisplayName(userIdToContact![message.senderId]!); + } else { + if (!combineTextMessageWithNext(prevMessage!, message)) { + if (userIdToContact![message.senderId] != null) { + displayUserName = + getContactDisplayName(userIdToContact![message.senderId]!); + } } } } diff --git a/lib/src/views/components/avatar_icon.component.dart b/lib/src/views/components/avatar_icon.component.dart index 341ba41..f82bbbc 100644 --- a/lib/src/views/components/avatar_icon.component.dart +++ b/lib/src/views/components/avatar_icon.component.dart @@ -150,7 +150,6 @@ class _AvatarIconState extends State { } return Container( - key: GlobalKey(), constraints: BoxConstraints( minHeight: 2 * (widget.fontSize ?? 20), minWidth: 2 * (widget.fontSize ?? 20), diff --git a/lib/src/views/groups/group_create_select_members.view.dart b/lib/src/views/groups/group_create_select_members.view.dart index a497622..892c202 100644 --- a/lib/src/views/groups/group_create_select_members.view.dart +++ b/lib/src/views/groups/group_create_select_members.view.dart @@ -254,7 +254,6 @@ class _Chip extends StatelessWidget { return GestureDetector( onTap: () => onTap(contact.userId), child: Chip( - key: GlobalKey(), avatar: AvatarIcon( contactId: contact.userId, fontSize: 10,