fix newlines, wip edits

This commit is contained in:
Henry Hiles 2025-12-27 23:42:30 -05:00
commit 9663995114
No known key found for this signature in database
6 changed files with 79 additions and 33 deletions

View file

@ -7,15 +7,18 @@ import "package:fluttertagger/fluttertagger.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:matrix/matrix.dart";
import "package:nexus/controllers/room_chat_controller.dart";
import "package:nexus/models/relation_type.dart";
import "package:nexus/widgets/chat_page/mention_overlay.dart";
import "package:nexus/widgets/chat_page/reply_preview.dart";
import "package:nexus/widgets/chat_page/relation_preview.dart";
class ChatBox extends HookConsumerWidget {
final Message? replyToMessage;
final Message? relatedMessage;
final RelationType relationType;
final VoidCallback onDismiss;
final Room room;
const ChatBox({
required this.replyToMessage,
required this.relatedMessage,
required this.relationType,
required this.onDismiss,
required this.room,
super.key,
@ -28,14 +31,25 @@ class ChatBox extends HookConsumerWidget {
final triggerCharacter = useState("");
final query = useState("");
if (relationType == RelationType.edit &&
relatedMessage is TextMessage &&
controller.value.text.isEmpty) {
final text = (relatedMessage as TextMessage).text;
controller.value.text = relatedMessage?.replyToMessageId == null
? text
: text.split("\n\n").sublist(1).join("\n\n");
}
void send() {
ref
.watch(RoomChatController.provider(room).notifier)
.send(
controller.value.formattedText,
replyTo: replyToMessage,
relation: relatedMessage,
relationType: relationType,
tags: controller.value.tags,
);
onDismiss();
controller.value.text = "";
}
@ -71,8 +85,9 @@ class ChatBox extends HookConsumerWidget {
borderRadius: BorderRadius.all(Radius.circular(12)),
child: Column(
children: [
ReplyPreview(
replyToMessage: replyToMessage,
RelationPreview(
relatedMessage: relatedMessage,
relationType: relationType,
onDismiss: onDismiss,
room: room,
),

View file

@ -4,14 +4,17 @@ 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/models/relation_type.dart";
import "package:nexus/widgets/avatar_or_hash.dart";
class ReplyPreview extends ConsumerWidget {
final Message? replyToMessage;
class RelationPreview extends ConsumerWidget {
final Message? relatedMessage;
final RelationType relationType;
final VoidCallback onDismiss;
final Room room;
const ReplyPreview({
required this.replyToMessage,
const RelationPreview({
required this.relatedMessage,
required this.relationType,
required this.onDismiss,
required this.room,
super.key,
@ -19,9 +22,9 @@ class ReplyPreview extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
if (relatedMessage == null) return SizedBox.shrink();
final theme = Theme.of(context);
if (replyToMessage == null) return SizedBox.shrink();
return Container(
color: theme.colorScheme.surfaceContainerHigh,
padding: EdgeInsets.symmetric(horizontal: 8),
@ -29,34 +32,40 @@ class ReplyPreview extends ConsumerWidget {
spacing: 8,
children: [
SizedBox(width: 4),
if (relationType == RelationType.edit)
Text(
"Editing message:",
style: TextStyle(fontWeight: FontWeight.bold),
),
AvatarOrHash(
ref
.watch(
AvatarController.provider(
replyToMessage!.metadata!["avatarUrl"],
relatedMessage!.metadata!["avatarUrl"],
),
)
.whenOrNull(data: (data) => data),
replyToMessage!.metadata!["displayName"].toString(),
relatedMessage!.metadata!["displayName"].toString(),
headers: room.client.headers,
height: 16,
),
Text(
replyToMessage!.metadata?["displayName"] ??
replyToMessage!.authorId,
relatedMessage!.metadata?["displayName"] ??
relatedMessage!.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(),
child: Text(
(relatedMessage is TextMessage)
? (relatedMessage as TextMessage).text
: relatedMessage?.metadata?["body"] ??
relatedMessage?.metadata?["eventType"],
overflow: TextOverflow.ellipsis,
style: theme.textTheme.labelMedium,
maxLines: 1,
),
),
IconButton(
onPressed: onDismiss,

View file

@ -13,6 +13,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/helpers/extensions/show_context_menu.dart";
import "package:nexus/models/relation_type.dart";
import "package:nexus/widgets/chat_page/chat_box.dart";
import "package:nexus/widgets/chat_page/html/html.dart";
import "package:nexus/widgets/chat_page/member_list.dart";
@ -34,6 +35,7 @@ class RoomChat extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final replyToMessage = useState<Message?>(null);
final memberListOpened = useState<bool>(showMembersByDefault);
final relationType = useState(RelationType.reply);
final theme = Theme.of(context);
final danger = theme.colorScheme.error;
@ -56,7 +58,10 @@ class RoomChat extends HookConsumerWidget {
List<PopupMenuEntry> getMessageOptions(Message message) => [
PopupMenuItem(
onTap: () => replyToMessage.value = message,
onTap: () {
replyToMessage.value = message;
relationType.value = RelationType.reply;
},
child: ListTile(
leading: Icon(Icons.reply),
title: Text("Reply"),
@ -64,7 +69,10 @@ class RoomChat extends HookConsumerWidget {
),
if (message.authorId == room.roomData.client.userID)
PopupMenuItem(
onTap: () {},
onTap: () {
replyToMessage.value = message;
relationType.value = RelationType.edit;
},
child: ListTile(
leading: Icon(Icons.edit),
title: Text("Edit"),
@ -217,7 +225,8 @@ class RoomChat extends HookConsumerWidget {
bottomPadding: 72,
),
composerBuilder: (_) => ChatBox(
replyToMessage: replyToMessage.value,
relationType: relationType.value,
relatedMessage: replyToMessage.value,
onDismiss: () =>
replyToMessage.value = null,
room: room.roomData,
@ -231,7 +240,8 @@ class RoomChat extends HookConsumerWidget {
MessageGroupStatus? groupStatus,
}) => FlyerChatTextMessage(
customWidget: Html(
message.metadata?["formatted"]
(message.metadata?["formatted"]
as String)
.replaceAllMapped(
RegExp(
regexLink,
@ -239,7 +249,8 @@ class RoomChat extends HookConsumerWidget {
),
(m) =>
"<a href=\"${m.group(0)!}\">${m.group(0)!}</a>",
) +
)
.replaceAll("\n", "<br/>") +
((message.editedAt != null)
? "<sub edited>(edited)</sub>"
: ""),