diff --git a/lib/src/components/message_send_state_icon.dart b/lib/src/components/message_send_state_icon.dart index 3259594..29c5cc2 100644 --- a/lib/src/components/message_send_state_icon.dart +++ b/lib/src/components/message_send_state_icon.dart @@ -149,7 +149,17 @@ class _MessageSendStateIconState extends State { if (icons.length == 2) { icon = Stack( - children: icons, + alignment: Alignment.center, + children: [ + // First icon (bottom icon) + icons[0], + Positioned( + top: 5.0, + left: 5.0, + child: icons[1], + ), + // Second icon (top icon, slightly offset) + ], ); } diff --git a/lib/src/database/daos/contacts_dao.dart b/lib/src/database/daos/contacts_dao.dart index 690d200..28fc3c4 100644 --- a/lib/src/database/daos/contacts_dao.dart +++ b/lib/src/database/daos/contacts_dao.dart @@ -42,13 +42,13 @@ class ContactsDao extends DatabaseAccessor Value lastMessageSend = Value.absent(); Value lastMessageReceived = Value.absent(); - Value lastMessage = Value.absent(); + Value lastFlameCounterChange = Value.absent(); - if (contact.lastMessage != null) { + if (contact.lastFlameCounterChange != null) { final now = DateTime.now(); final startOfToday = DateTime(now.year, now.month, now.day); - if (contact.lastMessage!.isBefore(startOfToday)) { + if (contact.lastFlameCounterChange!.isBefore(startOfToday)) { // last flame update was yesterday. check if it can be updated. bool updateFlame = false; if (received) { @@ -62,12 +62,12 @@ class ContactsDao extends DatabaseAccessor } if (updateFlame) { flameCounter += 1; - lastMessage = Value(timestamp); + lastFlameCounterChange = Value(timestamp); } } } else { // There where no message until no... - lastMessage = Value(timestamp); + lastFlameCounterChange = Value(timestamp); } if (received) { @@ -79,7 +79,7 @@ class ContactsDao extends DatabaseAccessor return (update(contacts)..where((t) => t.userId.equals(contactId))).write( ContactsCompanion( totalMediaCounter: Value(totalMediaCounter), - lastMessage: lastMessage, + lastFlameCounterChange: lastFlameCounterChange, lastMessageReceived: lastMessageReceived, lastMessageSend: lastMessageSend, flameCounter: Value(flameCounter), @@ -100,6 +100,11 @@ class ContactsDao extends DatabaseAccessor .write(updatedValues); } + Future newMessageExchange(int userId) { + return updateContact( + userId, ContactsCompanion(lastMessageExchange: Value(DateTime.now()))); + } + Stream> watchNotAcceptedContacts() { return (select(contacts)..where((t) => t.accepted.equals(false))).watch(); // return (select(contacts)).watch(); @@ -113,7 +118,7 @@ class ContactsDao extends DatabaseAccessor Stream> watchContactsForChatList() { return (select(contacts) ..where((t) => t.accepted.equals(true) & t.blocked.equals(false)) - ..orderBy([(t) => OrderingTerm.desc(t.lastMessage)])) + ..orderBy([(t) => OrderingTerm.desc(t.lastMessageExchange)])) .watch(); } diff --git a/lib/src/database/daos/messages_dao.dart b/lib/src/database/daos/messages_dao.dart index b759df1..d54ebb9 100644 --- a/lib/src/database/daos/messages_dao.dart +++ b/lib/src/database/daos/messages_dao.dart @@ -1,5 +1,6 @@ import 'package:drift/drift.dart'; import 'package:logging/logging.dart'; +import 'package:twonly/globals.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/json_models/message.dart'; @@ -110,6 +111,8 @@ class MessagesDao extends DatabaseAccessor Future insertMessage(MessagesCompanion message) async { try { + await twonlyDatabase.contactsDao + .newMessageExchange(message.contactId.value); return await into(messages).insert(message); } catch (e) { Logger("twonlyDatabase").shout("Error while inserting message: $e"); diff --git a/lib/src/database/tables/contacts_table.dart b/lib/src/database/tables/contacts_table.dart index 8dc66a0..340608a 100644 --- a/lib/src/database/tables/contacts_table.dart +++ b/lib/src/database/tables/contacts_table.dart @@ -19,7 +19,9 @@ class Contacts extends Table { DateTimeColumn get lastMessageSend => dateTime().nullable()(); DateTimeColumn get lastMessageReceived => dateTime().nullable()(); - DateTimeColumn get lastMessage => dateTime().nullable()(); + DateTimeColumn get lastFlameCounterChange => dateTime().nullable()(); + DateTimeColumn get lastMessageExchange => + dateTime().withDefault(currentDateAndTime)(); IntColumn get flameCounter => integer().withDefault(Constant(0))(); diff --git a/lib/src/database/twonly_database.g.dart b/lib/src/database/twonly_database.g.dart index bc6e389..926fbb0 100644 --- a/lib/src/database/twonly_database.g.dart +++ b/lib/src/database/twonly_database.g.dart @@ -101,12 +101,20 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> { late final GeneratedColumn lastMessageReceived = GeneratedColumn('last_message_received', aliasedName, true, type: DriftSqlType.dateTime, requiredDuringInsert: false); - static const VerificationMeta _lastMessageMeta = - const VerificationMeta('lastMessage'); + static const VerificationMeta _lastFlameCounterChangeMeta = + const VerificationMeta('lastFlameCounterChange'); @override - late final GeneratedColumn lastMessage = GeneratedColumn( - 'last_message', aliasedName, true, - type: DriftSqlType.dateTime, requiredDuringInsert: false); + late final GeneratedColumn lastFlameCounterChange = + GeneratedColumn('last_flame_counter_change', aliasedName, true, + type: DriftSqlType.dateTime, requiredDuringInsert: false); + static const VerificationMeta _lastMessageExchangeMeta = + const VerificationMeta('lastMessageExchange'); + @override + late final GeneratedColumn lastMessageExchange = + GeneratedColumn('last_message_exchange', aliasedName, false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: currentDateAndTime); static const VerificationMeta _flameCounterMeta = const VerificationMeta('flameCounter'); @override @@ -129,7 +137,8 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> { totalMediaCounter, lastMessageSend, lastMessageReceived, - lastMessage, + lastFlameCounterChange, + lastMessageExchange, flameCounter ]; @override @@ -200,11 +209,17 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> { lastMessageReceived.isAcceptableOrUnknown( data['last_message_received']!, _lastMessageReceivedMeta)); } - if (data.containsKey('last_message')) { + if (data.containsKey('last_flame_counter_change')) { context.handle( - _lastMessageMeta, - lastMessage.isAcceptableOrUnknown( - data['last_message']!, _lastMessageMeta)); + _lastFlameCounterChangeMeta, + lastFlameCounterChange.isAcceptableOrUnknown( + data['last_flame_counter_change']!, _lastFlameCounterChangeMeta)); + } + if (data.containsKey('last_message_exchange')) { + context.handle( + _lastMessageExchangeMeta, + lastMessageExchange.isAcceptableOrUnknown( + data['last_message_exchange']!, _lastMessageExchangeMeta)); } if (data.containsKey('flame_counter')) { context.handle( @@ -246,8 +261,12 @@ class $ContactsTable extends Contacts with TableInfo<$ContactsTable, Contact> { lastMessageReceived: attachedDatabase.typeMapping.read( DriftSqlType.dateTime, data['${effectivePrefix}last_message_received']), - lastMessage: attachedDatabase.typeMapping - .read(DriftSqlType.dateTime, data['${effectivePrefix}last_message']), + lastFlameCounterChange: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}last_flame_counter_change']), + lastMessageExchange: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}last_message_exchange'])!, flameCounter: attachedDatabase.typeMapping .read(DriftSqlType.int, data['${effectivePrefix}flame_counter'])!, ); @@ -272,7 +291,8 @@ class Contact extends DataClass implements Insertable { final int totalMediaCounter; final DateTime? lastMessageSend; final DateTime? lastMessageReceived; - final DateTime? lastMessage; + final DateTime? lastFlameCounterChange; + final DateTime lastMessageExchange; final int flameCounter; const Contact( {required this.userId, @@ -287,7 +307,8 @@ class Contact extends DataClass implements Insertable { required this.totalMediaCounter, this.lastMessageSend, this.lastMessageReceived, - this.lastMessage, + this.lastFlameCounterChange, + required this.lastMessageExchange, required this.flameCounter}); @override Map toColumns(bool nullToAbsent) { @@ -312,9 +333,11 @@ class Contact extends DataClass implements Insertable { if (!nullToAbsent || lastMessageReceived != null) { map['last_message_received'] = Variable(lastMessageReceived); } - if (!nullToAbsent || lastMessage != null) { - map['last_message'] = Variable(lastMessage); + if (!nullToAbsent || lastFlameCounterChange != null) { + map['last_flame_counter_change'] = + Variable(lastFlameCounterChange); } + map['last_message_exchange'] = Variable(lastMessageExchange); map['flame_counter'] = Variable(flameCounter); return map; } @@ -341,9 +364,10 @@ class Contact extends DataClass implements Insertable { lastMessageReceived: lastMessageReceived == null && nullToAbsent ? const Value.absent() : Value(lastMessageReceived), - lastMessage: lastMessage == null && nullToAbsent + lastFlameCounterChange: lastFlameCounterChange == null && nullToAbsent ? const Value.absent() - : Value(lastMessage), + : Value(lastFlameCounterChange), + lastMessageExchange: Value(lastMessageExchange), flameCounter: Value(flameCounter), ); } @@ -365,7 +389,10 @@ class Contact extends DataClass implements Insertable { lastMessageSend: serializer.fromJson(json['lastMessageSend']), lastMessageReceived: serializer.fromJson(json['lastMessageReceived']), - lastMessage: serializer.fromJson(json['lastMessage']), + lastFlameCounterChange: + serializer.fromJson(json['lastFlameCounterChange']), + lastMessageExchange: + serializer.fromJson(json['lastMessageExchange']), flameCounter: serializer.fromJson(json['flameCounter']), ); } @@ -385,7 +412,9 @@ class Contact extends DataClass implements Insertable { 'totalMediaCounter': serializer.toJson(totalMediaCounter), 'lastMessageSend': serializer.toJson(lastMessageSend), 'lastMessageReceived': serializer.toJson(lastMessageReceived), - 'lastMessage': serializer.toJson(lastMessage), + 'lastFlameCounterChange': + serializer.toJson(lastFlameCounterChange), + 'lastMessageExchange': serializer.toJson(lastMessageExchange), 'flameCounter': serializer.toJson(flameCounter), }; } @@ -403,7 +432,8 @@ class Contact extends DataClass implements Insertable { int? totalMediaCounter, Value lastMessageSend = const Value.absent(), Value lastMessageReceived = const Value.absent(), - Value lastMessage = const Value.absent(), + Value lastFlameCounterChange = const Value.absent(), + DateTime? lastMessageExchange, int? flameCounter}) => Contact( userId: userId ?? this.userId, @@ -422,7 +452,10 @@ class Contact extends DataClass implements Insertable { lastMessageReceived: lastMessageReceived.present ? lastMessageReceived.value : this.lastMessageReceived, - lastMessage: lastMessage.present ? lastMessage.value : this.lastMessage, + lastFlameCounterChange: lastFlameCounterChange.present + ? lastFlameCounterChange.value + : this.lastFlameCounterChange, + lastMessageExchange: lastMessageExchange ?? this.lastMessageExchange, flameCounter: flameCounter ?? this.flameCounter, ); Contact copyWithCompanion(ContactsCompanion data) { @@ -446,8 +479,12 @@ class Contact extends DataClass implements Insertable { lastMessageReceived: data.lastMessageReceived.present ? data.lastMessageReceived.value : this.lastMessageReceived, - lastMessage: - data.lastMessage.present ? data.lastMessage.value : this.lastMessage, + lastFlameCounterChange: data.lastFlameCounterChange.present + ? data.lastFlameCounterChange.value + : this.lastFlameCounterChange, + lastMessageExchange: data.lastMessageExchange.present + ? data.lastMessageExchange.value + : this.lastMessageExchange, flameCounter: data.flameCounter.present ? data.flameCounter.value : this.flameCounter, @@ -469,7 +506,8 @@ class Contact extends DataClass implements Insertable { ..write('totalMediaCounter: $totalMediaCounter, ') ..write('lastMessageSend: $lastMessageSend, ') ..write('lastMessageReceived: $lastMessageReceived, ') - ..write('lastMessage: $lastMessage, ') + ..write('lastFlameCounterChange: $lastFlameCounterChange, ') + ..write('lastMessageExchange: $lastMessageExchange, ') ..write('flameCounter: $flameCounter') ..write(')')) .toString(); @@ -489,7 +527,8 @@ class Contact extends DataClass implements Insertable { totalMediaCounter, lastMessageSend, lastMessageReceived, - lastMessage, + lastFlameCounterChange, + lastMessageExchange, flameCounter); @override bool operator ==(Object other) => @@ -507,7 +546,8 @@ class Contact extends DataClass implements Insertable { other.totalMediaCounter == this.totalMediaCounter && other.lastMessageSend == this.lastMessageSend && other.lastMessageReceived == this.lastMessageReceived && - other.lastMessage == this.lastMessage && + other.lastFlameCounterChange == this.lastFlameCounterChange && + other.lastMessageExchange == this.lastMessageExchange && other.flameCounter == this.flameCounter); } @@ -524,7 +564,8 @@ class ContactsCompanion extends UpdateCompanion { final Value totalMediaCounter; final Value lastMessageSend; final Value lastMessageReceived; - final Value lastMessage; + final Value lastFlameCounterChange; + final Value lastMessageExchange; final Value flameCounter; const ContactsCompanion({ this.userId = const Value.absent(), @@ -539,7 +580,8 @@ class ContactsCompanion extends UpdateCompanion { this.totalMediaCounter = const Value.absent(), this.lastMessageSend = const Value.absent(), this.lastMessageReceived = const Value.absent(), - this.lastMessage = const Value.absent(), + this.lastFlameCounterChange = const Value.absent(), + this.lastMessageExchange = const Value.absent(), this.flameCounter = const Value.absent(), }); ContactsCompanion.insert({ @@ -555,7 +597,8 @@ class ContactsCompanion extends UpdateCompanion { this.totalMediaCounter = const Value.absent(), this.lastMessageSend = const Value.absent(), this.lastMessageReceived = const Value.absent(), - this.lastMessage = const Value.absent(), + this.lastFlameCounterChange = const Value.absent(), + this.lastMessageExchange = const Value.absent(), this.flameCounter = const Value.absent(), }) : username = Value(username); static Insertable custom({ @@ -571,7 +614,8 @@ class ContactsCompanion extends UpdateCompanion { Expression? totalMediaCounter, Expression? lastMessageSend, Expression? lastMessageReceived, - Expression? lastMessage, + Expression? lastFlameCounterChange, + Expression? lastMessageExchange, Expression? flameCounter, }) { return RawValuesInsertable({ @@ -588,7 +632,10 @@ class ContactsCompanion extends UpdateCompanion { if (lastMessageSend != null) 'last_message_send': lastMessageSend, if (lastMessageReceived != null) 'last_message_received': lastMessageReceived, - if (lastMessage != null) 'last_message': lastMessage, + if (lastFlameCounterChange != null) + 'last_flame_counter_change': lastFlameCounterChange, + if (lastMessageExchange != null) + 'last_message_exchange': lastMessageExchange, if (flameCounter != null) 'flame_counter': flameCounter, }); } @@ -606,7 +653,8 @@ class ContactsCompanion extends UpdateCompanion { Value? totalMediaCounter, Value? lastMessageSend, Value? lastMessageReceived, - Value? lastMessage, + Value? lastFlameCounterChange, + Value? lastMessageExchange, Value? flameCounter}) { return ContactsCompanion( userId: userId ?? this.userId, @@ -621,7 +669,9 @@ class ContactsCompanion extends UpdateCompanion { totalMediaCounter: totalMediaCounter ?? this.totalMediaCounter, lastMessageSend: lastMessageSend ?? this.lastMessageSend, lastMessageReceived: lastMessageReceived ?? this.lastMessageReceived, - lastMessage: lastMessage ?? this.lastMessage, + lastFlameCounterChange: + lastFlameCounterChange ?? this.lastFlameCounterChange, + lastMessageExchange: lastMessageExchange ?? this.lastMessageExchange, flameCounter: flameCounter ?? this.flameCounter, ); } @@ -666,8 +716,13 @@ class ContactsCompanion extends UpdateCompanion { map['last_message_received'] = Variable(lastMessageReceived.value); } - if (lastMessage.present) { - map['last_message'] = Variable(lastMessage.value); + if (lastFlameCounterChange.present) { + map['last_flame_counter_change'] = + Variable(lastFlameCounterChange.value); + } + if (lastMessageExchange.present) { + map['last_message_exchange'] = + Variable(lastMessageExchange.value); } if (flameCounter.present) { map['flame_counter'] = Variable(flameCounter.value); @@ -690,7 +745,8 @@ class ContactsCompanion extends UpdateCompanion { ..write('totalMediaCounter: $totalMediaCounter, ') ..write('lastMessageSend: $lastMessageSend, ') ..write('lastMessageReceived: $lastMessageReceived, ') - ..write('lastMessage: $lastMessage, ') + ..write('lastFlameCounterChange: $lastFlameCounterChange, ') + ..write('lastMessageExchange: $lastMessageExchange, ') ..write('flameCounter: $flameCounter') ..write(')')) .toString(); @@ -2400,7 +2456,8 @@ typedef $$ContactsTableCreateCompanionBuilder = ContactsCompanion Function({ Value totalMediaCounter, Value lastMessageSend, Value lastMessageReceived, - Value lastMessage, + Value lastFlameCounterChange, + Value lastMessageExchange, Value flameCounter, }); typedef $$ContactsTableUpdateCompanionBuilder = ContactsCompanion Function({ @@ -2416,7 +2473,8 @@ typedef $$ContactsTableUpdateCompanionBuilder = ContactsCompanion Function({ Value totalMediaCounter, Value lastMessageSend, Value lastMessageReceived, - Value lastMessage, + Value lastFlameCounterChange, + Value lastMessageExchange, Value flameCounter, }); @@ -2488,8 +2546,13 @@ class $$ContactsTableFilterComposer column: $table.lastMessageReceived, builder: (column) => ColumnFilters(column)); - ColumnFilters get lastMessage => $composableBuilder( - column: $table.lastMessage, builder: (column) => ColumnFilters(column)); + ColumnFilters get lastFlameCounterChange => $composableBuilder( + column: $table.lastFlameCounterChange, + builder: (column) => ColumnFilters(column)); + + ColumnFilters get lastMessageExchange => $composableBuilder( + column: $table.lastMessageExchange, + builder: (column) => ColumnFilters(column)); ColumnFilters get flameCounter => $composableBuilder( column: $table.flameCounter, builder: (column) => ColumnFilters(column)); @@ -2564,8 +2627,13 @@ class $$ContactsTableOrderingComposer column: $table.lastMessageReceived, builder: (column) => ColumnOrderings(column)); - ColumnOrderings get lastMessage => $composableBuilder( - column: $table.lastMessage, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get lastFlameCounterChange => $composableBuilder( + column: $table.lastFlameCounterChange, + builder: (column) => ColumnOrderings(column)); + + ColumnOrderings get lastMessageExchange => $composableBuilder( + column: $table.lastMessageExchange, + builder: (column) => ColumnOrderings(column)); ColumnOrderings get flameCounter => $composableBuilder( column: $table.flameCounter, @@ -2617,8 +2685,11 @@ class $$ContactsTableAnnotationComposer GeneratedColumn get lastMessageReceived => $composableBuilder( column: $table.lastMessageReceived, builder: (column) => column); - GeneratedColumn get lastMessage => $composableBuilder( - column: $table.lastMessage, builder: (column) => column); + GeneratedColumn get lastFlameCounterChange => $composableBuilder( + column: $table.lastFlameCounterChange, builder: (column) => column); + + GeneratedColumn get lastMessageExchange => $composableBuilder( + column: $table.lastMessageExchange, builder: (column) => column); GeneratedColumn get flameCounter => $composableBuilder( column: $table.flameCounter, builder: (column) => column); @@ -2680,7 +2751,8 @@ class $$ContactsTableTableManager extends RootTableManager< Value totalMediaCounter = const Value.absent(), Value lastMessageSend = const Value.absent(), Value lastMessageReceived = const Value.absent(), - Value lastMessage = const Value.absent(), + Value lastFlameCounterChange = const Value.absent(), + Value lastMessageExchange = const Value.absent(), Value flameCounter = const Value.absent(), }) => ContactsCompanion( @@ -2696,7 +2768,8 @@ class $$ContactsTableTableManager extends RootTableManager< totalMediaCounter: totalMediaCounter, lastMessageSend: lastMessageSend, lastMessageReceived: lastMessageReceived, - lastMessage: lastMessage, + lastFlameCounterChange: lastFlameCounterChange, + lastMessageExchange: lastMessageExchange, flameCounter: flameCounter, ), createCompanionCallback: ({ @@ -2712,7 +2785,8 @@ class $$ContactsTableTableManager extends RootTableManager< Value totalMediaCounter = const Value.absent(), Value lastMessageSend = const Value.absent(), Value lastMessageReceived = const Value.absent(), - Value lastMessage = const Value.absent(), + Value lastFlameCounterChange = const Value.absent(), + Value lastMessageExchange = const Value.absent(), Value flameCounter = const Value.absent(), }) => ContactsCompanion.insert( @@ -2728,7 +2802,8 @@ class $$ContactsTableTableManager extends RootTableManager< totalMediaCounter: totalMediaCounter, lastMessageSend: lastMessageSend, lastMessageReceived: lastMessageReceived, - lastMessage: lastMessage, + lastFlameCounterChange: lastFlameCounterChange, + lastMessageExchange: lastMessageExchange, flameCounter: flameCounter, ), withReferenceMapper: (p0) => p0 diff --git a/lib/src/views/chats/chat_list_view.dart b/lib/src/views/chats/chat_list_view.dart index 475f4be..c32ca65 100644 --- a/lib/src/views/chats/chat_list_view.dart +++ b/lib/src/views/chats/chat_list_view.dart @@ -212,19 +212,35 @@ class _UserListItem extends State { if (notOpenedMessagesSnapshot.data != null && notOpenedMessagesSnapshot.data!.isNotEmpty) { // filter first for only received messages - lastMessages = notOpenedMessagesSnapshot.data! + var notOpenedMessages = notOpenedMessagesSnapshot.data!; + + lastMessages = notOpenedMessages .where((x) => x.messageOtherId != null) .toList(); - if (lastMessages.isEmpty) { - lastMessages = notOpenedMessagesSnapshot.data!; - } - var media = - lastMessages.where((x) => x.kind == MessageKind.media); - if (media.isNotEmpty) { - currentMessage = media.first; + // For send images show only one + if (lastMessages.isEmpty) { + var media = notOpenedMessages + .where((x) => x.kind == MessageKind.media); + + if (media.isNotEmpty) { + currentMessage = media.first; + lastMessages = [currentMessage!]; + } else { + currentMessage = notOpenedMessages.first; + lastMessages = [currentMessage!]; + } } else { - currentMessage = lastMessages.first; + // there are multiple messages received + + var media = + lastMessages.where((x) => x.kind == MessageKind.media); + + if (media.isNotEmpty) { + currentMessage = media.first; + } else { + currentMessage = lastMessages.first; + } } } else { currentMessage = lastMessage;