🐛 Fixes on post compose

This commit is contained in:
2025-06-23 23:40:29 +08:00
parent 9482594117
commit ffbe399614
9 changed files with 222 additions and 172 deletions

View File

@ -2,10 +2,13 @@ import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_highlight/themes/a11y-dark.dart';
import 'package:flutter_highlight/themes/a11y-light.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:island/pods/config.dart';
import 'package:island/widgets/alert.dart';
import 'package:island/widgets/content/markdown_latex.dart';
import 'package:markdown/markdown.dart' as markdown;
import 'package:markdown_widget/markdown_widget.dart';
import 'package:url_launcher/url_launcher.dart';
@ -18,6 +21,7 @@ class MarkdownTextContent extends HookConsumerWidget {
final TextScaler? textScaler;
final TextStyle? textStyle;
final TextStyle? linkStyle;
final EdgeInsets? linesMargin;
final bool isSelectable;
const MarkdownTextContent({
@ -28,6 +32,7 @@ class MarkdownTextContent extends HookConsumerWidget {
this.textStyle,
this.linkStyle,
this.isSelectable = false,
this.linesMargin,
});
@override
@ -54,19 +59,13 @@ class MarkdownTextContent extends HookConsumerWidget {
config: config.copy(
configs: [
isDark
? PreConfig.darkConfig.copy(
textStyle: textStyle,
padding: EdgeInsets.zero,
margin: EdgeInsets.zero,
)
: PreConfig().copy(
textStyle: textStyle,
padding: EdgeInsets.zero,
margin: EdgeInsets.zero,
),
? PreConfig.darkConfig.copy(textStyle: textStyle)
: PreConfig().copy(textStyle: textStyle),
PConfig(
textStyle: textStyle ?? Theme.of(context).textTheme.bodyMedium!,
),
HrConfig(height: 1, color: Theme.of(context).dividerColor),
PreConfig(theme: isDark ? a11yDarkTheme : a11yLightTheme),
LinkConfig(
style:
linkStyle ??
@ -146,8 +145,13 @@ class MarkdownTextContent extends HookConsumerWidget {
],
),
generator: MarkdownGenerator(
inlineSyntaxList: [_UserNameCardInlineSyntax(), _StickerInlineSyntax()],
linesMargin: EdgeInsets.zero,
generators: [latexGenerator],
inlineSyntaxList: [
_UserNameCardInlineSyntax(),
_StickerInlineSyntax(),
LatexSyntax(isDark),
],
linesMargin: linesMargin ?? EdgeInsets.symmetric(vertical: 4),
),
);
}

View File

@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
import 'package:markdown_widget/markdown_widget.dart';
import 'package:flutter_math_fork/flutter_math.dart';
import 'package:markdown/markdown.dart' as m;
SpanNodeGeneratorWithTag latexGenerator = SpanNodeGeneratorWithTag(
tag: _latexTag,
generator:
(e, config, visitor) => LatexNode(e.attributes, e.textContent, config),
);
const _latexTag = 'latex';
class LatexSyntax extends m.InlineSyntax {
final bool isDark;
LatexSyntax(this.isDark) : super(r'(\$\$[\s\S]+\$\$)|(\$.+?\$)');
@override
bool onMatch(m.InlineParser parser, Match match) {
final input = match.input;
final matchValue = input.substring(match.start, match.end);
String content = '';
bool isInline = true;
const blockSyntax = '\$\$';
const inlineSyntax = '\$';
if (matchValue.startsWith(blockSyntax) &&
matchValue.endsWith(blockSyntax) &&
(matchValue != blockSyntax)) {
content = matchValue.substring(2, matchValue.length - 2);
isInline = false;
} else if (matchValue.startsWith(inlineSyntax) &&
matchValue.endsWith(inlineSyntax) &&
matchValue != inlineSyntax) {
content = matchValue.substring(1, matchValue.length - 1);
}
m.Element el = m.Element.text(_latexTag, matchValue);
el.attributes['content'] = content;
el.attributes['isInline'] = '$isInline';
el.attributes['isDark'] = isDark.toString();
parser.addNode(el);
return true;
}
}
class LatexNode extends SpanNode {
final Map<String, String> attributes;
final String textContent;
final MarkdownConfig config;
LatexNode(this.attributes, this.textContent, this.config);
@override
InlineSpan build() {
final content = attributes['content'] ?? '';
final isInline = attributes['isInline'] == 'true';
final isDark = attributes['isDark'] == 'true';
final style = parentStyle ?? config.p.textStyle;
if (content.isEmpty) return TextSpan(style: style, text: textContent);
final latex = Math.tex(
content,
mathStyle: MathStyle.text,
textStyle: style.copyWith(color: isDark ? Colors.white : Colors.black),
textScaleFactor: 1,
onErrorFallback: (error) {
return Text(textContent, style: style.copyWith(color: Colors.red));
},
);
return WidgetSpan(
alignment: PlaceholderAlignment.middle,
child:
!isInline
? Container(
width: double.infinity,
margin: EdgeInsets.symmetric(vertical: 16),
child: Center(child: latex),
)
: latex,
);
}
}