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
|
|
|
}
|
|
|
|
}
|