Files
apidash/lib/dashbot/widgets/content_renderer.dart
Udhay-Adithya 346e4c3ef0 feat: refactor code highlighting and add scripts editor pane
- replace `flutter_highlighter` and `highlighter` with `flutter_highlight` and `highlight`.
- add `flutter_code_editor` dependency.
- introduce a new scripts editor pane in the REST request view.
2025-04-22 14:34:43 +05:30

101 lines
2.8 KiB
Dart

// lib/dashbot/widgets/content_renderer.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_highlight/flutter_highlight.dart';
import 'package:flutter_highlight/themes/monokai-sublime.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
Widget renderContent(BuildContext context, String text) {
if (text.isEmpty) {
return const Text("No content to display.");
}
final codeBlockPattern = RegExp(r'```(\w+)?\n([\s\S]*?)```', multiLine: true);
final matches = codeBlockPattern.allMatches(text);
if (matches.isEmpty) {
return _renderMarkdown(context, text);
}
List<Widget> children = [];
int lastEnd = 0;
for (var match in matches) {
if (match.start > lastEnd) {
children
.add(_renderMarkdown(context, text.substring(lastEnd, match.start)));
}
final language = match.group(1) ?? 'text';
final code = match.group(2)!.trim();
children.add(_renderCodeBlock(context, language, code));
lastEnd = match.end;
}
if (lastEnd < text.length) {
children.add(_renderMarkdown(context, text.substring(lastEnd)));
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: children,
);
}
Widget _renderMarkdown(BuildContext context, String markdown) {
return MarkdownBody(
data: markdown,
selectable: true,
styleSheet: MarkdownStyleSheet(
p: TextStyle(color: Theme.of(context).colorScheme.onSurface),
),
);
}
Widget _renderCodeBlock(BuildContext context, String language, String code) {
if (language == 'json') {
try {
final prettyJson =
const JsonEncoder.withIndent(' ').convert(jsonDecode(code));
return Container(
padding: const EdgeInsets.all(8),
color: Theme.of(context).colorScheme.surfaceContainerLow,
child: SelectableText(
prettyJson,
style: const TextStyle(fontFamily: 'monospace', fontSize: 12),
),
);
} catch (e) {
return _renderFallbackCode(context, code);
}
} else {
try {
return Container(
padding: const EdgeInsets.all(8),
color: Theme.of(context).colorScheme.surfaceContainerLow,
child: HighlightView(
code,
language: language,
theme: monokaiSublimeTheme,
textStyle: const TextStyle(fontFamily: 'monospace', fontSize: 12),
),
);
} catch (e) {
return _renderFallbackCode(context, code);
}
}
}
Widget _renderFallbackCode(BuildContext context, String code) {
return Container(
padding: const EdgeInsets.all(8),
color: Theme.of(context).colorScheme.surfaceContainerLow,
child: SelectableText(
code,
style: const TextStyle(
fontFamily: 'monospace', fontSize: 12, color: Colors.red),
),
);
}