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 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:PiliPalaX/utils/app_scheme.dart';
|
||||||
|
import 'package:PiliPalaX/utils/utils.dart';
|
||||||
import 'package:easy_debounce/easy_throttle.dart';
|
import 'package:easy_debounce/easy_throttle.dart';
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
@@ -78,41 +82,48 @@ class _SysMsgPageState extends State<SysMsgPage> {
|
|||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
return ListTile(
|
return ListTile(
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
title: Text(
|
title: Text(
|
||||||
"${_sysMsgController.msgFeedSysMsgList[i].title}",
|
"${_sysMsgController.msgFeedSysMsgList[i].title}",
|
||||||
style: Theme.of(context)
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
.textTheme
|
),
|
||||||
.titleMedium!
|
subtitle: Column(
|
||||||
.copyWith(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
color: Theme.of(context).colorScheme.primary),
|
children: [
|
||||||
),
|
const SizedBox(height: 4),
|
||||||
subtitle: Column(
|
Text.rich(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
_buildContent(content ?? ''),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onSurface
|
||||||
|
.withOpacity(0.75),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
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(
|
Text(
|
||||||
"${_sysMsgController.msgFeedSysMsgList[i].timeAt}",
|
"${_sysMsgController.msgFeedSysMsgList[i].timeAt}",
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodySmall!
|
.bodySmall!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.outline
|
.outline
|
||||||
.withOpacity(0.8))),
|
.withOpacity(0.8),
|
||||||
]));
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
separatorBuilder: (BuildContext context, int index) {
|
separatorBuilder: (BuildContext context, int index) {
|
||||||
return Divider(
|
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