refactor(markdown): Replace markdown library with gpt_markdown and update styling

This commit is contained in:
cogwheel0
2025-12-07 22:01:18 +05:30
parent fa6f6570ff
commit ccde2e4a46
4 changed files with 274 additions and 797 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import '../../theme/theme_extensions.dart';
import 'markdown_config.dart';
import 'markdown_preprocessor.dart';
@@ -70,71 +69,62 @@ class StreamingMarkdownWidget extends StatelessWidget {
specialBlocks.sort((a, b) => a.start.compareTo(b.start));
Widget buildMarkdown(String data) {
return ConduitMarkdown.buildBlock(
return ConduitMarkdown.build(
context: context,
data: data,
onTapLink: onTapLink,
selectable: false,
imageBuilderOverride: imageBuilderOverride,
);
}
Widget result;
if (specialBlocks.isEmpty) {
return SelectionArea(
child: Theme(
data: Theme.of(context).copyWith(
textSelectionTheme: TextSelectionThemeData(
cursorColor: context.conduitTheme.buttonPrimary,
),
),
child: buildMarkdown(normalized),
),
result = buildMarkdown(normalized);
} else {
final children = <Widget>[];
var currentIndex = 0;
for (final block in specialBlocks) {
// Skip overlapping blocks
if (block.start < currentIndex) continue;
final before = normalized.substring(currentIndex, block.start);
if (before.trim().isNotEmpty) {
children.add(buildMarkdown(before));
}
switch (block.type) {
case _BlockType.mermaid:
children.add(
ConduitMarkdown.buildMermaidBlock(context, block.content),
);
case _BlockType.chartJs:
children.add(
ConduitMarkdown.buildChartJsBlock(context, block.content),
);
}
currentIndex = block.end;
}
final tail = normalized.substring(currentIndex);
if (tail.trim().isNotEmpty) {
children.add(buildMarkdown(tail));
}
result = Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: children,
);
}
final children = <Widget>[];
var currentIndex = 0;
for (final block in specialBlocks) {
// Skip overlapping blocks
if (block.start < currentIndex) continue;
final before = normalized.substring(currentIndex, block.start);
if (before.trim().isNotEmpty) {
children.add(buildMarkdown(before));
}
switch (block.type) {
case _BlockType.mermaid:
children.add(
ConduitMarkdown.buildMermaidBlock(context, block.content),
);
case _BlockType.chartJs:
children.add(
ConduitMarkdown.buildChartJsBlock(context, block.content),
);
}
currentIndex = block.end;
// Only wrap in SelectionArea when not streaming to avoid concurrent
// modification errors in Flutter's selection system during rapid updates
if (isStreaming) {
return result;
}
final tail = normalized.substring(currentIndex);
if (tail.trim().isNotEmpty) {
children.add(buildMarkdown(tail));
}
return SelectionArea(
child: Theme(
data: Theme.of(context).copyWith(
textSelectionTheme: TextSelectionThemeData(
cursorColor: context.conduitTheme.buttonPrimary,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: children,
),
),
);
return SelectionArea(child: result);
}
}

View File

@@ -539,14 +539,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_markdown_plus:
dependency: "direct main"
description:
name: flutter_markdown_plus
sha256: "7f349c075157816da399216a4127096108fd08e1ac931e34e72899281db4113c"
url: "https://pub.dev"
source: hosted
version: "1.0.5"
flutter_math_fork:
dependency: "direct main"
description:
@@ -701,6 +693,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "17.0.0"
gpt_markdown:
dependency: "direct main"
description:
name: gpt_markdown
sha256: "8174983f2ed7d8576d25810913e3afe3f8ffdaa3172c0c823b7cfc289b67f380"
url: "https://pub.dev"
source: hosted
version: "1.1.4"
graphs:
dependency: transitive
description:

View File

@@ -31,12 +31,12 @@ dependencies:
# UI Components - Markdown Rendering
cached_network_image: ^3.3.1
flutter_markdown_plus: ^1.0.5
gpt_markdown: ^1.1.4
flutter_math_fork: ^0.7.2
markdown: ^7.3.0
webview_flutter: ^4.7.0
socket_io_client: ^3.1.2
yaml: ^3.1.2
flutter_math_fork: ^0.7.4