Reputation: 3198
I am trying to make a wats-app like link preview feature , it has two parts ,
Part 2 has so many plugins to show the preview , but I am stuck with part 1 , how to detect and parse a URL on user typing on textfield .
Also is there a plugin serving both ?
Upvotes: 2
Views: 3314
Reputation: 2729
I hope that this could help others, talking about step 1:
To detect a URL from the text view, I do the following (taking into consideration that my use case is a chat message in which in the middle of the text could be 1 or several links)
First, having a function that given a String, identify that are URLs:
bool hasURLs(String text) {
const pattern =
r"(https?:\/\/(www.)?|www.)([\w-]+.([\w-]+.)?[\w]+)([\w./?=%-]*)";
final regExp = RegExp(pattern);
return regExp.hasMatch(text);
}
Then a logic to display the text message with a link or without links:
final hasUrls = formatter.hasURLs(stringMessage);
In a widget:
return hasUrls
? UrlMessage(
textContent: messageContents,
textColor: textColor,
isMyMessage: isMyMessage,
)
: Text(
messageContents,
style: TextStyle(color: textColor, fontSize: 13),
);
For UrlMessage
widget the code as follows:
class UrlMessage extends StatefulWidget {
const UrlMessage({
Key? key,
required this.textContent,
required this.textColor,
required this.isMyMessage,
}) : super(key: key);
final String textContent;
final Color textColor;
final bool isMyMessage;
@override
State<UrlMessage> createState() => _UrlMessageState();
}
class _UrlMessageState extends State<UrlMessage> {
final formatter = Formatter();
@override
Widget build(BuildContext context) {
final text = widget.textContent;
final textColor = widget.textColor;
final isMyMessage = widget.isMyMessage;
final linkTextStyle = TextStyle(
color: isMyMessage ? Colors.blueGrey : Colors.blue,
fontSize: 13,
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
);
return RichText(
// map each word of the message, ask if it is a URL then set it with each
// TextSpan as a link or not. If it's a link use launchUrl from `url_launcher`
// package to open it
text: TextSpan(
children: text.split(' ').map((word) {
// Check for URLs
if (formatter.hasURLs(word)) {
return TextSpan(
text: word,
style: linkTextStyle,
recognizer: TapGestureRecognizer()
..onTap = () {
// Handle link - here we use `url_launcher`
launchUrl(Uri.parse(word));
},
);
} else {
return TextSpan(
text: '$word ',
style: TextStyle(color: textColor, fontSize: 13),
);
}
}).toList(),
),
);
}
}
Regarding step 2, there are several options to work with the preview, in our case Any Link Preview does what we need
Upvotes: 0
Reputation: 6145
Detect URLs in String/Paragraph and convert them in links in DART:
//
String convertStringToLink(String textData) {
//
final urlRegExp = new RegExp(
r"((https?:www\.)|(https?:\/\/)|(www\.))[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9]{1,6}(\/[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)?");
final urlMatches = urlRegExp.allMatches(textData);
List<String> urls = urlMatches.map(
(urlMatch) => textData.substring(urlMatch.start, urlMatch.end))
.toList();
List linksString = [];
urls.forEach((String linkText){
linksString.add(linkText);
});
if (linksString.length > 0) {
linksString.forEach((linkTextData) {
textData = textData.replaceAll(
linkTextData,
'<a href="' +
linkTextData +
'" target="_blank">' +
linkTextData +
'</a>');
});
}
return textData;
}
Demo and how to call
String text = "This is my website url: https://github.com/ Google search using: www.google.com, Flutter url: http://example.com/method?param=flutter stackoverflow website url is https://www.stackoverflow.com is greatest website and also check this hashed url https://support.google.com/firebase?authuser=0#topic=6399725";
print(convertStringToLink(text));
Output:
This is my website url: <a href="https://github.com/" target="_blank">https://github.com/</a> Google search using: <a href="www.google.com" target="_blank">www.google.com</a>, Flutter url: <a href="http://example.com/method?param=flutter" target="_blank">http://example.com/method?param=flutter</a> stackoverflow website url is <a href="https://www.stackoverflow.com" target="_blank">https://www.stackoverflow.com</a> is greatest website and also check this hashed url <a href="https://support.google.com/firebase?authuser=0#topic=6399725" target="_blank">https://support.google.com/firebase?authuser=0#topic=6399725</a>
It worked for me, will definitely help my friends :)
Upvotes: 4
Reputation: 231
You could try Uri.parse(). Do check the link https://www.geeksforgeeks.org/dart-uris/
Get the value from the textfield Using onChanged function and controller
https://medium.com/flutter-community/a-deep-dive-into-flutter-textfields-f0e676aaab7a
Upvotes: -2