opt: resCode, post panel

fix: bangumi panel

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2024-11-25 20:47:05 +08:00
parent bae395c5d0
commit 2fc4760269
12 changed files with 329 additions and 404 deletions

View File

@@ -158,7 +158,9 @@ class _ListSheetContentState extends State<ListSheetContent>
late String title; late String title;
if (episode.runtimeType.toString() == "EpisodeItem") { if (episode.runtimeType.toString() == "EpisodeItem") {
if (episode.longTitle != null && episode.longTitle != "") { if (episode.longTitle != null && episode.longTitle != "") {
title = "${(episode.title ?? '${index + 1}')}话 ${episode.longTitle!}"; dynamic leading = episode.title ?? index + 1;
title =
"${Utils.isStringNumeric(leading) ? '$leading话' : leading} ${episode.longTitle!}";
} else { } else {
title = episode.title!; title = episode.title!;
} }
@@ -255,13 +257,12 @@ class _ListSheetContentState extends State<ListSheetContent>
'assets/images/big-vip.png', 'assets/images/big-vip.png',
height: 20, height: 20,
semanticLabel: "大会员", semanticLabel: "大会员",
), )
if (episode.badge != '会员') Text(episode.badge), else
Text(episode.badge),
const SizedBox(width: 10), const SizedBox(width: 10),
], ],
if (!(episode.runtimeType.toString() == 'EpisodeItem' && if (episode is! bangumi.EpisodeItem) Text('${index + 1}/$length'),
(episode.longTitle != null && episode.longTitle != '')))
Text('${index + 1}/$length'),
], ],
), ),
); );

View File

