From 84c38500d074beef137e701877e66789184415ad Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Tue, 23 Sep 2025 15:20:45 +0800 Subject: [PATCH] :sparkles: Edited message diff --- lib/database/drift_db.dart | 12 +++++++++ lib/database/message.dart | 40 +++++++++++++++++++++++++++--- lib/screens/chat/room.dart | 2 +- lib/screens/chat/room.g.dart | 2 +- lib/widgets/chat/message_item.dart | 37 +++++++++++++++++++++------ pubspec.lock | 16 ++++++++++++ pubspec.yaml | 1 + 7 files changed, 96 insertions(+), 14 deletions(-) diff --git a/lib/database/drift_db.dart b/lib/database/drift_db.dart index 2316aff8..ce3aaa38 100644 --- a/lib/database/drift_db.dart +++ b/lib/database/drift_db.dart @@ -206,6 +206,18 @@ class AppDatabase extends _$AppDatabase { createdAt: dbMessage.createdAt, status: dbMessage.status, nonce: dbMessage.nonce, + content: dbMessage.content, + isDeleted: dbMessage.isDeleted, + updatedAt: dbMessage.updatedAt, + deletedAt: dbMessage.deletedAt, + type: dbMessage.type, + meta: dbMessage.meta, + membersMentioned: dbMessage.membersMentioned, + editedAt: dbMessage.editedAt, + attachments: dbMessage.attachments, + reactions: dbMessage.reactions, + repliedMessageId: dbMessage.repliedMessageId, + forwardedMessageId: dbMessage.forwardedMessageId, ); } diff --git a/lib/database/message.dart b/lib/database/message.dart index 1be3457d..b3fa5efa 100644 --- a/lib/database/message.dart +++ b/lib/database/message.dart @@ -76,8 +76,19 @@ class LocalChatMessage { final DateTime createdAt; MessageStatus status; final String? nonce; + final String? content; + final bool? isDeleted; + final DateTime? updatedAt; + final DateTime? deletedAt; + final String type; + final Map meta; + final List membersMentioned; + final DateTime? editedAt; + final List> attachments; + final List> reactions; + final String? repliedMessageId; + final String? forwardedMessageId; List? localAttachments; - bool isRead; LocalChatMessage({ required this.id, @@ -87,8 +98,19 @@ class LocalChatMessage { required this.createdAt, required this.nonce, required this.status, + this.content, + this.isDeleted, + this.updatedAt, + this.deletedAt, + required this.type, + required this.meta, + required this.membersMentioned, + this.editedAt, + required this.attachments, + required this.reactions, + this.repliedMessageId, + this.forwardedMessageId, this.localAttachments, - this.isRead = false, }); SnChatMessage toRemoteMessage() { @@ -99,7 +121,6 @@ class LocalChatMessage { SnChatMessage message, MessageStatus status, { String? nonce, - bool isRead = false, }) { return LocalChatMessage( id: message.id, @@ -109,7 +130,18 @@ class LocalChatMessage { createdAt: message.createdAt, status: status, nonce: nonce ?? message.nonce, - isRead: isRead, + content: message.content, + isDeleted: false, + updatedAt: message.updatedAt, + deletedAt: null, + type: message.type, + meta: message.meta, + membersMentioned: message.membersMentioned, + editedAt: message.editedAt, + attachments: message.attachments.map((e) => e.toJson()).toList(), + reactions: message.reactions.map((e) => e.toJson()).toList(), + repliedMessageId: message.repliedMessageId, + forwardedMessageId: message.forwardedMessageId, ); } } diff --git a/lib/screens/chat/room.dart b/lib/screens/chat/room.dart index f4446a76..411d61f8 100644 --- a/lib/screens/chat/room.dart +++ b/lib/screens/chat/room.dart @@ -904,7 +904,7 @@ class MessagesNotifier extends _$MessagesNotifier { final remote = messageToUpdate.toRemoteMessage(); final updatedRemote = remote.copyWith( content: 'This message was deleted', - type: 'deleted', + deletedAt: DateTime.now(), attachments: [], ); diff --git a/lib/screens/chat/room.g.dart b/lib/screens/chat/room.g.dart index 03277c06..937c3647 100644 --- a/lib/screens/chat/room.g.dart +++ b/lib/screens/chat/room.g.dart @@ -6,7 +6,7 @@ part of 'room.dart'; // RiverpodGenerator // ************************************************************************** -String _$messagesNotifierHash() => r'ebbbc77a74b7130ca5885aaaa06478888cb50262'; +String _$messagesNotifierHash() => r'196fe42438c716b2f975f5f14733974174b3dde7'; /// Copied from Dart SDK class _SystemHash { diff --git a/lib/widgets/chat/message_item.dart b/lib/widgets/chat/message_item.dart index 29b323a6..94df7a53 100644 --- a/lib/widgets/chat/message_item.dart +++ b/lib/widgets/chat/message_item.dart @@ -24,6 +24,7 @@ import 'package:island/widgets/content/cloud_files.dart'; import 'package:island/widgets/content/embed/link.dart'; import 'package:island/widgets/content/markdown.dart'; import 'package:material_symbols_icons/material_symbols_icons.dart'; +import 'package:pretty_diff_text/pretty_diff_text.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:super_context_menu/super_context_menu.dart'; @@ -566,18 +567,38 @@ class _MessageItemContent extends StatelessWidget { ).colorScheme.onSurfaceVariant.withOpacity(0.6), ), const Gap(4), - Text( - item.content ?? 'Edited a message', - style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of( + if (item.meta['previous_content'] is String) + PrettyDiffText( + oldText: item.meta['previous_content'], + newText: item.content ?? 'Edited a message', + defaultTextStyle: Theme.of( context, - ).colorScheme.onSurfaceVariant.withOpacity(0.6), - fontStyle: FontStyle.italic, + ).textTheme.bodySmall!.copyWith( + color: Theme.of(context).colorScheme.onSurfaceVariant, + ), + addedTextStyle: TextStyle( + backgroundColor: Theme.of( + context, + ).colorScheme.primaryFixedDim.withOpacity(0.4), + ), + deletedTextStyle: TextStyle( + decoration: TextDecoration.lineThrough, + color: Theme.of( + context, + ).colorScheme.onSurfaceVariant.withOpacity(0.7), + ), + ) + else + Text( + item.content ?? 'Edited a message', + style: Theme.of(context).textTheme.bodySmall?.copyWith( + color: Theme.of( + context, + ).colorScheme.onSurfaceVariant.withOpacity(0.6), + ), ), - ), ], ); - case 'deleted': // Client side history // TODO add seprate is_deleted column to indicate it case 'messages.delete': return Row( mainAxisSize: MainAxisSize.min, diff --git a/pubspec.lock b/pubspec.lock index a0e8cc15..7b92515a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -449,6 +449,14 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.3" + diff_match_patch: + dependency: transitive + description: + name: diff_match_patch + sha256: "2efc9e6e8f449d0abe15be240e2c2a3bcd977c8d126cfd70598aee60af35c0a4" + url: "https://pub.dev" + source: hosted + version: "0.4.1" dio: dependency: "direct main" description: @@ -1885,6 +1893,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.3" + pretty_diff_text: + dependency: "direct main" + description: + name: pretty_diff_text + sha256: "2d4decf2bb6dac14c4e7a2cbd2da9ae7e004ccadc1155c723a0ca20a5daa7c57" + url: "https://pub.dev" + source: hosted + version: "2.1.0" process_run: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index f312e4ea..bf35f491 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -152,6 +152,7 @@ dependencies: win32: ^5.14.0 ffi: ^2.1.4 dart_ipc: ^1.0.1 + pretty_diff_text: ^2.1.0 dev_dependencies: flutter_test: