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);
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ class PiliSchame {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scheme == 'https') {
|
||||
if (['http', 'https'].contains(scheme)) {
|
||||
fullPathPush(value);
|
||||
}
|
||||
}
|
||||
@ -148,16 +148,16 @@ class PiliSchame {
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> fullPathPush(SchemeEntity value) async {
|
||||
static Future<void> fullPathPush(Uri value) async {
|
||||
// https://m.bilibili.com/bangumi/play/ss39708
|
||||
// https | m.bilibili.com | /bangumi/play/ss39708
|
||||
// final String scheme = value.scheme!;
|
||||
final String host = value.host!;
|
||||
final String? path = value.path;
|
||||
Map<String, String>? query = value.query;
|
||||
final String host = value.host;
|
||||
final String path = value.path;
|
||||
Map<String, String>? query = value.queryParameters;
|
||||
RegExp regExp = RegExp(r'^((www\.)|(m\.))?bilibili\.com$');
|
||||
if (regExp.hasMatch(host)) {
|
||||
final String lastPathSegment = path!.split('/').last;
|
||||
final String lastPathSegment = path.split('/').last;
|
||||
if (path.startsWith('/video')) {
|
||||
Map matchRes = IdUtils.matchAvorBv(input: path);
|
||||
if (matchRes.containsKey('AV')) {
|
||||
@ -182,13 +182,13 @@ class PiliSchame {
|
||||
_videoPush(Utils.matchNum(path.split('?').first).first, null);
|
||||
}
|
||||
} else if (host.contains('live')) {
|
||||
int roomId = int.parse(path!.split('/').last);
|
||||
int roomId = int.parse(path.split('/').last);
|
||||
Get.toNamed(
|
||||
'/liveRoom?roomid=$roomId',
|
||||
arguments: {'liveItem': null, 'heroTag': roomId.toString()},
|
||||
);
|
||||
} else if (host.contains('space')) {
|
||||
var mid = path!.split('/').last;
|
||||
var mid = path.split('/').last;
|
||||
Get.toNamed('/member?mid=$mid', arguments: {'face': ''});
|
||||
return;
|
||||
} else if (host == 'b23.tv') {
|
||||
@ -223,7 +223,7 @@ class PiliSchame {
|
||||
parameters: {'url': redirectUrl, 'type': 'url', 'pageTitle': ''},
|
||||
);
|
||||
}
|
||||
} else if (path != null) {
|
||||
} else {
|
||||
final String area = path.split('/').last;
|
||||
switch (area) {
|
||||
case 'bangumi':
|
||||
@ -247,12 +247,12 @@ class PiliSchame {
|
||||
break;
|
||||
case 'read':
|
||||
print('专栏');
|
||||
String id = Utils.matchNum(query!['id']!).first.toString();
|
||||
String id = Utils.matchNum(query['id']!).first.toString();
|
||||
Get.toNamed('/read', parameters: {
|
||||
'url': value.dataString!,
|
||||
'url': value.toString(),
|
||||
'title': '',
|
||||
'id': id,
|
||||
'articleType': 'read'
|
||||
'articleType': 'read',
|
||||
});
|
||||
break;
|
||||
case 'space':
|
||||
@ -270,9 +270,9 @@ class PiliSchame {
|
||||
Get.toNamed(
|
||||
'/webview',
|
||||
parameters: {
|
||||
'url': value.dataString ?? "",
|
||||
'url': value.toString(),
|
||||
'type': 'url',
|
||||
'pageTitle': ''
|
||||
'pageTitle': '',
|
||||
},
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user