@@ -1,3 +1,6 @@
import 'package:PiliPalaX/common/widgets/stat/danmu.dart';
import 'package:PiliPalaX/common/widgets/stat/view.dart';
import 'package:PiliPalaX/common/widgets/video_popup_menu.dart';
import 'package:PiliPalaX/models/space_archive/item.dart'; import 'package:PiliPalaX/models/space_archive/item.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -14,163 +17,98 @@ class VideoCardHMemberVideo extends StatelessWidget {
required this.videoItem, required this.videoItem,
this.longPress, this.longPress,
this.longPressEnd, this.longPressEnd,
this.source = 'normal',
this.showOwner = true,
this.showView = true,
this.showDanmaku = true,
this.showPubdate = false,
}); });
final Item videoItem; final Item videoItem;
final Function()? longPress; final Function()? longPress;
final Function()? longPressEnd; final Function()? longPressEnd;
final String source;
final bool showOwner;
final bool showView;
final bool showDanmaku;
final bool showPubdate;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final int aid = int.tryParse(videoItem.param ?? '') ?? -1; final int aid = int.tryParse(videoItem.param ?? '') ?? -1;
final String bvid = videoItem.bvid ?? ''; final String bvid = videoItem.bvid ?? '';
String type = 'video';
// try {
// type = videoItem.type;
// } catch (_) {}
// List<VideoCustomAction> actions =
// VideoCustomActions(videoItem, context).actions;
final String heroTag = Utils.makeHeroTag(aid); final String heroTag = Utils.makeHeroTag(aid);
return Stack(children: [ return Stack(children: [
Semantics( InkWell(
// label: Utils.videoItemSemantics(videoItem), borderRadius: BorderRadius.circular(12),
excludeSemantics: true, onLongPress: () {
// customSemanticsActions: <CustomSemanticsAction, void Function()>{ if (longPress != null) {
// for (var item in actions) longPress!();
// CustomSemanticsAction(label: item.title): item.onTap!, }
// }, },
child: InkWell( onTap: () async {
borderRadius: BorderRadius.circular(12), try {
onLongPress: () { Get.toNamed('/video?bvid=$bvid&cid=${videoItem.firstCid}',
if (longPress != null) { arguments: {'heroTag': heroTag});
longPress!(); } catch (err) {
} SmartDialog.showToast(err.toString());
}, }
onTap: () async { },
if (type == 'ketang') { child: LayoutBuilder(
SmartDialog.showToast('课堂视频暂不支持播放'); builder: (BuildContext context, BoxConstraints boxConstraints) {
return; return Row(
} mainAxisAlignment: MainAxisAlignment.start,
try { crossAxisAlignment: CrossAxisAlignment.start,
// PiliScheme.routePush(Uri.parse(videoItem.smallCoverV5.base.uri)); children: <Widget>[
// final int cid = AspectRatio(
// videoItem.smallCoverV5.base.playerArgs.cid.toInt() ?? aspectRatio: StyleString.aspectRatio,
// await SearchHttp.ab2c(aid: aid, bvid: bvid); child: LayoutBuilder(
Get.toNamed('/video?bvid=$bvid&cid=${videoItem.firstCid}', builder:
arguments: {'heroTag': heroTag}); (BuildContext context, BoxConstraints boxConstraints) {
// Get.toNamed('/video?bvid=$bvid&cid=$cid', final double maxWidth = boxConstraints.maxWidth;
// arguments: {'videoItem': videoItem, 'heroTag': heroTag}); final double maxHeight = boxConstraints.maxHeight;
} catch (err) { return Stack(
SmartDialog.showToast(err.toString()); children: [
} Hero(
}, tag: heroTag,
child: LayoutBuilder( child: NetworkImgLayer(
builder: (BuildContext context, BoxConstraints boxConstraints) { src: videoItem.cover,
return Row( width: maxWidth,
mainAxisAlignment: MainAxisAlignment.start, height: maxHeight,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
AspectRatio(
aspectRatio: StyleString.aspectRatio,
child: LayoutBuilder(
builder: (BuildContext context,
BoxConstraints boxConstraints) {
final double maxWidth = boxConstraints.maxWidth;
final double maxHeight = boxConstraints.maxHeight;
return Stack(
children: [
Hero(
tag: heroTag,
child: NetworkImgLayer(
src: videoItem.cover,
width: maxWidth,
height: maxHeight,
),
), ),
if (videoItem.duration != null) ),
PBadge( if (videoItem.duration != null)
text: Utils.timeFormat(videoItem.duration), PBadge(
right: 6.0, text: Utils.timeFormat(videoItem.duration),
bottom: 6.0, right: 6.0,
type: 'gray', bottom: 6.0,
), type: 'gray',
if (type != 'video') ),
PBadge( ],
text: type, );
left: 6.0, },
bottom: 6.0,
type: 'primary',
),
// if (videoItem.rcmdReason != null &&
// videoItem.rcmdReason.content != '')
// pBadge(videoItem.rcmdReason.content, context,
// 6.0, 6.0, null, null),
],
);
},
),
), ),
VideoContent( ),
videoItem: videoItem, VideoContent(
source: source, videoItem: videoItem,
showOwner: showOwner, )
showView: showView, ],
showDanmaku: showDanmaku, );
showPubdate: showPubdate, },
) ),
], ),
); Positioned(
}, bottom: 0,
), right: 0,
child: VideoPopupMenu(
size: 29,
iconSize: 17,
actions: VideoCustomActions(videoItem, context).actions,
), ),
), ),
// if (source == 'normal')
// Positioned(
// bottom: 0,
// right: 0,
// child: VideoPopupMenu(
// size: 29,
// iconSize: 17,
// actions: actions,
// ),
// ),
]); ]);
} }
} }
class VideoContent extends StatelessWidget { class VideoContent extends StatelessWidget {
final Item videoItem; final Item videoItem;
final String source;
final bool showOwner;
final bool showView;
final bool showDanmaku;
final bool showPubdate;
const VideoContent({ const VideoContent({
super.key, super.key,
required this.videoItem, required this.videoItem,
this.source = 'normal',
this.showOwner = true,
this.showView = true,
this.showDanmaku = true,
this.showPubdate = false,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// String pubdate = showPubdate
// ? Utils.dateFormat(videoItem.pubdate!, formatType: 'day')
// : '';
// if (pubdate != '') pubdate += ' ';
return Expanded( return Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.fromLTRB(10, 0, 6, 0), padding: const EdgeInsets.fromLTRB(10, 0, 6, 0),
@@ -193,39 +131,8 @@ class VideoContent extends StatelessWidget {
), ),
), ),
], ],
// const Spacer(),
// if (videoItem.rcmdReason != null &&
// videoItem.rcmdReason.content != '')
// Container(
// padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 5),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(4),
// border: Border.all(
// color: Theme.of(context).colorScheme.surfaceTint),
// ),
// child: Text(
// videoItem.rcmdReason.content,
// style: TextStyle(
// fontSize: 9,
// color: Theme.of(context).colorScheme.surfaceTint),
// ),
// ),
// const SizedBox(height: 4),
if (showOwner || showPubdate)
Text(
videoItem.publishTimeText ?? '',
maxLines: 1,
style: TextStyle(
fontWeight: FontWeight.w400,
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
height: 1,
color: Theme.of(context).colorScheme.outline,
overflow: TextOverflow.clip,
),
),
const SizedBox(height: 3),
Text( Text(
'${videoItem.viewContent} · ${videoItem.danmaku}', videoItem.publishTimeText ?? '',
maxLines: 1, maxLines: 1,
style: TextStyle( style: TextStyle(
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
@@ -235,24 +142,20 @@ class VideoContent extends StatelessWidget {
overflow: TextOverflow.clip, overflow: TextOverflow.clip,
), ),
), ),
// Row( const SizedBox(height: 3),
// children: [ Row(
// if (showView) ...[ children: [
// StatView( StatView(
// theme: 'gray', theme: 'gray',
// view: videoItem.stat.view as int, view: videoItem.viewContent,
// ), ),
// const SizedBox(width: 8), const SizedBox(width: 8),
// ], StatDanMu(
// if (showDanmaku) theme: 'gray',
// StatDanMu( danmu: videoItem.danmaku,
// theme: 'gray', ),
// danmu: videoItem.stat.danmu as int, ],
// ), ),
// const Spacer(),
// if (source == 'normal') const SizedBox(width: 24),
// ],
// ),
], ],
), ),
), ),

