diff --git a/lib/controllers/chat_message_controller.dart b/lib/controllers/chat_message_controller.dart index 471f877..6e209d7 100644 --- a/lib/controllers/chat_message_controller.dart +++ b/lib/controllers/chat_message_controller.dart @@ -279,7 +279,7 @@ class ChatMessageController extends ChangeNotifier { }) async { late List out; if (_box != null && (_box!.length >= take + offset || forceLocal)) { - out = _box!.values.skip(offset).take(take).toList(); + out = _box!.values.skip(offset).take(take).toList().reversed.toList(); } else { final resp = await _sn.client.get( '/cgi/im/channels/${channel!.keyPath}/events', @@ -300,18 +300,18 @@ class ChatMessageController extends ChangeNotifier { out.expand((e) => (e.body['attachments'] as List?) ?? []), ); final attachments = await _attach.getMultiple(attachmentRid); - out = out.reversed - .map((ele) => ele.copyWith( - preload: SnChatMessagePreload( - attachments: attachments - .where((e) => - (ele.body['attachments'] as List?) - ?.contains(e) ?? - false) - .toList(), - ), - )) - .toList(); + for (var i = 0; i < out.length; i++) { + out[i] = out[i].copyWith( + preload: SnChatMessagePreload( + attachments: attachments + .where( + (ele) => + out[i].body['attachments']?.contains(ele?.rid) ?? false, + ) + .toList(), + ), + ); + } // Preload sender accounts await _ud.listAccount(out.map((ele) => ele.sender.accountId).toSet()); diff --git a/lib/widgets/attachment/attachment_list.dart b/lib/widgets/attachment/attachment_list.dart index 6015ab3..0c6605c 100644 --- a/lib/widgets/attachment/attachment_list.dart +++ b/lib/widgets/attachment/attachment_list.dart @@ -7,13 +7,15 @@ import 'package:surface/widgets/attachment/attachment_item.dart'; class AttachmentList extends StatelessWidget { final List data; - final bool? bordered; + final bool bordered; + final bool noGrow; final double? maxHeight; final EdgeInsets? listPadding; const AttachmentList({ super.key, required this.data, - this.bordered, + this.bordered = false, + this.noGrow = false, this.maxHeight, this.listPadding, }); @@ -23,7 +25,7 @@ class AttachmentList extends StatelessWidget { @override Widget build(BuildContext context) { - final borderSide = (bordered ?? false) + final borderSide = bordered ? BorderSide(width: 1, color: Theme.of(context).dividerColor) : BorderSide.none; final backgroundColor = Theme.of(context).colorScheme.surfaceContainer; @@ -34,7 +36,7 @@ class AttachmentList extends StatelessWidget { if (data.isEmpty) return const SizedBox.shrink(); if (data.length == 1) { - if (ResponsiveBreakpoints.of(context).largerThan(MOBILE)) { + if (ResponsiveBreakpoints.of(context).largerThan(MOBILE) || noGrow) { return Padding( // Single child list-like displaying padding: listPadding ?? EdgeInsets.zero, diff --git a/lib/widgets/chat/chat_message.dart b/lib/widgets/chat/chat_message.dart index 647d93f..3577c6f 100644 --- a/lib/widgets/chat/chat_message.dart +++ b/lib/widgets/chat/chat_message.dart @@ -29,53 +29,59 @@ class ChatMessage extends StatelessWidget { final dateFormatter = DateFormat('MM/dd HH:mm'); - return Row( + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (!isMerged) - AccountImage( - content: user?.avatar, - ) - else - const Gap(40), - const Gap(8), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (!isMerged) - Row( - crossAxisAlignment: CrossAxisAlignment.baseline, - textBaseline: TextBaseline.alphabetic, - children: [ - Text( - (data.sender.nick?.isNotEmpty ?? false) - ? data.sender.nick! - : user!.nick, - ).bold(), - const Gap(6), - Text( - dateFormatter.format(data.createdAt.toLocal()), - ).fontSize(13), - ], - ), - if (data.body['text'] != null) - MarkdownTextContent( - content: data.body['text'], - isAutoWarp: true, - ), - if (data.preload?.attachments?.isNotEmpty ?? false) - AttachmentList( - data: data.preload!.attachments!, - bordered: true, - maxHeight: 520, - listPadding: const EdgeInsets.symmetric(horizontal: 12), - ), - if (!hasMerged) const Gap(8), - ], + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (!isMerged) + AccountImage( + content: user?.avatar, + ) + else + const Gap(40), + const Gap(8), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (!isMerged) + Row( + crossAxisAlignment: CrossAxisAlignment.baseline, + textBaseline: TextBaseline.alphabetic, + children: [ + Text( + (data.sender.nick?.isNotEmpty ?? false) + ? data.sender.nick! + : user!.nick, + ).bold(), + const Gap(6), + Text( + dateFormatter.format(data.createdAt.toLocal()), + ).fontSize(13), + ], + ), + if (data.body['text'] != null) + MarkdownTextContent( + content: data.body['text'], + isAutoWarp: true, + ), + ], + ), + ) + ], + ).opacity(isPending ? 0.5 : 1), + if (data.preload?.attachments?.isNotEmpty ?? false) + AttachmentList( + data: data.preload!.attachments!, + bordered: true, + noGrow: true, + maxHeight: 520, + listPadding: const EdgeInsets.only(top: 8), ), - ) + if (!hasMerged) const Gap(8), ], - ).opacity(isPending ? 0.5 : 1); + ); } }