opt: system message
This commit is contained in:
@ -1,7 +1,10 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:pilipala/common/widgets/http_error.dart';
|
||||
import 'package:pilipala/models/msg/system.dart';
|
||||
import 'package:pilipala/pages/message/utils/index.dart';
|
||||
import 'package:pilipala/utils/app_scheme.dart';
|
||||
import 'controller.dart';
|
||||
|
||||
class MessageSystemPage extends StatefulWidget {
|
||||
@ -97,6 +100,13 @@ class SystemItem extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// if (item.content is Map) {
|
||||
// var res = MessageUtils().extractLinks(item.content['web']);
|
||||
// print('res: $res');
|
||||
// } else {
|
||||
// var res = MessageUtils().extractLinks(item.content);
|
||||
// print('res: $res');
|
||||
// }
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(14, 14, 14, 12),
|
||||
child: Column(
|
||||
@ -111,9 +121,73 @@ class SystemItem extends StatelessWidget {
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.outline),
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Text(item.content is String ? item.content : item.content!['web']),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
buildContent(
|
||||
context,
|
||||
item.content is String ? item.content : item.content!['web']!,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// if (item.content is String)
|
||||
// Text(item.content)
|
||||
// else ...[
|
||||
// Text(item.content!['web']!),
|
||||
// ]
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
InlineSpan buildContent(
|
||||
BuildContext context,
|
||||
String content,
|
||||
) {
|
||||
final ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||
final List<InlineSpan> spanChilds = <InlineSpan>[];
|
||||
Map<String, dynamic> contentMap = MessageUtils().extractLinks(content);
|
||||
List<String> keys = contentMap.keys.toList();
|
||||
keys.removeWhere((element) => element == 'message');
|
||||
String patternStr = keys.join('|');
|
||||
RegExp regExp = RegExp(patternStr, caseSensitive: false);
|
||||
|
||||
contentMap['message'].splitMapJoin(
|
||||
regExp,
|
||||
onMatch: (Match match) {
|
||||
if (!match.group(0)!.startsWith('BV')) {
|
||||
spanChilds.add(
|
||||
WidgetSpan(
|
||||
child: Icon(Icons.link, color: colorScheme.primary, size: 16),
|
||||
),
|
||||
);
|
||||
}
|
||||
spanChilds.add(
|
||||
TextSpan(
|
||||
text: match.group(0),
|
||||
style: TextStyle(
|
||||
color: colorScheme.primary,
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
PiliSchame.routePush(Uri.parse(contentMap[match.group(0)]));
|
||||
},
|
||||
),
|
||||
);
|
||||
return '';
|
||||
},
|
||||
onNonMatch: (String text) {
|
||||
spanChilds.add(
|
||||
TextSpan(
|
||||
text: text,
|
||||
),
|
||||
);
|
||||
return '';
|
||||
},
|
||||
);
|
||||
return TextSpan(
|
||||
children: spanChilds,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,4 +86,56 @@ class MessageUtils {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// 匹配链接
|
||||
Map<String, String> extractLinks(String text) {
|
||||
Map<String, String> result = {};
|
||||
String message = '';
|
||||
// 是否匹配到bv
|
||||
RegExp bvRegex = RegExp(r'bv1[\d\w]{9}', caseSensitive: false);
|
||||
final Iterable<RegExpMatch> bvMatches = bvRegex.allMatches(text);
|
||||
for (var match in bvMatches) {
|
||||
result[match.group(0)!] =
|
||||
'https://www.bilibili.com/video/${match.group(0)!}';
|
||||
}
|
||||
|
||||
// 定义正则表达式
|
||||
RegExp regex = RegExp(
|
||||
r'(?:(?:(?:http:\/\/|https:\/\/)(?:[a-zA-Z0-9_.-]+\.)*(?:bilibili|biligame)\.com(?:\/[/.$*?~=#!%@&\-\w]*)?)|(?:(?:http:\/\/|https:\/\/)(?:[a-zA-Z0-9_.-]+\.)*(?:acg|b23)\.tv(?:\/[/.$*?~=#!%@&\-\w]*)?)|(?:(?:http:\/\/|https:\/\/)dl\.(?:hdslb)\.com(?:\/[/.$*?~=#!%@&\-\w]*)?))');
|
||||
// 链接文字
|
||||
RegExp linkTextRegex = RegExp(r"#\{(.*?)\}");
|
||||
final Iterable<RegExpMatch> matches = regex.allMatches(text);
|
||||
int lastMatchEnd = 0;
|
||||
if (matches.isNotEmpty) {
|
||||
for (var match in matches) {
|
||||
final int start = match.start;
|
||||
final int end = match.end;
|
||||
String str = text.substring(lastMatchEnd, start);
|
||||
final Iterable<RegExpMatch> linkTextMatches =
|
||||
linkTextRegex.allMatches(str);
|
||||
|
||||
if (linkTextMatches.isNotEmpty) {
|
||||
for (var linkTextMatch in linkTextMatches) {
|
||||
if (linkTextMatch.group(1) != null) {
|
||||
String linkText = linkTextMatch.group(1)!;
|
||||
str = str
|
||||
.replaceAll(linkTextMatch.group(0)!, linkText)
|
||||
.replaceAll('{', '')
|
||||
.replaceAll('}', '');
|
||||
result[linkText] = match.group(0)!;
|
||||
}
|
||||
message += str;
|
||||
}
|
||||
} else {
|
||||
message += '$str查看详情';
|
||||
result['查看详情'] = match.group(0)!;
|
||||
}
|
||||
lastMatchEnd = end;
|
||||
}
|
||||
result['message'] = message;
|
||||
} else {
|
||||
result['message'] = text;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -764,14 +764,14 @@ InlineSpan buildContent(
|
||||
});
|
||||
} else {
|
||||
Uri uri = Uri.parse(matchStr.replaceAll('/?', '?'));
|
||||
SchemeEntity scheme = SchemeEntity(
|
||||
Uri scheme = Uri(
|
||||
scheme: uri.scheme,
|
||||
host: uri.host,
|
||||
port: uri.port,
|
||||
path: uri.path,
|
||||
query: uri.queryParameters,
|
||||
source: '',
|
||||
dataString: matchStr,
|
||||
// query: uri.queryParameters,
|
||||
// source: '',
|
||||
// dataString: matchStr,
|
||||
);
|
||||
PiliSchame.fullPathPush(scheme);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user