Message with attachment

This commit is contained in:
LittleSheep 2024-11-18 21:38:15 +08:00
parent 359cd94532
commit 9f7a3082cb
3 changed files with 69 additions and 61 deletions

View File

@ -279,7 +279,7 @@ class ChatMessageController extends ChangeNotifier {
}) async { }) async {
late List<SnChatMessage> out; late List<SnChatMessage> out;
if (_box != null && (_box!.length >= take + offset || forceLocal)) { 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 { } else {
final resp = await _sn.client.get( final resp = await _sn.client.get(
'/cgi/im/channels/${channel!.keyPath}/events', '/cgi/im/channels/${channel!.keyPath}/events',
@ -300,18 +300,18 @@ class ChatMessageController extends ChangeNotifier {
out.expand((e) => (e.body['attachments'] as List<dynamic>?) ?? []), out.expand((e) => (e.body['attachments'] as List<dynamic>?) ?? []),
); );
final attachments = await _attach.getMultiple(attachmentRid); final attachments = await _attach.getMultiple(attachmentRid);
out = out.reversed for (var i = 0; i < out.length; i++) {
.map((ele) => ele.copyWith( out[i] = out[i].copyWith(
preload: SnChatMessagePreload( preload: SnChatMessagePreload(
attachments: attachments attachments: attachments
.where((e) => .where(
(ele.body['attachments'] as List<dynamic>?) (ele) =>
?.contains(e) ?? out[i].body['attachments']?.contains(ele?.rid) ?? false,
false) )
.toList(), .toList(),
), ),
)) );
.toList(); }
// Preload sender accounts // Preload sender accounts
await _ud.listAccount(out.map((ele) => ele.sender.accountId).toSet()); await _ud.listAccount(out.map((ele) => ele.sender.accountId).toSet());

View File

@ -7,13 +7,15 @@ import 'package:surface/widgets/attachment/attachment_item.dart';
class AttachmentList extends StatelessWidget { class AttachmentList extends StatelessWidget {
final List<SnAttachment?> data; final List<SnAttachment?> data;
final bool? bordered; final bool bordered;
final bool noGrow;
final double? maxHeight; final double? maxHeight;
final EdgeInsets? listPadding; final EdgeInsets? listPadding;
const AttachmentList({ const AttachmentList({
super.key, super.key,
required this.data, required this.data,
this.bordered, this.bordered = false,
this.noGrow = false,
this.maxHeight, this.maxHeight,
this.listPadding, this.listPadding,
}); });
@ -23,7 +25,7 @@ class AttachmentList extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final borderSide = (bordered ?? false) final borderSide = bordered
? BorderSide(width: 1, color: Theme.of(context).dividerColor) ? BorderSide(width: 1, color: Theme.of(context).dividerColor)
: BorderSide.none; : BorderSide.none;
final backgroundColor = Theme.of(context).colorScheme.surfaceContainer; final backgroundColor = Theme.of(context).colorScheme.surfaceContainer;
@ -34,7 +36,7 @@ class AttachmentList extends StatelessWidget {
if (data.isEmpty) return const SizedBox.shrink(); if (data.isEmpty) return const SizedBox.shrink();
if (data.length == 1) { if (data.length == 1) {
if (ResponsiveBreakpoints.of(context).largerThan(MOBILE)) { if (ResponsiveBreakpoints.of(context).largerThan(MOBILE) || noGrow) {
return Padding( return Padding(
// Single child list-like displaying // Single child list-like displaying
padding: listPadding ?? EdgeInsets.zero, padding: listPadding ?? EdgeInsets.zero,

View File

@ -29,53 +29,59 @@ class ChatMessage extends StatelessWidget {
final dateFormatter = DateFormat('MM/dd HH:mm'); final dateFormatter = DateFormat('MM/dd HH:mm');
return Row( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (!isMerged) Row(
AccountImage( crossAxisAlignment: CrossAxisAlignment.start,
content: user?.avatar, children: [
) if (!isMerged)
else AccountImage(
const Gap(40), content: user?.avatar,
const Gap(8), )
Expanded( else
child: Column( const Gap(40),
crossAxisAlignment: CrossAxisAlignment.start, const Gap(8),
children: [ Expanded(
if (!isMerged) child: Column(
Row( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.baseline, children: [
textBaseline: TextBaseline.alphabetic, if (!isMerged)
children: [ Row(
Text( crossAxisAlignment: CrossAxisAlignment.baseline,
(data.sender.nick?.isNotEmpty ?? false) textBaseline: TextBaseline.alphabetic,
? data.sender.nick! children: [
: user!.nick, Text(
).bold(), (data.sender.nick?.isNotEmpty ?? false)
const Gap(6), ? data.sender.nick!
Text( : user!.nick,
dateFormatter.format(data.createdAt.toLocal()), ).bold(),
).fontSize(13), const Gap(6),
], Text(
), dateFormatter.format(data.createdAt.toLocal()),
if (data.body['text'] != null) ).fontSize(13),
MarkdownTextContent( ],
content: data.body['text'], ),
isAutoWarp: true, if (data.body['text'] != null)
), MarkdownTextContent(
if (data.preload?.attachments?.isNotEmpty ?? false) content: data.body['text'],
AttachmentList( isAutoWarp: true,
data: data.preload!.attachments!, ),
bordered: true, ],
maxHeight: 520, ),
listPadding: const EdgeInsets.symmetric(horizontal: 12), )
), ],
if (!hasMerged) const Gap(8), ).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); );
} }
} }