From ce6e9c185aeb7151930234828236a2bec2ca9fe0 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Tue, 4 Mar 2025 21:32:20 +0800 Subject: [PATCH] :recycle: Refactor channel list :lipstick: Stop previewing encrypted message raw message --- assets/translations/en-US.json | 4 +- assets/translations/zh-CN.json | 4 +- assets/translations/zh-HK.json | 4 +- assets/translations/zh-TW.json | 4 +- lib/screens/chat.dart | 241 ++++++++++++++------------------- 5 files changed, 114 insertions(+), 143 deletions(-) diff --git a/assets/translations/en-US.json b/assets/translations/en-US.json index fdf6e86..fb3e6ef 100644 --- a/assets/translations/en-US.json +++ b/assets/translations/en-US.json @@ -761,5 +761,7 @@ "enrollNewKeyPairDescription": "Generate a new key pair.", "keyPairHasPrivateKey": "With private key", "decrypting": "Decrypting……", - "decryptingKeyNotFound": "Key not found or exchange failed, the other party may not be online" + "decryptingKeyNotFound": "Key not found or exchange failed, the other party may not be online", + "messageUnablePreview": "Unable preview", + "messageUnablePreviewEncrypted": "Unable preview encrypted message" } diff --git a/assets/translations/zh-CN.json b/assets/translations/zh-CN.json index b1160ad..3275ab8 100644 --- a/assets/translations/zh-CN.json +++ b/assets/translations/zh-CN.json @@ -759,5 +759,7 @@ "enrollNewKeyPairDescription": "生成一对新密钥对。", "keyPairHasPrivateKey": "有私钥", "decrypting": "解密中……", - "decryptingKeyNotFound": "未找到密钥对或交换失败,对方可能不在线" + "decryptingKeyNotFound": "未找到密钥对或交换失败,对方可能不在线", + "messageUnablePreview": "无法预览消息", + "messageUnablePreviewEncrypted": "无法预览加密消息" } diff --git a/assets/translations/zh-HK.json b/assets/translations/zh-HK.json index d1ce236..2ed18a3 100644 --- a/assets/translations/zh-HK.json +++ b/assets/translations/zh-HK.json @@ -759,5 +759,7 @@ "enrollNewKeyPairDescription": "生成一對新密鑰對。", "keyPairHasPrivateKey": "有私鑰", "decrypting": "解密中……", - "decryptingKeyNotFound": "未找到密鑰對或交換失敗,對方可能不在線" + "decryptingKeyNotFound": "未找到密鑰對或交換失敗,對方可能不在線", + "messageUnablePreview": "無法預覽消息", + "messageUnablePreviewEncrypted": "無法預覽加密消息" } diff --git a/assets/translations/zh-TW.json b/assets/translations/zh-TW.json index de46854..1960c99 100644 --- a/assets/translations/zh-TW.json +++ b/assets/translations/zh-TW.json @@ -759,5 +759,7 @@ "enrollNewKeyPairDescription": "生成一對新密鑰對。", "keyPairHasPrivateKey": "有私鑰", "decrypting": "解密中……", - "decryptingKeyNotFound": "未找到密鑰對或交換失敗,對方可能不在線" + "decryptingKeyNotFound": "未找到密鑰對或交換失敗,對方可能不在線", + "messageUnablePreview": "無法預覽消息", + "messageUnablePreviewEncrypted": "無法預覽加密消息" } diff --git a/lib/screens/chat.dart b/lib/screens/chat.dart index ee718e6..3aa8ca1 100644 --- a/lib/screens/chat.dart +++ b/lib/screens/chat.dart @@ -163,7 +163,6 @@ class _ChatScreenState extends State { @override Widget build(BuildContext context) { - final ud = context.read(); final ua = context.read(); if (!ua.isAuthorized) { @@ -266,144 +265,10 @@ class _ChatScreenState extends State { final channel = _channels![idx]; final lastMessage = _lastMessages?[channel.id]; - if (channel.type == 1) { - final otherMember = - channel.members?.cast().firstWhere( - (ele) => ele?.accountId != ua.user?.id, - orElse: () => null, - ); - - return ListTile( - title: Row( - children: [ - Expanded( - child: Text(ud - .getAccountFromCache( - otherMember?.accountId) - ?.nick ?? - channel.name), - ), - const Gap(8), - if (_unreadCounts?[channel.id] != null && - _unreadCounts![channel.id]! > 0) - Badge( - label: Text('${_unreadCounts![channel.id]}'), - ), - ], - ), - subtitle: lastMessage != null - ? Row( - children: [ - Expanded( - child: Text( - lastMessage.body['text'] ?? - 'Unable preview', - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), - const Gap(4), - Text( - DateFormat( - lastMessage.createdAt.toLocal().day == - DateTime.now().day - ? 'HH:mm' - : lastMessage.createdAt - .toLocal() - .year == - DateTime.now().year - ? 'MM/dd' - : 'yy/MM/dd', - ).format(lastMessage.createdAt.toLocal()), - style: GoogleFonts.robotoMono( - fontSize: 12, - ), - ), - ], - ) - : Text( - channel.description, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - contentPadding: - const EdgeInsets.symmetric(horizontal: 16), - leading: AccountImage( - content: ud - .getAccountFromCache(otherMember?.accountId) - ?.avatar, - ), - onTap: () { - _onTapChannel(channel); - }, - ); - } - - return ListTile( - title: Row( - children: [ - Expanded(child: Text(channel.name)), - const Gap(8), - if (_unreadCounts?[channel.id] != null && - _unreadCounts![channel.id]! > 0) - Badge( - label: Text('${_unreadCounts![channel.id]}'), - ), - ], - ), - subtitle: lastMessage != null - ? Row( - children: [ - Badge( - label: Text(ud - .getAccountFromCache( - lastMessage.sender.accountId) - ?.nick ?? - 'unknown'.tr()), - backgroundColor: - Theme.of(context).colorScheme.primary, - textColor: - Theme.of(context).colorScheme.onPrimary, - ), - const Gap(6), - Expanded( - child: Text( - lastMessage.body['text'] ?? - 'Unable preview', - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ), - const Gap(4), - Text( - DateFormat( - lastMessage.createdAt.toLocal().day == - DateTime.now().day - ? 'HH:mm' - : lastMessage.createdAt - .toLocal() - .year == - DateTime.now().year - ? 'MM/dd' - : 'yy/MM/dd', - ).format(lastMessage.createdAt.toLocal()), - style: GoogleFonts.robotoMono( - fontSize: 12, - ), - ), - ], - ) - : Text( - channel.description, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - contentPadding: - const EdgeInsets.symmetric(horizontal: 16), - leading: AccountImage( - content: channel.realm?.avatar, - fallbackWidget: const Icon(Symbols.chat, size: 20), - ), + return _ChatChannelEntry( + channel: channel, + lastMessage: lastMessage, + unreadCount: _unreadCounts?[channel.id], onTap: () { if (doExpand) { _unreadCounts?[channel.id] = 0; @@ -445,3 +310,101 @@ class _ChatScreenState extends State { return chatList; } } + +class _ChatChannelEntry extends StatelessWidget { + final SnChannel channel; + final int? unreadCount; + final SnChatMessage? lastMessage; + final Function? onTap; + const _ChatChannelEntry({ + required this.channel, + this.unreadCount, + this.lastMessage, + this.onTap, + }); + + @override + Widget build(BuildContext context) { + final ud = context.read(); + final ua = context.read(); + + final otherMember = channel.type == 1 + ? channel.members?.cast().firstWhere( + (ele) => ele?.accountId != ua.user?.id, + orElse: () => null, + ) + : null; + + final title = otherMember != null + ? ud.getAccountFromCache(otherMember.accountId)?.nick ?? channel.name + : channel.name; + + return ListTile( + title: Row( + children: [ + Expanded(child: Text(title)), + const Gap(8), + if (unreadCount != null && unreadCount! > 0) + Badge( + label: Text(unreadCount.toString()), + ), + ], + ), + subtitle: lastMessage != null + ? Row( + children: [ + Badge( + label: Text(ud + .getAccountFromCache(lastMessage!.sender.accountId) + ?.nick ?? + 'unknown'.tr()), + backgroundColor: Theme.of(context).colorScheme.primary, + textColor: Theme.of(context).colorScheme.onPrimary, + ), + const Gap(6), + Expanded( + child: Text( + lastMessage!.body['algorithm'] == 'plain' + ? lastMessage!.body['text'] ?? + 'messageUnablePreview'.tr() + : 'messageUnablePreviewEncrypted'.tr(), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: lastMessage!.body['algorithm'] != 'plain' || + lastMessage!.body['text'] == null + ? TextStyle(fontStyle: FontStyle.italic) + : null, + ), + ), + const Gap(4), + Text( + DateFormat( + lastMessage!.createdAt.toLocal().day == DateTime.now().day + ? 'HH:mm' + : lastMessage!.createdAt.toLocal().year == + DateTime.now().year + ? 'MM/dd' + : 'yy/MM/dd', + ).format(lastMessage!.createdAt.toLocal()), + style: GoogleFonts.robotoMono( + fontSize: 12, + ), + ), + ], + ) + : Text( + channel.description, + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + contentPadding: const EdgeInsets.symmetric(horizontal: 16), + leading: AccountImage( + content: otherMember != null + ? ud.getAccountFromCache(otherMember.accountId)?.avatar + : channel.realm?.avatar, + fallbackWidget: const Icon(Symbols.chat, size: 20), + ), + onTap: () => onTap?.call(), + ); + } +}