diff --git a/assets/translations/en.json b/assets/translations/en.json index 2ab46a6..fc6af7b 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -165,5 +165,11 @@ "messageDeleteDescription": "Are you sure you want to delete this message? This operation is irreversible. You will leave a record of the deleted message.", "messageDeleted": "Message {} has been deleted", "messageEdited": "Message {} has been edited", - "messageEditedHint": "Edited" + "messageEditedHint": "Edited", + "messageUnsupported": "Unsupported message {}", + "messageFileHint": { + "zero": "No attachments", + "one": "{} attachment", + "other": "{} attachments" + } } diff --git a/assets/translations/zh.json b/assets/translations/zh.json index b0b133e..e8af7ec 100644 --- a/assets/translations/zh.json +++ b/assets/translations/zh.json @@ -165,5 +165,11 @@ "messageDeleteDescription": "你确定要删除这个消息吗?该操作不可撤销。同时您将留下一条删除消息的记录。", "messageDeleted": "消息 {} 已被删除", "messageEdited": "消息 {} 已被编辑", - "messageEditedHint": "已编辑" + "messageEditedHint": "已编辑", + "messageUnsupported": "不支持的消息 {}", + "messageFileHint": { + "zero": "没有附件", + "one": "{} 个附件", + "other": "{} 个附件" + } } diff --git a/lib/widgets/chat/chat_message.dart b/lib/widgets/chat/chat_message.dart index ae24e52..09d771f 100644 --- a/lib/widgets/chat/chat_message.dart +++ b/lib/widgets/chat/chat_message.dart @@ -146,33 +146,10 @@ class ChatMessage extends StatelessWidget { onDelete: onDelete, ), )).padding(bottom: 4, top: isMerged ? 4 : 2), - if (data.type == 'messages.edit') - Row( - children: [ - const Icon(Symbols.edit, size: 20), - const Gap(4), - Text( - 'messageEdited' - .tr(args: ['#${data.relatedEventId}']), - ), - ], - ).opacity(0.75) - else if (data.body['text'] != null) - MarkdownTextContent( - content: data.body['text'], - isAutoWarp: true, - ), - if (data.type == 'messages.delete') - Row( - children: [ - const Icon(Symbols.delete, size: 20), - const Gap(4), - Text( - 'messageDeleted' - .tr(args: ['#${data.relatedEventId}']), - ), - ], - ).opacity(0.75), + switch (data.type) { + 'messages.new' => _ChatMessageText(data: data), + _ => _ChatMessageSystemNotify(data: data), + }, ], ), ) @@ -193,3 +170,71 @@ class ChatMessage extends StatelessWidget { ); } } + +class _ChatMessageText extends StatelessWidget { + final SnChatMessage data; + const _ChatMessageText({super.key, required this.data}); + + @override + Widget build(BuildContext context) { + if (data.body['text'] != null && data.body['text'].isNotEmpty) { + return MarkdownTextContent( + content: data.body['text'], + isAutoWarp: true, + ); + } else if (data.body['attachments']?.isNotEmpty) { + return Row( + children: [ + const Icon(Symbols.file_present, size: 20), + const Gap(4), + Text( + 'messageFileHint'.plural( + data.body['attachments']!.length, + ), + ), + ], + ).opacity(0.75); + } + + return const SizedBox.shrink(); + } +} + +class _ChatMessageSystemNotify extends StatelessWidget { + final SnChatMessage data; + const _ChatMessageSystemNotify({super.key, required this.data}); + + @override + Widget build(BuildContext context) { + switch (data.type) { + case 'messages.edit': + return Row( + children: [ + const Icon(Symbols.edit, size: 20), + const Gap(4), + Text( + 'messageEdited'.tr(args: ['#${data.relatedEventId}']), + ), + ], + ).opacity(0.75); + case 'messages.delete': + return Row( + children: [ + const Icon(Symbols.delete, size: 20), + const Gap(4), + Text( + 'messageDeleted'.tr(args: ['#${data.relatedEventId}']), + ), + ], + ).opacity(0.75); + default: + return Row( + children: [ + const Icon(Symbols.info, size: 20), + const Gap(4), + Text('messageUnsupported'.tr(args: [data.type])), + ], + ).opacity(0.75); + } + } +}