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

import 'package:comunic/models/displayed_content.dart';
import 'package:comunic/utils/bbcode_parser.dart';
import 'package:comunic/utils/input_utils.dart';
import 'package:comunic/utils/navigation_utils.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
/// Text widget
///
/// The content passed to this widget is automatically parsed
///
/// @author Pierre Hubert
class TextWidget extends StatelessWidget {
final DisplayedString content;
final bool parseBBcode;
final TextStyle style;
final TextAlign textAlign;
final Color linksColor;
const TextWidget({
Key key,
@required this.content,
this.parseBBcode = false,
this.textAlign = TextAlign.start,
this.style,
this.linksColor = Colors.blueAccent,
}) : assert(content != null),
assert(parseBBcode != null),
assert(linksColor != null),
super(key: key);
@override
Widget build(BuildContext context) {
if (this.content.isNull || this.content.isEmpty) return Text("");
var content = this.content.parsedString;
// Parse BBcode
if (parseBBcode)
return BBCodeParsedWidget(
text: content,
parseCallback: (style, text) => _parseLinks(context, text, style),
);
// Just parse link
return RichText(
textAlign: textAlign,
text: TextSpan(children: _parseLinks(context, content, style)),
);
}
/// Sub parse function
List<InlineSpan> _parseLinks(
BuildContext context, String text, TextStyle style) {
if (style == null) style = TextStyle();
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
if (word.startsWith("https://") || word.startsWith("http://")) {
changeWordType();
list.add(
WidgetSpan(
child: InkWell(
child: Text(
word,
style: style.copyWith(color: linksColor),
),
onTap: () => launch(word),
),
),
);
buff.write(" ");
}
// Check if it is a directory reference
else if (validateDirectoryReference(word)) {
changeWordType();
list.add(
WidgetSpan(
child: InkWell(
child: Text(
word,
style: style.copyWith(color: linksColor),
),
onTap: () => openVirtualDirectory(context, word),
),
),
);
buff.write(" ");
}
// Simple word
else {
buff.write(word);
buff.write(" ");
}
}
if (buff.isNotEmpty && (buff.length > 1 || buff.toString() != " "))
changeWordType();
return list;
}
}