add chat stuff

This commit is contained in:
Henry Hiles 2025-11-15 15:19:34 -05:00
commit 0bb3961cd2
No known key found for this signature in database
4 changed files with 95 additions and 5 deletions

View file

@ -1,3 +1,4 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter/foundation.dart";
import "package:flutter/material.dart";
import "package:flutter_chat_core/flutter_chat_core.dart";
@ -8,6 +9,7 @@ import "package:flyer_chat_file_message/flyer_chat_file_message.dart";
import "package:flyer_chat_image_message/flyer_chat_image_message.dart";
import "package:flyer_chat_system_message/flyer_chat_system_message.dart";
import "package:flyer_chat_text_message/flyer_chat_text_message.dart";
import "package:gpt_markdown/custom_widgets/code_field.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:nexus/controllers/current_room_controller.dart";
import "package:nexus/controllers/room_chat_controller.dart";
@ -16,6 +18,7 @@ import "package:nexus/helpers/launch_helper.dart";
import "package:nexus/widgets/chat_box.dart";
import "package:nexus/widgets/member_list.dart";
import "package:nexus/widgets/room_appbar.dart";
import "package:nexus/widgets/spoiler_text.dart";
import "package:nexus/widgets/top_widget.dart";
import "package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart";
@ -125,10 +128,67 @@ class RoomChat extends HookConsumerWidget {
}) => FlyerChatTextMessage(
customWidget: HtmlWidget(
message.metadata?["formatted"],
customWidgetBuilder: (element) =>
element.localName == "mx-reply"
? SizedBox.shrink()
: null,
customWidgetBuilder: (element) {
if (element.localName == "mx-reply") {
return SizedBox.shrink();
}
if (element.localName == "code") {
return SizedBox(
width: 400,
child: CodeField(
name: element.className
.replaceAll("language-", ""),
codes: element.text,
),
);
}
if (element.localName == "img") {
final src = Uri.tryParse(
element.attributes["src"] ?? "",
);
if (src?.scheme != "mxc") {
return SizedBox.shrink();
}
// TODO: Should do something like:
// return Image.network(
// src!.getThumbnailUri(
// room.roomData.client,
// ),
// );
return SizedBox.shrink();
}
if (element.attributes.keys.contains(
"data-mx-spoiler",
)) {
return SpoilerText(
text: element.text,
);
}
return null;
},
customStylesBuilder: (element) => {
"width": "auto",
...Map.fromEntries(
element.attributes
.mapTo<MapEntry<String, String>?>(
(key, value) => switch (key) {
"data-mx-color" => MapEntry(
"color",
value,
),
"data-mx-bg-color" =>
MapEntry(
"background-color",
value,
),
_ => null,
},
)
.nonNulls,
),
},
onTapUrl: (url) => ref
.watch(LaunchHelper.provider)
.launchUrl(Uri.parse(url)),

View file

@ -0,0 +1,29 @@
import "package:flutter/material.dart";
import "package:flutter_hooks/flutter_hooks.dart";
class SpoilerText extends HookWidget {
final String text;
const SpoilerText({super.key, required this.text});
@override
Widget build(BuildContext context) {
final revealed = useState(false);
return InkWell(
onTap: () => revealed.value = !revealed.value,
child: AnimatedContainer(
duration: const Duration(milliseconds: 100),
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
decoration: BoxDecoration(
color: revealed.value ? Colors.transparent : Colors.blueGrey,
borderRadius: BorderRadius.circular(4),
),
child: Text(
text,
style: TextStyle(color: revealed.value ? null : Colors.transparent),
),
),
);
}
}

View file

@ -664,7 +664,7 @@ packages:
source: hosted
version: "2.1.3"
gpt_markdown:
dependency: transitive
dependency: "direct main"
description:
name: gpt_markdown
sha256: "8174983f2ed7d8576d25810913e3afe3f8ffdaa3172c0c823b7cfc289b67f380"

View file

@ -58,6 +58,7 @@ dependencies:
scaled_app: ^2.3.0
flutter_vodozemac: ^0.4.1
flutter_widget_from_html_core: ^0.17.0
gpt_markdown: ^1.1.4
dev_dependencies:
build_runner: ^2.4.11