Fix state errors when dismissing replies

This commit is contained in:
Henry Hiles 2025-12-26 13:22:45 -05:00
commit f249f39972
No known key found for this signature in database
2 changed files with 76 additions and 45 deletions

View file

@ -12,6 +12,7 @@ import "package:nexus/controllers/room_chat_controller.dart";
import "package:nexus/helpers/extensions/better_when.dart";
import "package:nexus/helpers/extensions/get_headers.dart";
import "package:nexus/widgets/avatar_or_hash.dart";
import "package:nexus/widgets/chat_page/reply_preview.dart";
import "package:nexus/widgets/loading.dart";
class ChatBox extends HookConsumerWidget {
@ -69,51 +70,11 @@ class ChatBox extends HookConsumerWidget {
borderRadius: BorderRadius.all(Radius.circular(12)),
child: Column(
children: [
if (replyToMessage != null)
Container(
color: theme.colorScheme.surfaceContainerHigh,
padding: EdgeInsets.symmetric(horizontal: 8),
child: Row(
spacing: 8,
children: [
SizedBox(width: 4),
AvatarOrHash(
ref
.watch(
AvatarController.provider(
replyToMessage!.metadata!["avatarUrl"],
),
)
.whenOrNull(data: (data) => data),
replyToMessage!.metadata!["displayName"].toString(),
headers: room.client.headers,
height: 16,
),
Text(
replyToMessage!.metadata?["displayName"] ??
replyToMessage!.authorId,
style: theme.textTheme.labelMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
Expanded(
child: (replyToMessage is TextMessage)
? Text(
(replyToMessage as TextMessage).text,
overflow: TextOverflow.ellipsis,
style: theme.textTheme.labelMedium,
maxLines: 1,
)
: SizedBox(),
),
IconButton(
onPressed: onDismiss,
icon: Icon(Icons.close),
iconSize: 20,
),
],
),
),
ReplyPreview(
replyToMessage: replyToMessage,
onDismiss: onDismiss,
room: room,
),
Container(
color: theme.colorScheme.surfaceContainerHighest,
padding: EdgeInsets.symmetric(horizontal: 8),

View file

@ -0,0 +1,70 @@
import "package:flutter/material.dart";
import "package:flutter_chat_core/flutter_chat_core.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:matrix/matrix.dart";
import "package:nexus/controllers/avatar_controller.dart";
import "package:nexus/helpers/extensions/get_headers.dart";
import "package:nexus/widgets/avatar_or_hash.dart";
class ReplyPreview extends ConsumerWidget {
final Message? replyToMessage;
final VoidCallback onDismiss;
final Room room;
const ReplyPreview({
required this.replyToMessage,
required this.onDismiss,
required this.room,
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context);
if (replyToMessage == null) return SizedBox.shrink();
return Container(
color: theme.colorScheme.surfaceContainerHigh,
padding: EdgeInsets.symmetric(horizontal: 8),
child: Row(
spacing: 8,
children: [
SizedBox(width: 4),
AvatarOrHash(
ref
.watch(
AvatarController.provider(
replyToMessage!.metadata!["avatarUrl"],
),
)
.whenOrNull(data: (data) => data),
replyToMessage!.metadata!["displayName"].toString(),
headers: room.client.headers,
height: 16,
),
Text(
replyToMessage!.metadata?["displayName"] ??
replyToMessage!.authorId,
style: theme.textTheme.labelMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
Expanded(
child: (replyToMessage is TextMessage)
? Text(
(replyToMessage as TextMessage).text,
overflow: TextOverflow.ellipsis,
style: theme.textTheme.labelMedium,
maxLines: 1,
)
: SizedBox(),
),
IconButton(
onPressed: onDismiss,
icon: Icon(Icons.close),
iconSize: 20,
),
],
),
);
}
}