1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-26 23:09:21 +00:00
comunicmobile/lib/ui/widgets/text_widget.dart

125 lines
3.0 KiB
Dart
Raw Normal View History

2020-04-16 12:07:21 +00:00
import 'package:comunic/models/displayed_content.dart';
2020-04-16 07:53:19 +00:00
import 'package:comunic/utils/bbcode_parser.dart';
2020-04-16 08:53:09 +00:00
import 'package:comunic/utils/input_utils.dart';
2020-04-16 10:06:01 +00:00
import 'package:comunic/utils/navigation_utils.dart';
2020-04-16 07:53:19 +00:00
import 'package:flutter/material.dart';
2020-04-16 08:53:09 +00:00
import 'package:url_launcher/url_launcher.dart';
2020-04-16 07:53:19 +00:00
/// Text widget
///
/// The content passed to this widget is automatically parsed
///
/// @author Pierre Hubert
2020-04-16 12:07:21 +00:00
class TextWidget extends StatelessWidget {
final DisplayedString content;
2020-04-16 08:14:45 +00:00
final bool parseBBcode;
final TextStyle style;
2020-04-16 13:10:47 +00:00
final TextAlign textAlign;
2020-04-17 09:56:28 +00:00
final Color linksColor;
2020-04-16 07:53:19 +00:00
2020-04-16 08:14:45 +00:00
const TextWidget({
Key key,
@required this.content,
this.parseBBcode = false,
2020-04-16 13:10:47 +00:00
this.textAlign = TextAlign.start,
2020-04-16 08:14:45 +00:00
this.style,
2020-04-17 09:56:28 +00:00
this.linksColor = Colors.blueAccent,
2020-04-16 08:14:45 +00:00
}) : assert(content != null),
assert(parseBBcode != null),
2020-04-17 09:56:28 +00:00
assert(linksColor != null),
2020-04-16 07:53:19 +00:00
super(key: key);
@override
Widget build(BuildContext context) {
2020-04-16 12:07:21 +00:00
if (this.content.isNull || this.content.isEmpty) return Text("");
2020-04-16 10:18:39 +00:00
2020-04-16 12:07:21 +00:00
var content = this.content.parsedString;
2020-04-16 08:14:45 +00:00
2020-04-16 08:53:09 +00:00
// Parse BBcode
2020-04-16 12:07:21 +00:00
if (parseBBcode)
2020-04-16 08:53:09 +00:00
return BBCodeParsedWidget(
text: content,
2020-04-16 12:07:21 +00:00
parseCallback: (style, text) => _parseLinks(context, text, style),
2020-04-16 08:14:45 +00:00
);
2020-04-16 08:53:09 +00:00
// Just parse link
return RichText(
2020-04-16 13:10:47 +00:00
textAlign: textAlign,
2020-04-16 12:07:21 +00:00
text: TextSpan(children: _parseLinks(context, content, style)),
2020-04-16 08:53:09 +00:00
);
}
/// Sub parse function
2020-04-16 12:07:21 +00:00
List<InlineSpan> _parseLinks(
BuildContext context, String text, TextStyle style) {
2020-04-16 10:18:39 +00:00
if (style == null) style = TextStyle();
2020-04-16 08:53:09 +00:00
var buff = StringBuffer();
final list = new List<InlineSpan>();
// Change word function
final changeWordType = () {
list.add(TextSpan(style: style, text: buff.toString()));
buff.clear();
};
for (final word in text.replaceAll("\n", " \n ").split(" ")) {
// Line break
if (word == "\n") {
buff.write("\n");
continue;
}
// Check if it is an URL
2020-04-16 11:34:49 +00:00
if (word.startsWith("https://") || word.startsWith("http://")) {
2020-04-16 08:53:09 +00:00
changeWordType();
list.add(
WidgetSpan(
child: InkWell(
child: Text(
word,
2020-04-17 09:56:28 +00:00
style: style.copyWith(color: linksColor),
2020-04-16 08:53:09 +00:00
),
onTap: () => launch(word),
),
),
);
buff.write(" ");
}
2020-04-16 10:06:57 +00:00
// Check if it is a directory reference
else if (validateDirectoryReference(word)) {
2020-04-16 10:06:01 +00:00
changeWordType();
list.add(
WidgetSpan(
child: InkWell(
child: Text(
word,
2020-04-17 09:56:28 +00:00
style: style.copyWith(color: linksColor),
2020-04-16 10:06:01 +00:00
),
onTap: () => openVirtualDirectory(context, word),
),
),
);
buff.write(" ");
}
2020-04-16 08:53:09 +00:00
// Simple word
else {
buff.write(word);
buff.write(" ");
}
}
2020-04-16 13:10:47 +00:00
if (buff.isNotEmpty && (buff.length > 1 || buff.toString() != " "))
changeWordType();
2020-04-16 08:53:09 +00:00
return list;
2020-04-16 07:53:19 +00:00
}
}