202 lines
8.2 KiB
Dart
202 lines
8.2 KiB
Dart
// ignore_for_file: deprecated_member_use_from_same_package, use_build_context_synchronously
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_highlight/flutter_highlight.dart';
|
|
import 'package:hoshan/core/gen/assets.gen.dart';
|
|
import 'package:hoshan/core/utils/strings.dart';
|
|
import 'package:hoshan/ui/theme/colors.dart';
|
|
import 'package:hoshan/ui/theme/text.dart';
|
|
import 'package:hoshan/ui/widgets/components/snackbar/snackbar_manager.dart';
|
|
import 'package:hoshan/ui/widgets/components/text/latex.dart';
|
|
import 'package:markdown_widget/markdown_widget.dart';
|
|
import 'package:flutter_highlight/themes/atom-one-dark-reasonable.dart';
|
|
import 'package:flutter_highlight/themes/atom-one-light.dart';
|
|
|
|
class DefaultMarkdownText extends StatefulWidget {
|
|
final String text;
|
|
final Color? color;
|
|
final double? width;
|
|
final bool fromBot;
|
|
const DefaultMarkdownText(
|
|
{super.key,
|
|
required this.text,
|
|
this.color,
|
|
this.width,
|
|
this.fromBot = false});
|
|
|
|
@override
|
|
State<DefaultMarkdownText> createState() => DefaultMarkdownTextState();
|
|
}
|
|
|
|
class DefaultMarkdownTextState extends State<DefaultMarkdownText> {
|
|
late TextDirection textDirection =
|
|
widget.text.startsWithEnglish() ? TextDirection.ltr : TextDirection.rtl;
|
|
|
|
String changeDirection() {
|
|
setState(() {
|
|
if (textDirection == TextDirection.rtl) {
|
|
textDirection = TextDirection.ltr;
|
|
} else {
|
|
textDirection = TextDirection.rtl;
|
|
}
|
|
});
|
|
return textDirection.name.toUpperCase();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final isDark = Theme.of(context).brightness == Brightness.dark;
|
|
|
|
final config = isDark
|
|
? MarkdownConfig.darkConfig.copy(configs: [
|
|
CodeConfig(
|
|
style: MarkdownConfig.darkConfig.code.style.copyWith(
|
|
color: widget.color,
|
|
backgroundColor:
|
|
atomOneDarkReasonableTheme['root']!.backgroundColor)),
|
|
])
|
|
: MarkdownConfig.defaultConfig;
|
|
return Column(
|
|
children: [
|
|
Directionality(
|
|
textDirection: textDirection,
|
|
child: SizedBox(
|
|
width: widget.width,
|
|
child: MarkdownBlock(
|
|
data: widget.text,
|
|
selectable: true,
|
|
generator: MarkdownGenerator(
|
|
generators: [latexGenerator],
|
|
inlineSyntaxList: [LatexSyntax()],
|
|
// richTextBuilder: (span) => Text.rich(
|
|
// span,
|
|
// softWrap: true,
|
|
// style: config.p.textStyle.copyWith(
|
|
// fontFamily: AppTextStyles.defaultFontFamily,
|
|
// color: widget.color),
|
|
// ),
|
|
),
|
|
config: config.copy(configs: [
|
|
PreConfig(
|
|
builder: (code, language) => Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 18.0),
|
|
child: Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: ClipRRect(
|
|
borderRadius: BorderRadius.circular(8),
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(8),
|
|
decoration: BoxDecoration(
|
|
color: isDark
|
|
? AppColors.black[900]
|
|
: AppColors.primaryColor.defaultShade),
|
|
child: Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
language,
|
|
style: const TextStyle(
|
|
color: Colors.white,
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 16),
|
|
),
|
|
InkWell(
|
|
onTap: () async {
|
|
await Clipboard.setData(
|
|
ClipboardData(text: code));
|
|
if (mounted) {
|
|
SnackBarManager(context, id: 'Copy')
|
|
.show(
|
|
status: SnackBarStatus.success,
|
|
message: 'پیام با موفقیت کپی شد 😃',
|
|
);
|
|
}
|
|
},
|
|
child: Row(
|
|
children: [
|
|
const Text(
|
|
'copy',
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 14),
|
|
),
|
|
const SizedBox(
|
|
width: 4,
|
|
),
|
|
Assets.icon.outline.copy
|
|
.svg(color: Colors.white),
|
|
],
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
Container(
|
|
constraints: const BoxConstraints(
|
|
minWidth: double.infinity),
|
|
child: HighlightView(
|
|
code,
|
|
language: language,
|
|
theme: isDark
|
|
? atomOneDarkReasonableTheme
|
|
: atomOneLightTheme,
|
|
textStyle:
|
|
TextStyle(color: widget.color, height: 1.4),
|
|
padding: const EdgeInsets.all(8),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
H1Config(
|
|
style: config.h1.style.copyWith(
|
|
fontSize: 22,
|
|
fontFamily: AppTextStyles.defaultFontFamily,
|
|
color: widget.color)),
|
|
H2Config(
|
|
style: config.h2.style.copyWith(
|
|
fontSize: 21,
|
|
fontFamily: AppTextStyles.defaultFontFamily,
|
|
color: widget.color)),
|
|
H3Config(
|
|
style: config.h3.style.copyWith(
|
|
fontSize: 20,
|
|
fontFamily: AppTextStyles.defaultFontFamily,
|
|
color: widget.color)),
|
|
H4Config(
|
|
style: config.h4.style.copyWith(
|
|
fontSize: 19,
|
|
fontFamily: AppTextStyles.defaultFontFamily,
|
|
color: widget.color)),
|
|
H5Config(
|
|
style: config.h5.style.copyWith(
|
|
fontSize: 18,
|
|
fontFamily: AppTextStyles.defaultFontFamily,
|
|
color: widget.color)),
|
|
H6Config(
|
|
style: config.h6.style.copyWith(
|
|
fontSize: 17,
|
|
fontFamily: AppTextStyles.defaultFontFamily,
|
|
color: widget.color)),
|
|
PConfig(
|
|
textStyle: config.p.textStyle.copyWith(
|
|
fontSize: 16,
|
|
fontFamily: AppTextStyles.defaultFontFamily,
|
|
color: widget.color),
|
|
),
|
|
]),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|