mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
opt: sys msg
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:PiliPalaX/utils/app_scheme.dart';
|
||||
import 'package:PiliPalaX/utils/utils.dart';
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'controller.dart';
|
||||
@@ -78,41 +82,48 @@ class _SysMsgPageState extends State<SysMsgPage> {
|
||||
} catch (_) {}
|
||||
}
|
||||
return ListTile(
|
||||
onTap: () {},
|
||||
title: Text(
|
||||
"${_sysMsgController.msgFeedSysMsgList[i].title}",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
color: Theme.of(context).colorScheme.primary),
|
||||
),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
onTap: () {},
|
||||
title: Text(
|
||||
"${_sysMsgController.msgFeedSysMsgList[i].title}",
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
Text.rich(
|
||||
_buildContent(content ?? ''),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurface
|
||||
.withOpacity(0.75),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
const SizedBox(height: 4),
|
||||
SelectableText("$content",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline)),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
"${_sysMsgController.msgFeedSysMsgList[i].timeAt}",
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline
|
||||
.withOpacity(0.8))),
|
||||
]));
|
||||
"${_sysMsgController.msgFeedSysMsgList[i].timeAt}",
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline
|
||||
.withOpacity(0.8),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return Divider(
|
||||
@@ -130,4 +141,85 @@ class _SysMsgPageState extends State<SysMsgPage> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
InlineSpan _buildContent(String content) {
|
||||
final List<InlineSpan> spanChildren = <InlineSpan>[];
|
||||
RegExp urlRegExp = RegExp('#\\{([^}]*)\\}\\{"([^}]*)"\\}');
|
||||
Iterable<Match> matches = urlRegExp.allMatches(content);
|
||||
int previousEndIndex = 0;
|
||||
if (matches.isNotEmpty) {
|
||||
for (final Match match in matches) {
|
||||
if (match.start > previousEndIndex) {
|
||||
spanChildren.add(
|
||||
TextSpan(
|
||||
text: content.substring(previousEndIndex, match.start),
|
||||
),
|
||||
);
|
||||
}
|
||||
spanChildren.add(
|
||||
TextSpan(
|
||||
text: match.group(1),
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.primary),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
try {
|
||||
Uri uri = Uri.parse(match.group(2)!);
|
||||
PiliScheme.routePush(uri);
|
||||
} catch (err) {
|
||||
SmartDialog.showToast(err.toString());
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
previousEndIndex = match.end;
|
||||
}
|
||||
} else {
|
||||
urlRegExp = RegExp(
|
||||
'https?:\\/\\/[^\\s/\$.?#].[^\\s]*|www\\.[^\\s/\$.?#].[^\\s]*');
|
||||
matches = urlRegExp.allMatches(content);
|
||||
if (matches.isNotEmpty) {
|
||||
for (final Match match in matches) {
|
||||
if (match.start > previousEndIndex) {
|
||||
spanChildren.add(
|
||||
TextSpan(
|
||||
text: content.substring(previousEndIndex, match.start),
|
||||
),
|
||||
);
|
||||
}
|
||||
spanChildren.add(
|
||||
WidgetSpan(
|
||||
alignment: PlaceholderAlignment.middle,
|
||||
child: Icon(
|
||||
size: MediaQuery.of(context).textScaler.scale(14),
|
||||
Icons.link,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
spanChildren.add(
|
||||
TextSpan(
|
||||
text: '网页链接',
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.primary),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
try {
|
||||
Uri uri = Uri.parse(match.group(0)!);
|
||||
PiliScheme.routePush(uri);
|
||||
} catch (err) {
|
||||
SmartDialog.showToast(err.toString());
|
||||
Utils.copyText(match.group(0) ?? '');
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
previousEndIndex = match.end;
|
||||
}
|
||||
} else {
|
||||
spanChildren.add(
|
||||
TextSpan(text: content),
|
||||
);
|
||||
}
|
||||
}
|
||||
return TextSpan(children: spanChildren);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user