diff --git a/lib/common/widgets/stat/stat.dart b/lib/common/widgets/stat/stat.dart index 53845887a..817a2de77 100644 --- a/lib/common/widgets/stat/stat.dart +++ b/lib/common/widgets/stat/stat.dart @@ -1,92 +1,48 @@ +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:flutter/material.dart'; -abstract class _StatItemBase extends StatelessWidget { - final BuildContext context; - final Object value; - final String? theme; +class StatWidget extends StatelessWidget { + final StatType type; + final dynamic value; final Color? textColor; final double iconSize; - const _StatItemBase({ - required this.context, + const StatWidget({ + super.key, + required this.type, required this.value, - this.theme, this.textColor, this.iconSize = 13, }); - IconData get iconData; - String get semanticsLabel; - - Color get color { - return textColor ?? - switch (theme) { - 'gray' => - Theme.of(context).colorScheme.outline.withValues(alpha: 0.8), - 'black' => - Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7), - _ => Colors.white, - }; - } - @override Widget build(BuildContext context) { + IconData iconData = switch (type) { + StatType.view => Icons.remove_red_eye_outlined, + StatType.danmaku => Icons.subtitles_outlined, + StatType.like => Icons.thumb_up_outlined, + StatType.reply => Icons.comment_outlined, + StatType.follow => Icons.favorite_border, + StatType.play => Icons.play_circle_outlined, + }; + + Color color = textColor ?? + Theme.of(context).colorScheme.outline.withValues(alpha: 0.8); + return Row( + spacing: 2, children: [ Icon( iconData, size: iconSize, color: color, ), - const SizedBox(width: 2), Text( Utils.numFormat(value), style: TextStyle(fontSize: 12, color: color), - overflow: TextOverflow.clip, - semanticsLabel: semanticsLabel, - ) + ), ], ); } } - -class StatView extends _StatItemBase { - final String? goto; - - const StatView({ - required super.context, - required super.value, - this.goto, - super.theme, - super.textColor, - }) : super(iconSize: 13); - - @override - IconData get iconData => switch (goto) { - 'picture' => Icons.remove_red_eye_outlined, - 'like' => Icons.thumb_up_outlined, - 'reply' => Icons.comment_outlined, - 'follow' => Icons.favorite_border, - _ => Icons.play_circle_outlined, - }; - - @override - String get semanticsLabel => - '${Utils.numFormat(value)}次${goto == "picture" ? "浏览" : "播放"}'; -} - -class StatDanMu extends _StatItemBase { - const StatDanMu({ - required super.context, - required super.value, - super.theme, - super.textColor, - }) : super(iconSize: 14); - - @override - IconData get iconData => Icons.subtitles_outlined; - - @override - String get semanticsLabel => '${Utils.numFormat(value)}条弹幕'; -} diff --git a/lib/common/widgets/video_card/video_card_h.dart b/lib/common/widgets/video_card/video_card_h.dart index 73042ece7..b3da8283a 100644 --- a/lib/common/widgets/video_card/video_card_h.dart +++ b/lib/common/widgets/video_card/video_card_h.dart @@ -7,6 +7,7 @@ import 'package:PiliPlus/common/widgets/stat/stat.dart'; import 'package:PiliPlus/common/widgets/video_popup_menu.dart'; import 'package:PiliPlus/http/search.dart'; import 'package:PiliPlus/models/common/badge_type.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models/model_hot_video_item.dart'; import 'package:PiliPlus/models/model_video.dart'; import 'package:PiliPlus/models/search/result.dart'; @@ -257,16 +258,14 @@ class VideoCardH extends StatelessWidget { spacing: 8, children: [ if (showView) - StatView( - context: context, - theme: 'gray', - value: videoItem.stat.viewStr, + StatWidget( + type: StatType.view, + value: videoItem.stat.view, ), if (showDanmaku) - StatDanMu( - context: context, - theme: 'gray', - value: videoItem.stat.danmuStr, + StatWidget( + type: StatType.danmaku, + value: videoItem.stat.danmu, ), ], ), diff --git a/lib/common/widgets/video_card/video_card_v.dart b/lib/common/widgets/video_card/video_card_v.dart index d41e7e65b..7bffc6fee 100644 --- a/lib/common/widgets/video_card/video_card_v.dart +++ b/lib/common/widgets/video_card/video_card_v.dart @@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/stat/stat.dart'; import 'package:PiliPlus/common/widgets/video_popup_menu.dart'; import 'package:PiliPlus/http/search.dart'; import 'package:PiliPlus/models/common/badge_type.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models/home/rcmd/result.dart'; import 'package:PiliPlus/models/model_rec_video_item.dart'; import 'package:PiliPlus/utils/app_scheme.dart'; @@ -234,19 +235,17 @@ class VideoCardV extends StatelessWidget { Widget videoStat(BuildContext context, ThemeData theme) { return Row( children: [ - StatView( - context: context, - theme: 'gray', - value: videoItem.stat.viewStr, - goto: videoItem.goto, + StatWidget( + value: videoItem.stat.view, + type: StatType.view, ), - const SizedBox(width: 4), - if (videoItem.goto != 'picture') - StatDanMu( - context: context, - theme: 'gray', - value: videoItem.stat.danmuStr, + if (videoItem.goto != 'picture') ...[ + const SizedBox(width: 4), + StatWidget( + type: StatType.danmaku, + value: videoItem.stat.danmu, ), + ], if (videoItem is RecVideoItemModel) ...[ const Spacer(), Text.rich( diff --git a/lib/http/api.dart b/lib/http/api.dart index bd135b9cd..ffab87e77 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -697,9 +697,6 @@ class Api { static const String pgcSeasonRank = "/pgc/season/rank/web/list"; - /// 取消订阅-合集 - static const String unfavSeason = '/x/v3/fav/season/unfav'; - /// 取消订阅-播单 static const String unfavFolder = '/x/v3/fav/folder/unfav'; @@ -731,7 +728,9 @@ class Api { // 点赞投币收藏关注 static const String videoRelation = '/x/web-interface/archive/relation'; - static const String seasonFav = '/x/v3/fav/season/'; // + fav unfav + static const String favSeason = '/x/v3/fav/season/fav'; + + static const String unfavSeason = '/x/v3/fav/season/unfav'; /// 稍后再看&收藏夹视频列表 static const String mediaList = '/x/v2/medialist/resource/list'; diff --git a/lib/http/fav.dart b/lib/http/fav.dart index 6ba35cc28..5108c7199 100644 --- a/lib/http/fav.dart +++ b/lib/http/fav.dart @@ -510,7 +510,7 @@ class FavHttp { required dynamic seasonId, }) async { var res = await Request().post( - Api.seasonFav + (isFav ? 'unfav' : 'fav'), + isFav ? Api.unfavSeason : Api.favSeason, data: { 'platform': 'web', 'season_id': seasonId, diff --git a/lib/models/common/stat_type.dart b/lib/models/common/stat_type.dart new file mode 100644 index 000000000..bf38a5190 --- /dev/null +++ b/lib/models/common/stat_type.dart @@ -0,0 +1 @@ +enum StatType { view, danmaku, like, reply, follow, play } diff --git a/lib/models/home/rcmd/result.dart b/lib/models/home/rcmd/result.dart index c0fea4132..318c764d8 100644 --- a/lib/models/home/rcmd/result.dart +++ b/lib/models/home/rcmd/result.dart @@ -50,34 +50,13 @@ class RecVideoItemAppModel extends BaseRecVideoItemModel { : null; desc = json['desc']; } - - // @override - // int? get pubdate => null; } -class RcmdStat implements BaseStat { - @override - int? like; - - @override - int? get view => Utils.parseNum(viewStr); - @override - int? get danmu => Utils.parseNum(danmuStr); - - @override - late String viewStr; - @override - late String danmuStr; - +class RcmdStat extends BaseStat { RcmdStat.fromJson(Map json) { - viewStr = json["cover_left_text_1"] ?? ''; - danmuStr = json['cover_left_text_2'] ?? ''; + view = Utils.parseNum(json["cover_left_text_1"] ?? ''); + danmu = Utils.parseNum(json["cover_left_text_2"] ?? ''); } - - @override - set danmu(_) {} - @override - set view(_) {} } class RcmdOwner extends BaseOwner { diff --git a/lib/models/model_video.dart b/lib/models/model_video.dart index c687b5672..5334061c7 100644 --- a/lib/models/model_video.dart +++ b/lib/models/model_video.dart @@ -1,5 +1,3 @@ -import 'package:PiliPlus/utils/utils.dart'; - abstract class BaseSimpleVideoItemModel { late String title; String? bvid; @@ -26,9 +24,6 @@ abstract class BaseStat { int? view; int? like; int? danmu; - - String get viewStr => Utils.numFormat(view); - String get danmuStr => Utils.numFormat(danmu); } class Stat extends BaseStat { diff --git a/lib/pages/article/view.dart b/lib/pages/article/view.dart index 3fcfd4d29..6af7e52fc 100644 --- a/lib/pages/article/view.dart +++ b/lib/pages/article/view.dart @@ -455,6 +455,7 @@ class _ArticlePageState extends State return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => context.imageView( + quality: 60, imgList: pics .map( (e) => SourceModel(url: e.url!)) @@ -474,6 +475,10 @@ class _ArticlePageState extends State : null, imageUrl: Utils.thumbnailImgUrl( pic.url, 60), + fadeInDuration: const Duration( + milliseconds: 120), + fadeOutDuration: const Duration( + milliseconds: 120), ), ), if (pic.isLongPic == true) diff --git a/lib/pages/article_list/view.dart b/lib/pages/article_list/view.dart index 6ebd704ba..249cb7e61 100644 --- a/lib/pages/article_list/view.dart +++ b/lib/pages/article_list/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; @@ -71,12 +70,7 @@ class _ArticleListPageState extends State { ), Success(:var response) => response?.isNotEmpty == true ? SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: 2, - maxCrossAxisExtent: Grid.smallCardWidth * 2, - childAspectRatio: StyleString.aspectRatio * 2.6, - minHeight: MediaQuery.textScalerOf(context).scale(90), - ), + gridDelegate: Grid.videoCardHDelegate(context), delegate: SliverChildBuilderDelegate( (context, index) { return ArticleListItem( @@ -197,7 +191,8 @@ class _ArticleListPageState extends State { onPressed: () => PageUtils.inAppWebview( '${HttpString.baseUrl}/read/mobile-readlist/rl${_controller.id}'), icon: const Icon(Icons.open_in_browser_outlined, size: 19), - ) + ), + const SizedBox(width: 10), ], ); } diff --git a/lib/pages/article_list/widgets/item.dart b/lib/pages/article_list/widgets/item.dart index 0464bf5e7..61235a70d 100644 --- a/lib/pages/article_list/widgets/item.dart +++ b/lib/pages/article_list/widgets/item.dart @@ -1,6 +1,7 @@ import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/stat/stat.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/article/article_list/article.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -33,65 +34,10 @@ class ArticleListItem extends StatelessWidget { vertical: 5, ), child: Row( - mainAxisAlignment: MainAxisAlignment.start, + spacing: 10, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - item.title!, - style: const TextStyle( - fontSize: 15, - height: 1.42, - letterSpacing: 0.3, - ), - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), - const SizedBox(height: 3), - if (item.summary != null) - Text( - item.summary!, - style: TextStyle( - fontSize: 13, - color: theme.colorScheme.outline, - ), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - const Spacer(), - Row( - children: [ - StatView( - context: context, - value: item.stats?.view ?? 0, - goto: 'picture', - textColor: theme.colorScheme.outline, - ), - const SizedBox(width: 16), - StatView( - context: context, - goto: 'like', - value: item.stats?.like ?? 0, - textColor: theme.colorScheme.outline, - ), - const SizedBox(width: 16), - StatView( - context: context, - goto: 'reply', - value: item.stats?.reply ?? 0, - textColor: theme.colorScheme.outline, - ), - ], - ), - ], - ), - ), - if (item.imageUrls?.isNotEmpty == true) ...[ - const SizedBox(width: 10), + if (item.imageUrls?.isNotEmpty == true) AspectRatio( aspectRatio: StyleString.aspectRatio, child: LayoutBuilder( @@ -104,7 +50,56 @@ class ArticleListItem extends StatelessWidget { }, ), ), - ], + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + item.title!, + style: const TextStyle( + fontSize: 14, + height: 1.42, + letterSpacing: 0.3, + ), + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 3), + if (item.summary != null) + Text( + item.summary!, + style: TextStyle( + fontSize: 12, + color: theme.colorScheme.outline, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + const Spacer(), + Row( + spacing: 16, + children: [ + StatWidget( + value: item.stats?.view, + textColor: theme.colorScheme.outline, + type: StatType.view, + ), + StatWidget( + type: StatType.like, + value: item.stats?.like, + textColor: theme.colorScheme.outline, + ), + StatWidget( + type: StatType.reply, + value: item.stats?.reply, + textColor: theme.colorScheme.outline, + ), + ], + ), + ], + ), + ), ], ), ), diff --git a/lib/pages/dynamics/widgets/live_panel_sub.dart b/lib/pages/dynamics/widgets/live_panel_sub.dart index b53fdbecf..cd86c7c49 100644 --- a/lib/pages/dynamics/widgets/live_panel_sub.dart +++ b/lib/pages/dynamics/widgets/live_panel_sub.dart @@ -42,7 +42,7 @@ Widget livePanelSub( PBadge( text: content.watchedShow?.textLarge, top: 6, - right: 70, + right: 65, fontSize: 10.5, type: PBadgeType.gray, ), diff --git a/lib/pages/episode_panel/view.dart b/lib/pages/episode_panel/view.dart index 5b0d06058..911f40738 100644 --- a/lib/pages/episode_panel/view.dart +++ b/lib/pages/episode_panel/view.dart @@ -14,6 +14,7 @@ import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/video.dart'; import 'package:PiliPlus/models/common/badge_type.dart'; import 'package:PiliPlus/models/common/episode_panel_type.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/pgc/pgc_info_model/episode.dart' as pgc; import 'package:PiliPlus/models_new/video/video_detail/episode.dart' as ugc; import 'package:PiliPlus/models_new/video/video_detail/page.dart'; @@ -514,16 +515,14 @@ class _EpisodePanelState extends CommonSlidePageState { Row( spacing: 8, children: [ - StatView( - context: context, - theme: 'gray', + StatWidget( value: view, + type: StatType.view, ), if (danmaku != null) - StatDanMu( - context: context, - theme: 'gray', + StatWidget( value: danmaku, + type: StatType.danmaku, ), ], ), diff --git a/lib/pages/fav/article/widget/item.dart b/lib/pages/fav/article/widget/item.dart index 2d4494986..b11588a21 100644 --- a/lib/pages/fav/article/widget/item.dart +++ b/lib/pages/fav/article/widget/item.dart @@ -2,6 +2,7 @@ import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/widgets/button/icon_button.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/stat/stat.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/fav/fav_article/item.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -74,35 +75,34 @@ class FavArticleItem extends StatelessWidget { overflow: TextOverflow.ellipsis, ), ), - Row( - children: [ - // StatView( - // context: context, - // value: item.stat!.view!, - // goto: 'picture', - // textColor: theme.colorScheme.outline, - // ), - // const SizedBox(width: 16), - StatView( - context: context, - goto: 'like', - value: - item.stat!.like == '' ? 0 : item.stat!.like!, - textColor: theme.colorScheme.outline, - ), - ], - ), - const SizedBox(height: 3), Text( - '${item.author!.name} · ${item.pubTime}', + item.author!.name!, maxLines: 1, style: TextStyle( fontSize: 13, height: 1, color: theme.colorScheme.outline, - overflow: TextOverflow.clip, ), ), + const SizedBox(height: 3), + Row( + children: [ + StatWidget( + type: StatType.like, + value: item.stat!.like, + textColor: theme.colorScheme.outline, + ), + Text( + ' · ${item.pubTime}', + maxLines: 1, + style: TextStyle( + fontSize: 13, + height: 1, + color: theme.colorScheme.outline, + ), + ), + ], + ), ], ), ), diff --git a/lib/pages/fav/note/widget/item.dart b/lib/pages/fav/note/widget/item.dart index f5060f294..e1f5f907d 100644 --- a/lib/pages/fav/note/widget/item.dart +++ b/lib/pages/fav/note/widget/item.dart @@ -47,56 +47,14 @@ class FavNoteItem extends StatelessWidget { vertical: 5, ), child: Row( - mainAxisAlignment: MainAxisAlignment.start, + spacing: 10, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - item.title ?? '', - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - height: 1.4, - fontSize: 14, - fontWeight: FontWeight.bold, - ), - ), - const Spacer(), - Text( - item.summary ?? '', - maxLines: 1, - style: TextStyle( - fontSize: 14, - height: 1, - color: theme.colorScheme.outline, - overflow: TextOverflow.clip, - ), - ), - const Spacer(), - Text( - item.message ?? '', - maxLines: 1, - style: TextStyle( - fontSize: 13, - height: 1, - color: theme.colorScheme.outline, - overflow: TextOverflow.clip, - ), - ), - ], - ), - ), - if (item.pic?.isNotEmpty == true) ...[ - const SizedBox(width: 10), + if (item.pic?.isNotEmpty == true) AspectRatio( aspectRatio: StyleString.aspectRatio, child: LayoutBuilder( - builder: - (BuildContext context, BoxConstraints boxConstraints) { + builder: (context, boxConstraints) { return Stack( clipBehavior: Clip.none, children: [ @@ -161,7 +119,42 @@ class FavNoteItem extends StatelessWidget { }, ), ), - ], + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + item.title ?? '', + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + height: 1.4, + fontSize: 14, + ), + ), + const Spacer(), + Text( + item.summary ?? '', + maxLines: 1, + style: TextStyle( + fontSize: 14, + height: 1, + color: theme.colorScheme.outline, + ), + ), + const Spacer(), + Text( + item.message ?? '', + maxLines: 1, + style: TextStyle( + fontSize: 13, + height: 1, + color: theme.colorScheme.outline, + ), + ), + ], + ), + ), ], ), ), diff --git a/lib/pages/fav/topic/view.dart b/lib/pages/fav/topic/view.dart index f8c3dda2a..b2af06b55 100644 --- a/lib/pages/fav/topic/view.dart +++ b/lib/pages/fav/topic/view.dart @@ -51,7 +51,14 @@ class _FavTopicPageState extends State Widget _buildBody( ThemeData theme, LoadingState?> loadingState) { return switch (loadingState) { - Loading() => const SliverToBoxAdapter(child: LinearProgressIndicator()), + Loading() => const SliverToBoxAdapter( + child: SizedBox( + height: 125, + child: Center( + child: CircularProgressIndicator(), + ), + ), + ), Success(:var response) => response?.isNotEmpty == true ? SliverGrid( gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( diff --git a/lib/pages/fav/video/widgets/item.dart b/lib/pages/fav/video/widgets/item.dart index c7f839e3c..f4bea5322 100644 --- a/lib/pages/fav/video/widgets/item.dart +++ b/lib/pages/fav/video/widgets/item.dart @@ -91,7 +91,7 @@ class FavVideoItem extends StatelessWidget { ), const Spacer(), Text( - Utils.isPublicFavText(item.attr ?? 0), + Utils.isPublicFavText(item.attr), style: TextStyle( fontSize: fontSize, color: color, diff --git a/lib/pages/fav_detail/controller.dart b/lib/pages/fav_detail/controller.dart index 561db90a2..3c30cad6e 100644 --- a/lib/pages/fav_detail/controller.dart +++ b/lib/pages/fav_detail/controller.dart @@ -4,6 +4,7 @@ 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/common/multi_select_controller.dart'; +import 'package:PiliPlus/pages/fav_sort/view.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; @@ -16,10 +17,10 @@ class FavDetailController extends MultiSelectController { late int mediaId; late String heroTag; - Rx item = FavVideoItemModel().obs; - RxBool isOwner = false.obs; + final Rx item = FavVideoItemModel().obs; + final Rx isOwner = Rx(null); - late int mid; + final int mid = Accounts.main.mid; @override void onInit() { @@ -28,8 +29,6 @@ class FavDetailController mediaId = int.parse(Get.parameters['mediaId']!); heroTag = Get.parameters['heroTag']!; - mid = Accounts.main.mid; - queryData(); } @@ -159,7 +158,7 @@ class FavDetailController 'favTitle': item.value.title, 'count': item.value.mediaCount, 'desc': true, - 'isOwner': isOwner.value, + 'isOwner': isOwner.value ?? false, }, ); break; @@ -175,6 +174,10 @@ class FavDetailController } Future onFav(bool isFav) async { + if (mid == 0) { + SmartDialog.showToast('账号未登录'); + return; + } var res = isFav ? await FavHttp.unfavFavFolder(mediaId) : await FavHttp.favFavFolder(mediaId); @@ -186,4 +189,27 @@ class FavDetailController } SmartDialog.showToast(res['msg']); } + + Future cleanFav() async { + var res = await FavHttp.cleanFav(mediaId: mediaId); + if (res['status']) { + SmartDialog.showToast('清除成功'); + Future.delayed(const Duration(milliseconds: 200), () { + onReload(); + }); + } else { + SmartDialog.showToast(res['msg']); + } + } + + void onSort() { + if (loadingState.value.isSuccess && + loadingState.value.data?.isNotEmpty == true) { + if ((item.value.mediaCount ?? 0) > 1000) { + SmartDialog.showToast('内容太多啦!超过1000不支持排序'); + return; + } + Get.to(FavSortPage(favDetailController: this)); + } + } } diff --git a/lib/pages/fav_detail/view.dart b/lib/pages/fav_detail/view.dart index 05263d8a0..03da756cc 100644 --- a/lib/pages/fav_detail/view.dart +++ b/lib/pages/fav_detail/view.dart @@ -1,5 +1,6 @@ import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/skeleton/video_card_h.dart'; +import 'package:PiliPlus/common/widgets/button/icon_button.dart'; import 'package:PiliPlus/common/widgets/dialog/dialog.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; @@ -12,7 +13,6 @@ 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'; import 'package:PiliPlus/utils/grid.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/request_utils.dart'; @@ -130,128 +130,96 @@ class _FavDetailPageState extends State { 'mediaId': int.parse(mediaId), 'title': _favDetailController.item.value.title, 'count': _favDetailController.item.value.mediaCount, - 'isOwner': _favDetailController.isOwner.value, + 'isOwner': _favDetailController.isOwner.value ?? false, }, ), icon: const Icon(Icons.search_outlined), ), Obx( - () => Utils.isPublicFav(_favDetailController.item.value.attr ?? 0) - ? IconButton( - tooltip: '分享', + () => _favDetailController.item.value.attr == null || + !Utils.isPublicFav(_favDetailController.item.value.attr!) + ? const SizedBox.shrink() + : IconButton( + iconSize: 22, 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( - icon: const Icon(Icons.more_vert), - itemBuilder: (context) => [ - PopupMenuItem( - onTap: () => Get.toNamed( - '/createFav', - parameters: {'mediaId': mediaId}, - )?.then((res) { - if (res is FavVideoItemModel) { - _favDetailController.item.value = res; - } - }), - child: const Text('编辑信息'), + PopupMenuButton( + icon: const Icon(Icons.more_vert), + itemBuilder: (context) => [ + if (_favDetailController.isOwner.value == true) ...[ + PopupMenuItem( + onTap: _favDetailController.onSort, + child: const Text('排序'), + ), + PopupMenuItem( + onTap: () => Get.toNamed( + '/createFav', + parameters: {'mediaId': mediaId}, + )?.then((res) { + if (res is FavVideoItemModel) { + _favDetailController.item.value = res; + } + }), + child: const Text('编辑信息'), + ), + ] else + PopupMenuItem( + onTap: () => _favDetailController + .onFav(_favDetailController.item.value.favState == 1), + child: Text( + '${_favDetailController.item.value.favState == 1 ? '取消' : ''}收藏'), + ), + 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('分享至动态'), + ), + if (_favDetailController.isOwner.value == true) ...[ + PopupMenuItem( + onTap: _favDetailController.cleanFav, + child: const Text('清除失效内容'), + ), + if (!Utils.isDefaultFav( + _favDetailController.item.value.attr)) ...[ + const PopupMenuDivider(height: 12), + PopupMenuItem( + onTap: () => showConfirmDialog( + context: context, + title: '确定删除该收藏夹?', + onConfirm: () => + FavHttp.deleteFolder(mediaIds: [mediaId]).then((data) { + if (data['status']) { + SmartDialog.showToast('删除成功'); + Get.back(result: true); + } else { + SmartDialog.showToast(data['msg']); + } + }), + ), + child: Text( + '删除', + style: TextStyle( + color: theme.colorScheme.error, ), - 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) { - if (data['status']) { - SmartDialog.showToast('清除成功'); - Future.delayed(const Duration(milliseconds: 200), () { - _favDetailController.onReload(); - }); - } else { - SmartDialog.showToast(data['msg']); - } - }), - child: const Text('清除失效内容'), - ), - PopupMenuItem( - onTap: () { - if (_favDetailController.loadingState.value.isSuccess && - _favDetailController - .loadingState.value.data?.isNotEmpty == - true) { - if ((_favDetailController.item.value.mediaCount ?? - 0) > - 1000) { - SmartDialog.showToast('内容太多啦!超过1000不支持排序'); - return; - } - Get.to( - FavSortPage( - favDetailController: _favDetailController), - ); - } - }, - child: const Text('排序'), - ), - if (!Utils.isDefaultFav( - _favDetailController.item.value.attr ?? 0)) - PopupMenuItem( - onTap: () => showConfirmDialog( - context: context, - title: '确定删除该收藏夹?', - onConfirm: () => - FavHttp.deleteFolder(mediaIds: [mediaId]) - .then((data) { - if (data['status']) { - SmartDialog.showToast('删除成功'); - Get.back(result: true); - } else { - SmartDialog.showToast(data['msg']); - } - }), - ), - child: Text( - '删除', - style: TextStyle( - color: theme.colorScheme.error, - ), - ), - ), - ], - ) - : _favDetailController.mid != 0 - ? Builder( - builder: (context) { - bool isFav = - _favDetailController.item.value.favState == 1; - return IconButton( - onPressed: () => _favDetailController.onFav(isFav), - icon: isFav - ? const Icon(Icons.favorite) - : const Icon(Icons.favorite_border), - ); - }, - ) - : const SizedBox.shrink(), + ), + ), + ], + ], + ], ), const SizedBox(width: 10), ]; @@ -312,7 +280,7 @@ class _FavDetailPageState extends State { style: TextStyle(color: theme.colorScheme.error), ), ), - const SizedBox(width: 12), + const SizedBox(width: 10), ]; Widget _flexibleSpace(ThemeData theme) { @@ -336,13 +304,41 @@ class _FavDetailPageState extends State { spacing: 12, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Hero( - tag: _favDetailController.heroTag, - child: NetworkImgLayer( - width: 176, - height: 110, - src: item.cover, - ), + Stack( + clipBehavior: Clip.none, + children: [ + Hero( + tag: _favDetailController.heroTag, + child: NetworkImgLayer( + width: 176, + height: 110, + src: item.cover, + ), + ), + Positioned( + right: 6, + top: 6, + child: Obx(() { + if (_favDetailController.isOwner.value != false) { + return const SizedBox.shrink(); + } + bool isFav = + _favDetailController.item.value.favState == 1; + return iconButton( + context: context, + size: 28, + iconSize: 18, + tooltip: '${isFav ? '取消' : ''}收藏', + onPressed: () => _favDetailController.onFav(isFav), + icon: isFav ? Icons.favorite : Icons.favorite_border, + bgColor: + isFav ? null : theme.colorScheme.onInverseSurface, + iconColor: + isFav ? null : theme.colorScheme.onSurfaceVariant, + ); + }), + ) + ], ), if (item.title != null) Expanded( @@ -379,7 +375,7 @@ class _FavDetailPageState extends State { child: Align( alignment: Alignment.bottomLeft, child: Text( - '共${item.mediaCount}条视频 · ${Utils.isPublicFavText(item.attr ?? 0)}', + '共${item.mediaCount}条视频 · ${Utils.isPublicFavText(item.attr)}', textAlign: TextAlign.end, style: style, ), @@ -439,7 +435,7 @@ class _FavDetailPageState extends State { Positioned.fill( child: FavVideoCardH( item: item, - onDelFav: _favDetailController.isOwner.value + onDelFav: _favDetailController.isOwner.value == true ? () => _favDetailController.onCancelFav( index, item.id!, @@ -459,22 +455,24 @@ class _FavDetailPageState extends State { _favDetailController.item.value.mediaCount, 'desc': true, 'isContinuePlaying': index != 0, - 'isOwner': _favDetailController.isOwner.value, + 'isOwner': + _favDetailController.isOwner.value ?? false, }, ), onTap: _favDetailController.enableMultiSelect.value ? () => _favDetailController.onSelect(index) : null, - onLongPress: _favDetailController.isOwner.value - ? () { - if (!_favDetailController - .enableMultiSelect.value) { - _favDetailController - .enableMultiSelect.value = true; - _favDetailController.onSelect(index); - } - } - : null, + onLongPress: + _favDetailController.isOwner.value == true + ? () { + if (!_favDetailController + .enableMultiSelect.value) { + _favDetailController + .enableMultiSelect.value = true; + _favDetailController.onSelect(index); + } + } + : null, ), ), Positioned( diff --git a/lib/pages/fav_detail/widget/fav_video_card.dart b/lib/pages/fav_detail/widget/fav_video_card.dart index 43dae0d35..068a18760 100644 --- a/lib/pages/fav_detail/widget/fav_video_card.dart +++ b/lib/pages/fav_detail/widget/fav_video_card.dart @@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/image/image_save.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/stat/stat.dart'; import 'package:PiliPlus/models/common/badge_type.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/fav/fav_detail/media.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/utils.dart'; @@ -153,15 +154,13 @@ class FavVideoCardH extends StatelessWidget { Row( spacing: 8, children: [ - StatView( - context: context, - theme: 'gray', - value: Utils.numFormat(item.cntInfo?.play), + StatWidget( + type: StatType.play, + value: item.cntInfo?.play, ), - StatDanMu( - context: context, - theme: 'gray', - value: Utils.numFormat(item.cntInfo?.danmaku), + StatWidget( + type: StatType.danmaku, + value: item.cntInfo?.danmaku, ), ], ), diff --git a/lib/pages/fav_panel/view.dart b/lib/pages/fav_panel/view.dart index 39c71ded5..5df4bc894 100644 --- a/lib/pages/fav_panel/view.dart +++ b/lib/pages/fav_panel/view.dart @@ -1,5 +1,5 @@ import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; -import 'package:PiliPlus/models_new/fav/fav_video/list.dart'; +import 'package:PiliPlus/models_new/fav/fav_video/data.dart'; import 'package:PiliPlus/utils/feed_back.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:flutter/material.dart'; @@ -43,11 +43,10 @@ class _FavPanelState extends State { title: const Text('添加到收藏夹'), actions: [ TextButton.icon( - onPressed: () => - Get.toNamed('/createFav')?.then((data) { + onPressed: () => Get.toNamed('/createFav')?.then((data) { if (data != null) { - widget.ctr?.favFolderData - ..value.data?.list?.insert(1, data) + (widget.ctr?.favFolderData as Rx) + ..value.list?.insert(1, data) ..refresh(); } }), diff --git a/lib/pages/history/widgets/item.dart b/lib/pages/history/widgets/item.dart index a1f98d4a2..14aeb0ff6 100644 --- a/lib/pages/history/widgets/item.dart +++ b/lib/pages/history/widgets/item.dart @@ -142,8 +142,11 @@ class HistoryItem extends StatelessWidget { text: item.badge, top: 6.0, right: 6.0, - bottom: null, - left: null, + type: item.history.business == + HistoryBusinessType.live.type && + item.liveStatus != 1 + ? PBadgeType.gray + : PBadgeType.primary, ), if (item.duration != null && item.duration != 0 && diff --git a/lib/pages/later/widgets/video_card_h_later.dart b/lib/pages/later/widgets/video_card_h_later.dart index f59891899..f233a8c9a 100644 --- a/lib/pages/later/widgets/video_card_h_later.dart +++ b/lib/pages/later/widgets/video_card_h_later.dart @@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/progress_bar/video_progress_indicator.da 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/common/stat_type.dart'; import 'package:PiliPlus/models/search/result.dart'; import 'package:PiliPlus/models_new/later/list.dart'; import 'package:PiliPlus/utils/page_utils.dart'; @@ -174,10 +175,9 @@ class VideoCardHLater extends StatelessWidget { overflow: TextOverflow.ellipsis, ), const Spacer(), - StatView( - context: context, - theme: 'gray', - value: Utils.numFormat(videoItem.stat?.view), + StatWidget( + type: StatType.view, + value: videoItem.stat?.view, ), ] else ...[ Expanded( @@ -206,15 +206,13 @@ class VideoCardHLater extends StatelessWidget { Row( spacing: 8, children: [ - StatView( - context: context, - theme: 'gray', - value: Utils.numFormat(videoItem.stat?.view), + StatWidget( + type: StatType.view, + value: videoItem.stat?.view, ), - StatDanMu( - context: context, - theme: 'gray', - value: Utils.numFormat(videoItem.stat?.danmaku), + StatWidget( + type: StatType.danmaku, + value: videoItem.stat?.danmaku, ), ], ), diff --git a/lib/pages/later_search/view.dart b/lib/pages/later_search/view.dart index e26189f4f..3f48836cc 100644 --- a/lib/pages/later_search/view.dart +++ b/lib/pages/later_search/view.dart @@ -1,4 +1,5 @@ import 'package:PiliPlus/common/widgets/button/icon_button.dart'; +import 'package:PiliPlus/common/widgets/dialog/dialog.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'; @@ -64,10 +65,15 @@ class _LaterSearchPageState child: iconButton( tooltip: '移除', context: context, - onPressed: () => controller.toViewDel( - context, - index, - item.aid, + onPressed: () => showConfirmDialog( + context: context, + title: '提示', + content: '即将移除该视频,确定是否移除', + onConfirm: () => controller.toViewDel( + context, + index, + item.aid, + ), ), icon: Icons.clear, iconColor: Theme.of(context).colorScheme.onSurfaceVariant, diff --git a/lib/pages/media/widgets/item.dart b/lib/pages/media/widgets/item.dart index 3c0919385..595cd2413 100644 --- a/lib/pages/media/widgets/item.dart +++ b/lib/pages/media/widgets/item.dart @@ -76,7 +76,7 @@ class FavFolderItem extends StatelessWidget { maxLines: 1, ), Text( - ' 共${item.mediaCount}条视频 · ${Utils.isPublicFavText(item.attr ?? 0)}', + ' 共${item.mediaCount}条视频 · ${Utils.isPublicFavText(item.attr)}', style: theme.textTheme.labelSmall! .copyWith(color: theme.colorScheme.outline), ) diff --git a/lib/pages/member_article/widget/item.dart b/lib/pages/member_article/widget/item.dart index ed78a6f01..bf0440e29 100644 --- a/lib/pages/member_article/widget/item.dart +++ b/lib/pages/member_article/widget/item.dart @@ -2,6 +2,7 @@ import 'package:PiliPlus/common/constants.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/stat/stat.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/space/space_article/item.dart'; import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:flutter/material.dart'; @@ -81,18 +82,16 @@ class MemberArticleItem extends StatelessWidget { ), const SizedBox(height: 3), Row( + spacing: 16, children: [ - StatView( - context: context, - value: item.stats?.view ?? 0, - goto: 'picture', + StatWidget( + type: StatType.view, + value: item.stats?.view, textColor: outline, ), - const SizedBox(width: 16), - StatView( - context: context, - goto: 'reply', - value: item.stats?.reply ?? 0, + StatWidget( + type: StatType.play, + value: item.stats?.reply, textColor: outline, ), ], diff --git a/lib/pages/member_coin/widgets/item.dart b/lib/pages/member_coin/widgets/item.dart index af4c924d6..708c9c885 100644 --- a/lib/pages/member_coin/widgets/item.dart +++ b/lib/pages/member_coin/widgets/item.dart @@ -5,6 +5,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.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/common/stat_type.dart'; import 'package:PiliPlus/models/member/coin.dart'; import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:PiliPlus/utils/page_utils.dart'; @@ -91,16 +92,14 @@ class MemberCoinsItem extends StatelessWidget { const SizedBox(height: 4), Row( children: [ - StatView( - context: context, - value: coinItem.stat.viewStr, - theme: 'gray', + StatWidget( + type: StatType.view, + value: coinItem.stat.view, ), const SizedBox(width: 8), - StatDanMu( - context: context, - theme: 'gray', - value: coinItem.stat.danmuStr, + StatWidget( + type: StatType.danmaku, + value: coinItem.stat.danmu, ), const Spacer(), Text( diff --git a/lib/pages/member_favorite/widget/item.dart b/lib/pages/member_favorite/widget/item.dart index b10c6d224..f00b0df15 100644 --- a/lib/pages/member_favorite/widget/item.dart +++ b/lib/pages/member_favorite/widget/item.dart @@ -128,7 +128,7 @@ class MemberFavItem extends StatelessWidget { const Spacer(), Text( item.type == 0 - ? '${item.mediaCount}个内容 · ${Utils.isPublicFavText(item.attr ?? 0)}' + ? '${item.mediaCount}个内容 · ${Utils.isPublicFavText(item.attr)}' : item.type == 11 ? '${item.mediaCount}个内容 · ${item.upper?.name}' : item.type == 21 diff --git a/lib/pages/member_opus/widgets/space_opus_item.dart b/lib/pages/member_opus/widgets/space_opus_item.dart index 802f0cab4..a270a32eb 100644 --- a/lib/pages/member_opus/widgets/space_opus_item.dart +++ b/lib/pages/member_opus/widgets/space_opus_item.dart @@ -1,6 +1,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/stat/stat.dart'; import 'package:PiliPlus/models/common/image_type.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/space/space_opus/item.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:flutter/material.dart'; @@ -57,10 +58,9 @@ class SpaceOpusItem extends StatelessWidget { colors: [Colors.transparent, Colors.black54], ), ), - child: StatView( - context: context, - value: item.stat?.like ?? 0, - goto: 'like', + child: StatWidget( + type: StatType.like, + value: item.stat?.like, ), ), ), @@ -79,10 +79,9 @@ class SpaceOpusItem extends StatelessWidget { if (!hasPic) Padding( padding: const EdgeInsets.only(left: 8, bottom: 8, right: 8), - child: StatView( - context: context, - value: item.stat?.like ?? 0, - goto: 'like', + child: StatWidget( + type: StatType.like, + value: item.stat?.like, textColor: Theme.of(context).colorScheme.onSurfaceVariant, ), ), 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 b7a6bb626..8e7781f48 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 @@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/progress_bar/video_progress_indicator.da import 'package:PiliPlus/common/widgets/stat/stat.dart'; import 'package:PiliPlus/common/widgets/video_popup_menu.dart'; import 'package:PiliPlus/models/common/badge_type.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/space/space_archive/item.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/utils.dart'; @@ -223,15 +224,13 @@ class VideoCardHMemberVideo extends StatelessWidget { Row( spacing: 8, children: [ - StatView( - context: context, - theme: 'gray', - value: videoItem.stat.viewStr, + StatWidget( + type: StatType.view, + value: videoItem.stat.view, ), - StatDanMu( - context: context, - theme: 'gray', - value: videoItem.stat.danmuStr, + StatWidget( + type: StatType.danmaku, + value: videoItem.stat.danmu, ), ], ), diff --git a/lib/pages/rank/zone/widget/pgc_rank_item.dart b/lib/pages/rank/zone/widget/pgc_rank_item.dart index 52494b564..1ec7f4bfc 100644 --- a/lib/pages/rank/zone/widget/pgc_rank_item.dart +++ b/lib/pages/rank/zone/widget/pgc_rank_item.dart @@ -2,6 +2,7 @@ import 'package:PiliPlus/common/constants.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/stat/stat.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/pgc/pgc_rank/pgc_rank_item_model.dart'; import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:flutter/material.dart'; @@ -69,17 +70,14 @@ class PgcRankItem extends StatelessWidget { ], Row( children: [ - StatView( - context: context, - theme: 'gray', - value: item.stat!.view!, + StatWidget( + type: StatType.view, + value: item.stat!.view, ), const SizedBox(width: 8), - StatView( - context: context, - theme: 'gray', - goto: 'follow', - value: item.stat!.follow!, + StatWidget( + type: StatType.follow, + value: item.stat!.follow, ), ], ) diff --git a/lib/pages/subscription_detail/widget/sub_video_card.dart b/lib/pages/subscription_detail/widget/sub_video_card.dart index 81e1b0eeb..1a4e7d275 100644 --- a/lib/pages/subscription_detail/widget/sub_video_card.dart +++ b/lib/pages/subscription_detail/widget/sub_video_card.dart @@ -6,6 +6,7 @@ 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/common/search_type.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/sub/sub_detail/media.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/utils.dart'; @@ -111,15 +112,13 @@ class SubVideoCardH extends StatelessWidget { Row( spacing: 8, children: [ - StatView( - context: context, - theme: 'gray', - value: Utils.numFormat(videoItem.cntInfo?.play), + StatWidget( + type: StatType.play, + value: videoItem.cntInfo?.play, ), - StatDanMu( - context: context, - theme: 'gray', - value: Utils.numFormat(videoItem.cntInfo?.danmaku), + StatWidget( + type: StatType.danmaku, + value: videoItem.cntInfo?.danmaku, ), ], ), diff --git a/lib/pages/video/introduction/pgc/view.dart b/lib/pages/video/introduction/pgc/view.dart index afcf9e228..9d264b112 100644 --- a/lib/pages/video/introduction/pgc/view.dart +++ b/lib/pages/video/introduction/pgc/view.dart @@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/dialog/dialog.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/stat/stat.dart'; import 'package:PiliPlus/models/common/image_preview_type.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/pgc/pgc_info_model/result.dart'; import 'package:PiliPlus/pages/video/controller.dart'; import 'package:PiliPlus/pages/video/introduction/pgc/controller.dart'; @@ -202,15 +203,13 @@ class _PgcIntroPageState extends State Row( spacing: 6, children: [ - StatView( - context: context, - theme: 'gray', - value: Utils.numFormat(item.stat!.views), + StatWidget( + type: StatType.view, + value: item.stat!.views, ), - StatDanMu( - context: context, - theme: 'gray', - value: Utils.numFormat(item.stat!.danmakus), + StatWidget( + type: StatType.danmaku, + value: item.stat!.danmakus, ), if (isLandscape) ...[ areasAndPubTime(theme, item), diff --git a/lib/pages/video/introduction/pgc/widgets/intro_detail.dart b/lib/pages/video/introduction/pgc/widgets/intro_detail.dart index 4d36d4a5b..bd0d07b44 100644 --- a/lib/pages/video/introduction/pgc/widgets/intro_detail.dart +++ b/lib/pages/video/introduction/pgc/widgets/intro_detail.dart @@ -3,6 +3,7 @@ import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart'; import 'package:PiliPlus/common/widgets/page/tabs.dart'; import 'package:PiliPlus/common/widgets/scroll_physics.dart'; import 'package:PiliPlus/common/widgets/stat/stat.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/pgc/pgc_info_model/result.dart'; import 'package:PiliPlus/models_new/video/video_tag/data.dart'; import 'package:PiliPlus/pages/common/common_collapse_slide_page.dart'; @@ -108,15 +109,13 @@ class _IntroDetailState extends CommonCollapseSlidePageState { Row( spacing: 6, children: [ - StatView( - context: context, - theme: 'gray', - value: Utils.numFormat(widget.item.stat!.views), + StatWidget( + type: StatType.view, + value: widget.item.stat!.views, ), - StatDanMu( - context: context, - theme: 'gray', - value: Utils.numFormat(widget.item.stat!.danmakus), + StatWidget( + type: StatType.danmaku, + value: widget.item.stat!.danmakus, ), ], ), diff --git a/lib/pages/video/introduction/pgc/widgets/pgc_panel.dart b/lib/pages/video/introduction/pgc/widgets/pgc_panel.dart index a1a9028f1..5302968de 100644 --- a/lib/pages/video/introduction/pgc/widgets/pgc_panel.dart +++ b/lib/pages/video/introduction/pgc/widgets/pgc_panel.dart @@ -118,7 +118,7 @@ class _PgcPanelState extends State { ), child: Text( widget.newEp?.desc?.contains('连载') == true - ? '连载中,更新至${Utils.isStringNumeric(widget.newEp!.title) ? '第${widget.newEp!.title}话' : '${widget.newEp!.title}'}' + ? '连载中,更新至${Utils.isStringNumeric(widget.newEp!.title!) ? '第${widget.newEp!.title}话' : '${widget.newEp!.title}'}' : widget.newEp?.desc ?? '', style: const TextStyle(fontSize: 13), ), diff --git a/lib/pages/video/introduction/ugc/view.dart b/lib/pages/video/introduction/ugc/view.dart index c80840785..e65aaaf7e 100644 --- a/lib/pages/video/introduction/ugc/view.dart +++ b/lib/pages/video/introduction/ugc/view.dart @@ -6,6 +6,7 @@ import 'package:PiliPlus/common/widgets/pendant_avatar.dart'; import 'package:PiliPlus/common/widgets/self_sized_horizontal_list.dart'; import 'package:PiliPlus/common/widgets/stat/stat.dart'; import 'package:PiliPlus/models/common/image_type.dart'; +import 'package:PiliPlus/models/common/stat_type.dart'; import 'package:PiliPlus/models_new/video/video_detail/data.dart'; import 'package:PiliPlus/pages/mine/controller.dart'; import 'package:PiliPlus/pages/search/widgets/search_text.dart'; @@ -553,20 +554,18 @@ class _VideoInfoState extends State { Row( spacing: 10, children: [ - StatView( - context: context, - theme: 'gray', - value: Utils.numFormat(!widget.isLoading - ? videoDetail.stat?.view ?? '-' - : videoItem['stat']?.view ?? '-'), + StatWidget( + type: StatType.view, + value: !widget.isLoading + ? videoDetail.stat?.view + : videoItem['stat']?.view, textColor: theme.colorScheme.outline, ), - StatDanMu( - context: context, - theme: 'gray', - value: Utils.numFormat(!widget.isLoading - ? videoDetail.stat?.danmaku ?? '-' - : videoItem['stat']?.danmu ?? '-'), + StatWidget( + type: StatType.danmaku, + value: !widget.isLoading + ? videoDetail.stat?.danmaku + : videoItem['stat']?.danmu, textColor: theme.colorScheme.outline, ), Text( diff --git a/lib/pages/video/medialist/view.dart b/lib/pages/video/medialist/view.dart index 6ff0f6c12..d6b91662a 100644 --- a/lib/pages/video/medialist/view.dart +++ b/lib/pages/video/medialist/view.dart @@ -8,6 +8,7 @@ import 'package:PiliPlus/common/widgets/refresh_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/common/stat_type.dart'; import 'package:PiliPlus/models_new/media_list/media_list.dart'; import 'package:PiliPlus/pages/common/common_collapse_slide_page.dart'; import 'package:PiliPlus/utils/utils.dart'; @@ -264,17 +265,13 @@ class _MediaListPanelState Row( spacing: 8, children: [ - StatView( - context: context, - theme: 'gray', - value: Utils.numFormat( - item.cntInfo!.play!), + StatWidget( + type: StatType.play, + value: item.cntInfo!.play, ), - StatDanMu( - context: context, - theme: 'gray', - value: Utils.numFormat( - item.cntInfo!.danmaku!), + StatWidget( + type: StatType.danmaku, + value: item.cntInfo!.danmaku, ), ], ), diff --git a/lib/utils/grid.dart b/lib/utils/grid.dart index 968a7dd60..d0b392406 100644 --- a/lib/utils/grid.dart +++ b/lib/utils/grid.dart @@ -8,7 +8,8 @@ import 'package:flutter/rendering.dart'; class Grid { static double smallCardWidth = GStorage.smallCardWidth; - static SliverGridDelegateWithExtentAndRatio videoCardHDelegate(context, + static SliverGridDelegateWithExtentAndRatio videoCardHDelegate( + BuildContext context, {double minHeight = 90}) => SliverGridDelegateWithExtentAndRatio( mainAxisSpacing: 2, diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 151b9e68a..2b2512502 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -94,24 +94,22 @@ class Utils { return absolutePaths.join(':'); } - static void showCopyTextDialog(text) { - Get.dialog( - AlertDialog( - content: SelectableText('$text'), - ), - ); - } - - static bool isStringNumeric(str) { + static bool isStringNumeric(String str) { RegExp numericRegex = RegExp(r'^[\d\.]+$'); - return numericRegex.hasMatch(str.toString()); + return numericRegex.hasMatch(str); } - static bool isDefaultFav(int attr) { + static bool isDefaultFav(int? attr) { + if (attr == null) { + return false; + } return (attr & 2) == 0; } - static String isPublicFavText(int attr) { + static String isPublicFavText(int? attr) { + if (attr == null) { + return ''; + } return isPublicFav(attr) ? '公开' : '私密'; }