View File

@@ -20,11 +20,6 @@ class VideoCardVMemberHome extends StatelessWidget {
this.longPressEnd, this.longPressEnd,
}); });
bool isStringNumeric(String str) {
RegExp numericRegex = RegExp(r'^\d+$');
return numericRegex.hasMatch(str);
}
void onPushDetail(heroTag) async { void onPushDetail(heroTag) async {
String goto = videoItem.goto ?? ''; String goto = videoItem.goto ?? '';
switch (goto) { switch (goto) {

View File

@@ -9,6 +9,7 @@ import '../../http/video.dart';
import '../../models/home/rcmd/result.dart'; import '../../models/home/rcmd/result.dart';
import '../../pages/mine/controller.dart'; import '../../pages/mine/controller.dart';
import '../../utils/storage.dart'; import '../../utils/storage.dart';
import 'package:PiliPalaX/models/space_archive/item.dart';
class VideoCustomAction { class VideoCustomAction {
String title; String title;
@@ -47,211 +48,215 @@ class VideoCustomActions {
SmartDialog.showToast(res['msg']); SmartDialog.showToast(res['msg']);
}, },
), ),
VideoCustomAction( if (videoItem is! Item)
'访问:${videoItem.owner.name}', VideoCustomAction(
'visit', '访问:${videoItem.owner.name}',
Icon(MdiIcons.accountCircleOutline, size: 16), 'visit',
() async { Icon(MdiIcons.accountCircleOutline, size: 16),
Get.toNamed('/member?mid=${videoItem.owner.mid}', arguments: {
// 'face': videoItem.owner.face,
'heroTag': '${videoItem.owner.mid}',
});
},
),
VideoCustomAction(
'不感兴趣', 'dislike', Icon(MdiIcons.thumbDownOutline, size: 16),
() async { () async {
String? accessKey = GStorage.localCache Get.toNamed('/member?mid=${videoItem.owner.mid}', arguments: {
.get(LocalCacheKey.accessKey, defaultValue: {})['value']; // 'face': videoItem.owner.face,
if (accessKey == null || accessKey == "") { 'heroTag': '${videoItem.owner.mid}',
SmartDialog.showToast("请退出账号后重新登录"); });
return;
}
if (videoItem is RecVideoItemAppModel) {
RecVideoItemAppModel v = videoItem as RecVideoItemAppModel;
ThreePoint? tp = v.threePoint;
if (tp == null) {
SmartDialog.showToast("未能获取threePoint");
return;
}
if (tp.dislikeReasons == null && tp.feedbacks == null) {
SmartDialog.showToast("未能获取dislikeReasons或feedbacks");
return;
}
Widget actionButton(DislikeReason? r, FeedbackReason? f) {
return ElevatedButton(
style: ElevatedButton.styleFrom(
padding:
const EdgeInsets.symmetric(horizontal: 12.0, vertical: 0.0),
),
onPressed: () async {
SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.feedDislike(
reasonId: r?.id,
feedbackId: f?.id,
id: v.param!,
goto: v.goto!,
);
SmartDialog.dismiss();
SmartDialog.showToast(
res['status'] ? (r?.toast ?? f?.toast) : res['msg']);
Get.back();
},
child: Text(r?.name ?? f?.name ?? '未知'),
);
}
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('请选择'),
content: SingleChildScrollView(
child: Column(
children: [
if (tp.dislikeReasons != null)
const Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Text('我不想看'),
),
if (tp.dislikeReasons != null)
Wrap(
spacing: 5.0,
runSpacing: 2.0,
children: tp.dislikeReasons!.map((item) {
return actionButton(item, null);
}).toList(),
),
if (tp.feedbacks != null)
const Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Text('反馈'),
),
if (tp.feedbacks != null)
Wrap(
spacing: 5.0,
runSpacing: 2.0,
children: tp.feedbacks!.map((item) {
return actionButton(null, item);
}).toList(),
),
//分割线
const Divider(),
ElevatedButton(
onPressed: () async {
SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.feedDislikeCancel(
// reasonId: r?.id,
// feedbackId: f?.id,
id: v.param!,
goto: v.goto!,
);
SmartDialog.dismiss();
SmartDialog.showToast(
res['status'] ? "成功" : res['msg']);
Get.back();
},
child: const Text("撤销"),
),
],
),
),
);
},
);
} else {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('点踩该视频?'),
content: SingleChildScrollView(
child: Column(
children: [
const SizedBox(height: 5),
const Text("web端暂不支持精细选择"),
const SizedBox(height: 5),
Wrap(
spacing: 5.0,
runSpacing: 2.0,
children: [
ElevatedButton(
onPressed: () async {
SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.dislikeVideo(
bvid: videoItem.bvid as String, type: true);
SmartDialog.dismiss();
SmartDialog.showToast(
res['status'] ? "点踩成功" : res['msg']);
Get.back();
},
child: const Text("点踩"),
),
ElevatedButton(
onPressed: () async {
SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.dislikeVideo(
bvid: videoItem.bvid as String, type: false);
SmartDialog.dismiss();
SmartDialog.showToast(
res['status'] ? "取消踩" : res['msg']);
Get.back();
},
child: const Text("撤销"),
),
],
)
],
),
),
);
},
);
}
}),
VideoCustomAction('拉黑:${videoItem.owner.name}', 'block',
Icon(MdiIcons.cancel, size: 16), () async {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('提示'),
content:
Text('确定拉黑:${videoItem.owner.name}(${videoItem.owner.mid})?'
'\n\n被拉黑的Up可以在隐私设置-黑名单管理中解除'),
actions: [
TextButton(
onPressed: () => Get.back(),
child: Text(
'点错了',
style:
TextStyle(color: Theme.of(context).colorScheme.outline),
),
),
TextButton(
onPressed: () async {
var res = await VideoHttp.relationMod(
mid: videoItem.owner.mid,
act: 5,
reSrc: 11,
);
List<int> blackMidsList = GStorage.localCache
.get(LocalCacheKey.blackMidsList, defaultValue: [-1])
.map<int>((i) => i as int)
.toList();
blackMidsList.insert(0, videoItem.owner.mid);
GStorage.localCache
.put(LocalCacheKey.blackMidsList, blackMidsList);
Get.back();
SmartDialog.showToast(res['msg'] ?? '成功');
},
child: const Text('确认'),
)
],
);
}, },
); ),
}), if (videoItem is! Item)
VideoCustomAction(
'不感兴趣', 'dislike', Icon(MdiIcons.thumbDownOutline, size: 16),
() async {
String? accessKey = GStorage.localCache
.get(LocalCacheKey.accessKey, defaultValue: {})['value'];
if (accessKey == null || accessKey == "") {
SmartDialog.showToast("请退出账号后重新登录");
return;
}
if (videoItem is RecVideoItemAppModel) {
RecVideoItemAppModel v = videoItem as RecVideoItemAppModel;
ThreePoint? tp = v.threePoint;
if (tp == null) {
SmartDialog.showToast("未能获取threePoint");
return;
}
if (tp.dislikeReasons == null && tp.feedbacks == null) {
SmartDialog.showToast("未能获取dislikeReasons或feedbacks");
return;
}
Widget actionButton(DislikeReason? r, FeedbackReason? f) {
return ElevatedButton(
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 12.0, vertical: 0.0),
),
onPressed: () async {
SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.feedDislike(
reasonId: r?.id,
feedbackId: f?.id,
id: v.param!,
goto: v.goto!,
);
SmartDialog.dismiss();
SmartDialog.showToast(
res['status'] ? (r?.toast ?? f?.toast) : res['msg']);
Get.back();
},
child: Text(r?.name ?? f?.name ?? '未知'),
);
}
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('请选择'),
content: SingleChildScrollView(
child: Column(
children: [
if (tp.dislikeReasons != null)
const Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Text('我不想看'),
),
if (tp.dislikeReasons != null)
Wrap(
spacing: 5.0,
runSpacing: 2.0,
children: tp.dislikeReasons!.map((item) {
return actionButton(item, null);
}).toList(),
),
if (tp.feedbacks != null)
const Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Text('反馈'),
),
if (tp.feedbacks != null)
Wrap(
spacing: 5.0,
runSpacing: 2.0,
children: tp.feedbacks!.map((item) {
return actionButton(null, item);
}).toList(),
),
//分割线
const Divider(),
ElevatedButton(
onPressed: () async {
SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.feedDislikeCancel(
// reasonId: r?.id,
// feedbackId: f?.id,
id: v.param!,
goto: v.goto!,
);
SmartDialog.dismiss();
SmartDialog.showToast(
res['status'] ? "成功" : res['msg']);
Get.back();
},
child: const Text("撤销"),
),
],
),
),
);
},
);
} else {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('点踩该视频?'),
content: SingleChildScrollView(
child: Column(
children: [
const SizedBox(height: 5),
const Text("web端暂不支持精细选择"),
const SizedBox(height: 5),
Wrap(
spacing: 5.0,
runSpacing: 2.0,
children: [
ElevatedButton(
onPressed: () async {
SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.dislikeVideo(
bvid: videoItem.bvid as String, type: true);
SmartDialog.dismiss();
SmartDialog.showToast(
res['status'] ? "点踩成功" : res['msg']);
Get.back();
},
child: const Text("点踩"),
),
ElevatedButton(
onPressed: () async {
SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.dislikeVideo(
bvid: videoItem.bvid as String,
type: false);
SmartDialog.dismiss();
SmartDialog.showToast(
res['status'] ? "取消踩" : res['msg']);
Get.back();
},
child: const Text("撤销"),
),
],
)
],
),
),
);
},
);
}
}),
if (videoItem is! Item)
VideoCustomAction('拉黑:${videoItem.owner.name}', 'block',
Icon(MdiIcons.cancel, size: 16), () async {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('提示'),
content:
Text('确定拉黑:${videoItem.owner.name}(${videoItem.owner.mid})?'
'\n\n被拉黑的Up可以在隐私设置-黑名单管理中解除'),
actions: [
TextButton(
onPressed: () => Get.back(),
child: Text(
'点错了',
style: TextStyle(
color: Theme.of(context).colorScheme.outline),
),
),
TextButton(
onPressed: () async {
var res = await VideoHttp.relationMod(
mid: videoItem.owner.mid,
act: 5,
reSrc: 11,
);
List<int> blackMidsList = GStorage.localCache
.get(LocalCacheKey.blackMidsList, defaultValue: [-1])
.map<int>((i) => i as int)
.toList();
blackMidsList.insert(0, videoItem.owner.mid);
GStorage.localCache
.put(LocalCacheKey.blackMidsList, blackMidsList);
Get.back();
SmartDialog.showToast(res['msg'] ?? '成功');
},
child: const Text('确认'),
)
],
);
},
);
}),
VideoCustomAction( VideoCustomAction(
"${MineController.anonymity ? '退出' : '进入'}无痕模式", "${MineController.anonymity ? '退出' : '进入'}无痕模式",
'anonymity', 'anonymity',

View File

@@ -212,7 +212,7 @@ class Request {
data: { data: {
'message': await ApiInterceptor.dioError(e) 'message': await ApiInterceptor.dioError(e)
}, // 将自定义 Map 数据赋值给 Response 的 data 属性 }, // 将自定义 Map 数据赋值给 Response 的 data 属性
statusCode: 200, statusCode: -1,
requestOptions: RequestOptions(), requestOptions: RequestOptions(),
); );
return errResponse; return errResponse;
@@ -241,7 +241,7 @@ class Request {
data: { data: {
'message': await ApiInterceptor.dioError(e) 'message': await ApiInterceptor.dioError(e)
}, // 将自定义 Map 数据赋值给 Response 的 data 属性 }, // 将自定义 Map 数据赋值给 Response 的 data 属性
statusCode: 200, statusCode: -1,
requestOptions: RequestOptions(), requestOptions: RequestOptions(),
); );
return errResponse; return errResponse;

View File

@@ -76,7 +76,7 @@ class _BangumiIntroPanelState extends State<BangumiIntroPanel>
bangumiDetail: null, bangumiDetail: null,
cid: cid, cid: cid,
showEpisodes: widget.showEpisodes, showEpisodes: widget.showEpisodes,
showIntroDetail: widget.showIntroDetail, showIntroDetail: () {},
), ),
Success() => BangumiInfo( Success() => BangumiInfo(
heroTag: widget.heroTag, heroTag: widget.heroTag,

View File

@@ -49,7 +49,7 @@ class IntroDetail extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( SelectableText(
bangumiDetail!.title, bangumiDetail!.title,
style: const TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
@@ -97,7 +97,7 @@ class IntroDetail extends StatelessWidget {
style: Theme.of(context).textTheme.titleMedium, style: Theme.of(context).textTheme.titleMedium,
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( SelectableText(
'${bangumiDetail!.evaluate!}', '${bangumiDetail!.evaluate!}',
style: smallTitle.copyWith(fontSize: 13), style: smallTitle.copyWith(fontSize: 13),
), ),
@@ -107,7 +107,7 @@ class IntroDetail extends StatelessWidget {
style: Theme.of(context).textTheme.titleMedium, style: Theme.of(context).textTheme.titleMedium,
), ),
const SizedBox(height: 4), const SizedBox(height: 4),
Text( SelectableText(
bangumiDetail.actors, bangumiDetail.actors,
style: smallTitle.copyWith(fontSize: 13), style: smallTitle.copyWith(fontSize: 13),
), ),

View File

@@ -1,3 +1,4 @@
import 'package:PiliPalaX/utils/utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -129,8 +130,8 @@ class _BangumiPanelState extends State<BangumiPanel> {
), ),
child: Text( child: Text(
widget.newEp?['desc']?.contains('连载') == true widget.newEp?['desc']?.contains('连载') == true
? '连载中,更新至${widget.newEp?['title']}' ? '连载中,更新至${Utils.isStringNumeric(widget.newEp['title']) ? '${widget.newEp?['title']}' : '${widget.newEp?['title']}'}'
: '${widget.newEp?['title']}', : '${widget.pages.length}',
style: const TextStyle(fontSize: 13), style: const TextStyle(fontSize: 13),
), ),
), ),

