extract out image message builder

This commit is contained in:
Henry Hiles 2026-03-13 19:48:46 -04:00
commit fe3de47407
No known key found for this signature in database
2 changed files with 86 additions and 193 deletions

View file

@ -0,0 +1,58 @@
import "dart:math";
import "package:cross_cache/cross_cache.dart";
import "package:flutter/material.dart";
import "package:flutter_chat_core/flutter_chat_core.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:flyer_chat_image_message/flyer_chat_image_message.dart";
import "package:nexus/controllers/cross_cache_controller.dart";
import "package:nexus/helpers/extensions/get_headers.dart";
class ExpandableImageMessage extends ConsumerWidget {
final ImageMessage message;
final int index;
const ExpandableImageMessage(this.message, {required this.index, super.key});
@override
Widget build(BuildContext context, WidgetRef ref) => InkWell(
onTap: () => showDialog(
context: context,
builder: (_) => LayoutBuilder(
builder: (context, constraints) => Dialog(
backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.all(constraints.maxWidth / 100),
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: min(constraints.maxWidth, 1000),
),
child: InteractiveViewer(
child: Image(
fit: BoxFit.contain,
image: CachedNetworkImage(
message.source,
ref.watch(CrossCacheController.provider),
headers: ref.headers,
),
),
),
),
),
),
),
child: FlyerChatImageMessage(
customImageProvider: CachedNetworkImage(
message.source,
ref.watch(CrossCacheController.provider),
headers: ref.headers,
),
errorBuilder: (context, error, stackTrace) => Center(
child: Text(
"Image Failed to Load",
style: TextStyle(color: Theme.of(context).colorScheme.error),
),
),
message: message,
index: index,
),
);
}

View file

