opt: system message

This commit is contained in:
guozhigq
2024-10-19 21:38:03 +08:00
parent be29f70b30
commit bb2d5e5494
4 changed files with 145 additions and 19 deletions

View File

@ -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,
);
}
}

View File

@ -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;
}
}

View File

@ -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);
}