💄 Mergeable chat messages

This commit is contained in:
LittleSheep 2024-11-17 22:42:09 +08:00
parent 2065350698
commit 432705c570
2 changed files with 67 additions and 13 deletions

View File

@ -76,9 +76,10 @@ class _ChatRoomScreenState extends State<ChatRoomScreen> {
Expanded( Expanded(
child: InfiniteList( child: InfiniteList(
reverse: true, reverse: true,
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.only(
horizontal: 12, left: 12,
vertical: 12, right: 12,
top: 12,
), ),
hasReachedMax: _messageController.isAllLoaded, hasReachedMax: _messageController.isAllLoaded,
itemCount: _messageController.messages.length, itemCount: _messageController.messages.length,
@ -88,8 +89,32 @@ class _ChatRoomScreenState extends State<ChatRoomScreen> {
}, },
itemBuilder: (context, idx) { itemBuilder: (context, idx) {
final message = _messageController.messages[idx]; final message = _messageController.messages[idx];
final nextMessage =
idx < _messageController.messages.length - 1
? _messageController.messages[idx + 1]
: null;
final previousMessage =
idx > 0 ? _messageController.messages[idx - 1] : null;
final canMerge = nextMessage != null &&
nextMessage.senderId == message.senderId &&
message.createdAt
.difference(nextMessage.createdAt)
.inMinutes
.abs() <=
3;
final canMergePrevious = previousMessage != null &&
previousMessage.senderId == message.senderId &&
message.createdAt
.difference(previousMessage.createdAt)
.inMinutes
.abs() <=
3;
return ChatMessage( return ChatMessage(
data: message, data: message,
isMerged: canMerge,
hasMerged: canMergePrevious,
isPending: _messageController.unconfirmedMessages isPending: _messageController.unconfirmedMessages
.contains(message.uuid), .contains(message.uuid),
); );

View File

@ -1,3 +1,4 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:gap/gap.dart'; import 'package:gap/gap.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -9,32 +10,60 @@ import 'package:surface/widgets/markdown_content.dart';
class ChatMessage extends StatelessWidget { class ChatMessage extends StatelessWidget {
final SnChatMessage data; final SnChatMessage data;
final bool isMerged;
final bool hasMerged;
final bool isPending; final bool isPending;
const ChatMessage({super.key, required this.data, this.isPending = false}); const ChatMessage({
super.key,
required this.data,
this.isMerged = false,
this.hasMerged = false,
this.isPending = false,
});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ud = context.read<UserDirectoryProvider>(); final ud = context.read<UserDirectoryProvider>();
final user = ud.getAccountFromCache(data.sender.accountId); final user = ud.getAccountFromCache(data.sender.accountId);
final dateFormatter = DateFormat('MM/dd HH:mm');
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (!isMerged)
AccountImage( AccountImage(
content: user?.avatar, content: user?.avatar,
), )
else
const Gap(40),
const Gap(8), const Gap(8),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!isMerged)
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [ children: [
Text( Text(
(data.sender.nick?.isNotEmpty ?? false) (data.sender.nick?.isNotEmpty ?? false)
? data.sender.nick! ? data.sender.nick!
: user!.nick, : user!.nick,
).bold(), ).bold(),
const Gap(6),
Text(
dateFormatter.format(data.createdAt.toLocal()),
).fontSize(13),
],
),
if (data.body['text'] != null) if (data.body['text'] != null)
MarkdownTextContent(content: data.body['text']), MarkdownTextContent(
content: data.body['text'],
isAutoWarp: true,
),
if (!hasMerged) const Gap(8),
], ],
), ),
) )