-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(PostView): 使用 MarkdownBody 显示 Markdown 文本
移除 markdown_widget, flutter_inappwebview 改为使用 flutter_markdown, flutter_markdown_latex 显示预览
- Loading branch information
1 parent
e9b4793
commit 0a83640
Showing
14 changed files
with
306 additions
and
405 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,126 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:get/get.dart' show Get, GetNavigationExt, Inst; | ||
import 'package:glidea/controller/site/site.dart'; | ||
import 'package:flutter_markdown/flutter_markdown.dart' show MarkdownBody, MarkdownStyleSheet; | ||
import 'package:flutter_markdown_latex/flutter_markdown_latex.dart' show LatexElementBuilder; | ||
import 'package:glidea/components/Common/drawer_editor.dart'; | ||
import 'package:glidea/helpers/constants.dart'; | ||
import 'package:glidea/helpers/date.dart'; | ||
import 'package:glidea/helpers/image.dart'; | ||
import 'package:glidea/helpers/markdown.dart'; | ||
import 'package:glidea/models/post.dart'; | ||
import 'package:markdown_widget/markdown_widget.dart' show MarkdownConfig, MarkdownGenerator, MarkdownWidget; | ||
|
||
class PostPreview extends StatefulWidget { | ||
const PostPreview({super.key, required this.entity, required this.markdown}); | ||
|
||
/// 实体 | ||
final Post entity; | ||
/// 预览 [Post] | ||
class PostPreview extends DrawerEditor<Post> { | ||
const PostPreview({ | ||
super.key, | ||
required super.entity, | ||
super.controller, | ||
super.header = '', | ||
super.showAction = false, | ||
required this.markdown, | ||
}); | ||
|
||
/// markdown 内容 | ||
final String markdown; | ||
|
||
@override | ||
State<PostPreview> createState() => _PostPreviewState(); | ||
DrawerEditorState<PostPreview> createState() => _PostPreviewState(); | ||
} | ||
|
||
class _PostPreviewState extends State<PostPreview> { | ||
/// 站点控制器 | ||
final site = Get.find<SiteController>(tag: SiteController.tag); | ||
class _PostPreviewState extends DrawerEditorState<PostPreview> { | ||
/// 时间文本 | ||
late final dateText = widget.entity.date.format(pattern: site.themeConfig.dateFormat); | ||
|
||
/// 时间文本的样式 | ||
late final dateStyle = theme.textTheme.bodyMedium?.copyWith(color: theme.colorScheme.outline); | ||
|
||
/// 定义要为哪些 Markdown 元素使用哪些 TextStyle 对象 | ||
late final MarkdownStyleSheet styleSheet = createStyle(); | ||
|
||
/// 主题颜色 | ||
late final theme = Theme.of(Get.context!); | ||
/// 构建控件的函数集合 | ||
late final _buildFun = <ValueGetter<Widget>>{ | ||
_buildFeature, | ||
_buildTitle, | ||
_buildDate, | ||
if (widget.entity.tags.isNotEmpty) _buildTags, | ||
_buildView, | ||
}; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
// TODO: 改善性能 - 使用 WebView 或者其它方式, 添加 Latex 支持 | ||
final colorScheme = theme.colorScheme; | ||
final textTheme = theme.textTheme; | ||
final post = widget.entity; | ||
final dateStr = post.date.format(pattern: site.themeConfig.dateFormat); | ||
final dateStyle = textTheme.bodyMedium?.copyWith(color: colorScheme.outline); | ||
// 控件 | ||
final List<Widget> children = [ | ||
ImageConfig.builderImg(site.getFeaturePath(widget.entity)), | ||
Text(post.title, style: textTheme.headlineSmall), | ||
Text(dateStr, style: dateStyle), | ||
if (post.tags.isNotEmpty) | ||
Row( | ||
mainAxisSize: MainAxisSize.min, | ||
mainAxisAlignment: MainAxisAlignment.start, | ||
children: [ | ||
for (var tag in site.getTagsWithPost(post)) | ||
Container( | ||
padding: kVerPadding4 + kHorPadding8, | ||
decoration: BoxDecoration( | ||
color: colorScheme.onInverseSurface, | ||
borderRadius: const BorderRadius.all(Radius.circular(20)), | ||
), | ||
child: Text(tag.name, style: textTheme.bodySmall), | ||
), | ||
], | ||
), | ||
MarkdownWidget( | ||
data: widget.markdown ?? '', | ||
shrinkWrap: true, | ||
config: MarkdownConfig(configs: [ | ||
const ImageConfig(), | ||
]), | ||
markdownGenerator: MarkdownGenerator( | ||
extensionSet: Markdown.custom, | ||
textGenerator: CustomTextNode.new, | ||
), | ||
), | ||
]; | ||
// 返回 | ||
return Column( | ||
Widget? buildContent(BuildContext context, int index) { | ||
final child = _buildFun.elementAtOrNull(index)?.call(); | ||
return child != null ? wrapperField(child: child) : null; | ||
} | ||
|
||
/// 封面 | ||
Widget _buildFeature() => ImageConfig.builderImg(site.getFeaturePath(widget.entity)); | ||
|
||
/// 标题 | ||
Widget _buildTitle() => Text(widget.entity.title, style: theme.textTheme.headlineMedium); | ||
|
||
/// 创建时间 | ||
Widget _buildDate() => Text(dateText, style: dateStyle); | ||
|
||
/// 构建标签 | ||
Widget _buildTags() { | ||
return Row( | ||
spacing: kHorPadding8.right, | ||
mainAxisSize: MainAxisSize.min, | ||
crossAxisAlignment: CrossAxisAlignment.stretch, | ||
mainAxisAlignment: MainAxisAlignment.start, | ||
children: [ | ||
for (var i = 0; i < children.length; i++) | ||
Padding( | ||
padding: i <= 0 ? kTopPadding8 : kTopPadding16, | ||
child: children[i], | ||
for (var tag in site.getTagsWithPost(widget.entity)) | ||
DecoratedBox( | ||
decoration: BoxDecoration( | ||
color: theme.colorScheme.onInverseSurface, | ||
borderRadius: const BorderRadius.all(Radius.circular(20)), | ||
), | ||
child: Padding( | ||
padding: kVerPadding4 + kHorPadding8, | ||
child: Text(tag.name, style: theme.textTheme.bodySmall), | ||
), | ||
), | ||
], | ||
); | ||
} | ||
|
||
/// 构建 MarkDown 视图 | ||
Widget _buildView() { | ||
return MarkdownBody( | ||
selectable: true, | ||
fitContent: false, | ||
data: widget.markdown, | ||
styleSheet: styleSheet, | ||
builders: { | ||
'latex': LatexElementBuilder( | ||
textStyle: theme.textTheme.bodyMedium, | ||
textScaleFactor: 1.2, | ||
), | ||
}, | ||
extensionSet: Markdown.custom, | ||
); | ||
} | ||
|
||
/// 创建样式 | ||
MarkdownStyleSheet createStyle() { | ||
var style = MarkdownStyleSheet.fromTheme(theme); | ||
style = style.copyWith( | ||
pPadding: kVerPadding4, | ||
h1Padding: kVerPadding4, | ||
h2Padding: kVerPadding4, | ||
h3Padding: kVerPadding4, | ||
h4Padding: kVerPadding4, | ||
h5Padding: kVerPadding4, | ||
h6Padding: kVerPadding4, | ||
code: style.code?.copyWith(fontSize: style.p?.fontSize), | ||
codeblockDecoration: BoxDecoration( | ||
color: theme.colorScheme.surfaceContainerHigh, | ||
borderRadius: BorderRadius.circular(2.0), | ||
), | ||
blockquoteDecoration: BoxDecoration( | ||
color: theme.secondaryHeaderColor, //Colors.blue.shade100, | ||
borderRadius: BorderRadius.circular(2.0), | ||
), | ||
textScaler: const TextScaler.linear(1.1), | ||
); | ||
return style; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.