@ -19,6 +19,7 @@ import "package:nexus/helpers/extensions/show_context_menu.dart";
import "package:nexus/models/relation_type.dart"; import "package:nexus/models/relation_type.dart";
import "package:nexus/models/requests/report_request.dart"; import "package:nexus/models/requests/report_request.dart";
import "package:nexus/widgets/chat_page/chat_box.dart"; import "package:nexus/widgets/chat_page/chat_box.dart";
import "package:nexus/widgets/chat_page/image_message.dart";
import "package:nexus/widgets/chat_page/member_list.dart"; import "package:nexus/widgets/chat_page/member_list.dart";
import "package:nexus/widgets/chat_page/message_wrapper.dart"; import "package:nexus/widgets/chat_page/message_wrapper.dart";
import "package:nexus/widgets/chat_page/room_appbar.dart"; import "package:nexus/widgets/chat_page/room_appbar.dart";
@ -238,6 +239,7 @@ class RoomChat extends HookConsumerWidget {
), ),
builders: Builders( builders: Builders(
loadMoreBuilder: (_) => Loading(), loadMoreBuilder: (_) => Loading(),
chatAnimatedListBuilder: (_, itemBuilder) => chatAnimatedListBuilder: (_, itemBuilder) =>
ChatAnimatedList( ChatAnimatedList(
itemBuilder: itemBuilder, itemBuilder: itemBuilder,
@ -247,6 +249,7 @@ class RoomChat extends HookConsumerWidget {
onStartReached: () => client.markRead(room), onStartReached: () => client.markRead(room),
bottomPadding: 72, bottomPadding: 72,
), ),
composerBuilder: (_) => ChatBox( composerBuilder: (_) => ChatBox(
relationType: relationType.value, relationType: relationType.value,
relatedMessage: replyToMessage.value, relatedMessage: replyToMessage.value,
@ -254,104 +257,6 @@ class RoomChat extends HookConsumerWidget {
room: room, room: room,
), ),
// TODO: Polls
// customMessageBuilder:
// (
// context,
// message,
// index, {
// required bool isSentByMe,
// MessageGroupStatus? groupStatus,
// }) {
// final poll =
// message.metadata?["poll"]
// as PollStartContent;
// final responses =
// (message.metadata?["responses"]
// as Map<
// String,
// Set<String>
// >)
// .values
// .expand((set) => set)
// .fold(<String, int>{}, (
// acc,
// value,
// ) {
// acc[value] =
// (acc[value] ?? 0) + 1;
// return acc;
// });
// return Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// spacing: 4,
// children: [
// TopWidget(
// message,
// headers: room
// .roomData
// .client
// .headers,
// groupStatus: groupStatus,
// ),
// DynamicPolls(
// startDate: DateTime.now(),
// endDate: DateTime.now(),
// private:
// poll.kind ==
// PollKind.undisclosed,
// allowReselection: true,
// backgroundDecoration:
// BoxDecoration(
// borderRadius:
// BorderRadius.all(
// Radius.circular(16),
// ),
// border: Border.all(
// color: theme
// .colorScheme
// .primaryContainer,
// width: 4,
// ),
// ),
// allStyle: Styles(
// titleStyle: TitleStyle(
// style: theme
// .textTheme
// .headlineSmall,
// ),
// optionStyle: OptionStyle(
// fillColor: theme
// .colorScheme
// .primaryContainer,
// selectedBorderColor: theme
// .colorScheme
// .primary,
// borderColor: theme
// .colorScheme
// .primary,
// unselectedBorderColor:
// Colors.transparent,
// textSelectColor: theme
// .colorScheme
// .primary,
// ),
// ),
// onOptionSelected:
// (int index) {},
// title: poll.question.mText,
// options: poll.answers
// .map(
// (option) => option.mText,
// )
// .toList(),
// ),
// ],
// );
// },
textMessageBuilder: textMessageBuilder:
( (
context, context,
@ -372,6 +277,7 @@ class RoomChat extends HookConsumerWidget {
groupStatus, groupStatus,
), ),
imageMessageBuilder: imageMessageBuilder:
( (
context, context,
@ -379,11 +285,8 @@ class RoomChat extends HookConsumerWidget {
index, { index, {
required bool isSentByMe, required bool isSentByMe,
MessageGroupStatus? groupStatus, MessageGroupStatus? groupStatus,
}) { }) => MessageWrapper(
final text = message,
message.metadata?["text"] as TextMessage?;
return MessageWrapper(
text ?? message,
Column( Column(
spacing: 4, spacing: 4,
crossAxisAlignment: crossAxisAlignment:
@ -394,88 +297,18 @@ class RoomChat extends HookConsumerWidget {
content: message.text, content: message.text,
groupStatus: groupStatus, groupStatus: groupStatus,
onTapReply: notifier.scrollToMessage, onTapReply: notifier.scrollToMessage,
updateMessage: updateMessage: controller.updateMessage,
controller.updateMessage,
isSentByMe: isSentByMe, isSentByMe: isSentByMe,
extra: InkWell( extra: ExpandableImageMessage(
onTap: () => showDialog( message,
context: context,
builder: (_) => LayoutBuilder(
builder:
(
context,
constraints,
) => Dialog(
backgroundColor:
Colors.transparent,
insetPadding:
EdgeInsets.all(
constraints
.maxWidth /
100,
),
child: ConstrainedBox(
constraints:
BoxConstraints(
minWidth: min(
constraints
.maxWidth,
1000,
),
),
child: InteractiveViewer(
child: Image(
fit: BoxFit.contain,
image: CachedNetworkImage(
message.source,
ref.watch(
CrossCacheController
.provider,
),
headers:
ref.headers,
),
),
),
),
),
),
),
child: FlyerChatImageMessage(
customImageProvider:
CachedNetworkImage(
message.source,
ref.watch(
CrossCacheController
.provider,
),
headers: ref.headers,
),
errorBuilder:
(
context,
error,
stackTrace,
) => Center(
child: Text(
"Image Failed to Load",
style: TextStyle(
color: Theme.of(
context,
).colorScheme.error,
),
),
),
message: message,
index: index, index: index,
), ),
), ),
),
], ],
), ),
groupStatus, groupStatus,
); ),
},
fileMessageBuilder: fileMessageBuilder:
( (
_, _,
@ -506,6 +339,7 @@ class RoomChat extends HookConsumerWidget {
), ),
groupStatus, groupStatus,
), ),
systemMessageBuilder: systemMessageBuilder:
( (
_, _,
@ -517,6 +351,7 @@ class RoomChat extends HookConsumerWidget {
message: message, message: message,
index: index, index: index,
), ),
unsupportedMessageBuilder: unsupportedMessageBuilder:
( (
_, _,