diff --git a/lib/widgets/code_element.dart b/lib/widgets/code_element.dart new file mode 100644 index 0000000..7987fc4 --- /dev/null +++ b/lib/widgets/code_element.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_highlighter/flutter_highlighter.dart'; +import 'package:flutter_highlighter/themes/atom-one-dark.dart'; +import 'package:flutter_highlighter/themes/atom-one-light.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:get/get.dart'; +import 'package:markdown/markdown.dart' as md; +import 'package:google_fonts/google_fonts.dart'; + +class CodeElementBuilder extends MarkdownElementBuilder { + @override + Widget? visitElementAfter(md.Element element, TextStyle? preferredStyle) { + final brightness = Get.theme.brightness; + + var language = ''; + + if (element.attributes['class'] != null) { + String lg = element.attributes['class'] as String; + language = lg.substring(9); + } + return SingleChildScrollView( + scrollDirection: Axis.horizontal, + // https://stackoverflow.com/questions/59592640/how-to-add-code-syntax-highlighter-to-flutter-markdown + child: HighlightView( + // The original code to be highlighted + element.textContent, + + // Specify language + // It is recommended to give it a value for performance + language: language, + + // Specify highlight theme + // All available themes are listed in `themes` folder + theme: brightness == Brightness.light + ? atomOneLightTheme + : atomOneDarkTheme, + + // Specify padding + padding: const EdgeInsets.all(8), + + // Specify text style + textStyle: GoogleFonts.robotoMono(), + + // Specify tab size + tabSize: 4, + ), + ); + } +} diff --git a/lib/widgets/message_tile.dart b/lib/widgets/message_tile.dart index d2362d0..9f9bde2 100644 --- a/lib/widgets/message_tile.dart +++ b/lib/widgets/message_tile.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_markdown/flutter_markdown.dart'; +import 'package:flutter_markdown/flutter_markdown.dart' as md; import 'package:get/get.dart'; -import 'package:google_fonts/google_fonts.dart'; import 'package:sydney_webui/models/message.dart'; import 'package:sydney_webui/utils/array.dart'; +import 'package:sydney_webui/widgets/code_element.dart'; class MessageTile extends StatelessWidget { const MessageTile( @@ -19,10 +19,6 @@ class MessageTile extends StatelessWidget { Widget build(BuildContext context) { final theme = Theme.of(context); - final markdownTheme = MarkdownStyleSheet.fromTheme(theme).copyWith( - code: theme.textTheme.bodyMedium! - .copyWith(fontFamily: GoogleFonts.robotoMono().fontFamily)); - void copyContent() async { try { await Clipboard.setData(ClipboardData(text: message.content)); @@ -66,11 +62,10 @@ class MessageTile extends StatelessWidget { ], ), ), - subtitle: MarkdownBody( - selectable: true, - data: message.content, - styleSheet: markdownTheme, - ), + subtitle: + md.MarkdownBody(selectable: true, data: message.content, builders: { + 'code': CodeElementBuilder(), + }), titleTextStyle: theme.textTheme.bodySmall, ); } diff --git a/pubspec.lock b/pubspec.lock index da3e611..2085d06 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -86,6 +86,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_highlighter: + dependency: "direct main" + description: + name: flutter_highlighter + sha256: "93173afd47a9ada53f3176371755e7ea4a1065362763976d06d6adfb4d946e10" + url: "https://pub.dev" + source: hosted + version: "0.1.1" flutter_lints: dependency: "direct dev" description: @@ -144,6 +152,14 @@ packages: url: "https://pub.dev" source: hosted version: "6.1.0" + highlighter: + dependency: transitive + description: + name: highlighter + sha256: "92180c72b9da8758e1acf39a45aa305a97dcfe2fdc8f3d1d2947c23f2772bfbc" + url: "https://pub.dev" + source: hosted + version: "0.1.1" http: dependency: transitive description: @@ -169,7 +185,7 @@ packages: source: hosted version: "2.1.1" markdown: - dependency: transitive + dependency: "direct main" description: name: markdown sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd diff --git a/pubspec.yaml b/pubspec.yaml index 9532564..20a64b2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,8 @@ dependencies: file_picker: ^6.1.1 flutter_markdown: google_fonts: + markdown: + flutter_highlighter: dev_dependencies: flutter_test: