mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
@@ -3,5 +3,5 @@ enum RcmdType { web, app, notLogin }
|
|||||||
|
|
||||||
extension RcmdTypeExtension on RcmdType {
|
extension RcmdTypeExtension on RcmdType {
|
||||||
String get values => ['web', 'app', 'notLogin'][index];
|
String get values => ['web', 'app', 'notLogin'][index];
|
||||||
String get labels => ['web端', 'app端', '模拟未登录'][index];
|
String get labels => ['web端', 'app端', '游客模式'][index];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
enum ReplySortType { time, like, reply }
|
enum ReplySortType { time, like }
|
||||||
|
|
||||||
extension ReplySortTypeExtension on ReplySortType {
|
extension ReplySortTypeExtension on ReplySortType {
|
||||||
String get titles => ['最新评论', '最热评论', '回复最多'][index];
|
String get titles => ['最新评论', '最热评论'][index];
|
||||||
String get labels => ['最新', '最热', '最多回复'][index];
|
String get labels => ['最新', '最热'][index];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void changeFucCall(item, i) async {
|
void changeFucCall(item, i) async {
|
||||||
if (item.badge != null && vipStatus != 1) {
|
if (item.badge != null && item.badge == '会员' && vipStatus != 1) {
|
||||||
SmartDialog.showToast('需要大会员');
|
SmartDialog.showToast('需要大会员');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -255,11 +255,24 @@ class _BangumiPanelState extends State<BangumiPanel> {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 2),
|
const SizedBox(width: 2),
|
||||||
if (widget.pages[i].badge != null) ...[
|
if (widget.pages[i].badge != null) ...[
|
||||||
Image.asset(
|
if (widget.pages[i].badge == '会员') ...[
|
||||||
'assets/images/big-vip.png',
|
Image.asset(
|
||||||
height: 16,
|
'assets/images/big-vip.png',
|
||||||
),
|
height: 16,
|
||||||
],
|
),
|
||||||
|
],
|
||||||
|
if (widget.pages[i].badge != '会员') ...[
|
||||||
|
const Spacer(),
|
||||||
|
Text(
|
||||||
|
widget.pages[i].badge!,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 11,
|
||||||
|
color:
|
||||||
|
Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
]
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 3),
|
const SizedBox(height: 3),
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ class DynamicDetailController extends GetxController {
|
|||||||
}
|
}
|
||||||
int deaultReplySortIndex =
|
int deaultReplySortIndex =
|
||||||
setting.get(SettingBoxKey.replySortType, defaultValue: 0);
|
setting.get(SettingBoxKey.replySortType, defaultValue: 0);
|
||||||
|
if (deaultReplySortIndex == 2) {
|
||||||
|
setting.put(SettingBoxKey.replySortType, 0);
|
||||||
|
deaultReplySortIndex = 0;
|
||||||
|
}
|
||||||
_sortType = ReplySortType.values[deaultReplySortIndex];
|
_sortType = ReplySortType.values[deaultReplySortIndex];
|
||||||
sortTypeTitle.value = _sortType.titles;
|
sortTypeTitle.value = _sortType.titles;
|
||||||
sortTypeLabel.value = _sortType.labels;
|
sortTypeLabel.value = _sortType.labels;
|
||||||
@@ -92,9 +96,6 @@ class DynamicDetailController extends GetxController {
|
|||||||
_sortType = ReplySortType.like;
|
_sortType = ReplySortType.like;
|
||||||
break;
|
break;
|
||||||
case ReplySortType.like:
|
case ReplySortType.like:
|
||||||
_sortType = ReplySortType.reply;
|
|
||||||
break;
|
|
||||||
case ReplySortType.reply:
|
|
||||||
_sortType = ReplySortType.time;
|
_sortType = ReplySortType.time;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -96,9 +96,6 @@ class HtmlRenderController extends GetxController {
|
|||||||
_sortType = ReplySortType.like;
|
_sortType = ReplySortType.like;
|
||||||
break;
|
break;
|
||||||
case ReplySortType.like:
|
case ReplySortType.like:
|
||||||
_sortType = ReplySortType.reply;
|
|
||||||
break;
|
|
||||||
case ReplySortType.reply:
|
|
||||||
_sortType = ReplySortType.time;
|
_sortType = ReplySortType.time;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class RcmdController extends GetxController {
|
|||||||
setting.get(SettingBoxKey.enableSaveLastData, defaultValue: false);
|
setting.get(SettingBoxKey.enableSaveLastData, defaultValue: false);
|
||||||
defaultRcmdType =
|
defaultRcmdType =
|
||||||
setting.get(SettingBoxKey.defaultRcmdType, defaultValue: 'web');
|
setting.get(SettingBoxKey.defaultRcmdType, defaultValue: 'web');
|
||||||
if (defaultRcmdType == 'web'){
|
if (defaultRcmdType == 'web') {
|
||||||
videoList = <RecVideoItemModel>[].obs;
|
videoList = <RecVideoItemModel>[].obs;
|
||||||
} else {
|
} else {
|
||||||
videoList = <RecVideoItemAppModel>[].obs;
|
videoList = <RecVideoItemAppModel>[].obs;
|
||||||
@@ -41,7 +41,7 @@ class RcmdController extends GetxController {
|
|||||||
if (type == 'onRefresh') {
|
if (type == 'onRefresh') {
|
||||||
_currentPage = 0;
|
_currentPage = 0;
|
||||||
}
|
}
|
||||||
late final Map<String,dynamic> res;
|
late final Map<String, dynamic> res;
|
||||||
switch (defaultRcmdType) {
|
switch (defaultRcmdType) {
|
||||||
case 'app':
|
case 'app':
|
||||||
case 'notLogin':
|
case 'notLogin':
|
||||||
@@ -75,13 +75,12 @@ class RcmdController extends GetxController {
|
|||||||
_currentPage += 1;
|
_currentPage += 1;
|
||||||
// 若videoList数量太小,可能会影响翻页,此时再次请求
|
// 若videoList数量太小,可能会影响翻页,此时再次请求
|
||||||
// 为避免请求到的数据太少时还在反复请求,要求本次返回数据大于1条才触发
|
// 为避免请求到的数据太少时还在反复请求,要求本次返回数据大于1条才触发
|
||||||
if (res['data'].length > 1 && videoList.length < 10){
|
if (res['data'].length > 1 && videoList.length < 10) {
|
||||||
queryRcmdFeed('onLoad');
|
queryRcmdFeed('onLoad');
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Get.snackbar('提示', res['msg']);
|
|
||||||
}
|
}
|
||||||
isLoadingMore = false;
|
isLoadingMore = false;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下拉刷新
|
// 下拉刷新
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import 'package:get/get.dart';
|
|||||||
import 'package:pilipala/common/constants.dart';
|
import 'package:pilipala/common/constants.dart';
|
||||||
import 'package:pilipala/common/skeleton/video_card_v.dart';
|
import 'package:pilipala/common/skeleton/video_card_v.dart';
|
||||||
import 'package:pilipala/common/widgets/animated_dialog.dart';
|
import 'package:pilipala/common/widgets/animated_dialog.dart';
|
||||||
// import 'package:pilipala/common/widgets/http_error.dart';
|
import 'package:pilipala/common/widgets/http_error.dart';
|
||||||
import 'package:pilipala/common/widgets/overlay_pop.dart';
|
import 'package:pilipala/common/widgets/overlay_pop.dart';
|
||||||
import 'package:pilipala/common/widgets/video_card_v.dart';
|
import 'package:pilipala/common/widgets/video_card_v.dart';
|
||||||
import 'package:pilipala/pages/home/index.dart';
|
import 'package:pilipala/pages/home/index.dart';
|
||||||
@@ -26,6 +26,7 @@ class RcmdPage extends StatefulWidget {
|
|||||||
class _RcmdPageState extends State<RcmdPage>
|
class _RcmdPageState extends State<RcmdPage>
|
||||||
with AutomaticKeepAliveClientMixin {
|
with AutomaticKeepAliveClientMixin {
|
||||||
final RcmdController _rcmdController = Get.put(RcmdController());
|
final RcmdController _rcmdController = Get.put(RcmdController());
|
||||||
|
late Future _futureBuilderFuture;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get wantKeepAlive => true;
|
bool get wantKeepAlive => true;
|
||||||
@@ -33,7 +34,7 @@ class _RcmdPageState extends State<RcmdPage>
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_rcmdController.queryRcmdFeed('init');
|
_futureBuilderFuture = _rcmdController.queryRcmdFeed('init');
|
||||||
ScrollController scrollController = _rcmdController.scrollController;
|
ScrollController scrollController = _rcmdController.scrollController;
|
||||||
StreamController<bool> mainStream =
|
StreamController<bool> mainStream =
|
||||||
Get.find<MainController>().bottomBarStream;
|
Get.find<MainController>().bottomBarStream;
|
||||||
@@ -90,21 +91,40 @@ class _RcmdPageState extends State<RcmdPage>
|
|||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding:
|
padding:
|
||||||
const EdgeInsets.fromLTRB(0, StyleString.safeSpace, 0, 0),
|
const EdgeInsets.fromLTRB(0, StyleString.safeSpace, 0, 0),
|
||||||
sliver: Obx(() {
|
sliver: FutureBuilder(
|
||||||
// 使用Obx来监听数据的变化
|
future: _futureBuilderFuture,
|
||||||
if (_rcmdController.isLoadingMore &&
|
builder: (context, snapshot) {
|
||||||
_rcmdController.videoList.isEmpty) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
return contentGrid(_rcmdController, []);
|
Map data = snapshot.data as Map;
|
||||||
// 如果正在加载并且列表为空,则显示加载指示器
|
if (data['status']) {
|
||||||
// return const SliverToBoxAdapter(
|
return Obx(
|
||||||
// child: Center(child: CircularProgressIndicator()),
|
() {
|
||||||
// );
|
if (_rcmdController.isLoadingMore &&
|
||||||
} else {
|
_rcmdController.videoList.isEmpty) {
|
||||||
// 显示视频列表
|
return contentGrid(_rcmdController, []);
|
||||||
return contentGrid(
|
} else {
|
||||||
_rcmdController, _rcmdController.videoList);
|
// 显示视频列表
|
||||||
}
|
return contentGrid(
|
||||||
}),
|
_rcmdController, _rcmdController.videoList);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return HttpError(
|
||||||
|
errMsg: data['msg'],
|
||||||
|
fn: () {
|
||||||
|
setState(() {
|
||||||
|
_futureBuilderFuture =
|
||||||
|
_rcmdController.queryRcmdFeed('init');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return contentGrid(_rcmdController, []);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
LoadingMore(ctr: _rcmdController),
|
LoadingMore(ctr: _rcmdController),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
// 默认优先显示最新评论
|
// 默认优先显示最新评论
|
||||||
defaultReplySort =
|
defaultReplySort =
|
||||||
setting.get(SettingBoxKey.replySortType, defaultValue: 0);
|
setting.get(SettingBoxKey.replySortType, defaultValue: 0);
|
||||||
|
if (defaultReplySort == 2) {
|
||||||
|
setting.put(SettingBoxKey.replySortType, 0);
|
||||||
|
defaultReplySort = 0;
|
||||||
|
}
|
||||||
// 优先展示全部动态 all
|
// 优先展示全部动态 all
|
||||||
defaultDynamicType =
|
defaultDynamicType =
|
||||||
setting.get(SettingBoxKey.defaultDynamicType, defaultValue: 0);
|
setting.get(SettingBoxKey.defaultDynamicType, defaultValue: 0);
|
||||||
|
|||||||
@@ -41,8 +41,12 @@ class VideoReplyController extends GetxController {
|
|||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
final int deaultReplySortIndex =
|
int deaultReplySortIndex =
|
||||||
setting.get(SettingBoxKey.replySortType, defaultValue: 0) as int;
|
setting.get(SettingBoxKey.replySortType, defaultValue: 0) as int;
|
||||||
|
if (deaultReplySortIndex == 2) {
|
||||||
|
setting.put(SettingBoxKey.replySortType, 0);
|
||||||
|
deaultReplySortIndex = 0;
|
||||||
|
}
|
||||||
_sortType = ReplySortType.values[deaultReplySortIndex];
|
_sortType = ReplySortType.values[deaultReplySortIndex];
|
||||||
sortTypeTitle.value = _sortType.titles;
|
sortTypeTitle.value = _sortType.titles;
|
||||||
sortTypeLabel.value = _sortType.labels;
|
sortTypeLabel.value = _sortType.labels;
|
||||||
@@ -115,9 +119,6 @@ class VideoReplyController extends GetxController {
|
|||||||
_sortType = ReplySortType.like;
|
_sortType = ReplySortType.like;
|
||||||
break;
|
break;
|
||||||
case ReplySortType.like:
|
case ReplySortType.like:
|
||||||
_sortType = ReplySortType.reply;
|
|
||||||
break;
|
|
||||||
case ReplySortType.reply:
|
|
||||||
_sortType = ReplySortType.time;
|
_sortType = ReplySortType.time;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -571,7 +571,8 @@ InlineSpan buildContent(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// content.message = content.message.replaceAll(RegExp(r"\{vote:.*?\}"), ' ');
|
// content.message = content.message.replaceAll(RegExp(r"\{vote:.*?\}"), ' ');
|
||||||
content.message = content.message.replaceAll('&', '&')
|
content.message = content.message
|
||||||
|
.replaceAll('&', '&')
|
||||||
.replaceAll('<', '<')
|
.replaceAll('<', '<')
|
||||||
.replaceAll('>', '>')
|
.replaceAll('>', '>')
|
||||||
.replaceAll('"', '"')
|
.replaceAll('"', '"')
|
||||||
@@ -586,21 +587,21 @@ InlineSpan buildContent(
|
|||||||
e.replaceAll('?', '\\?').replaceAll('+', '\\+').replaceAll('*', '\\*')),
|
e.replaceAll('?', '\\?').replaceAll('+', '\\+').replaceAll('*', '\\*')),
|
||||||
];
|
];
|
||||||
|
|
||||||
String patternStr =
|
String patternStr = specialTokens.map(RegExp.escape).join('|');
|
||||||
specialTokens.map(RegExp.escape).join('|');
|
|
||||||
if (patternStr.isNotEmpty) {
|
if (patternStr.isNotEmpty) {
|
||||||
patternStr += "|";
|
patternStr += "|";
|
||||||
}
|
}
|
||||||
patternStr += r'(\b\d{1,2}[::]\d{2}\b)';
|
patternStr += r'(\b\d{1,2}[::]\d{2}\b)';
|
||||||
final RegExp pattern = RegExp(patternStr);
|
final RegExp pattern = RegExp(patternStr);
|
||||||
List<String> matchedStrs = [];
|
List<String> matchedStrs = [];
|
||||||
void addPlainTextSpan(str){
|
void addPlainTextSpan(str) {
|
||||||
spanChilds.add(TextSpan(
|
spanChilds.add(TextSpan(
|
||||||
text: str,
|
text: str,
|
||||||
recognizer: TapGestureRecognizer()
|
recognizer: TapGestureRecognizer()
|
||||||
..onTap = () =>
|
..onTap =
|
||||||
replyReply(replyItem.root == 0 ? replyItem : fReplyItem)));
|
() => replyReply(replyItem.root == 0 ? replyItem : fReplyItem)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分割文本并处理每个部分
|
// 分割文本并处理每个部分
|
||||||
content.message.splitMapJoin(
|
content.message.splitMapJoin(
|
||||||
pattern,
|
pattern,
|
||||||
@@ -674,57 +675,56 @@ InlineSpan buildContent(
|
|||||||
addPlainTextSpan(matchStr);
|
addPlainTextSpan(matchStr);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
spanChilds.add(
|
spanChilds.addAll(
|
||||||
TextSpan(
|
[
|
||||||
text: content.jumpUrl[matchStr]['title'],
|
if (content.jumpUrl[matchStr]?['prefix_icon'] != null) ...[
|
||||||
style: TextStyle(
|
WidgetSpan(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
child: Image.network(
|
||||||
),
|
content.jumpUrl[matchStr]['prefix_icon'],
|
||||||
recognizer: TapGestureRecognizer()
|
height: 19,
|
||||||
..onTap = () {
|
color: Theme.of(context).colorScheme.primary,
|
||||||
if (appUrlSchema == '') {
|
),
|
||||||
final String str = Uri.parse(matchStr).pathSegments[0];
|
)
|
||||||
final Map matchRes = IdUtils.matchAvorBv(input: str);
|
],
|
||||||
final List matchKeys = matchRes.keys.toList();
|
TextSpan(
|
||||||
if (matchKeys.isNotEmpty) {
|
text: content.jumpUrl[matchStr]['title'],
|
||||||
if (matchKeys.first == 'BV') {
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
recognizer: TapGestureRecognizer()
|
||||||
|
..onTap = () {
|
||||||
|
if (appUrlSchema == '') {
|
||||||
|
final String str = Uri.parse(matchStr).pathSegments[0];
|
||||||
|
final Map matchRes = IdUtils.matchAvorBv(input: str);
|
||||||
|
final List matchKeys = matchRes.keys.toList();
|
||||||
|
if (matchKeys.isNotEmpty) {
|
||||||
|
if (matchKeys.first == 'BV') {
|
||||||
|
Get.toNamed(
|
||||||
|
'/searchResult',
|
||||||
|
parameters: {'keyword': matchRes['BV']},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
Get.toNamed(
|
Get.toNamed(
|
||||||
'/searchResult',
|
'/webview',
|
||||||
parameters: {'keyword': matchRes['BV']},
|
parameters: {
|
||||||
|
'url': matchStr,
|
||||||
|
'type': 'url',
|
||||||
|
'pageTitle': ''
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Get.toNamed(
|
if (appUrlSchema.startsWith('bilibili://search')) {
|
||||||
'/webview',
|
Get.toNamed('/searchResult', parameters: {
|
||||||
parameters: {
|
'keyword': content.jumpUrl[matchStr]['title']
|
||||||
'url': matchStr,
|
});
|
||||||
'type': 'url',
|
}
|
||||||
'pageTitle': ''
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
if (appUrlSchema.startsWith('bilibili://search')) {
|
)
|
||||||
Get.toNamed('/searchResult', parameters: {
|
],
|
||||||
'keyword': content.jumpUrl[matchStr]['title']
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
if (appUrlSchema.startsWith('bilibili://search')) {
|
|
||||||
spanChilds.add(
|
|
||||||
WidgetSpan(
|
|
||||||
child: Icon(
|
|
||||||
FontAwesomeIcons.magnifyingGlass,
|
|
||||||
size: 9,
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
alignment: PlaceholderAlignment.top,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// 只显示一次
|
// 只显示一次
|
||||||
matchedStrs.add(matchStr);
|
matchedStrs.add(matchStr);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user