make message flash when tapping reply

This commit is contained in:
Henry Hiles 2026-03-18 21:49:43 -04:00
commit a6aee7565a
No known key found for this signature in database
5 changed files with 127 additions and 102 deletions

View file

@ -66,6 +66,7 @@ class MessageController extends AsyncNotifier<Message?> {
), ),
).future, ).future,
), ),
"flashing": false,
"timelineId": event.timelineRowId, "timelineId": event.timelineRowId,
"big": event.localContent?.bigEmoji == true, "big": event.localContent?.bigEmoji == true,
"eventType": type, "eventType": type,

View file

@ -1,3 +1,5 @@
import "dart:async";
import "package:collection/collection.dart"; import "package:collection/collection.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_chat_core/flutter_chat_core.dart"; import "package:flutter_chat_core/flutter_chat_core.dart";
@ -282,6 +284,16 @@ class RoomChatController extends AsyncNotifier<InMemoryChatController> {
Future<void> scrollToMessage(Message message) async { Future<void> scrollToMessage(Message message) async {
final controller = await future; final controller = await future;
Future<void> setFlashing(bool flashing) => controller.updateMessage(
message,
message.copyWith(
metadata: {...(message.metadata ?? {}), "flashing": flashing},
),
);
await setFlashing(true);
Timer(Duration(seconds: 1), () => setFlashing(false));
return await controller.scrollToMessage(message.id); return await controller.scrollToMessage(message.id);
} }

View file

@ -9,7 +9,17 @@ class MessageWrapper extends StatelessWidget {
const MessageWrapper(this.message, this.child, this.groupStatus, {super.key}); const MessageWrapper(this.message, this.child, this.groupStatus, {super.key});
@override @override
Widget build(BuildContext context) => Row( Widget build(BuildContext context) => ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(12)),
child: AnimatedContainer(
padding: message.metadata?["flashing"] == true
? EdgeInsets.all(8)
: EdgeInsets.all(0),
color: message.metadata?["flashing"] == true
? Theme.of(context).colorScheme.onSurface.withAlpha(50)
: Colors.transparent,
duration: Duration(milliseconds: 250),
child: Row(
spacing: 8, spacing: 8,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -29,14 +39,16 @@ class MessageWrapper extends StatelessWidget {
Text( Text(
message.metadata?["displayName"] ?? message.authorId, message.metadata?["displayName"] ?? message.authorId,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: Theme.of( style: Theme.of(context).textTheme.titleMedium?.copyWith(
context, fontWeight: FontWeight.bold,
).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold), ),
), ),
child, child,
], ],
), ),
), ),
], ],
),
),
); );
} }

View file

@ -259,9 +259,7 @@ class RoomChat extends HookConsumerWidget {
index, { index, {
required bool isSentByMe, required bool isSentByMe,
MessageGroupStatus? groupStatus, MessageGroupStatus? groupStatus,
}) => MessageWrapper( }) => TextMessageWrapper(
message,
TextMessageWrapper(
message, message,
content: message.text, content: message.text,
groupStatus: groupStatus, groupStatus: groupStatus,
@ -270,9 +268,6 @@ class RoomChat extends HookConsumerWidget {
isSentByMe: isSentByMe, isSentByMe: isSentByMe,
), ),
groupStatus,
),
imageMessageBuilder: imageMessageBuilder:
( (
context, context,

View file

@ -2,6 +2,7 @@ import "package:flutter/material.dart";
import "package:flutter_chat_core/flutter_chat_core.dart"; import "package:flutter_chat_core/flutter_chat_core.dart";
import "package:flutter_link_previewer/flutter_link_previewer.dart"; import "package:flutter_link_previewer/flutter_link_previewer.dart";
import "package:nexus/widgets/chat_page/html/html.dart"; import "package:nexus/widgets/chat_page/html/html.dart";
import "package:nexus/widgets/chat_page/message_wrapper.dart";
import "package:nexus/widgets/chat_page/top_widget.dart"; import "package:nexus/widgets/chat_page/top_widget.dart";
class TextMessageWrapper extends StatelessWidget { class TextMessageWrapper extends StatelessWidget {
@ -31,7 +32,9 @@ class TextMessageWrapper extends StatelessWidget {
final colorScheme = theme.colorScheme; final colorScheme = theme.colorScheme;
final textMessage = message is TextMessage ? message as TextMessage : null; final textMessage = message is TextMessage ? message as TextMessage : null;
return ClipRRect( return MessageWrapper(
message,
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(8)), borderRadius: BorderRadius.all(Radius.circular(8)),
child: Container( child: Container(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 12), padding: EdgeInsets.symmetric(vertical: 8, horizontal: 12),
@ -100,6 +103,8 @@ class TextMessageWrapper extends StatelessWidget {
], ],
), ),
), ),
),
groupStatus,
); );
} }
} }