mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 13:08:42 +00:00
fix #63
This commit is contained in:
parent
ad674dc77f
commit
672a8cff01
6 changed files with 95 additions and 13 deletions
77
lib/src/components/better_text.dart
Normal file
77
lib/src/components/better_text.dart
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
class BetterText extends StatelessWidget {
|
||||||
|
final String text;
|
||||||
|
|
||||||
|
const BetterText({super.key, required this.text});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// Regular expression to find URLs and domains
|
||||||
|
final RegExp urlRegExp = RegExp(
|
||||||
|
r'(?:(?:https?://|www\.)[^\s]+|(?:[a-zA-Z0-9-]+\.[a-zA-Z]{2,}))',
|
||||||
|
caseSensitive: false,
|
||||||
|
multiLine: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Split the text into parts based on the URLs and domains
|
||||||
|
final List<TextSpan> spans = [];
|
||||||
|
final Iterable<RegExpMatch> matches = urlRegExp.allMatches(text);
|
||||||
|
|
||||||
|
int lastMatchEnd = 0;
|
||||||
|
|
||||||
|
for (final match in matches) {
|
||||||
|
// Add the text before the URL/domain
|
||||||
|
if (match.start > lastMatchEnd) {
|
||||||
|
spans.add(TextSpan(text: text.substring(lastMatchEnd, match.start)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the URL/domain as a clickable TextSpan
|
||||||
|
final String? url = match.group(0);
|
||||||
|
spans.add(TextSpan(
|
||||||
|
text: url,
|
||||||
|
style: TextStyle(color: Colors.blue),
|
||||||
|
recognizer: TapGestureRecognizer()
|
||||||
|
..onTap = () async {
|
||||||
|
final lUrl =
|
||||||
|
Uri.parse(url!.startsWith('http') ? url : 'http://$url');
|
||||||
|
try {
|
||||||
|
await launchUrl(lUrl);
|
||||||
|
} catch (e) {
|
||||||
|
Logger("launchUrl").shout("Could not launch $e");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
lastMatchEnd = match.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add any remaining text after the last URL/domain
|
||||||
|
if (lastMatchEnd < text.length) {
|
||||||
|
spans.add(TextSpan(text: text.substring(lastMatchEnd)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SelectableText.rich(
|
||||||
|
TextSpan(
|
||||||
|
children: spans,
|
||||||
|
),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white, // Set text color for contrast
|
||||||
|
fontSize: 17,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// child: SelectableText(
|
||||||
|
// content.text,
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: Colors.white, // Set text color for contrast
|
||||||
|
// fontSize: 17,
|
||||||
|
// ),
|
||||||
|
// textAlign: TextAlign.left, // Center the text
|
||||||
|
// ),
|
||||||
|
// RichText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
"onboardingTryForFree": "Kostenlos testen",
|
"onboardingTryForFree": "Kostenlos testen",
|
||||||
"registerUsernameSlogan": "Bitte wähle einen Benutzernamen, damit dich andere finden können!",
|
"registerUsernameSlogan": "Bitte wähle einen Benutzernamen, damit dich andere finden können!",
|
||||||
"registerUsernameDecoration": "Benutzername",
|
"registerUsernameDecoration": "Benutzername",
|
||||||
"registerUsernameLimits": "Der Benutzername muss 4 bis 12 Zeichen lang sein und darf nur aus Buchstaben (a-z) und Zahlen (0-9) bestehen.",
|
"registerUsernameLimits": "Der Benutzername muss 3 bis 12 Zeichen lang sein und darf nur aus Buchstaben (a-z) und Zahlen (0-9) bestehen.",
|
||||||
"registerSubmitButton": "Jetzt registrieren!",
|
"registerSubmitButton": "Jetzt registrieren!",
|
||||||
"newMessageTitle": "Neue Nachricht",
|
"newMessageTitle": "Neue Nachricht",
|
||||||
"chatsTapToSend": "Klicke, um dein erstes Bild zu teilen.",
|
"chatsTapToSend": "Klicke, um dein erstes Bild zu teilen.",
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
"onboardingTryForFree": "Try for free",
|
"onboardingTryForFree": "Try for free",
|
||||||
"registerUsernameSlogan": "Please select a username so others can find you!",
|
"registerUsernameSlogan": "Please select a username so others can find you!",
|
||||||
"registerUsernameDecoration": "Username",
|
"registerUsernameDecoration": "Username",
|
||||||
"registerUsernameLimits": "Username must be 4 to 12 characters long, consisting only of letters (a-z) and numbers (0-9).",
|
"registerUsernameLimits": "Username must be 3 to 12 characters long, consisting only of letters (a-z) and numbers (0-9).",
|
||||||
"registerSubmitButton": "Register now!",
|
"registerSubmitButton": "Register now!",
|
||||||
"newMessageTitle": "New message",
|
"newMessageTitle": "New message",
|
||||||
"chatsTapToSend": "Click to send your first image",
|
"chatsTapToSend": "Click to send your first image",
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,14 @@ Future initMediaStorage() async {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Box> getMediaStorage() async {
|
Future<Box> getMediaStorage() async {
|
||||||
await initMediaStorage();
|
|
||||||
|
|
||||||
final storage = getSecureStorage();
|
final storage = getSecureStorage();
|
||||||
|
|
||||||
|
var containsEncryptionKey =
|
||||||
|
await storage.containsKey(key: 'hive_encryption_key');
|
||||||
|
if (!containsEncryptionKey) {
|
||||||
|
await initMediaStorage();
|
||||||
|
}
|
||||||
|
|
||||||
var encryptionKey =
|
var encryptionKey =
|
||||||
base64Url.decode((await storage.read(key: 'hive_encryption_key'))!);
|
base64Url.decode((await storage.read(key: 'hive_encryption_key'))!);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:twonly/globals.dart';
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/src/components/animate_icon.dart';
|
import 'package:twonly/src/components/animate_icon.dart';
|
||||||
|
import 'package:twonly/src/components/better_text.dart';
|
||||||
import 'package:twonly/src/components/initialsavatar.dart';
|
import 'package:twonly/src/components/initialsavatar.dart';
|
||||||
import 'package:twonly/src/components/message_send_state_icon.dart';
|
import 'package:twonly/src/components/message_send_state_icon.dart';
|
||||||
import 'package:twonly/src/components/verified_shield.dart';
|
import 'package:twonly/src/components/verified_shield.dart';
|
||||||
|
|
@ -62,14 +63,7 @@ class ChatListEntry extends StatelessWidget {
|
||||||
83, 68, 137, 255), // Set the background color
|
83, 68, 137, 255), // Set the background color
|
||||||
borderRadius: BorderRadius.circular(12.0), // Set border radius
|
borderRadius: BorderRadius.circular(12.0), // Set border radius
|
||||||
),
|
),
|
||||||
child: SelectableText(
|
child: BetterText(text: content.text),
|
||||||
content.text,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white, // Set text color for contrast
|
|
||||||
fontSize: 17,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.left, // Center the text
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (content is MediaMessageContent && !content.isVideo) {
|
} else if (content is MediaMessageContent && !content.isVideo) {
|
||||||
|
|
|
||||||
|
|
@ -105,9 +105,15 @@ class _RegisterViewState extends State<RegisterView> {
|
||||||
const SizedBox(height: 15),
|
const SizedBox(height: 15),
|
||||||
TextField(
|
TextField(
|
||||||
controller: usernameController,
|
controller: usernameController,
|
||||||
|
onChanged: (value) {
|
||||||
|
usernameController.text = value.toLowerCase();
|
||||||
|
usernameController.selection = TextSelection.fromPosition(
|
||||||
|
TextPosition(offset: usernameController.text.length),
|
||||||
|
);
|
||||||
|
},
|
||||||
inputFormatters: [
|
inputFormatters: [
|
||||||
LengthLimitingTextInputFormatter(12),
|
LengthLimitingTextInputFormatter(12),
|
||||||
FilteringTextInputFormatter.allow(RegExp(r'[a-z0-9]')),
|
FilteringTextInputFormatter.allow(RegExp(r'[a-z0-9A-Z]')),
|
||||||
],
|
],
|
||||||
style: TextStyle(fontSize: 17),
|
style: TextStyle(fontSize: 17),
|
||||||
decoration: getInputDecoration(
|
decoration: getInputDecoration(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue