diff --git a/lib/common/widgets/image/network_img_layer.dart b/lib/common/widgets/image/network_img_layer.dart index 428f9ce11..c608d2393 100644 --- a/lib/common/widgets/image/network_img_layer.dart +++ b/lib/common/widgets/image/network_img_layer.dart @@ -56,7 +56,7 @@ class NetworkImgLayer extends StatelessWidget { : getPlaceHolder?.call() ?? placeholder(context); } - Widget _buildImage(context) { + Widget _buildImage(BuildContext context) { int? memCacheWidth, memCacheHeight; if (height == null || callback?.call() == true || width <= height!) { memCacheWidth = width.cacheSize(context); diff --git a/lib/common/widgets/video_card/video_card_h.dart b/lib/common/widgets/video_card/video_card_h.dart index 1e965019c..73042ece7 100644 --- a/lib/common/widgets/video_card/video_card_h.dart +++ b/lib/common/widgets/video_card/video_card_h.dart @@ -21,7 +21,6 @@ class VideoCardH extends StatelessWidget { const VideoCardH({ super.key, required this.videoItem, - this.source = 'normal', this.showOwner = true, this.showView = true, this.showDanmaku = true, @@ -31,7 +30,6 @@ class VideoCardH extends StatelessWidget { this.onViewLater, }); final BaseVideoItemModel videoItem; - final String source; final bool showOwner; final bool showView; final bool showDanmaku; @@ -42,8 +40,6 @@ class VideoCardH extends StatelessWidget { @override Widget build(BuildContext context) { - final int aid = videoItem.aid!; - final String bvid = videoItem.bvid!; String type = 'video'; if (videoItem case SearchVideoItemModel item) { var typeOrNull = item.type; @@ -90,19 +86,16 @@ class VideoCardH extends StatelessWidget { } try { final int? cid = videoItem.cid ?? - await SearchHttp.ab2c(aid: aid, bvid: bvid); + await SearchHttp.ab2c( + aid: videoItem.aid, bvid: videoItem.bvid); if (cid != null) { - if (source == 'later') { - onViewLater!(cid); - } else { - PageUtils.toVideoPage( - 'bvid=$bvid&cid=$cid', - arguments: { - 'videoItem': videoItem, - 'heroTag': Utils.makeHeroTag(aid) - }, - ); - } + PageUtils.toVideoPage( + 'bvid=${videoItem.bvid}&cid=$cid', + arguments: { + 'videoItem': videoItem, + 'heroTag': Utils.makeHeroTag(videoItem.aid) + }, + ); } } catch (err) { SmartDialog.showToast(err.toString()); @@ -181,28 +174,27 @@ class VideoCardH extends StatelessWidget { ), ), const SizedBox(width: 10), - videoContent(context), + content(context), ], ), ), ), ), - if (source == 'normal') - Positioned( - bottom: 0, - right: 12, - child: VideoPopupMenu( - size: 29, - iconSize: 17, - videoItem: videoItem, - ), + Positioned( + bottom: 0, + right: 12, + child: VideoPopupMenu( + size: 29, + iconSize: 17, + videoItem: videoItem, ), + ), ], ), ); } - Widget videoContent(BuildContext context) { + Widget content(BuildContext context) { final theme = Theme.of(context); String pubdate = showPubdate ? Utils.dateFormat(videoItem.pubdate!, formatType: 'day') @@ -262,23 +254,20 @@ class VideoCardH extends StatelessWidget { ), const SizedBox(height: 3), Row( + spacing: 8, children: [ - if (showView) ...[ + if (showView) StatView( context: context, theme: 'gray', value: videoItem.stat.viewStr, ), - const SizedBox(width: 8), - ], if (showDanmaku) StatDanMu( context: context, theme: 'gray', value: videoItem.stat.danmuStr, ), - const Spacer(), - if (source == 'normal') const SizedBox(width: 24), ], ), ], diff --git a/lib/common/widgets/video_card/video_card_v.dart b/lib/common/widgets/video_card/video_card_v.dart index 1f284cf21..d41e7e65b 100644 --- a/lib/common/widgets/video_card/video_card_v.dart +++ b/lib/common/widgets/video_card/video_card_v.dart @@ -32,7 +32,7 @@ class VideoCardV extends StatelessWidget { return numericRegex.hasMatch(str); } - Future onPushDetail(heroTag) async { + Future onPushDetail(String heroTag) async { String? goto = videoItem.goto; switch (goto) { case 'bangumi': @@ -136,7 +136,7 @@ class VideoCardV extends StatelessWidget { ); }), ), - videoContent(context) + content(context) ], ), ), @@ -157,7 +157,7 @@ class VideoCardV extends StatelessWidget { ); } - Widget videoContent(context) { + Widget content(BuildContext context) { final theme = Theme.of(context); return Expanded( child: Padding( diff --git a/lib/http/dynamics.dart b/lib/http/dynamics.dart index 8bde6127c..f0ac902e9 100644 --- a/lib/http/dynamics.dart +++ b/lib/http/dynamics.dart @@ -41,36 +41,36 @@ class DynamicsHttp { }; var res = await Request().get(Api.followDynamic, queryParameters: data); if (res.data['code'] == 0) { - // try { - DynamicsDataModel data = DynamicsDataModel.fromJson(res.data['data']); - final antiGoodsDyn = GStorage.antiGoodsDyn; - final filterWord = banWordForDyn.pattern.isNotEmpty; + try { + DynamicsDataModel data = DynamicsDataModel.fromJson(res.data['data']); + final antiGoodsDyn = GStorage.antiGoodsDyn; + final filterWord = banWordForDyn.pattern.isNotEmpty; - data.items?.removeWhere( - (item) => - (antiGoodsDyn && - (item.orig?.modules.moduleDynamic?.additional?.type == - 'ADDITIONAL_TYPE_GOODS' || - item.modules.moduleDynamic?.additional?.type == - 'ADDITIONAL_TYPE_GOODS')) || - (filterWord && - (item.orig?.modules.moduleDynamic?.major?.opus?.summary?.text - ?.contains(banWordForDyn) == - true || - item.modules.moduleDynamic?.major?.opus?.summary?.text - ?.contains(banWordForDyn) == - true || - item.orig?.modules.moduleDynamic?.desc?.text - ?.contains(banWordForDyn) == - true || - item.modules.moduleDynamic?.desc?.text - ?.contains(banWordForDyn) == - true)), - ); - return Success(data); - // } catch (err) { - // return Error(err.toString()); - // } + data.items?.removeWhere( + (item) => + (antiGoodsDyn && + (item.orig?.modules.moduleDynamic?.additional?.type == + 'ADDITIONAL_TYPE_GOODS' || + item.modules.moduleDynamic?.additional?.type == + 'ADDITIONAL_TYPE_GOODS')) || + (filterWord && + (item.orig?.modules.moduleDynamic?.major?.opus?.summary?.text + ?.contains(banWordForDyn) == + true || + item.modules.moduleDynamic?.major?.opus?.summary?.text + ?.contains(banWordForDyn) == + true || + item.orig?.modules.moduleDynamic?.desc?.text + ?.contains(banWordForDyn) == + true || + item.modules.moduleDynamic?.desc?.text + ?.contains(banWordForDyn) == + true)), + ); + return Success(data); + } catch (err) { + return Error(err.toString()); + } } else { return Error(res.data['message']); } diff --git a/lib/http/user.dart b/lib/http/user.dart index 5c961fbaa..3be43e283 100644 --- a/lib/http/user.dart +++ b/lib/http/user.dart @@ -2,10 +2,10 @@ import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/http/api.dart'; import 'package:PiliPlus/http/init.dart'; import 'package:PiliPlus/http/loading_state.dart'; -import 'package:PiliPlus/models/model_hot_video_item.dart'; import 'package:PiliPlus/models/user/info.dart'; import 'package:PiliPlus/models/user/stat.dart'; import 'package:PiliPlus/models_new/history/data.dart'; +import 'package:PiliPlus/models_new/later/data.dart'; import 'package:PiliPlus/models_new/media_list/data.dart'; import 'package:PiliPlus/models_new/sub/sub/data.dart'; import 'package:PiliPlus/models_new/sub/sub/list.dart'; @@ -48,7 +48,7 @@ class UserHttp { } // 稍后再看 - static Future> seeYouLater({ + static Future> seeYouLater({ required int page, int viewed = 0, String keyword = '', @@ -67,19 +67,7 @@ class UserHttp { }), ); if (res.data['code'] == 0) { - if (res.data['data']['count'] == 0) { - return const Success({'count': 0}); - } - List list = []; - if (res.data['data']?['list'] != null) { - for (var i in res.data['data']['list']) { - list.add(HotVideoItemModel.fromJson(i)); - } - } - return Success({ - 'list': list, - 'count': res.data['data']?['count'] ?? 0, - }); + return Success(LaterData.fromJson(res.data['data'])); } else { return Error(res.data['message']); } diff --git a/lib/models_new/later/bangumi.dart b/lib/models_new/later/bangumi.dart new file mode 100644 index 000000000..5fe502e5d --- /dev/null +++ b/lib/models_new/later/bangumi.dart @@ -0,0 +1,33 @@ +import 'package:PiliPlus/models_new/later/season.dart'; + +class Bangumi { + int? epId; + String? title; + String? longTitle; + int? episodeStatus; + int? follow; + String? cover; + Season? season; + + Bangumi({ + this.epId, + this.title, + this.longTitle, + this.episodeStatus, + this.follow, + this.cover, + this.season, + }); + + factory Bangumi.fromJson(Map json) => Bangumi( + epId: json['ep_id'] as int?, + title: json['title'] as String?, + longTitle: json['long_title'] as String?, + episodeStatus: json['episode_status'] as int?, + follow: json['follow'] as int?, + cover: json['cover'] as String?, + season: json['season'] == null + ? null + : Season.fromJson(json['season'] as Map), + ); +} diff --git a/lib/models_new/later/data.dart b/lib/models_new/later/data.dart new file mode 100644 index 000000000..87b09814d --- /dev/null +++ b/lib/models_new/later/data.dart @@ -0,0 +1,15 @@ +import 'package:PiliPlus/models_new/later/list.dart'; + +class LaterData { + int? count; + List? list; + + LaterData({this.count, this.list}); + + factory LaterData.fromJson(Map json) => LaterData( + count: json['count'] as int?, + list: (json['list'] as List?) + ?.map((e) => LaterItemModel.fromJson(e as Map)) + .toList(), + ); +} diff --git a/lib/models_new/later/dimension.dart b/lib/models_new/later/dimension.dart new file mode 100644 index 000000000..3de7639ce --- /dev/null +++ b/lib/models_new/later/dimension.dart @@ -0,0 +1,13 @@ +class Dimension { + int? width; + int? height; + int? rotate; + + Dimension({this.width, this.height, this.rotate}); + + factory Dimension.fromJson(Map json) => Dimension( + width: json['width'] as int?, + height: json['height'] as int?, + rotate: json['rotate'] as int?, + ); +} diff --git a/lib/models_new/later/list.dart b/lib/models_new/later/list.dart new file mode 100644 index 000000000..4b6322c5d --- /dev/null +++ b/lib/models_new/later/list.dart @@ -0,0 +1,164 @@ +import 'package:PiliPlus/pages/common/multi_select_controller.dart'; + +import 'package:PiliPlus/models_new/later/bangumi.dart'; +import 'package:PiliPlus/models_new/later/dimension.dart'; +import 'package:PiliPlus/models_new/later/owner.dart'; +import 'package:PiliPlus/models_new/later/page.dart'; +import 'package:PiliPlus/models_new/later/rights.dart'; +import 'package:PiliPlus/models_new/later/stat.dart'; + +class LaterItemModel with MultiSelectData { + int? aid; + int? videos; + int? tid; + String? tname; + int? copyright; + String? pic; + String? title; + String? subtitle; + int? pubdate; + int? ctime; + String? desc; + int? state; + int? duration; + String? redirectUrl; + Rights? rights; + Owner? owner; + Stat? stat; + String? dynam1c; + Dimension? dimension; + String? shortLinkV2; + int? upFromV2; + String? pubLocation; + String? cover43; + int? tidv2; + String? tnamev2; + int? pidV2; + String? pidNameV2; + List? pages; + Bangumi? bangumi; + int? cid; + int? progress; + int? addAt; + String? bvid; + String? uri; + bool? viewed; + int? seq; + int? enableVt; + String? viewText1; + bool? isPgc; + String? pgcLabel; + bool? isPugv; + int? missionId; + String? firstFrame; + int? seasonId; + + LaterItemModel({ + this.aid, + this.videos, + this.tid, + this.tname, + this.copyright, + this.pic, + this.title, + this.subtitle, + this.pubdate, + this.ctime, + this.desc, + this.state, + this.duration, + this.redirectUrl, + this.rights, + this.owner, + this.stat, + this.dynam1c, + this.dimension, + this.shortLinkV2, + this.upFromV2, + this.pubLocation, + this.cover43, + this.tidv2, + this.tnamev2, + this.pidV2, + this.pidNameV2, + this.pages, + this.bangumi, + this.cid, + this.progress, + this.addAt, + this.bvid, + this.uri, + this.viewed, + this.seq, + this.enableVt, + this.viewText1, + this.isPgc, + this.pgcLabel, + this.isPugv, + this.missionId, + this.firstFrame, + this.seasonId, + }); + + factory LaterItemModel.fromJson(Map json) => LaterItemModel( + aid: json['aid'] as int?, + videos: json['videos'] as int?, + tid: json['tid'] as int?, + tname: json['tname'] as String?, + copyright: json['copyright'] as int?, + pic: json['pic'] as String?, + title: json['title'] as String?, + pubdate: json['pubdate'] as int?, + ctime: json['ctime'] as int?, + desc: json['desc'] as String?, + state: json['state'] as int?, + duration: json['duration'] as int?, + redirectUrl: json['redirect_url'] as String?, + rights: json['rights'] == null + ? null + : Rights.fromJson(json['rights'] as Map), + owner: json['owner'] == null + ? null + : Owner.fromJson(json['owner'] as Map), + stat: json['stat'] == null + ? null + : Stat.fromJson(json['stat'] as Map), + dynam1c: json['dynamic'] as String?, + dimension: json['dimension'] == null + ? null + : Dimension.fromJson(json['dimension'] as Map), + shortLinkV2: json['short_link_v2'] as String?, + upFromV2: json['up_from_v2'] as int?, + pubLocation: json['pub_location'] as String?, + cover43: json['cover43'] as String?, + tidv2: json['tidv2'] as int?, + tnamev2: json['tnamev2'] as String?, + pidV2: json['pid_v2'] as int?, + pidNameV2: json['pid_name_v2'] as String?, + pages: (json['pages'] as List?) + ?.map((e) => Page.fromJson(e as Map)) + .toList(), + bangumi: json['bangumi'] == null + ? null + : Bangumi.fromJson(json['bangumi'] as Map), + subtitle: json['bangumi'] == null + ? null + : (json['title'] as String) + .replaceFirst('${json['bangumi']['season']['title']} ', ''), + cid: json['cid'] as int?, + progress: json['progress'] as int?, + addAt: json['add_at'] as int?, + bvid: json['bvid'] as String?, + uri: json['uri'] as String?, + viewed: json['viewed'] as bool?, + seq: json['seq'] as int?, + enableVt: json['enable_vt'] as int?, + viewText1: json['view_text_1'] as String?, + isPgc: json['is_pgc'] as bool?, + pgcLabel: json['pgc_label'] as String?, + isPugv: json['is_pugv'] as bool?, + missionId: json['mission_id'] as int?, + firstFrame: json['first_frame'] as String?, + seasonId: json['season_id'] as int?, + ); +} diff --git a/lib/models_new/later/owner.dart b/lib/models_new/later/owner.dart new file mode 100644 index 000000000..22e286a83 --- /dev/null +++ b/lib/models_new/later/owner.dart @@ -0,0 +1,13 @@ +class Owner { + int? mid; + String? name; + String? face; + + Owner({this.mid, this.name, this.face}); + + factory Owner.fromJson(Map json) => Owner( + mid: json['mid'] as int?, + name: json['name'] as String?, + face: json['face'] as String?, + ); +} diff --git a/lib/models_new/later/page.dart b/lib/models_new/later/page.dart new file mode 100644 index 000000000..3b2fbd4ec --- /dev/null +++ b/lib/models_new/later/page.dart @@ -0,0 +1,39 @@ +import 'package:PiliPlus/models_new/later/dimension.dart'; + +class Page { + int? cid; + int? page; + String? from; + String? part; + int? duration; + String? vid; + String? weblink; + Dimension? dimension; + int? ctime; + + Page({ + this.cid, + this.page, + this.from, + this.part, + this.duration, + this.vid, + this.weblink, + this.dimension, + this.ctime, + }); + + factory Page.fromJson(Map json) => Page( + cid: json['cid'] as int?, + page: json['page'] as int?, + from: json['from'] as String?, + part: json['part'] as String?, + duration: json['duration'] as int?, + vid: json['vid'] as String?, + weblink: json['weblink'] as String?, + dimension: json['dimension'] == null + ? null + : Dimension.fromJson(json['dimension'] as Map), + ctime: json['ctime'] as int?, + ); +} diff --git a/lib/models_new/later/rights.dart b/lib/models_new/later/rights.dart new file mode 100644 index 000000000..362eea6d8 --- /dev/null +++ b/lib/models_new/later/rights.dart @@ -0,0 +1,50 @@ +class Rights { + int? bp; + int? elec; + int? download; + int? movie; + int? pay; + int? hd5; + int? noReprint; + int? autoplay; + int? ugcPay; + int? isCooperation; + int? ugcPayPreview; + int? noBackground; + int? arcPay; + int? payFreeWatch; + + Rights({ + this.bp, + this.elec, + this.download, + this.movie, + this.pay, + this.hd5, + this.noReprint, + this.autoplay, + this.ugcPay, + this.isCooperation, + this.ugcPayPreview, + this.noBackground, + this.arcPay, + this.payFreeWatch, + }); + + factory Rights.fromJson(Map json) => Rights( + bp: json['bp'] as int?, + elec: json['elec'] as int?, + download: json['download'] as int?, + movie: json['movie'] as int?, + pay: json['pay'] as int?, + hd5: json['hd5'] as int?, + noReprint: json['no_reprint'] as int?, + autoplay: json['autoplay'] as int?, + ugcPay: json['ugc_pay'] as int?, + isCooperation: json['is_cooperation'] as int?, + ugcPayPreview: json['ugc_pay_preview'] as int?, + noBackground: json['no_background'] as int?, + arcPay: json['arc_pay'] as int?, + payFreeWatch: json['pay_free_watch'] as int?, + ); +} diff --git a/lib/models_new/later/season.dart b/lib/models_new/later/season.dart new file mode 100644 index 000000000..a7d5c75c4 --- /dev/null +++ b/lib/models_new/later/season.dart @@ -0,0 +1,32 @@ +class Season { + int? seasonId; + String? title; + int? seasonStatus; + int? isFinish; + int? totalCount; + int? newestEpId; + String? newestEpIndex; + int? seasonType; + + Season({ + this.seasonId, + this.title, + this.seasonStatus, + this.isFinish, + this.totalCount, + this.newestEpId, + this.newestEpIndex, + this.seasonType, + }); + + factory Season.fromJson(Map json) => Season( + seasonId: json['season_id'] as int?, + title: json['title'] as String?, + seasonStatus: json['season_status'] as int?, + isFinish: json['is_finish'] as int?, + totalCount: json['total_count'] as int?, + newestEpId: json['newest_ep_id'] as int?, + newestEpIndex: json['newest_ep_index'] as String?, + seasonType: json['season_type'] as int?, + ); +} diff --git a/lib/models_new/later/stat.dart b/lib/models_new/later/stat.dart new file mode 100644 index 000000000..a85b01f71 --- /dev/null +++ b/lib/models_new/later/stat.dart @@ -0,0 +1,47 @@ +class Stat { + int? aid; + int? view; + int? danmaku; + int? reply; + int? favorite; + int? coin; + int? share; + int? nowRank; + int? hisRank; + int? like; + int? dislike; + int? vt; + int? vv; + + Stat({ + this.aid, + this.view, + this.danmaku, + this.reply, + this.favorite, + this.coin, + this.share, + this.nowRank, + this.hisRank, + this.like, + this.dislike, + this.vt, + this.vv, + }); + + factory Stat.fromJson(Map json) => Stat( + aid: json['aid'] as int?, + view: json['view'] as int?, + danmaku: json['danmaku'] as int?, + reply: json['reply'] as int?, + favorite: json['favorite'] as int?, + coin: json['coin'] as int?, + share: json['share'] as int?, + nowRank: json['now_rank'] as int?, + hisRank: json['his_rank'] as int?, + like: json['like'] as int?, + dislike: json['dislike'] as int?, + vt: json['vt'] as int?, + vv: json['vv'] as int?, + ); +} diff --git a/lib/pages/article/view.dart b/lib/pages/article/view.dart index 1eca634a9..3fcfd4d29 100644 --- a/lib/pages/article/view.dart +++ b/lib/pages/article/view.dart @@ -193,7 +193,7 @@ class _ArticlePageState extends State id: id, oid: oid, rpid: rpid, - source: 'dynamic', + isVideoDetail: false, replyType: _articleCtr.commentType, firstFloor: replyItem, onDispose: onDispose, diff --git a/lib/pages/dynamics/widgets/author_panel.dart b/lib/pages/dynamics/widgets/author_panel.dart index 22f1394c0..6fc8aacf7 100644 --- a/lib/pages/dynamics/widgets/author_panel.dart +++ b/lib/pages/dynamics/widgets/author_panel.dart @@ -22,7 +22,7 @@ import 'package:get/get.dart'; class AuthorPanel extends StatelessWidget { final DynamicItemModel item; final Function? addBannedList; - final String? source; + final bool isDetail; final ValueChanged? onRemove; final bool isSave; final Function(bool isTop, dynamic dynId)? onSetTop; @@ -32,7 +32,7 @@ class AuthorPanel extends StatelessWidget { super.key, required this.item, this.addBannedList, - this.source, + this.isDetail = false, this.onRemove, this.isSave = false, this.onSetTop, @@ -119,7 +119,7 @@ class AuthorPanel extends StatelessWidget { ), Align( alignment: Alignment.centerRight, - child: source != 'detail' && item.modules.moduleTag?.text != null + child: !isDetail && item.modules.moduleTag?.text != null ? Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/pages/dynamics/widgets/content_panel.dart b/lib/pages/dynamics/widgets/content_panel.dart index 2c77597d4..7eae603ff 100644 --- a/lib/pages/dynamics/widgets/content_panel.dart +++ b/lib/pages/dynamics/widgets/content_panel.dart @@ -11,7 +11,7 @@ Widget content( bool isSave, BuildContext context, DynamicItemModel item, - String? source, + bool isDetail, Function(List, int)? callback, { floor = 1, }) { @@ -53,7 +53,7 @@ Widget content( style: TextStyle( fontSize: floor != 1 ? 14 - : source == 'detail' && !isSave + : isDetail && !isSave ? 16 : 15, color: theme.colorScheme.primary, @@ -61,7 +61,7 @@ Widget content( ), ), if (richNodes != null) - source == 'detail' && floor == 1 + isDetail && floor == 1 ? SelectableText.rich( richNodes, style: isSave diff --git a/lib/pages/dynamics/widgets/dynamic_panel.dart b/lib/pages/dynamics/widgets/dynamic_panel.dart index 979fb2e1a..44507c9d1 100644 --- a/lib/pages/dynamics/widgets/dynamic_panel.dart +++ b/lib/pages/dynamics/widgets/dynamic_panel.dart @@ -12,7 +12,7 @@ import 'package:get/get.dart'; class DynamicPanel extends StatelessWidget { final DynamicItemModel item; - final String? source; + final bool isDetail; final ValueChanged? onRemove; final Function(List, int)? callback; final bool isSave; @@ -22,7 +22,7 @@ class DynamicPanel extends StatelessWidget { const DynamicPanel({ super.key, required this.item, - this.source, + this.isDetail = false, this.onRemove, this.callback, this.isSave = false, @@ -35,7 +35,7 @@ class DynamicPanel extends StatelessWidget { final theme = Theme.of(context); final authorWidget = AuthorPanel( item: item, - source: source, + isDetail: isDetail, onRemove: onRemove, isSave: isSave, onSetTop: onSetTop, @@ -45,7 +45,7 @@ class DynamicPanel extends StatelessWidget { elevation: 0, color: Colors.transparent, child: InkWell( - onTap: source == 'detail' && + onTap: isDetail && !const { 'DYNAMIC_TYPE_AV', 'DYNAMIC_TYPE_UGC_SEASON', @@ -67,22 +67,21 @@ class DynamicPanel extends StatelessWidget { child: authorWidget, ), if (item.type != 'DYNAMIC_TYPE_NONE') - content(theme, isSave, context, item, source, callback), - module(theme, isSave, item, context, source, callback), + content(theme, isSave, context, item, isDetail, callback), + module(theme, isSave, item, context, isDetail, callback), if (item.modules.moduleDynamic?.additional != null) addWidget(theme, item, context), if (item.modules.moduleDynamic?.major?.blocked != null) blockedItem(theme, item.modules.moduleDynamic!.major!.blocked!), const SizedBox(height: 2), - if (source == null) ActionPanel(item: item), - if (source == 'detail' && !isSave) const SizedBox(height: 12), + if (!isDetail) ActionPanel(item: item), + if (isDetail && !isSave) const SizedBox(height: 12), ], ), ), ); if (isSave || - (source == 'detail' && - Get.context!.orientation == Orientation.landscape)) { + (isDetail && Get.context!.orientation == Orientation.landscape)) { return child; } return DecoratedBox( diff --git a/lib/pages/dynamics/widgets/live_panel.dart b/lib/pages/dynamics/widgets/live_panel.dart index 43dd5d767..981523878 100644 --- a/lib/pages/dynamics/widgets/live_panel.dart +++ b/lib/pages/dynamics/widgets/live_panel.dart @@ -6,7 +6,7 @@ import 'package:get/get.dart'; Widget livePanel( ThemeData theme, - String? source, + bool isDetail, DynamicItemModel item, BuildContext context, { int floor = 1, @@ -45,8 +45,8 @@ Widget livePanel( children: [ Text( content.live!.title!, - maxLines: source == 'detail' ? null : 2, - overflow: source == 'detail' ? null : TextOverflow.ellipsis, + maxLines: isDetail ? null : 2, + overflow: isDetail ? null : TextOverflow.ellipsis, ), const SizedBox(height: 4), if (content.live?.descFirst != null) diff --git a/lib/pages/dynamics/widgets/live_panel_sub.dart b/lib/pages/dynamics/widgets/live_panel_sub.dart index 9d9cf7a69..b53fdbecf 100644 --- a/lib/pages/dynamics/widgets/live_panel_sub.dart +++ b/lib/pages/dynamics/widgets/live_panel_sub.dart @@ -8,7 +8,7 @@ import 'package:get/get.dart'; Widget livePanelSub( ThemeData theme, - String? source, + bool isDetail, DynamicItemModel item, BuildContext context, { int floor = 1, @@ -113,9 +113,9 @@ Widget livePanelSub( const EdgeInsets.symmetric(horizontal: StyleString.safeSpace), child: Text( content.title!, - maxLines: source == 'detail' ? null : 1, + maxLines: isDetail ? null : 1, style: const TextStyle(fontWeight: FontWeight.bold), - overflow: source == 'detail' ? null : TextOverflow.ellipsis, + overflow: isDetail ? null : TextOverflow.ellipsis, ), ), const SizedBox(height: 2), diff --git a/lib/pages/dynamics/widgets/live_rcmd_panel.dart b/lib/pages/dynamics/widgets/live_rcmd_panel.dart index 294036690..3033c75a1 100644 --- a/lib/pages/dynamics/widgets/live_rcmd_panel.dart +++ b/lib/pages/dynamics/widgets/live_rcmd_panel.dart @@ -8,7 +8,7 @@ import 'package:flutter/material.dart'; Widget liveRcmdPanel( ThemeData theme, - String? source, + bool isDetail, DynamicItemModel item, BuildContext context, { int floor = 1, @@ -113,9 +113,9 @@ Widget liveRcmdPanel( const EdgeInsets.symmetric(horizontal: StyleString.safeSpace), child: Text( liveRcmd.title!, - maxLines: source == 'detail' ? null : 1, + maxLines: isDetail ? null : 1, style: const TextStyle(fontWeight: FontWeight.bold), - overflow: source == 'detail' ? null : TextOverflow.ellipsis, + overflow: isDetail ? null : TextOverflow.ellipsis, ), ), const SizedBox(height: 2), diff --git a/lib/pages/dynamics/widgets/module_panel.dart b/lib/pages/dynamics/widgets/module_panel.dart index effa2d8c8..a1e0a3041 100644 --- a/lib/pages/dynamics/widgets/module_panel.dart +++ b/lib/pages/dynamics/widgets/module_panel.dart @@ -22,7 +22,7 @@ Widget module( bool isSave, DynamicItemModel item, BuildContext context, - String? source, + bool isDetail, Function(List, int)? callback, { floor = 1, }) { @@ -36,7 +36,7 @@ Widget module( // 视频 case 'DYNAMIC_TYPE_AV': return videoSeasonWidget( - theme, isSave, source, item, context, 'archive', callback, + theme, isSave, isDetail, item, context, 'archive', callback, floor: floor); // 转发 case 'DYNAMIC_TYPE_FORWARD': @@ -45,108 +45,134 @@ Widget module( orig.modules.moduleDynamic?.major?.type == 'MAJOR_TYPE_NONE'; late final isNormalAuth = orig.modules.moduleAuthor!.type == 'AUTHOR_TYPE_NORMAL'; - return InkWell( - onTap: - isNoneMajor ? null : () => PageUtils.pushDynDetail(orig, floor + 1), - onLongPress: isNoneMajor - ? null - : () { - late String? title, cover; - late var origMajor = orig.modules.moduleDynamic?.major; - late var major = item.modules.moduleDynamic?.major; - switch (orig.type) { - case 'DYNAMIC_TYPE_AV': - title = origMajor?.archive?.title; - cover = origMajor?.archive?.cover; - break; - case 'DYNAMIC_TYPE_UGC_SEASON': - title = origMajor?.ugcSeason?.title; - cover = origMajor?.ugcSeason?.cover; - break; - case 'DYNAMIC_TYPE_PGC' || 'DYNAMIC_TYPE_PGC_UNION': - title = origMajor?.pgc?.title; - cover = origMajor?.pgc?.cover; - break; - case 'DYNAMIC_TYPE_LIVE_RCMD': - title = major?.liveRcmd?.title; - cover = major?.liveRcmd?.cover; - break; - case 'DYNAMIC_TYPE_LIVE': - title = major?.live?.title; - cover = major?.live?.cover; - break; - default: - return; - } - imageSaveDialog( - title: title, - cover: cover, - ); - }, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8), - color: theme.dividerColor.withValues(alpha: 0.08), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (orig.type != 'DYNAMIC_TYPE_NONE') ...[ - Row( - children: [ - GestureDetector( - onTap: isNormalAuth - ? () => Get.toNamed( - '/member?mid=${orig.modules.moduleAuthor!.mid}', - arguments: { - 'face': orig.modules.moduleAuthor!.face - }, - ) - : null, - child: Text( - '${isNormalAuth ? '@' : ''}${orig.modules.moduleAuthor!.name}', - style: TextStyle(color: theme.colorScheme.primary), + return orig.type == 'DYNAMIC_TYPE_NONE' + ? const SizedBox.shrink() + : InkWell( + onTap: isNoneMajor + ? null + : () => PageUtils.pushDynDetail(orig, floor + 1), + onLongPress: isNoneMajor + ? null + : () { + late String? title, cover; + late var origMajor = orig.modules.moduleDynamic?.major; + late var major = item.modules.moduleDynamic?.major; + switch (orig.type) { + case 'DYNAMIC_TYPE_AV': + title = origMajor?.archive?.title; + cover = origMajor?.archive?.cover; + break; + case 'DYNAMIC_TYPE_UGC_SEASON': + title = origMajor?.ugcSeason?.title; + cover = origMajor?.ugcSeason?.cover; + break; + case 'DYNAMIC_TYPE_PGC' || 'DYNAMIC_TYPE_PGC_UNION': + title = origMajor?.pgc?.title; + cover = origMajor?.pgc?.cover; + break; + case 'DYNAMIC_TYPE_LIVE_RCMD': + title = major?.liveRcmd?.title; + cover = major?.liveRcmd?.cover; + break; + case 'DYNAMIC_TYPE_LIVE': + title = major?.live?.title; + cover = major?.live?.cover; + break; + default: + return; + } + imageSaveDialog( + title: title, + cover: cover, + ); + }, + child: Container( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 8), + color: theme.dividerColor.withValues(alpha: 0.08), + child: isNoneMajor + ? Row( + children: [ + Icon( + Icons.error, + size: 18, + color: theme.colorScheme.outline, + ), + const SizedBox(width: 5), + Text( + orig.modules.moduleDynamic?.major?.none?.tips ?? + 'NONE', + style: TextStyle(color: theme.colorScheme.outline), + ), + ], + ) + : Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + GestureDetector( + onTap: isNormalAuth + ? () => Get.toNamed( + '/member?mid=${orig.modules.moduleAuthor!.mid}', + arguments: { + 'face': + orig.modules.moduleAuthor!.face + }, + ) + : null, + child: Text( + '${isNormalAuth ? '@' : ''}${orig.modules.moduleAuthor!.name}', + style: TextStyle( + color: theme.colorScheme.primary), + ), + ), + const SizedBox(width: 6), + Text( + Utils.dateFormat( + orig.modules.moduleAuthor!.pubTs), + style: TextStyle( + color: theme.colorScheme.outline, + fontSize: + theme.textTheme.labelSmall!.fontSize), + ), + ], + ), + const SizedBox(height: 5), + content( + theme, isSave, context, orig, isDetail, callback, + floor: floor + 1), + module( + theme, isSave, orig, context, isDetail, callback, + floor: floor + 1), + if (orig.modules.moduleDynamic?.additional != null) + addWidget(theme, orig, context, floor: floor + 1), + if (orig.modules.moduleDynamic?.major?.blocked != + null) + blockedItem(theme, + orig.modules.moduleDynamic!.major!.blocked!), + ], ), - ), - const SizedBox(width: 6), - Text( - Utils.dateFormat(orig.modules.moduleAuthor!.pubTs), - style: TextStyle( - color: theme.colorScheme.outline, - fontSize: theme.textTheme.labelSmall!.fontSize), - ), - ], - ), - const SizedBox(height: 5), - content(theme, isSave, context, orig, source, callback, - floor: floor + 1), - ], - module(theme, isSave, orig, context, source, callback, - floor: floor + 1), - if (orig.modules.moduleDynamic?.additional != null) - addWidget(theme, orig, context, floor: floor + 1), - if (orig.modules.moduleDynamic?.major?.blocked != null) - blockedItem(theme, orig.modules.moduleDynamic!.major!.blocked!), - ], - ), - ), - ); + ), + ); // 直播 case 'DYNAMIC_TYPE_LIVE_RCMD': - return liveRcmdPanel(theme, source, item, context, floor: floor); + return liveRcmdPanel(theme, isDetail, item, context, floor: floor); // 直播 case 'DYNAMIC_TYPE_LIVE': - return livePanel(theme, source, item, context, floor: floor); + return livePanel(theme, isDetail, item, context, floor: floor); // 合集 case 'DYNAMIC_TYPE_UGC_SEASON': return videoSeasonWidget( - theme, isSave, source, item, context, 'ugcSeason', callback); + theme, isSave, isDetail, item, context, 'ugcSeason', callback); case 'DYNAMIC_TYPE_PGC': return videoSeasonWidget( - theme, isSave, source, item, context, 'pgc', callback, + theme, isSave, isDetail, item, context, 'pgc', callback, floor: floor); case 'DYNAMIC_TYPE_PGC_UNION': return videoSeasonWidget( - theme, isSave, source, item, context, 'pgc', callback, + theme, isSave, isDetail, item, context, 'pgc', callback, floor: floor); case 'DYNAMIC_TYPE_NONE': return Row( @@ -342,7 +368,7 @@ Widget module( case 'DYNAMIC_TYPE_SUBSCRIPTION_NEW' when item.modules.moduleDynamic?.major?.type == 'MAJOR_TYPE_SUBSCRIPTION_NEW': - return livePanelSub(theme, source, item, context, floor: floor); + return livePanelSub(theme, isDetail, item, context, floor: floor); default: return Padding( diff --git a/lib/pages/dynamics/widgets/video_panel.dart b/lib/pages/dynamics/widgets/video_panel.dart index 1fcd85569..55c37e920 100644 --- a/lib/pages/dynamics/widgets/video_panel.dart +++ b/lib/pages/dynamics/widgets/video_panel.dart @@ -10,7 +10,7 @@ import 'package:flutter/material.dart'; Widget videoSeasonWidget( ThemeData theme, bool isSave, - String? source, + bool isDetail, DynamicItemModel item, BuildContext context, String type, @@ -29,9 +29,7 @@ Widget videoSeasonWidget( const SizedBox(width: 5), Text( item.modules.moduleDynamic!.major!.none!.tips!, - style: TextStyle( - color: theme.colorScheme.outline, - ), + style: TextStyle(color: theme.colorScheme.outline), ), ], ) @@ -159,9 +157,9 @@ Widget videoSeasonWidget( : EdgeInsets.zero, child: Text( itemContent.title!, - maxLines: source == 'detail' ? null : 1, + maxLines: isDetail ? null : 1, style: const TextStyle(fontWeight: FontWeight.bold), - overflow: source == 'detail' ? null : TextOverflow.ellipsis, + overflow: isDetail ? null : TextOverflow.ellipsis, ), ), ], diff --git a/lib/pages/dynamics_detail/view.dart b/lib/pages/dynamics_detail/view.dart index 550231006..0ea96d995 100644 --- a/lib/pages/dynamics_detail/view.dart +++ b/lib/pages/dynamics_detail/view.dart @@ -137,7 +137,7 @@ class _DynamicDetailPageState extends State id: id, oid: oid, rpid: rpid, - source: 'dynamic', + isVideoDetail: false, replyType: _controller.replyType, firstFloor: replyItem, onDispose: onDispose, @@ -253,7 +253,7 @@ class _DynamicDetailPageState extends State duration: const Duration(milliseconds: 300), child: AuthorPanel( item: _controller.dynItem, - source: 'detail', //to remove tag + isDetail: true, ), ); }, @@ -332,7 +332,7 @@ class _DynamicDetailPageState extends State SliverToBoxAdapter( child: DynamicPanel( item: _controller.dynItem, - source: 'detail', + isDetail: true, callback: _getImageCallback, ), ), @@ -363,7 +363,7 @@ class _DynamicDetailPageState extends State sliver: SliverToBoxAdapter( child: DynamicPanel( item: _controller.dynItem, - source: 'detail', + isDetail: true, callback: _getImageCallback, ), ), diff --git a/lib/pages/episode_panel/view.dart b/lib/pages/episode_panel/view.dart index 65c2c72a3..5b0d06058 100644 --- a/lib/pages/episode_panel/view.dart +++ b/lib/pages/episode_panel/view.dart @@ -512,20 +512,19 @@ class _EpisodePanelState extends CommonSlidePageState { if (view != null) ...[ const SizedBox(height: 2), Row( + spacing: 8, children: [ StatView( context: context, theme: 'gray', value: view, ), - if (danmaku != null) ...[ - const SizedBox(width: 8), + if (danmaku != null) StatDanMu( context: context, theme: 'gray', value: danmaku, ), - ], ], ), ], diff --git a/lib/pages/fav/video/view.dart b/lib/pages/fav/video/view.dart index c8aabcdfb..e6641a125 100644 --- a/lib/pages/fav/video/view.dart +++ b/lib/pages/fav/video/view.dart @@ -72,7 +72,7 @@ class _FavVideoPageState extends State String heroTag = Utils.makeHeroTag(item.fid); return FavVideoItem( heroTag: heroTag, - favFolderItem: item, + item: item, onTap: () async { var res = await Get.toNamed( '/favDetail', diff --git a/lib/pages/fav/video/widgets/item.dart b/lib/pages/fav/video/widgets/item.dart index 7e3e42030..c7f839e3c 100644 --- a/lib/pages/fav/video/widgets/item.dart +++ b/lib/pages/fav/video/widgets/item.dart @@ -7,7 +7,7 @@ import 'package:flutter/material.dart'; class FavVideoItem extends StatelessWidget { final String heroTag; - final FavVideoItemModel favFolderItem; + final FavVideoItemModel item; final VoidCallback? onTap; final VoidCallback? onLongPress; @@ -16,7 +16,7 @@ class FavVideoItem extends StatelessWidget { this.onTap, this.onLongPress, required this.heroTag, - required this.favFolderItem, + required this.item, }); @override @@ -27,8 +27,8 @@ class FavVideoItem extends StatelessWidget { (onTap == null ? null : () => imageSaveDialog( - title: favFolderItem.title, - cover: favFolderItem.cover, + title: item.title, + cover: item.cover, )), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5), @@ -43,7 +43,7 @@ class FavVideoItem extends StatelessWidget { return Hero( tag: heroTag, child: NetworkImgLayer( - src: favFolderItem.cover, + src: item.cover, width: boxConstraints.maxWidth, height: boxConstraints.maxHeight, ), @@ -52,14 +52,14 @@ class FavVideoItem extends StatelessWidget { ), ), const SizedBox(width: 10), - videoContent(context), + content(context), ], ), ), ); } - Widget videoContent(context) { + Widget content(BuildContext context) { final theme = Theme.of(context); final fontSize = theme.textTheme.labelMedium!.fontSize; final color = theme.colorScheme.outline; @@ -68,22 +68,22 @@ class FavVideoItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - favFolderItem.title ?? '', + item.title!, textAlign: TextAlign.start, style: const TextStyle( letterSpacing: 0.3, ), ), - if (favFolderItem.intro?.isNotEmpty == true) + if (item.intro?.isNotEmpty == true) Text( - favFolderItem.intro!, + item.intro!, style: TextStyle( fontSize: fontSize, color: color, ), ), Text( - '${favFolderItem.mediaCount}个内容', + '${item.mediaCount}个内容', style: TextStyle( fontSize: fontSize, color: color, @@ -91,7 +91,7 @@ class FavVideoItem extends StatelessWidget { ), const Spacer(), Text( - Utils.isPublicFavText(favFolderItem.attr ?? 0), + Utils.isPublicFavText(item.attr ?? 0), style: TextStyle( fontSize: fontSize, color: color, diff --git a/lib/pages/fav_detail/view.dart b/lib/pages/fav_detail/view.dart index 2694e2f04..05263d8a0 100644 --- a/lib/pages/fav_detail/view.dart +++ b/lib/pages/fav_detail/view.dart @@ -9,6 +9,7 @@ import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models_new/fav/fav_detail/data.dart'; import 'package:PiliPlus/models_new/fav/fav_detail/media.dart'; import 'package:PiliPlus/models_new/fav/fav_video/list.dart'; +import 'package:PiliPlus/pages/dynamics_repost/view.dart'; import 'package:PiliPlus/pages/fav_detail/controller.dart'; import 'package:PiliPlus/pages/fav_detail/widget/fav_video_card.dart'; import 'package:PiliPlus/pages/fav_sort/view.dart'; @@ -134,6 +135,16 @@ class _FavDetailPageState extends State { ), icon: const Icon(Icons.search_outlined), ), + Obx( + () => Utils.isPublicFav(_favDetailController.item.value.attr ?? 0) + ? IconButton( + tooltip: '分享', + onPressed: () => Utils.shareText( + 'https://www.bilibili.com/medialist/detail/ml${_favDetailController.mediaId}'), + icon: const Icon(Icons.share), + ) + : const SizedBox.shrink(), + ), Obx( () => _favDetailController.isOwner.value ? PopupMenuButton( @@ -150,6 +161,23 @@ class _FavDetailPageState extends State { }), child: const Text('编辑信息'), ), + if (Utils.isPublicFav( + _favDetailController.item.value.attr ?? 0)) + PopupMenuItem( + onTap: () => showModalBottomSheet( + context: context, + isScrollControlled: true, + useSafeArea: true, + builder: (context) => RepostPanel( + rid: _favDetailController.mediaId, + dynType: 4300, + pic: _favDetailController.item.value.cover, + title: _favDetailController.item.value.title, + uname: _favDetailController.item.value.upper?.name, + ), + ), + child: const Text('分享至动态'), + ), PopupMenuItem( onTap: () => FavHttp.cleanFav(mediaId: mediaId).then((data) { @@ -225,7 +253,7 @@ class _FavDetailPageState extends State { ) : const SizedBox.shrink(), ), - const SizedBox(width: 12), + const SizedBox(width: 10), ]; List _selectActions(ThemeData theme) => [ @@ -410,7 +438,7 @@ class _FavDetailPageState extends State { children: [ Positioned.fill( child: FavVideoCardH( - videoItem: item, + item: item, onDelFav: _favDetailController.isOwner.value ? () => _favDetailController.onCancelFav( index, diff --git a/lib/pages/fav_detail/widget/fav_video_card.dart b/lib/pages/fav_detail/widget/fav_video_card.dart index a39bc11c6..43dae0d35 100644 --- a/lib/pages/fav_detail/widget/fav_video_card.dart +++ b/lib/pages/fav_detail/widget/fav_video_card.dart @@ -13,7 +13,7 @@ import 'package:get/get.dart'; // 收藏视频卡片 - 水平布局 class FavVideoCardH extends StatelessWidget { - final FavDetailItemModel videoItem; + final FavDetailItemModel item; final GestureTapCallback? onTap; final GestureLongPressCallback? onLongPress; final VoidCallback? onDelFav; @@ -22,7 +22,7 @@ class FavVideoCardH extends StatelessWidget { const FavVideoCardH({ super.key, - required this.videoItem, + required this.item, this.onDelFav, this.onTap, this.onLongPress, @@ -37,16 +37,16 @@ class FavVideoCardH extends StatelessWidget { ? null : onTap ?? () { - if (!const [0, 16].contains(videoItem.attr)) { - Get.toNamed('/member?mid=${videoItem.upper?.mid}'); + if (!const [0, 16].contains(item.attr)) { + Get.toNamed('/member?mid=${item.upper?.mid}'); return; } // pgc - if (videoItem.type == 24) { + if (item.type == 24) { PageUtils.viewPgc( - seasonId: videoItem.ogv!.seasonId, - epId: videoItem.id, + seasonId: item.ogv!.seasonId, + epId: item.id, ); return; } @@ -57,8 +57,8 @@ class FavVideoCardH extends StatelessWidget { ? null : onLongPress ?? () => imageSaveDialog( - title: videoItem.title, - cover: videoItem.cover, + title: item.title, + cover: item.cover, ), child: Padding( padding: const EdgeInsets.symmetric( @@ -79,18 +79,18 @@ class FavVideoCardH extends StatelessWidget { clipBehavior: Clip.none, children: [ NetworkImgLayer( - src: videoItem.cover, + src: item.cover, width: maxWidth, height: maxHeight, ), PBadge( - text: Utils.timeFormat(videoItem.duration), + text: Utils.timeFormat(item.duration), right: 6.0, bottom: 6.0, type: PBadgeType.gray, ), PBadge( - text: videoItem.ogv?.typeName, + text: item.ogv?.typeName, top: 6.0, right: 6.0, bottom: null, @@ -102,35 +102,45 @@ class FavVideoCardH extends StatelessWidget { ), ), const SizedBox(width: 10), - videoContent(context), + content(context), ], ), ), ); } - Widget videoContent(BuildContext context) { + Widget content(BuildContext context) { final theme = Theme.of(context); return Expanded( child: Stack( clipBehavior: Clip.none, children: [ Column( + spacing: 3, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Text( - videoItem.title!, - textAlign: TextAlign.start, - style: const TextStyle( - letterSpacing: 0.3, - ), + Text( + item.title!, + textAlign: TextAlign.start, + style: const TextStyle( + letterSpacing: 0.3, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + if (item.type == 24 && item.intro?.isNotEmpty == true) + Text( + item.intro!, maxLines: 2, overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 13, + color: theme.colorScheme.outline, + ), ), - ), + const Spacer(), Text( - '${Utils.dateFormat(videoItem.favTime)} ${videoItem.upper?.name}', + '${Utils.dateFormat(item.favTime)} ${item.upper?.name}', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( @@ -139,23 +149,22 @@ class FavVideoCardH extends StatelessWidget { color: theme.colorScheme.outline, ), ), - const SizedBox(height: 3), - Row( - children: [ - StatView( - context: context, - theme: 'gray', - value: Utils.numFormat(videoItem.cntInfo?.play), - ), - const SizedBox(width: 8), - StatDanMu( - context: context, - theme: 'gray', - value: Utils.numFormat(videoItem.cntInfo?.danmaku), - ), - const Spacer(), - ], - ), + if (item.type != 24) + Row( + spacing: 8, + children: [ + StatView( + context: context, + theme: 'gray', + value: Utils.numFormat(item.cntInfo?.play), + ), + StatDanMu( + context: context, + theme: 'gray', + value: Utils.numFormat(item.cntInfo?.danmaku), + ), + ], + ), ], ), if (onDelFav != null) diff --git a/lib/pages/fav_folder_sort/view.dart b/lib/pages/fav_folder_sort/view.dart index 95b45ade1..56019345e 100644 --- a/lib/pages/fav_folder_sort/view.dart +++ b/lib/pages/fav_folder_sort/view.dart @@ -128,7 +128,7 @@ class _FavFolderSortPageState extends State { height: 98, child: FavVideoItem( heroTag: key, - favFolderItem: item, + item: item, onLongPress: index == 0 ? () => SmartDialog.showToast('默认收藏夹不支持排序') : null, ), diff --git a/lib/pages/fav_search/view.dart b/lib/pages/fav_search/view.dart index 46389e651..b9eaeab86 100644 --- a/lib/pages/fav_search/view.dart +++ b/lib/pages/fav_search/view.dart @@ -36,7 +36,7 @@ class _FavSearchPageState extends CommonSearchPageState controller.onCancelFav( index, diff --git a/lib/pages/fav_sort/view.dart b/lib/pages/fav_sort/view.dart index 3922bcd4a..5a70de934 100644 --- a/lib/pages/fav_sort/view.dart +++ b/lib/pages/fav_sort/view.dart @@ -135,7 +135,7 @@ class _FavSortPageState extends State { height: 98, child: FavVideoCardH( isSort: true, - videoItem: item, + item: item, ), ); }, diff --git a/lib/pages/history/view.dart b/lib/pages/history/view.dart index ff826eebf..86390c752 100644 --- a/lib/pages/history/view.dart +++ b/lib/pages/history/view.dart @@ -275,7 +275,7 @@ class _HistoryPageState extends State } final item = response[index]; return HistoryItem( - videoItem: item, + item: item, ctr: _historyController.baseCtr, onChoose: () => _historyController.onSelect(index), onDelete: (kid, business) => diff --git a/lib/pages/history/widgets/item.dart b/lib/pages/history/widgets/item.dart index ae3a983ec..a1f98d4a2 100644 --- a/lib/pages/history/widgets/item.dart +++ b/lib/pages/history/widgets/item.dart @@ -20,14 +20,14 @@ import 'package:get/get.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; class HistoryItem extends StatelessWidget { - final HistoryItemModel videoItem; + final HistoryItemModel item; final dynamic ctr; final Function? onChoose; final Function(dynamic kid, dynamic business) onDelete; const HistoryItem({ super.key, - required this.videoItem, + required this.item, this.ctr, this.onChoose, required this.onDelete, @@ -36,8 +36,8 @@ class HistoryItem extends StatelessWidget { @override Widget build(BuildContext context) { final theme = Theme.of(context); - int aid = videoItem.history.oid!; - String bvid = videoItem.history.bvid ?? IdUtils.av2bv(aid); + int aid = item.history.oid!; + String bvid = item.history.bvid ?? IdUtils.av2bv(aid); return InkWell( onTap: () async { if (ctr is MultiSelectController || ctr is HistoryBaseController) { @@ -46,37 +46,37 @@ class HistoryItem extends StatelessWidget { return; } } - if (videoItem.history.business?.contains('article') == true) { + if (item.history.business?.contains('article') == true) { PageUtils.toDupNamed( '/articlePage', parameters: { - 'id': videoItem.history.business == 'article-list' - ? '${videoItem.history.cid}' - : '${videoItem.history.oid}', + 'id': item.history.business == 'article-list' + ? '${item.history.cid}' + : '${item.history.oid}', 'type': 'read', }, ); - } else if (videoItem.history.business == 'live') { - if (videoItem.liveStatus == 1) { - Get.toNamed('/liveRoom?roomid=${videoItem.history.oid}'); + } else if (item.history.business == 'live') { + if (item.liveStatus == 1) { + Get.toNamed('/liveRoom?roomid=${item.history.oid}'); } else { SmartDialog.showToast('直播未开播'); } - } else if (videoItem.history.business == 'pgc') { - PageUtils.viewPgc(epId: videoItem.history.epid); + } else if (item.history.business == 'pgc') { + PageUtils.viewPgc(epId: item.history.epid); } else { - int? cid = videoItem.history.cid ?? + int? cid = item.history.cid ?? await SearchHttp.ab2c( aid: aid, bvid: bvid, - part: videoItem.history.page, + part: item.history.page, ); if (cid != null) { PageUtils.toVideoPage( 'bvid=$bvid&cid=$cid', arguments: { 'heroTag': Utils.makeHeroTag(aid), - 'pic': videoItem.cover, + 'pic': item.cover, }, ); } @@ -91,8 +91,8 @@ class HistoryItem extends StatelessWidget { return; } imageSaveDialog( - title: videoItem.title, - cover: videoItem.cover, + title: item.title, + cover: item.cover, ); }, child: Stack( @@ -117,51 +117,51 @@ class HistoryItem extends StatelessWidget { clipBehavior: Clip.none, children: [ NetworkImgLayer( - src: videoItem.cover?.isNotEmpty == true - ? videoItem.cover - : videoItem.covers?.firstOrNull ?? '', + src: item.cover?.isNotEmpty == true + ? item.cover + : item.covers?.firstOrNull ?? '', width: maxWidth, height: maxHeight, ), if (!HistoryBusinessType.hiddenDurationType - .contains(videoItem.history.business)) + .contains(item.history.business)) PBadge( - text: videoItem.progress == -1 + text: item.progress == -1 ? '已看完' - : '${Utils.timeFormat(videoItem.progress)}/${Utils.timeFormat(videoItem.duration!)}', + : '${Utils.timeFormat(item.progress)}/${Utils.timeFormat(item.duration!)}', right: 6.0, bottom: 8.0, type: PBadgeType.gray, ), // 右上角 if (HistoryBusinessType.showBadge - .contains(videoItem.history.business) || - videoItem.history.business == + .contains(item.history.business) || + item.history.business == HistoryBusinessType.live.type) PBadge( - text: videoItem.badge, + text: item.badge, top: 6.0, right: 6.0, bottom: null, left: null, ), - if (videoItem.duration != null && - videoItem.duration != 0 && - videoItem.progress != null && - videoItem.progress != 0) + if (item.duration != null && + item.duration != 0 && + item.progress != null && + item.progress != 0) Positioned( left: 0, right: 0, bottom: 0, child: videoProgressIndicator( - videoItem.progress == -1 + item.progress == -1 ? 1 - : videoItem.progress! / videoItem.duration!, + : item.progress! / item.duration!, ), ), Positioned.fill( child: AnimatedOpacity( - opacity: videoItem.checked == true ? 1 : 0, + opacity: item.checked == true ? 1 : 0, duration: const Duration(milliseconds: 200), child: Container( alignment: Alignment.center, @@ -173,7 +173,7 @@ class HistoryItem extends StatelessWidget { width: 34, height: 34, child: AnimatedScale( - scale: videoItem.checked == true ? 1 : 0, + scale: item.checked == true ? 1 : 0, duration: const Duration(milliseconds: 250), curve: Curves.easeInOut, child: IconButton( @@ -207,7 +207,7 @@ class HistoryItem extends StatelessWidget { ), ), const SizedBox(width: 10), - videoContent(theme), + content(theme), ], ), ), @@ -227,13 +227,13 @@ class HistoryItem extends StatelessWidget { ), position: PopupMenuPosition.under, itemBuilder: (BuildContext context) => >[ - if (videoItem.authorMid != null && - videoItem.authorName?.isNotEmpty == true) + if (item.authorMid != null && + item.authorName?.isNotEmpty == true) PopupMenuItem( onTap: () => Get.toNamed( - '/member?mid=${videoItem.authorMid}', + '/member?mid=${item.authorMid}', arguments: { - 'heroTag': '${videoItem.authorMid}', + 'heroTag': '${item.authorMid}', }, ), height: 35, @@ -242,21 +242,21 @@ class HistoryItem extends StatelessWidget { const Icon(MdiIcons.accountCircleOutline, size: 16), const SizedBox(width: 6), Text( - '访问:${videoItem.authorName}', + '访问:${item.authorName}', style: const TextStyle(fontSize: 13), ) ], ), ), - if (videoItem.history.business != 'pgc' && - videoItem.badge != '番剧' && - videoItem.tagName?.contains('动画') != true && - videoItem.history.business != 'live' && - videoItem.history.business?.contains('article') != true) + if (item.history.business != 'pgc' && + item.badge != '番剧' && + item.tagName?.contains('动画') != true && + item.history.business != 'live' && + item.history.business?.contains('article') != true) PopupMenuItem( onTap: () async { - var res = await UserHttp.toViewLater( - bvid: videoItem.history.bvid); + var res = + await UserHttp.toViewLater(bvid: item.history.bvid); SmartDialog.showToast(res['msg']); }, height: 35, @@ -269,8 +269,7 @@ class HistoryItem extends StatelessWidget { ), ), PopupMenuItem( - onTap: () => - onDelete(videoItem.kid, videoItem.history.business), + onTap: () => onDelete(item.kid, item.history.business), height: 35, child: const Row( children: [ @@ -289,27 +288,37 @@ class HistoryItem extends StatelessWidget { ); } - Widget videoContent(ThemeData theme) { + Widget content(ThemeData theme) { return Expanded( child: Column( + spacing: 2, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Text( - videoItem.title!, - textAlign: TextAlign.start, + Text( + item.title!, + style: TextStyle( + fontSize: theme.textTheme.bodyMedium!.fontSize, + height: 1.42, + letterSpacing: 0.3, + ), + maxLines: item.videos! > 1 ? 1 : 2, + overflow: TextOverflow.ellipsis, + ), + if (item.history.business == 'pgc' && + item.showTitle?.isNotEmpty == true) + Text( + item.showTitle!, style: TextStyle( - fontSize: theme.textTheme.bodyMedium!.fontSize, - height: 1.42, - letterSpacing: 0.3, + fontSize: 13, + color: theme.colorScheme.outline, ), - maxLines: videoItem.videos! > 1 ? 1 : 2, + maxLines: 2, overflow: TextOverflow.ellipsis, ), - ), - if (videoItem.authorName != '') + const Spacer(), + if (item.authorName?.isNotEmpty == true) Text( - videoItem.authorName!, + item.authorName!, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( @@ -317,9 +326,8 @@ class HistoryItem extends StatelessWidget { color: theme.colorScheme.outline, ), ), - const SizedBox(height: 2), Text( - Utils.dateFormat(videoItem.viewAt!), + Utils.dateFormat(item.viewAt!), style: TextStyle( fontSize: theme.textTheme.labelMedium!.fontSize, color: theme.colorScheme.outline, diff --git a/lib/pages/history_search/view.dart b/lib/pages/history_search/view.dart index 000034cdc..e82d9186c 100644 --- a/lib/pages/history_search/view.dart +++ b/lib/pages/history_search/view.dart @@ -35,7 +35,7 @@ class _HistorySearchPageState extends CommonSearchPageState ); } - Widget _buildBody(LoadingState?> loadingState) { + Widget _buildBody(LoadingState?> loadingState) { final theme = Theme.of(context); return switch (loadingState) { Loading() => SliverGrid( @@ -80,9 +80,8 @@ class _LaterViewChildPageState extends State return Stack( clipBehavior: Clip.none, children: [ - VideoCardH( + VideoCardHLater( videoItem: videoItem, - source: 'later', onViewLater: (cid) { PageUtils.toVideoPage( 'bvid=${videoItem.bvid}&cid=$cid', diff --git a/lib/pages/later/controller.dart b/lib/pages/later/controller.dart index c0682200c..ae5f0896e 100644 --- a/lib/pages/later/controller.dart +++ b/lib/pages/later/controller.dart @@ -1,8 +1,10 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:PiliPlus/common/widgets/dialog/dialog.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/user.dart'; import 'package:PiliPlus/models/common/later_view_type.dart'; -import 'package:PiliPlus/models/model_hot_video_item.dart'; +import 'package:PiliPlus/models_new/later/data.dart'; +import 'package:PiliPlus/models_new/later/list.dart'; import 'package:PiliPlus/pages/common/multi_select_controller.dart'; import 'package:PiliPlus/pages/later/base_controller.dart'; import 'package:PiliPlus/utils/extension.dart'; @@ -13,8 +15,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; -class LaterController extends MultiSelectController { - LaterController(this.laterViewType); +class LaterController extends MultiSelectController { + LaterController( + this.laterViewType, + ); final LaterViewType laterViewType; dynamic mid; @@ -23,7 +27,7 @@ class LaterController extends MultiSelectController { final LaterBaseController baseCtr = Get.put(LaterBaseController()); @override - Future> customGetData() => UserHttp.seeYouLater( + Future> customGetData() => UserHttp.seeYouLater( page: page, viewed: laterViewType.type, asc: asc.value, @@ -31,7 +35,7 @@ class LaterController extends MultiSelectController { @override void onSelect(int index, [bool disableSelect = true]) { - List list = loadingState.value.data!; + List list = loadingState.value.data!; list[index].checked = !(list[index].checked ?? false); baseCtr.checkedCount.value = list.where((item) => item.checked == true).length; @@ -44,9 +48,9 @@ class LaterController extends MultiSelectController { @override void handleSelect([bool checked = false, bool disableSelect = true]) { if (loadingState.value.isSuccess) { - List? list = loadingState.value.data; + List? list = loadingState.value.data; if (list?.isNotEmpty == true) { - for (HotVideoItemModel item in list!) { + for (LaterItemModel item in list!) { item.checked = checked; } baseCtr.checkedCount.value = checked ? list.length : 0; @@ -66,8 +70,9 @@ class LaterController extends MultiSelectController { } @override - List? getDataList(response) { - return response['list']; + List? getDataList(response) { + baseCtr.counts[laterViewType] = response.count ?? 0; + return response.list; } @override @@ -77,12 +82,6 @@ class LaterController extends MultiSelectController { } } - @override - bool customHandleResponse(bool isRefresh, Success response) { - baseCtr.counts[laterViewType] = response.response['count']; - return false; - } - // single void toViewDel(BuildContext context, int index, int? aid) { showDialog( @@ -180,12 +179,12 @@ class LaterController extends MultiSelectController { ); } - Future _onDelete(List result) async { + Future _onDelete(List result) async { SmartDialog.showLoading(msg: '请求中'); List aids = result.map((item) => item.aid).toList(); var res = await UserHttp.toViewDel(aids: aids); if (res['status']) { - Set remainList = + Set remainList = loadingState.value.data!.toSet().difference(result.toSet()); baseCtr.counts[laterViewType] = baseCtr.counts[laterViewType]! - aids.length; @@ -202,10 +201,10 @@ class LaterController extends MultiSelectController { // 稍后再看播放全部 void toViewPlayAll() { if (loadingState.value.isSuccess) { - List? list = loadingState.value.data; + List? list = loadingState.value.data; if (list.isNullOrEmpty) return; - for (HotVideoItemModel item in list!) { + for (LaterItemModel item in list!) { if (item.cid == null || item.pgcLabel?.isNotEmpty == true) { continue; } else { diff --git a/lib/pages/later/view.dart b/lib/pages/later/view.dart index 9f717a1ff..c29ae620b 100644 --- a/lib/pages/later/view.dart +++ b/lib/pages/later/view.dart @@ -1,6 +1,7 @@ import 'package:PiliPlus/common/widgets/scroll_physics.dart'; import 'package:PiliPlus/models/common/later_view_type.dart'; -import 'package:PiliPlus/models/model_hot_video_item.dart'; +import 'package:PiliPlus/models_new/later/data.dart'; +import 'package:PiliPlus/models_new/later/list.dart'; import 'package:PiliPlus/pages/history/view.dart' show AppBarWidget; import 'package:PiliPlus/pages/later/base_controller.dart'; import 'package:PiliPlus/pages/later/controller.dart'; @@ -266,7 +267,7 @@ class _LaterPageState extends State ), onPressed: () { final ctr = currCtr(); - RequestUtils.onCopyOrMove( + RequestUtils.onCopyOrMove( context: context, isCopy: true, ctr: ctr, @@ -287,7 +288,7 @@ class _LaterPageState extends State ), onPressed: () { final ctr = currCtr(); - RequestUtils.onCopyOrMove( + RequestUtils.onCopyOrMove( context: context, isCopy: false, ctr: ctr, diff --git a/lib/pages/later/widgets/video_card_h_later.dart b/lib/pages/later/widgets/video_card_h_later.dart new file mode 100644 index 000000000..f59891899 --- /dev/null +++ b/lib/pages/later/widgets/video_card_h_later.dart @@ -0,0 +1,226 @@ +import 'package:PiliPlus/common/constants.dart'; +import 'package:PiliPlus/common/widgets/badge.dart'; +import 'package:PiliPlus/common/widgets/image/image_save.dart'; +import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; +import 'package:PiliPlus/common/widgets/progress_bar/video_progress_indicator.dart'; +import 'package:PiliPlus/common/widgets/stat/stat.dart'; +import 'package:PiliPlus/http/search.dart'; +import 'package:PiliPlus/models/common/badge_type.dart'; +import 'package:PiliPlus/models/search/result.dart'; +import 'package:PiliPlus/models_new/later/list.dart'; +import 'package:PiliPlus/utils/page_utils.dart'; +import 'package:PiliPlus/utils/utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; + +// 视频卡片 - 水平布局 +class VideoCardHLater extends StatelessWidget { + const VideoCardHLater({ + super.key, + required this.videoItem, + this.onTap, + this.onLongPress, + this.onViewLater, + }); + final LaterItemModel videoItem; + final VoidCallback? onTap; + final VoidCallback? onLongPress; + final ValueChanged? onViewLater; + + @override + Widget build(BuildContext context) { + String type = 'video'; + if (videoItem case SearchVideoItemModel item) { + var typeOrNull = item.type; + if (typeOrNull?.isNotEmpty == true) { + type = typeOrNull!; + } + } + return Material( + color: Colors.transparent, + child: InkWell( + onLongPress: onLongPress ?? + () => imageSaveDialog( + title: videoItem.title, + cover: videoItem.pic, + ), + onTap: onTap ?? + () async { + if (type == 'ketang') { + SmartDialog.showToast('课堂视频暂不支持播放'); + return; + } + if (videoItem.isPgc == true) { + if (videoItem.bangumi?.epId != null) { + PageUtils.viewPgc(epId: videoItem.bangumi!.epId); + } else if (videoItem.redirectUrl?.isNotEmpty == true) { + PageUtils.viewPgcFromUri(videoItem.redirectUrl!); + } + return; + } + try { + final int? cid = videoItem.cid ?? + await SearchHttp.ab2c( + aid: videoItem.aid, bvid: videoItem.bvid); + if (cid != null) { + onViewLater!(cid); + } + } catch (err) { + SmartDialog.showToast(err.toString()); + } + }, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: StyleString.safeSpace, + vertical: 5, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AspectRatio( + aspectRatio: StyleString.aspectRatio, + child: LayoutBuilder( + builder: (context, boxConstraints) { + final double maxWidth = boxConstraints.maxWidth; + final double maxHeight = boxConstraints.maxHeight; + num? progress = videoItem.progress; + return Stack( + clipBehavior: Clip.none, + children: [ + NetworkImgLayer( + src: videoItem.pic, + width: maxWidth, + height: maxHeight, + ), + PBadge( + text: videoItem.pgcLabel, + top: 6.0, + right: 6.0, + ), + if (progress != null && progress != 0) ...[ + PBadge( + text: progress == -1 + ? '已看完' + : '${Utils.timeFormat(progress)}/${Utils.timeFormat(videoItem.duration)}', + right: 6, + bottom: 8, + type: PBadgeType.gray, + ), + Positioned( + left: 0, + bottom: 0, + right: 0, + child: videoProgressIndicator( + progress == -1 + ? 1 + : progress / videoItem.duration!, + ), + ) + ] else if (videoItem.duration! > 0) + PBadge( + text: Utils.timeFormat(videoItem.duration), + right: 6.0, + bottom: 6.0, + type: PBadgeType.gray, + ), + if (type != 'video') + PBadge( + text: type, + left: 6.0, + bottom: 6.0, + type: PBadgeType.primary, + ), + ], + ); + }, + ), + ), + const SizedBox(width: 10), + content(context), + ], + ), + ), + ), + ); + } + + Widget content(BuildContext context) { + final theme = Theme.of(context); + return Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (videoItem.isPgc == true && videoItem.bangumi != null) ...[ + Text( + videoItem.bangumi!.season!.title!, + style: TextStyle( + fontSize: theme.textTheme.bodyMedium!.fontSize, + height: 1.42, + letterSpacing: 0.3, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 3), + Text( + videoItem.subtitle!, + textAlign: TextAlign.start, + style: TextStyle( + fontSize: 13, + color: theme.colorScheme.outline, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + const Spacer(), + StatView( + context: context, + theme: 'gray', + value: Utils.numFormat(videoItem.stat?.view), + ), + ] else ...[ + Expanded( + child: Text( + videoItem.title!, + style: TextStyle( + fontSize: theme.textTheme.bodyMedium!.fontSize, + height: 1.42, + letterSpacing: 0.3, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ), + Text( + videoItem.owner!.name!, + maxLines: 1, + style: TextStyle( + fontSize: 12, + height: 1, + color: theme.colorScheme.outline, + overflow: TextOverflow.clip, + ), + ), + const SizedBox(height: 3), + Row( + spacing: 8, + children: [ + StatView( + context: context, + theme: 'gray', + value: Utils.numFormat(videoItem.stat?.view), + ), + StatDanMu( + context: context, + theme: 'gray', + value: Utils.numFormat(videoItem.stat?.danmaku), + ), + ], + ), + ] + ], + ), + ); + } +} diff --git a/lib/pages/later_search/controller.dart b/lib/pages/later_search/controller.dart index febc016d8..be8592a17 100644 --- a/lib/pages/later_search/controller.dart +++ b/lib/pages/later_search/controller.dart @@ -1,25 +1,26 @@ import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/user.dart'; -import 'package:PiliPlus/models/model_hot_video_item.dart'; +import 'package:PiliPlus/models_new/later/data.dart'; +import 'package:PiliPlus/models_new/later/list.dart'; import 'package:PiliPlus/pages/common/common_search_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; class LaterSearchController - extends CommonSearchController { + extends CommonSearchController { dynamic mid = Get.arguments['mid']; dynamic count = Get.arguments['count']; @override - Future> customGetData() => UserHttp.seeYouLater( + Future> customGetData() => UserHttp.seeYouLater( page: page, keyword: editController.value.text, ); @override - List? getDataList(Map response) { - return response['list']; + List? getDataList(LaterData response) { + return response.list; } Future toViewDel(BuildContext context, int index, aid) async { diff --git a/lib/pages/later_search/view.dart b/lib/pages/later_search/view.dart index 7098569a8..e26189f4f 100644 --- a/lib/pages/later_search/view.dart +++ b/lib/pages/later_search/view.dart @@ -1,7 +1,8 @@ import 'package:PiliPlus/common/widgets/button/icon_button.dart'; -import 'package:PiliPlus/common/widgets/video_card/video_card_h.dart'; -import 'package:PiliPlus/models/model_hot_video_item.dart'; +import 'package:PiliPlus/models_new/later/data.dart'; +import 'package:PiliPlus/models_new/later/list.dart'; import 'package:PiliPlus/pages/common/common_search_page.dart'; +import 'package:PiliPlus/pages/later/widgets/video_card_h_later.dart'; import 'package:PiliPlus/pages/later_search/controller.dart'; import 'package:PiliPlus/utils/grid.dart'; import 'package:PiliPlus/utils/page_utils.dart'; @@ -17,7 +18,7 @@ class LaterSearchPage extends CommonSearchPage { } class _LaterSearchPageState - extends CommonSearchPageState { + extends CommonSearchPageState { @override final LaterSearchController controller = Get.put( LaterSearchController(), @@ -25,7 +26,7 @@ class _LaterSearchPageState ); @override - Widget buildList(List list) { + Widget buildList(List list) { return SliverGrid( gridDelegate: Grid.videoCardHDelegate(context, minHeight: 110), delegate: SliverChildBuilderDelegate( @@ -38,9 +39,8 @@ class _LaterSearchPageState return Stack( clipBehavior: Clip.none, children: [ - VideoCardH( + VideoCardHLater( videoItem: item, - source: 'later', onViewLater: (cid) { PageUtils.toVideoPage( 'bvid=${item.bvid}&cid=$cid', diff --git a/lib/pages/live/widgets/live_item_app.dart b/lib/pages/live/widgets/live_item_app.dart index 92b8740c7..7cdc998fb 100644 --- a/lib/pages/live/widgets/live_item_app.dart +++ b/lib/pages/live/widgets/live_item_app.dart @@ -66,7 +66,7 @@ class LiveCardVApp extends StatelessWidget { ); } - Widget liveContent(context) { + Widget liveContent(BuildContext context) { final theme = Theme.of(context); return Expanded( flex: 1, @@ -107,7 +107,7 @@ class LiveCardVApp extends StatelessWidget { ); } - Widget videoStat(context) { + Widget videoStat(BuildContext context) { return Container( height: 50, padding: const EdgeInsets.only(top: 26, left: 10, right: 10), diff --git a/lib/pages/live_follow/widgets/live_item_follow.dart b/lib/pages/live_follow/widgets/live_item_follow.dart index 83ec8cde1..789329e8c 100644 --- a/lib/pages/live_follow/widgets/live_item_follow.dart +++ b/lib/pages/live_follow/widgets/live_item_follow.dart @@ -66,7 +66,7 @@ class LiveCardVFollow extends StatelessWidget { ); } - Widget liveContent(context) { + Widget liveContent(BuildContext context) { final theme = Theme.of(context); return Expanded( flex: 1, @@ -107,7 +107,7 @@ class LiveCardVFollow extends StatelessWidget { ); } - Widget videoStat(context) { + Widget videoStat(BuildContext context) { return Container( height: 50, padding: const EdgeInsets.only(top: 26, left: 10, right: 10), diff --git a/lib/pages/live_room/view.dart b/lib/pages/live_room/view.dart index f6588039b..55b4fd301 100644 --- a/lib/pages/live_room/view.dart +++ b/lib/pages/live_room/view.dart @@ -105,7 +105,7 @@ class _LiveRoomPageState extends State } } - double _getFontSize(isFullScreen) { + double _getFontSize(bool isFullScreen) { return isFullScreen == false || _isPipMode == true ? 15 * plPlayerController.fontSize : 15 * plPlayerController.fontSizeFS; diff --git a/lib/pages/live_search/widgets/live_search_room.dart b/lib/pages/live_search/widgets/live_search_room.dart index d72f291c7..8863d9c47 100644 --- a/lib/pages/live_search/widgets/live_search_room.dart +++ b/lib/pages/live_search/widgets/live_search_room.dart @@ -78,7 +78,7 @@ class LiveCardVSearch extends StatelessWidget { ); } - Widget videoStat(context) { + Widget videoStat(BuildContext context) { return Container( height: 50, padding: const EdgeInsets.only(top: 26, left: 10, right: 10), diff --git a/lib/pages/member_home/widgets/video_card_v_member_home.dart b/lib/pages/member_home/widgets/video_card_v_member_home.dart index de70fac67..8a16d6af2 100644 --- a/lib/pages/member_home/widgets/video_card_v_member_home.dart +++ b/lib/pages/member_home/widgets/video_card_v_member_home.dart @@ -95,14 +95,14 @@ class VideoCardVMemberHome extends StatelessWidget { }, ), ), - videoContent(context) + content(context) ], ), ), ); } - Widget videoContent(BuildContext context) { + Widget content(BuildContext context) { return Expanded( child: Padding( padding: const EdgeInsets.fromLTRB(6, 5, 6, 5), diff --git a/lib/pages/member_season_series/widget/season_series_card.dart b/lib/pages/member_season_series/widget/season_series_card.dart index 8fa38eb24..90841a1b4 100644 --- a/lib/pages/member_season_series/widget/season_series_card.dart +++ b/lib/pages/member_season_series/widget/season_series_card.dart @@ -58,14 +58,14 @@ class SeasonSeriesCard extends StatelessWidget { ), ), const SizedBox(width: 10), - videoContent(context), + content(context), ], ), ), ); } - Widget videoContent(context) { + Widget content(BuildContext context) { final theme = Theme.of(context); return Expanded( child: Column( diff --git a/lib/pages/member_video/widgets/video_card_h_member_video.dart b/lib/pages/member_video/widgets/video_card_h_member_video.dart index cea5f61ec..b7a6bb626 100644 --- a/lib/pages/member_video/widgets/video_card_h_member_video.dart +++ b/lib/pages/member_video/widgets/video_card_h_member_video.dart @@ -165,7 +165,7 @@ class VideoCardHMemberVideo extends StatelessWidget { ), ), const SizedBox(width: 10), - videoContent(context, theme), + content(context, theme), ], ); }, @@ -185,7 +185,7 @@ class VideoCardHMemberVideo extends StatelessWidget { ); } - Widget videoContent(BuildContext context, ThemeData theme) { + Widget content(BuildContext context, ThemeData theme) { final isCurr = fromViewAid == videoItem.param || (videoItem.bvid != null && videoItem.bvid == bvid); return Expanded( @@ -221,13 +221,13 @@ class VideoCardHMemberVideo extends StatelessWidget { ), const SizedBox(height: 3), Row( + spacing: 8, children: [ StatView( context: context, theme: 'gray', value: videoItem.stat.viewStr, ), - const SizedBox(width: 8), StatDanMu( context: context, theme: 'gray', diff --git a/lib/pages/pgc/widgets/pgc_card_v.dart b/lib/pages/pgc/widgets/pgc_card_v.dart index 0abf7bea7..0fd102ecb 100644 --- a/lib/pages/pgc/widgets/pgc_card_v.dart +++ b/lib/pages/pgc/widgets/pgc_card_v.dart @@ -66,14 +66,14 @@ class PgcCardV extends StatelessWidget { ); }), ), - bagumiContent(context) + content(context) ], ), ), ); } - Widget bagumiContent(context) { + Widget content(BuildContext context) { final theme = Theme.of(context); final style = TextStyle( fontSize: theme.textTheme.labelMedium!.fontSize, diff --git a/lib/pages/pgc/widgets/pgc_card_v_timeline.dart b/lib/pages/pgc/widgets/pgc_card_v_timeline.dart index 727ec114f..fef2f9df9 100644 --- a/lib/pages/pgc/widgets/pgc_card_v_timeline.dart +++ b/lib/pages/pgc/widgets/pgc_card_v_timeline.dart @@ -59,14 +59,14 @@ class PgcCardVTimeline extends StatelessWidget { ); }), ), - bagumiContent(context) + content(context) ], ), ), ); } - Widget bagumiContent(context) { + Widget content(BuildContext context) { final theme = Theme.of(context); return Expanded( child: Padding( diff --git a/lib/pages/pgc_index/widgets/pgc_card_v_pgc_index.dart b/lib/pages/pgc_index/widgets/pgc_card_v_pgc_index.dart index 7603bb6ae..b76ced613 100644 --- a/lib/pages/pgc_index/widgets/pgc_card_v_pgc_index.dart +++ b/lib/pages/pgc_index/widgets/pgc_card_v_pgc_index.dart @@ -61,14 +61,14 @@ class PgcCardVPgcIndex extends StatelessWidget { ); }), ), - bagumiContent(context) + conetent(context) ], ), ), ); } - Widget bagumiContent(context) { + Widget conetent(BuildContext context) { final theme = Theme.of(context); return Expanded( child: Padding( diff --git a/lib/pages/save_panel/view.dart b/lib/pages/save_panel/view.dart index a5ea903a1..8e857b182 100644 --- a/lib/pages/save_panel/view.dart +++ b/lib/pages/save_panel/view.dart @@ -323,7 +323,7 @@ class _SavePanelState extends State { IgnorePointer( child: DynamicPanel( item: _item, - source: 'detail', + isDetail: true, isSave: true, ), ), diff --git a/lib/pages/subscription/widgets/item.dart b/lib/pages/subscription/widgets/item.dart index 6a222ca48..5f13987b9 100644 --- a/lib/pages/subscription/widgets/item.dart +++ b/lib/pages/subscription/widgets/item.dart @@ -88,14 +88,14 @@ class SubItem extends StatelessWidget { ), ), const SizedBox(width: 10), - videoContent(context), + content(context), ], ), ), ); } - Widget videoContent(context) { + Widget content(BuildContext context) { final theme = Theme.of(context); final style = TextStyle( fontSize: 13, diff --git a/lib/pages/subscription_detail/widget/sub_video_card.dart b/lib/pages/subscription_detail/widget/sub_video_card.dart index 86252cc08..81e1b0eeb 100644 --- a/lib/pages/subscription_detail/widget/sub_video_card.dart +++ b/lib/pages/subscription_detail/widget/sub_video_card.dart @@ -24,17 +24,15 @@ class SubVideoCardH extends StatelessWidget { @override Widget build(BuildContext context) { - int id = videoItem.id!; - String bvid = videoItem.bvid!; return InkWell( onTap: () async { - int? cid = await SearchHttp.ab2c(bvid: bvid); + int? cid = await SearchHttp.ab2c(bvid: videoItem.bvid); if (cid != null) { PageUtils.toVideoPage( - 'bvid=$bvid&cid=$cid', + 'bvid=${videoItem.bvid}&cid=$cid', arguments: { 'videoItem': videoItem, - 'heroTag': Utils.makeHeroTag(id), + 'heroTag': Utils.makeHeroTag(videoItem.id), 'videoType': SearchType.video, }, ); @@ -79,21 +77,21 @@ class SubVideoCardH extends StatelessWidget { ), ), const SizedBox(width: 10), - videoContent(context), + content(context), ], ), ), ); } - Widget videoContent(context) { + Widget content(BuildContext context) { return Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Text( - '${videoItem.title}', + videoItem.title!, textAlign: TextAlign.start, style: const TextStyle( letterSpacing: 0.3, @@ -111,19 +109,18 @@ class SubVideoCardH extends StatelessWidget { ), const SizedBox(height: 3), Row( + spacing: 8, children: [ StatView( context: context, theme: 'gray', value: Utils.numFormat(videoItem.cntInfo?.play), ), - const SizedBox(width: 8), StatDanMu( context: context, theme: 'gray', value: Utils.numFormat(videoItem.cntInfo?.danmaku), ), - const Spacer(), ], ), ], diff --git a/lib/pages/video/ai_conclusion/view.dart b/lib/pages/video/ai_conclusion/view.dart index f5398b244..f3b26ee62 100644 --- a/lib/pages/video/ai_conclusion/view.dart +++ b/lib/pages/video/ai_conclusion/view.dart @@ -6,19 +6,19 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -class AiDetail extends CommonCollapseSlidePage { - final AiConclusionResult modelResult; +class AiConclusionPanel extends CommonCollapseSlidePage { + final AiConclusionResult item; - const AiDetail({ + const AiConclusionPanel({ super.key, - required this.modelResult, + required this.item, }); @override - State createState() => _AiDetailState(); + State createState() => _AiDetailState(); } -class _AiDetailState extends CommonCollapseSlidePageState { +class _AiDetailState extends CommonCollapseSlidePageState { @override Widget buildPage(ThemeData theme) { return Material( @@ -56,12 +56,12 @@ class _AiDetailState extends CommonCollapseSlidePageState { controller: ScrollController(), physics: const AlwaysScrollableScrollPhysics(), slivers: [ - if (widget.modelResult.summary?.isNotEmpty == true) ...[ + if (widget.item.summary?.isNotEmpty == true) ...[ SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 14), child: SelectableText( - widget.modelResult.summary!, + widget.item.summary!, style: const TextStyle( fontSize: 15, height: 1.5, @@ -69,7 +69,7 @@ class _AiDetailState extends CommonCollapseSlidePageState { ), ), ), - if (widget.modelResult.outline?.isNotEmpty == true) + if (widget.item.outline?.isNotEmpty == true) SliverToBoxAdapter( child: Divider( height: 20, @@ -78,7 +78,7 @@ class _AiDetailState extends CommonCollapseSlidePageState { ), ), ], - if (widget.modelResult.outline?.isNotEmpty == true) + if (widget.item.outline?.isNotEmpty == true) SliverPadding( padding: EdgeInsets.only( left: 14, @@ -86,14 +86,14 @@ class _AiDetailState extends CommonCollapseSlidePageState { bottom: MediaQuery.paddingOf(context).bottom + 80, ), sliver: SliverList.builder( - itemCount: widget.modelResult.outline!.length, + itemCount: widget.item.outline!.length, itemBuilder: (context, index) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (index != 0) const SizedBox(height: 10), SelectableText( - widget.modelResult.outline![index].title!, + widget.item.outline![index].title!, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.bold, @@ -101,10 +101,9 @@ class _AiDetailState extends CommonCollapseSlidePageState { ), ), const SizedBox(height: 6), - if (widget.modelResult.outline![index].partOutline - ?.isNotEmpty == + if (widget.item.outline![index].partOutline?.isNotEmpty == true) - ...widget.modelResult.outline![index].partOutline!.map( + ...widget.item.outline![index].partOutline!.map( (item) => Wrap( children: [ SelectableText.rich( @@ -122,7 +121,6 @@ class _AiDetailState extends CommonCollapseSlidePageState { ), recognizer: TapGestureRecognizer() ..onTap = () { - // 跳转到指定位置 try { Get.find( tag: Get.arguments['heroTag']) diff --git a/lib/pages/video/introduction/pgc/controller.dart b/lib/pages/video/introduction/pgc/controller.dart index 746c3c1e7..72c399b9e 100644 --- a/lib/pages/video/introduction/pgc/controller.dart +++ b/lib/pages/video/introduction/pgc/controller.dart @@ -220,7 +220,7 @@ class PgcIntroController extends GetxController { } // 分享视频 - void actionShareVideo(context) { + void actionShareVideo(BuildContext context) { showDialog( context: context, builder: (_) { @@ -360,7 +360,7 @@ class PgcIntroController extends GetxController { } // 修改分P或番剧分集 - void changeSeasonOrbangu(epId, bvid, cid, aid, cover) { + void changeSeasonOrbangu(dynamic epId, bvid, cid, aid, cover) { // 重新获取视频资源 this.epId = epId; this.bvid = bvid; @@ -420,7 +420,7 @@ class PgcIntroController extends GetxController { SmartDialog.showToast(result['msg']); } - Future pgcUpdate(status) async { + Future pgcUpdate(int status) async { var result = await VideoHttp.pgcUpdate( seasonId: [pgcItem.seasonId], status: status, diff --git a/lib/pages/video/introduction/pgc/view.dart b/lib/pages/video/introduction/pgc/view.dart index 1d6a3556c..afcf9e228 100644 --- a/lib/pages/video/introduction/pgc/view.dart +++ b/lib/pages/video/introduction/pgc/view.dart @@ -19,13 +19,13 @@ import 'package:flutter/services.dart' show HapticFeedback; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; -class PgcIntroPanel extends StatefulWidget { +class PgcIntroPage extends StatefulWidget { final int? cid; final String heroTag; final Function showEpisodes; final Function showIntroDetail; - const PgcIntroPanel({ + const PgcIntroPage({ super.key, this.cid, required this.heroTag, @@ -34,10 +34,10 @@ class PgcIntroPanel extends StatefulWidget { }); @override - State createState() => _PgcIntroPanelState(); + State createState() => _PgcIntroPageState(); } -class _PgcIntroPanelState extends State +class _PgcIntroPageState extends State with AutomaticKeepAliveClientMixin { late PgcIntroController pgcIntroController; late VideoDetailController videoDetailCtr; diff --git a/lib/pages/video/introduction/pgc/widgets/intro_detail.dart b/lib/pages/video/introduction/pgc/widgets/intro_detail.dart index ba44d33a5..4d36d4a5b 100644 --- a/lib/pages/video/introduction/pgc/widgets/intro_detail.dart +++ b/lib/pages/video/introduction/pgc/widgets/intro_detail.dart @@ -13,11 +13,11 @@ import 'package:PiliPlus/utils/utils.dart'; import 'package:flutter/material.dart' hide TabBarView; import 'package:get/get.dart'; -class IntroDetail extends CommonCollapseSlidePage { +class PgcIntroPanel extends CommonCollapseSlidePage { final PgcInfoModel item; final List? videoTags; - const IntroDetail({ + const PgcIntroPanel({ super.key, required this.item, super.enableSlide = false, @@ -25,10 +25,10 @@ class IntroDetail extends CommonCollapseSlidePage { }); @override - State createState() => _IntroDetailState(); + State createState() => _IntroDetailState(); } -class _IntroDetailState extends CommonCollapseSlidePageState { +class _IntroDetailState extends CommonCollapseSlidePageState { late final _tabController = TabController(length: 2, vsync: this); final _controller = ScrollController(); @@ -106,13 +106,13 @@ class _IntroDetailState extends CommonCollapseSlidePageState { ), const SizedBox(height: 4), Row( + spacing: 6, children: [ StatView( context: context, theme: 'gray', value: Utils.numFormat(widget.item.stat!.views), ), - const SizedBox(width: 6), StatDanMu( context: context, theme: 'gray', diff --git a/lib/pages/video/introduction/ugc/view.dart b/lib/pages/video/introduction/ugc/view.dart index 4fa2e8e83..c80840785 100644 --- a/lib/pages/video/introduction/ugc/view.dart +++ b/lib/pages/video/introduction/ugc/view.dart @@ -551,6 +551,7 @@ class _VideoInfoState extends State { clipBehavior: Clip.none, children: [ Row( + spacing: 10, children: [ StatView( context: context, @@ -560,7 +561,6 @@ class _VideoInfoState extends State { : videoItem['stat']?.view ?? '-'), textColor: theme.colorScheme.outline, ), - const SizedBox(width: 10), StatDanMu( context: context, theme: 'gray', @@ -569,7 +569,6 @@ class _VideoInfoState extends State { : videoItem['stat']?.danmu ?? '-'), textColor: theme.colorScheme.outline, ), - const SizedBox(width: 10), Text( Utils.dateFormat( !widget.isLoading @@ -581,16 +580,13 @@ class _VideoInfoState extends State { color: theme.colorScheme.outline, ), ), - if (MineController.anonymity.value) ...[ - const SizedBox(width: 10), + if (MineController.anonymity.value) Icon( MdiIcons.incognito, size: 15, color: theme.colorScheme.outline, semanticLabel: '无痕', ), - ], - const SizedBox(width: 10), if (videoIntroController.isShowOnlineTotal) Obx( () => Text( diff --git a/lib/pages/video/medialist/view.dart b/lib/pages/video/medialist/view.dart index 5028fa2be..6ff0f6c12 100644 --- a/lib/pages/video/medialist/view.dart +++ b/lib/pages/video/medialist/view.dart @@ -198,6 +198,16 @@ class _MediaListPanelState width: boxConstraints.maxWidth, height: boxConstraints.maxHeight, ), + if (item.badge?.text?.isNotEmpty == true) + PBadge( + text: item.badge?.text, + right: 6.0, + top: 6.0, + type: switch (item.badge?.text) { + '充电专属' => PBadgeType.error, + _ => PBadgeType.primary, + }, + ), PBadge( text: Utils.timeFormat(item.duration!), right: 6.0, @@ -216,7 +226,6 @@ class _MediaListPanelState children: [ Text( item.title!, - textAlign: TextAlign.start, maxLines: 2, overflow: TextOverflow.ellipsis, style: TextStyle( @@ -227,6 +236,19 @@ class _MediaListPanelState : null, ), ), + if (item.type == 24 && + item.intro?.isNotEmpty == true) ...[ + const SizedBox(height: 3), + Text( + item.intro!, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 13, + color: theme.colorScheme.outline, + ), + ), + ], const Spacer(), Text( item.upper!.name!, @@ -237,24 +259,26 @@ class _MediaListPanelState color: theme.colorScheme.outline, ), ), - const SizedBox(height: 3), - Row( - children: [ - StatView( - context: context, - theme: 'gray', - value: Utils.numFormat( - item.cntInfo!.play!), - ), - const SizedBox(width: 8), - StatDanMu( - context: context, - theme: 'gray', - value: Utils.numFormat( - item.cntInfo!.danmaku!), - ), - ], - ), + if (item.type == 2) ...[ + const SizedBox(height: 3), + Row( + spacing: 8, + children: [ + StatView( + context: context, + theme: 'gray', + value: Utils.numFormat( + item.cntInfo!.play!), + ), + StatDanMu( + context: context, + theme: 'gray', + value: Utils.numFormat( + item.cntInfo!.danmaku!), + ), + ], + ), + ], ], ), ), diff --git a/lib/pages/video/pay_coins/view.dart b/lib/pages/video/pay_coins/view.dart index d52c917b3..37703f3f1 100644 --- a/lib/pages/video/pay_coins/view.dart +++ b/lib/pages/video/pay_coins/view.dart @@ -218,7 +218,7 @@ class _PayCoinsPageState extends State }); } - Widget _buildBody(isV) => Stack( + Widget _buildBody(bool isV) => Stack( key: _key, clipBehavior: Clip.none, alignment: Alignment.center, diff --git a/lib/pages/video/reply_reply/view.dart b/lib/pages/video/reply_reply/view.dart index 1ecfc26b4..b4336ab2e 100644 --- a/lib/pages/video/reply_reply/view.dart +++ b/lib/pages/video/reply_reply/view.dart @@ -25,7 +25,7 @@ class VideoReplyReplyPanel extends CommonSlidePage { required this.rpid, this.dialog, this.firstFloor, - this.source, + required this.isVideoDetail, required this.replyType, this.isDialogue = false, this.onViewImage, @@ -37,7 +37,7 @@ class VideoReplyReplyPanel extends CommonSlidePage { final int rpid; final int? dialog; final ReplyInfo? firstFloor; - final String? source; + final bool isVideoDetail; final int replyType; final bool isDialogue; final VoidCallback? onViewImage; @@ -118,7 +118,7 @@ class _VideoReplyReplyPanelState resizeToAvoidBottomInset: false, body: Column( children: [ - widget.source == 'videoDetail' + widget.isVideoDetail ? Container( height: 45, decoration: BoxDecoration( @@ -439,7 +439,7 @@ class _VideoReplyReplyPanelState rpid: replyItem.root.toInt(), dialog: replyItem.dialog.toInt(), replyType: widget.replyType, - source: 'videoDetail', + isVideoDetail: true, isDialogue: true, ), ), diff --git a/lib/pages/video/view.dart b/lib/pages/video/view.dart index ce3a3006d..33f065203 100644 --- a/lib/pages/video/view.dart +++ b/lib/pages/video/view.dart @@ -1799,7 +1799,7 @@ class _VideoDetailPageVState extends State ] else if (videoDetailController.videoType == SearchType.media_bangumi) Obx( - () => PgcIntroPanel( + () => PgcIntroPage( key: pgcPanelKey, heroTag: heroTag, cid: videoDetailController.cid.value, @@ -2027,7 +2027,7 @@ class _VideoDetailPageVState extends State rpid: rpid, firstFloor: replyItem, replyType: 1, - source: 'videoDetail', + isVideoDetail: true, onViewImage: videoDetailController.onViewImage, onDismissed: videoDetailController.onDismissed, ), @@ -2040,7 +2040,7 @@ class _VideoDetailPageVState extends State videoDetailController.childKey.currentState?.showBottomSheet( backgroundColor: Colors.transparent, (context) => - AiDetail(modelResult: videoIntroController.aiConclusionResult!), + AiConclusionPanel(item: videoIntroController.aiConclusionResult!), ); } @@ -2048,7 +2048,7 @@ class _VideoDetailPageVState extends State PgcInfoModel videoDetail, List? videoTags) { videoDetailController.childKey.currentState?.showBottomSheet( backgroundColor: Colors.transparent, - (context) => IntroDetail( + (context) => PgcIntroPanel( item: videoDetail, videoTags: videoTags, ), diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 94decfb55..ab957165b 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -998,14 +998,7 @@ class PlPlayerController { if (event.startsWith("Failed to open .") || event.startsWith("Cannot open") || event.startsWith("Can not open")) { - List list = [ - if (dataSource.videoSource.isNullOrEmpty) '视频', - if (dataSource.audioSource.isNullOrEmpty) '音频', - ]; - if (list.isNotEmpty) { - SmartDialog.showToast('${list.join('、')}源为空'); - return; - } + return; } SmartDialog.showToast('视频加载错误, $event'); if (kDebugMode) debugPrint('视频加载错误, $event'); diff --git a/lib/utils/app_scheme.dart b/lib/utils/app_scheme.dart index 0af1fa477..c5dfcc11f 100644 --- a/lib/utils/app_scheme.dart +++ b/lib/utils/app_scheme.dart @@ -142,7 +142,7 @@ class PiliScheme { enableSlide: false, oid: int.parse(oid), rpid: rpid, - source: 'routePush', + isVideoDetail: false, replyType: 1, firstFloor: null, id: commentSecondaryId != null @@ -284,7 +284,7 @@ class PiliScheme { oid: oid, rpid: rootId, id: rpId, - source: 'routePush', + isVideoDetail: false, replyType: type, firstFloor: null, ), @@ -333,7 +333,7 @@ class PiliScheme { enableSlide: false, oid: oid, rpid: rpId, - source: 'routePush', + isVideoDetail: false, replyType: type, firstFloor: null, ), @@ -397,7 +397,7 @@ class PiliScheme { enableSlide: false, oid: oid ?? int.parse(dynId), rpid: rpid, - source: 'routePush', + isVideoDetail: false, replyType: businessId ?? 17, firstFloor: null, id: commentSecondaryId != null @@ -788,7 +788,7 @@ class PiliScheme { enableSlide: false, oid: int.parse(oid), rpid: int.parse(root), - source: 'routePush', + isVideoDetail: false, replyType: int.parse(pageType), firstFloor: null, id: commentSecondaryId != null