View File

@@ -130,7 +130,6 @@ class _MemberVideoState extends State<MemberVideo>
} }
return VideoCardHMemberVideo( return VideoCardHMemberVideo(
videoItem: loadingState.response[index], videoItem: loadingState.response[index],
showPubdate: true,
); );
}, },
childCount: loadingState.response.length, childCount: loadingState.response.length,

View File

@@ -7,6 +7,7 @@ import 'package:PiliPalaX/pages/video/detail/controller.dart'
show SegmentType, SegmentTypeExt, SkipType, SkipTypeExt; show SegmentType, SegmentTypeExt, SkipType, SkipTypeExt;
import 'package:PiliPalaX/utils/storage.dart'; import 'package:PiliPalaX/utils/storage.dart';
import 'package:PiliPalaX/utils/utils.dart'; import 'package:PiliPalaX/utils/utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -57,7 +58,20 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
); );
_checkServerStatus() { _checkServerStatus() {
Request().get('$_blockServer/api/status').then((res) { Request()
.get(
'$_blockServer/api/status',
options: Options(
headers: {
'env': '',
'app-key': '',
'x-bili-mid': '',
'x-bili-aurora-eid': '',
'x-bili-aurora-zone': '',
},
),
)
.then((res) {
if (res.data is Map) { if (res.data is Map) {
setState(() { setState(() {
_serverStatus = res.data['uptime'] != null; _serverStatus = res.data['uptime'] != null;

View File

@@ -3,6 +3,7 @@ import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:PiliPalaX/common/constants.dart'; import 'package:PiliPalaX/common/constants.dart';
import 'package:PiliPalaX/common/widgets/icon_button.dart'; import 'package:PiliPalaX/common/widgets/icon_button.dart';
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
import 'package:PiliPalaX/common/widgets/pair.dart'; import 'package:PiliPalaX/common/widgets/pair.dart';
import 'package:PiliPalaX/common/widgets/segment_progress_bar.dart'; import 'package:PiliPalaX/common/widgets/segment_progress_bar.dart';
import 'package:PiliPalaX/http/danmaku.dart'; import 'package:PiliPalaX/http/danmaku.dart';
@@ -1045,7 +1046,7 @@ class VideoDetailController extends GetxController
iconButton( iconButton(
context: context, context: context,
size: 26, size: 26,
tooltip: '使用当前位置', tooltip: '使用当前位置时间',
icon: Icons.my_location, icon: Icons.my_location,
onPressed: () { onPressed: () {
setState(() { setState(() {
@@ -1204,6 +1205,7 @@ class VideoDetailController extends GetxController
iconButton( iconButton(
context: context, context: context,
size: 26, size: 26,
tooltip: '移除',
icon: Icons.clear, icon: Icons.clear,
onPressed: () { onPressed: () {
setState(() { setState(() {
@@ -1365,7 +1367,7 @@ class VideoDetailController extends GetxController
) )
], ],
) )
: null, : errorWidget(),
); );
}, },
); );

View File

@@ -26,6 +26,11 @@ import 'package:url_launcher/url_launcher.dart';
class Utils { class Utils {
static final Random random = Random(); static final Random random = Random();
static bool isStringNumeric(str) {
RegExp numericRegex = RegExp(r'^\d+$');
return numericRegex.hasMatch(str.toString());
}
static ReplyInfo replyCast(res) { static ReplyInfo replyCast(res) {
Map? emote = res['content']['emote']; Map? emote = res['content']['emote'];
emote?.forEach((key, value) { emote?.forEach((key, value) {