add codeblock support

This commit is contained in:
Henry Hiles 2025-11-16 18:48:44 -05:00
commit e74a5d51a3
No known key found for this signature in database
4 changed files with 59 additions and 13 deletions

View file

@ -29,7 +29,7 @@ class RoomChatController extends AsyncNotifier<ChatController> {
response.chunk.map( response.chunk.map(
(event) => Event.fromMatrixEvent(event, room).toMessage(), (event) => Event.fromMatrixEvent(event, room).toMessage(),
), ),
)).nonNulls.toList(), )).nonNulls.toList().reversed.toList(),
); );
} }

View file

@ -0,0 +1,53 @@
import "dart:math";
import "package:flutter/material.dart";
class CodeBlock extends StatelessWidget {
final String code;
final String lang;
const CodeBlock(this.code, {required this.lang, super.key});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(16)),
child: ColoredBox(
color: theme.colorScheme.surfaceContainerHighest,
child: IntrinsicWidth(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 8),
child: Text(
lang.substring(0, min(lang.length, 15)),
style: TextStyle(fontFamily: "monospace"),
),
),
TextButton(
onPressed: () {},
child: Row(
spacing: 4,
children: [Icon(Icons.copy), Text("Copy")],
),
),
],
),
ColoredBox(
color: theme.colorScheme.surfaceContainer,
child: Container(
constraints: BoxConstraints(minWidth: 250),
padding: EdgeInsets.all(8),
child: SelectableText(code),
),
),
],
),
),
),
);
}
}

View file

@ -9,13 +9,13 @@ 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_image_message/flyer_chat_image_message.dart";
import "package:flyer_chat_system_message/flyer_chat_system_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: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:hooks_riverpod/hooks_riverpod.dart";
import "package:nexus/controllers/current_room_controller.dart"; import "package:nexus/controllers/current_room_controller.dart";
import "package:nexus/controllers/room_chat_controller.dart"; import "package:nexus/controllers/room_chat_controller.dart";
import "package:nexus/helpers/extension_helper.dart"; import "package:nexus/helpers/extension_helper.dart";
import "package:nexus/helpers/launch_helper.dart"; import "package:nexus/helpers/launch_helper.dart";
import "package:nexus/widgets/chat_box.dart"; import "package:nexus/widgets/chat_box.dart";
import "package:nexus/widgets/code_block.dart";
import "package:nexus/widgets/member_list.dart"; import "package:nexus/widgets/member_list.dart";
import "package:nexus/widgets/room_appbar.dart"; import "package:nexus/widgets/room_appbar.dart";
import "package:nexus/widgets/spoiler_text.dart"; import "package:nexus/widgets/spoiler_text.dart";
@ -138,16 +138,10 @@ class RoomChat extends HookConsumerWidget {
if (element.localName == "code") { if (element.localName == "code") {
if (element.parent?.localName == if (element.parent?.localName ==
"pre") { "pre") {
return SizedBox( return CodeBlock(
width: 400, element.text,
child: CodeField( lang: element.className
name: element.className .replaceAll("language-", ""),
.replaceAll(
"language-",
"",
),
codes: element.text,
),
); );
} }
} }

View file

@ -60,7 +60,6 @@ dependencies:
scaled_app: ^2.3.0 scaled_app: ^2.3.0
flutter_vodozemac: ^0.4.1 flutter_vodozemac: ^0.4.1
flutter_widget_from_html_core: ^0.17.0 flutter_widget_from_html_core: ^0.17.0
gpt_markdown: ^1.1.4
flutter_svg: ^2.2.2 flutter_svg: ^2.2.2
dev_dependencies: dev_dependencies: