From 7fe0f16a5cfde5de611c11c5826a4fba1382d025 Mon Sep 17 00:00:00 2001 From: otsmr Date: Sun, 26 Oct 2025 22:49:36 +0100 Subject: [PATCH] updating profile and minor issues --- lib/src/database/daos/contacts.dao.dart | 10 ++ lib/src/database/tables/messages.table.dart | 3 +- lib/src/database/twonly.db.g.dart | 105 ++---------------- lib/src/localization/app_de.arb | 3 +- lib/src/localization/app_en.arb | 3 +- .../generated/app_localizations.dart | 6 + .../generated/app_localizations_de.dart | 4 + .../generated/app_localizations_en.dart | 3 + lib/src/services/api/messages.dart | 2 + .../contact.server_messages.dart | 26 +++-- lib/src/views/chats/chat_messages.view.dart | 2 +- .../chat_text_entry.dart | 2 +- .../message_send_state_icon.dart | 12 +- .../response_container.dart | 91 ++++++++------- lib/src/views/chats/media_viewer.view.dart | 28 +---- 15 files changed, 124 insertions(+), 176 deletions(-) diff --git a/lib/src/database/daos/contacts.dao.dart b/lib/src/database/daos/contacts.dao.dart index 898297c..126b03d 100644 --- a/lib/src/database/daos/contacts.dao.dart +++ b/lib/src/database/daos/contacts.dao.dart @@ -1,4 +1,5 @@ import 'package:drift/drift.dart'; +import 'package:twonly/globals.dart'; import 'package:twonly/src/database/tables/contacts.table.dart'; import 'package:twonly/src/database/twonly.db.dart'; import 'package:twonly/src/database/twonly_database_old.dart' as old; @@ -45,6 +46,15 @@ class ContactsDao extends DatabaseAccessor with _$ContactsDaoMixin { final contact = await getContactByUserId(userId).getSingleOrNull(); if (contact != null) { await updatePushUser(contact); + final group = await twonlyDB.groupsDao.getDirectChat(userId); + if (group != null) { + await twonlyDB.groupsDao.updateGroup( + group.groupId, + GroupsCompanion( + groupName: Value(getContactDisplayName(contact)), + ), + ); + } } } } diff --git a/lib/src/database/tables/messages.table.dart b/lib/src/database/tables/messages.table.dart index cf18f12..628a720 100644 --- a/lib/src/database/tables/messages.table.dart +++ b/lib/src/database/tables/messages.table.dart @@ -26,8 +26,7 @@ class Messages extends Table { BlobColumn get downloadToken => blob().nullable()(); - TextColumn get quotesMessageId => - text().nullable().references(Messages, #messageId)(); + TextColumn get quotesMessageId => text().nullable()(); BoolColumn get isDeletedFromSender => boolean().withDefault(const Constant(false))(); diff --git a/lib/src/database/twonly.db.g.dart b/lib/src/database/twonly.db.g.dart index 98faa9a..0a501bb 100644 --- a/lib/src/database/twonly.db.g.dart +++ b/lib/src/database/twonly.db.g.dart @@ -2265,10 +2265,7 @@ class $MessagesTable extends Messages with TableInfo<$MessagesTable, Message> { @override late final GeneratedColumn quotesMessageId = GeneratedColumn( 'quotes_message_id', aliasedName, true, - type: DriftSqlType.string, - requiredDuringInsert: false, - defaultConstraints: GeneratedColumn.constraintIsAlways( - 'REFERENCES messages (message_id)')); + type: DriftSqlType.string, requiredDuringInsert: false); static const VerificationMeta _isDeletedFromSenderMeta = const VerificationMeta('isDeletedFromSender'); @override @@ -8207,21 +8204,6 @@ final class $$MessagesTableReferences manager.$state.copyWith(prefetchedData: [item])); } - static $MessagesTable _quotesMessageIdTable(_$TwonlyDB db) => - db.messages.createAlias($_aliasNameGenerator( - db.messages.quotesMessageId, db.messages.messageId)); - - $$MessagesTableProcessedTableManager? get quotesMessageId { - final $_column = $_itemColumn('quotes_message_id'); - if ($_column == null) return null; - final manager = $$MessagesTableTableManager($_db, $_db.messages) - .filter((f) => f.messageId.sqlEquals($_column)); - final item = $_typedResult.readTableOrNull(_quotesMessageIdTable($_db)); - if (item == null) return manager; - return ProcessedTableManager( - manager.$state.copyWith(prefetchedData: [item])); - } - static MultiTypedResultKey<$MessageHistoriesTable, List> _messageHistoriesRefsTable(_$TwonlyDB db) => MultiTypedResultKey.fromTable(db.messageHistories, @@ -8315,6 +8297,10 @@ class $$MessagesTableFilterComposer ColumnFilters get downloadToken => $composableBuilder( column: $table.downloadToken, builder: (column) => ColumnFilters(column)); + ColumnFilters get quotesMessageId => $composableBuilder( + column: $table.quotesMessageId, + builder: (column) => ColumnFilters(column)); + ColumnFilters get isDeletedFromSender => $composableBuilder( column: $table.isDeletedFromSender, builder: (column) => ColumnFilters(column)); @@ -8394,26 +8380,6 @@ class $$MessagesTableFilterComposer return composer; } - $$MessagesTableFilterComposer get quotesMessageId { - final $$MessagesTableFilterComposer composer = $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.quotesMessageId, - referencedTable: $db.messages, - getReferencedColumn: (t) => t.messageId, - builder: (joinBuilder, - {$addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer}) => - $$MessagesTableFilterComposer( - $db: $db, - $table: $db.messages, - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - )); - return composer; - } - Expression messageHistoriesRefs( Expression Function($$MessageHistoriesTableFilterComposer f) f) { final $$MessageHistoriesTableFilterComposer composer = $composerBuilder( @@ -8524,6 +8490,10 @@ class $$MessagesTableOrderingComposer column: $table.downloadToken, builder: (column) => ColumnOrderings(column)); + ColumnOrderings get quotesMessageId => $composableBuilder( + column: $table.quotesMessageId, + builder: (column) => ColumnOrderings(column)); + ColumnOrderings get isDeletedFromSender => $composableBuilder( column: $table.isDeletedFromSender, builder: (column) => ColumnOrderings(column)); @@ -8602,26 +8572,6 @@ class $$MessagesTableOrderingComposer )); return composer; } - - $$MessagesTableOrderingComposer get quotesMessageId { - final $$MessagesTableOrderingComposer composer = $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.quotesMessageId, - referencedTable: $db.messages, - getReferencedColumn: (t) => t.messageId, - builder: (joinBuilder, - {$addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer}) => - $$MessagesTableOrderingComposer( - $db: $db, - $table: $db.messages, - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - )); - return composer; - } } class $$MessagesTableAnnotationComposer @@ -8648,6 +8598,9 @@ class $$MessagesTableAnnotationComposer GeneratedColumn get downloadToken => $composableBuilder( column: $table.downloadToken, builder: (column) => column); + GeneratedColumn get quotesMessageId => $composableBuilder( + column: $table.quotesMessageId, builder: (column) => column); + GeneratedColumn get isDeletedFromSender => $composableBuilder( column: $table.isDeletedFromSender, builder: (column) => column); @@ -8726,26 +8679,6 @@ class $$MessagesTableAnnotationComposer return composer; } - $$MessagesTableAnnotationComposer get quotesMessageId { - final $$MessagesTableAnnotationComposer composer = $composerBuilder( - composer: this, - getCurrentColumn: (t) => t.quotesMessageId, - referencedTable: $db.messages, - getReferencedColumn: (t) => t.messageId, - builder: (joinBuilder, - {$addJoinBuilderToRootComposer, - $removeJoinBuilderFromRootComposer}) => - $$MessagesTableAnnotationComposer( - $db: $db, - $table: $db.messages, - $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer, - joinBuilder: joinBuilder, - $removeJoinBuilderFromRootComposer: - $removeJoinBuilderFromRootComposer, - )); - return composer; - } - Expression messageHistoriesRefs( Expression Function($$MessageHistoriesTableAnnotationComposer a) f) { final $$MessageHistoriesTableAnnotationComposer composer = $composerBuilder( @@ -8846,7 +8779,6 @@ class $$MessagesTableTableManager extends RootTableManager< {bool groupId, bool senderId, bool mediaId, - bool quotesMessageId, bool messageHistoriesRefs, bool reactionsRefs, bool receiptsRefs, @@ -8941,7 +8873,6 @@ class $$MessagesTableTableManager extends RootTableManager< {groupId = false, senderId = false, mediaId = false, - quotesMessageId = false, messageHistoriesRefs = false, reactionsRefs = false, receiptsRefs = false, @@ -8997,17 +8928,6 @@ class $$MessagesTableTableManager extends RootTableManager< $$MessagesTableReferences._mediaIdTable(db).mediaId, ) as T; } - if (quotesMessageId) { - state = state.withJoin( - currentTable: table, - currentColumn: table.quotesMessageId, - referencedTable: - $$MessagesTableReferences._quotesMessageIdTable(db), - referencedColumn: $$MessagesTableReferences - ._quotesMessageIdTable(db) - .messageId, - ) as T; - } return state; }, @@ -9086,7 +9006,6 @@ typedef $$MessagesTableProcessedTableManager = ProcessedTableManager< {bool groupId, bool senderId, bool mediaId, - bool quotesMessageId, bool messageHistoriesRefs, bool reactionsRefs, bool receiptsRefs, diff --git a/lib/src/localization/app_de.arb b/lib/src/localization/app_de.arb index 42bfe7e..f721f6a 100644 --- a/lib/src/localization/app_de.arb +++ b/lib/src/localization/app_de.arb @@ -341,5 +341,6 @@ "reportUserReason": "Meldegrund", "reportUser": "Benutzer melden", "newDeviceRegistered": "Du hast dich auf einem anderen Gerät angemeldet. Daher wurdest du hier abgemeldet.", - "tabToRemoveEmoji": "Tippen um zu entfernen" + "tabToRemoveEmoji": "Tippen um zu entfernen", + "quotedMessageWasDeleted": "Die zitierte Nachricht wurde gelöscht." } \ No newline at end of file diff --git a/lib/src/localization/app_en.arb b/lib/src/localization/app_en.arb index 68a6418..9d1c04d 100644 --- a/lib/src/localization/app_en.arb +++ b/lib/src/localization/app_en.arb @@ -497,5 +497,6 @@ "reportUserReason": "Reporting reason", "reportUser": "Report user", "newDeviceRegistered": "You have logged in on another device. You have therefore been logged out here.", - "tabToRemoveEmoji": "Tab to remove" + "tabToRemoveEmoji": "Tab to remove", + "quotedMessageWasDeleted": "The quoted message has been deleted." } \ No newline at end of file diff --git a/lib/src/localization/generated/app_localizations.dart b/lib/src/localization/generated/app_localizations.dart index b1a8873..9191830 100644 --- a/lib/src/localization/generated/app_localizations.dart +++ b/lib/src/localization/generated/app_localizations.dart @@ -2089,6 +2089,12 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Tab to remove'** String get tabToRemoveEmoji; + + /// No description provided for @quotedMessageWasDeleted. + /// + /// In en, this message translates to: + /// **'The quoted message has been deleted.'** + String get quotedMessageWasDeleted; } class _AppLocalizationsDelegate diff --git a/lib/src/localization/generated/app_localizations_de.dart b/lib/src/localization/generated/app_localizations_de.dart index 9b14157..614afb5 100644 --- a/lib/src/localization/generated/app_localizations_de.dart +++ b/lib/src/localization/generated/app_localizations_de.dart @@ -1109,4 +1109,8 @@ class AppLocalizationsDe extends AppLocalizations { @override String get tabToRemoveEmoji => 'Tippen um zu entfernen'; + + @override + String get quotedMessageWasDeleted => + 'Die zitierte Nachricht wurde gelöscht.'; } diff --git a/lib/src/localization/generated/app_localizations_en.dart b/lib/src/localization/generated/app_localizations_en.dart index 56a5f19..523ae87 100644 --- a/lib/src/localization/generated/app_localizations_en.dart +++ b/lib/src/localization/generated/app_localizations_en.dart @@ -1103,4 +1103,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get tabToRemoveEmoji => 'Tab to remove'; + + @override + String get quotedMessageWasDeleted => 'The quoted message has been deleted.'; } diff --git a/lib/src/services/api/messages.dart b/lib/src/services/api/messages.dart index 8c3408c..31cc9ee 100644 --- a/lib/src/services/api/messages.dart +++ b/lib/src/services/api/messages.dart @@ -214,6 +214,8 @@ Future<(Uint8List, Uint8List?)?> sendCipherText( bool onlyReturnEncryptedData = false, String? messageId, }) async { + encryptedContent.senderProfileCounter = Int64(gUser.avatarCounter); + final response = pb.Message() ..type = pb.Message_Type.CIPHERTEXT ..encryptedContent = encryptedContent.writeToBuffer(); diff --git a/lib/src/services/api/server_messages/contact.server_messages.dart b/lib/src/services/api/server_messages/contact.server_messages.dart index 2b3519e..fc96a85 100644 --- a/lib/src/services/api/server_messages/contact.server_messages.dart +++ b/lib/src/services/api/server_messages/contact.server_messages.dart @@ -106,19 +106,21 @@ Future checkForProfileUpdate( ) async { int? senderProfileCounter; - if (content.hasSenderProfileCounter() && !content.hasContactUpdate()) { + if (content.hasSenderProfileCounter()) { senderProfileCounter = content.senderProfileCounter.toInt(); - final contact = await twonlyDB.contactsDao - .getContactByUserId(fromUserId) - .getSingleOrNull(); - if (contact != null) { - if (contact.senderProfileCounter < senderProfileCounter) { - await sendCipherText( - fromUserId, - EncryptedContent() - ..contactUpdate = (EncryptedContent_ContactUpdate() - ..type = EncryptedContent_ContactUpdate_Type.REQUEST), - ); + if (!content.hasContactUpdate()) { + final contact = await twonlyDB.contactsDao + .getContactByUserId(fromUserId) + .getSingleOrNull(); + if (contact != null) { + if (contact.senderProfileCounter < senderProfileCounter) { + await sendCipherText( + fromUserId, + EncryptedContent() + ..contactUpdate = (EncryptedContent_ContactUpdate() + ..type = EncryptedContent_ContactUpdate_Type.REQUEST), + ); + } } } } diff --git a/lib/src/views/chats/chat_messages.view.dart b/lib/src/views/chats/chat_messages.view.dart index 63f236a..6d6ef42 100644 --- a/lib/src/views/chats/chat_messages.view.dart +++ b/lib/src/views/chats/chat_messages.view.dart @@ -277,7 +277,7 @@ class _ChatMessagesViewState extends State { return Transform.translate( offset: Offset( (focusedScrollItem == i) - ? (chatMessage.quotesMessageId == null) + ? (chatMessage.senderId == null) ? -8 : 8 : 0, 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 a09450d..3154ce2 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 @@ -57,7 +57,7 @@ class ChatTextEntry extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ - if (measureTextWidth(text) > 270) + if (measureTextWidth(text) > 270 || message.quotesMessageId != null) Expanded( child: BetterText(text: text), ) diff --git a/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart b/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart index 2354fd0..2cfe578 100644 --- a/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart +++ b/lib/src/views/chats/chat_messages_components/message_send_state_icon.dart @@ -76,12 +76,14 @@ class _MessageSendStateIconState extends State { @override Widget build(BuildContext context) { - final icons = []; + var icons = []; var text = ''; Widget? textWidget; textWidget = null; final kindsAlreadyShown = HashSet(); + var hasLoader = false; + for (final message in widget.messages) { if (icons.length == 2) break; if (kindsAlreadyShown.contains(message.type)) continue; @@ -130,6 +132,7 @@ class _MessageSendStateIconState extends State { if (mediaFile.downloadState == DownloadState.downloading) { text = context.lang.messageSendState_Loading; icon = getLoaderIcon(color); + hasLoader = true; } } case MessageSendState.send: @@ -139,9 +142,11 @@ class _MessageSendStateIconState extends State { case MessageSendState.sending: icon = getLoaderIcon(color); text = context.lang.messageSendState_Sending; + hasLoader = true; case MessageSendState.receiving: icon = getLoaderIcon(color); text = context.lang.messageSendState_Received; + hasLoader = true; } if (message.mediaStored) { @@ -165,6 +170,11 @@ class _MessageSendStateIconState extends State { } } + if (hasLoader) { + icons = [icon]; + break; + } + if (message.type == MessageType.media) { icons.insert(0, icon); } else { diff --git a/lib/src/views/chats/chat_messages_components/response_container.dart b/lib/src/views/chats/chat_messages_components/response_container.dart index ca4b9bb..4752b89 100644 --- a/lib/src/views/chats/chat_messages_components/response_container.dart +++ b/lib/src/views/chats/chat_messages_components/response_container.dart @@ -150,53 +150,58 @@ class _ResponsePreviewState extends State { @override Widget build(BuildContext context) { - if (message == null) return Container(); String? subtitle; + var color = const Color.fromARGB(233, 68, 137, 255); + var username = ''; - if (message!.type == MessageType.text) { - if (message!.content != null) { - subtitle = truncateString(message!.content!); + if (message != null) { + if (message!.type == MessageType.text) { + if (message!.content != null) { + subtitle = truncateString(message!.content!); + } + } + if (message!.type == MessageType.media && mediaService != null) { + subtitle = mediaService!.mediaFile.type == MediaType.video + ? context.lang.video + : context.lang.image; } - } - if (message!.type == MessageType.media && mediaService != null) { - subtitle = mediaService!.mediaFile.type == MediaType.video - ? context.lang.video - : context.lang.image; - } - var username = context.lang.you; - if (message!.senderId != null) { - username = message!.senderId.toString(); - } + username = context.lang.you; + if (message!.senderId != null) { + username = message!.senderId.toString(); + } - final color = getMessageColor(message!); + color = getMessageColor(message!); - if (!message!.mediaStored) { - return Container( - padding: widget.showBorder - ? const EdgeInsets.only(left: 10, right: 10) - : const EdgeInsets.symmetric(horizontal: 5), - decoration: (widget.showBorder) - ? BoxDecoration( - border: Border( - left: BorderSide( - color: color, - width: 2, + if (!message!.mediaStored) { + return Container( + padding: widget.showBorder + ? const EdgeInsets.only(left: 10, right: 10) + : const EdgeInsets.symmetric(horizontal: 5), + decoration: (widget.showBorder) + ? BoxDecoration( + border: Border( + left: BorderSide( + color: color, + width: 2, + ), ), - ), - ) - : null, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - username, - style: const TextStyle(fontWeight: FontWeight.bold), - ), - if (subtitle != null) Text(subtitle), - ], - ), - ); + ) + : null, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + username, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + if (subtitle != null) Text(subtitle), + ], + ), + ); + } + } else { + username = context.lang.quotedMessageWasDeleted; } return Container( @@ -227,7 +232,11 @@ class _ResponsePreviewState extends State { if (mediaService != null) SizedBox( height: widget.showBorder ? 100 : 210, - child: Image.file(mediaService!.thumbnailPath), + child: Image.file( + mediaService!.mediaFile.type == MediaType.video + ? mediaService!.thumbnailPath + : mediaService!.storedPath, + ), ), ], ), diff --git a/lib/src/views/chats/media_viewer.view.dart b/lib/src/views/chats/media_viewer.view.dart index 626ea9b..e1ad7dc 100644 --- a/lib/src/views/chats/media_viewer.view.dart +++ b/lib/src/views/chats/media_viewer.view.dart @@ -469,27 +469,6 @@ class _MediaViewerViewState extends State { child: Image.file( currentMedia!.tempPath, fit: BoxFit.contain, - frameBuilder: ( - context, - child, - frame, - wasSynchronouslyLoaded, - ) { - if (wasSynchronouslyLoaded) return child; - return AnimatedSwitcher( - duration: const Duration(milliseconds: 200), - child: frame != null - ? child - : Container( - height: 60, - color: Colors.transparent, - width: 60, - child: const CircularProgressIndicator( - strokeWidth: 2, - ), - ), - ); - }, ), ), ], @@ -534,13 +513,16 @@ class _MediaViewerViewState extends State { ], ), ), - if (currentMedia?.mediaFile.downloadState != DownloadState.ready) + if (currentMedia != null && + currentMedia?.mediaFile.downloadState != DownloadState.ready) const Positioned.fill( child: Center( child: SizedBox( height: 60, width: 60, - child: CircularProgressIndicator(strokeWidth: 6), + child: CircularProgressIndicator( + strokeWidth: 6, + ), ), ), ),