From 7de882338da4e3e0be6b06970beeb11bd7a487f2 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Thu, 16 Apr 2020 10:53:09 +0200 Subject: [PATCH] Parse URLs --- lib/ui/widgets/text_widget.dart | 65 ++++++++++++++++++++++++++++++--- lib/utils/bbcode_parser.dart | 3 +- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/lib/ui/widgets/text_widget.dart b/lib/ui/widgets/text_widget.dart index c8eb115..70f863f 100644 --- a/lib/ui/widgets/text_widget.dart +++ b/lib/ui/widgets/text_widget.dart @@ -1,6 +1,8 @@ import 'package:comunic/utils/bbcode_parser.dart'; +import 'package:comunic/utils/input_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_emoji/flutter_emoji.dart'; +import 'package:url_launcher/url_launcher.dart'; /// Text widget /// @@ -26,12 +28,65 @@ class TextWidget extends StatelessWidget { Widget build(BuildContext context) { var content = EmojiParser().emojify(this.content); + // Parse BBcode if (this.parseBBcode) - return BBCodeParsedWidget(text: content); - else - return Text( - content, - style: style, + return BBCodeParsedWidget( + text: content, + parseCallback: (style, text) => _parseLinks(text, style), ); + + // Just parse link + return RichText( + text: TextSpan(children: _parseLinks(content, style)), + ); + } + + /// Sub parse function + List _parseLinks(String text, TextStyle style) { + var buff = StringBuffer(); + final list = new List(); + + // 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 (validateUrl(word)) { + changeWordType(); + + list.add( + WidgetSpan( + child: InkWell( + child: Text( + word, + style: style.copyWith(color: Colors.blueAccent), + ), + onTap: () => launch(word), + ), + ), + ); + + buff.write(" "); + } + + // Simple word + else { + buff.write(word); + buff.write(" "); + } + } + + if (buff.isNotEmpty) changeWordType(); + + return list; } } diff --git a/lib/utils/bbcode_parser.dart b/lib/utils/bbcode_parser.dart index 33158f9..b339065 100644 --- a/lib/utils/bbcode_parser.dart +++ b/lib/utils/bbcode_parser.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart'; /// This callback return null if the text has to be left as is or a TextSpan /// if it has been sub parsed... -typedef ParseCallBack = List Function(TextStyle, String); +typedef ParseCallBack = List Function(TextStyle, String); class BBCodeParsedWidget extends StatelessWidget { final _Element _content; @@ -241,7 +241,6 @@ class _Element { if (parsed != null && parsed.length > 0) return TextSpan( - text: text, style: generatedStyle, children: parsed, );