Merge remote-tracking branch 'upstream/main'

This commit is contained in:
orz12
2024-02-07 13:45:16 +08:00
10 changed files with 128 additions and 93 deletions

View File

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

View File

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

View File

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

View File

@@ -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:

View File

@@ -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:

View File

@@ -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;
} }
// 下拉刷新 // 下拉刷新

View File

@@ -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),
], ],

View File

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

View File

@@ -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:

View File

@@ -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('&amp;', '&') content.message = content.message
.replaceAll('&amp;', '&')
.replaceAll('&lt;', '<') .replaceAll('&lt;', '<')
.replaceAll('&gt;', '>') .replaceAll('&gt;', '>')
.replaceAll('&quot;', '"') .replaceAll('&quot;', '"')
@@ -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 {