diff --git a/lib/pages/fav_detail/widget/fav_video_card.dart b/lib/pages/fav_detail/widget/fav_video_card.dart index edded621..e4b3eda8 100644 --- a/lib/pages/fav_detail/widget/fav_video_card.dart +++ b/lib/pages/fav_detail/widget/fav_video_card.dart @@ -34,6 +34,7 @@ class FavVideoCardH extends StatelessWidget { Widget build(BuildContext context) { final isOwner = !isSort && ctr!.isOwner; late final enableMultiSelect = ctr?.enableMultiSelect.value ?? false; + final theme = Theme.of(context); return Material( type: MaterialType.transparency, child: InkWell( @@ -62,8 +63,9 @@ class FavVideoCardH extends StatelessWidget { ? null : isOwner && !enableMultiSelect ? () { - ctr!.enableMultiSelect.value = true; - ctr!.onSelect(item); + ctr! + ..enableMultiSelect.value = true + ..onSelect(item); } : () => imageSaveDialog( title: item.title, @@ -108,7 +110,7 @@ class FavVideoCardH extends StatelessWidget { if (!isSort) Positioned.fill( child: selectMask( - Theme.of(context), + theme, item.checked == true, ), ), @@ -118,7 +120,7 @@ class FavVideoCardH extends StatelessWidget { ), ), const SizedBox(width: 10), - content(context, isOwner), + content(context, theme, isOwner), ], ), ), @@ -126,8 +128,7 @@ class FavVideoCardH extends StatelessWidget { ); } - Widget content(BuildContext context, bool isOwner) { - final theme = Theme.of(context); + Widget content(BuildContext context, ThemeData theme, isOwner) { return Expanded( child: Stack( clipBehavior: Clip.none, diff --git a/lib/pages/later/child_view.dart b/lib/pages/later/child_view.dart index 3f96f8f1..c433ea00 100644 --- a/lib/pages/later/child_view.dart +++ b/lib/pages/later/child_view.dart @@ -75,10 +75,9 @@ class _LaterViewChildPageState extends State _laterController.onLoadMore(); } var videoItem = response[index]; - final enableMultiSelect = - _laterController.baseCtr.enableMultiSelect.value; return VideoCardHLater( videoItem: videoItem, + ctr: _laterController, onViewLater: (cid) { PageUtils.toVideoPage( bvid: videoItem.bvid, @@ -98,20 +97,15 @@ class _LaterViewChildPageState extends State }, ); }, - onTap: !enableMultiSelect - ? null - : () => _laterController.onSelect(videoItem), - onLongPress: enableMultiSelect - ? null - : () { - _laterController.baseCtr.enableMultiSelect.value = - true; - _laterController.onSelect(videoItem); - }, onRemove: () => _laterController.toViewDel( context, index, videoItem.aid, + onSuccess: () { + final counts = _laterController.baseCtr.counts; + counts[widget.laterViewType] = + counts[widget.laterViewType]! - 1; + }, ), ); }, diff --git a/lib/pages/later/controller.dart b/lib/pages/later/controller.dart index 2746f9de..19fdf126 100644 --- a/lib/pages/later/controller.dart +++ b/lib/pages/later/controller.dart @@ -5,6 +5,9 @@ import 'package:PiliPlus/models/common/later_view_type.dart'; import 'package:PiliPlus/models/common/video/source_type.dart'; import 'package:PiliPlus/models_new/later/data.dart'; import 'package:PiliPlus/models_new/later/list.dart'; +import 'package:PiliPlus/pages/common/common_list_controller.dart' + show CommonListController; +import 'package:PiliPlus/pages/common/multi_select/base.dart'; import 'package:PiliPlus/pages/common/multi_select/multi_select_controller.dart'; import 'package:PiliPlus/pages/later/base_controller.dart'; import 'package:PiliPlus/services/account_service.dart'; @@ -14,7 +17,54 @@ import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; -class LaterController extends MultiSelectController { +mixin BaseLaterController + on + CommonListController, + CommonMultiSelectMixin { + // single + void toViewDel( + BuildContext context, + int index, + int? aid, { + VoidCallback? onSuccess, + }) { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: const Text('提示'), + content: const Text('即将移除该视频,确定是否移除'), + actions: [ + TextButton( + onPressed: Get.back, + child: Text( + '取消', + style: TextStyle(color: Theme.of(context).colorScheme.outline), + ), + ), + TextButton( + onPressed: () async { + Get.back(); + final res = await UserHttp.toViewDel(aids: aid.toString()); + if (res['status']) { + loadingState + ..value.data!.removeAt(index) + ..refresh(); + onSuccess?.call(); + } + SmartDialog.showToast(res['msg']); + }, + child: const Text('确认移除'), + ), + ], + ); + }, + ); + } +} + +class LaterController extends MultiSelectController + with BaseLaterController { LaterController(this.laterViewType); final LaterViewType laterViewType; @@ -56,43 +106,6 @@ class LaterController extends MultiSelectController { } } - // single - void toViewDel(BuildContext context, int index, int? aid) { - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: const Text('提示'), - content: const Text('即将移除该视频,确定是否移除'), - actions: [ - TextButton( - onPressed: Get.back, - child: Text( - '取消', - style: TextStyle(color: Theme.of(context).colorScheme.outline), - ), - ), - TextButton( - onPressed: () async { - Get.back(); - final res = await UserHttp.toViewDel(aids: aid.toString()); - if (res['status']) { - baseCtr.counts[laterViewType] = - baseCtr.counts[laterViewType]! - 1; - loadingState - ..value.data!.removeAt(index) - ..refresh(); - } - SmartDialog.showToast(res['msg']); - }, - child: const Text('确认移除'), - ), - ], - ); - }, - ); - } - // 一键清空 void toViewClear(BuildContext context, [int? cleanType]) { String content = switch (cleanType) { diff --git a/lib/pages/later/widgets/video_card_h_later.dart b/lib/pages/later/widgets/video_card_h_later.dart index 50dd9edc..8cc54326 100644 --- a/lib/pages/later/widgets/video_card_h_later.dart +++ b/lib/pages/later/widgets/video_card_h_later.dart @@ -1,7 +1,6 @@ import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/widgets/badge.dart'; import 'package:PiliPlus/common/widgets/button/icon_button.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/select_mask.dart'; @@ -11,6 +10,7 @@ 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/pages/later/controller.dart'; import 'package:PiliPlus/utils/duration_util.dart'; import 'package:PiliPlus/utils/page_utils.dart'; import 'package:flutter/material.dart'; @@ -20,17 +20,15 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; class VideoCardHLater extends StatelessWidget { const VideoCardHLater({ super.key, + required this.ctr, required this.videoItem, - this.onTap, - this.onLongPress, this.onViewLater, - this.onRemove, + required this.onRemove, }); + final BaseLaterController ctr; final LaterItemModel videoItem; - final VoidCallback? onTap; - final VoidCallback? onLongPress; final ValueChanged? onViewLater; - final VoidCallback? onRemove; + final VoidCallback onRemove; @override Widget build(BuildContext context) { @@ -41,45 +39,45 @@ class VideoCardHLater extends StatelessWidget { type = typeOrNull!; } } + final theme = Theme.of(context); + final enableMultiSelect = ctr.enableMultiSelect.value; return Material( type: MaterialType.transparency, child: InkWell( - onLongPress: - onLongPress ?? - () => imageSaveDialog( - title: videoItem.title, - cover: videoItem.pic, - bvid: videoItem.bvid, - ), - onTap: - onTap ?? - () async { - if (type == 'ketang') { - PageUtils.viewPugv(seasonId: videoItem.aid); - 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!); + onLongPress: enableMultiSelect + ? null + : () => ctr + ..enableMultiSelect.value = true + ..onSelect(videoItem), + onTap: enableMultiSelect + ? () => ctr.onSelect(videoItem) + : () async { + if (type == 'ketang') { + PageUtils.viewPugv(seasonId: videoItem.aid); + return; } - return; - } - try { - final int? cid = - videoItem.cid ?? - await SearchHttp.ab2c( - aid: videoItem.aid, - bvid: videoItem.bvid, - ); - if (cid != null) { - onViewLater!(cid); + 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; } - } catch (err) { - SmartDialog.showToast(err.toString()); - } - }, + 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, @@ -158,7 +156,7 @@ class VideoCardHLater extends StatelessWidget { ), Positioned.fill( child: selectMask( - Theme.of(context), + theme, videoItem.checked == true, ), ), @@ -168,7 +166,7 @@ class VideoCardHLater extends StatelessWidget { ), ), const SizedBox(width: 10), - content(context), + content(context, theme), ], ), ), @@ -176,13 +174,36 @@ class VideoCardHLater extends StatelessWidget { ); } - Widget content(BuildContext context) { - final theme = Theme.of(context); + Widget content(BuildContext context, ThemeData theme) { + final isPgc = videoItem.isPgc == true && videoItem.bangumi != null; + Widget bottom = Row( + spacing: 8, + children: [ + StatWidget( + type: StatType.play, + value: videoItem.stat?.view, + ), + if (!isPgc) + StatWidget( + type: StatType.danmaku, + value: videoItem.stat?.danmaku, + ), + const Spacer(), + iconButton( + tooltip: '移除', + context: context, + onPressed: onRemove, + icon: Icons.clear, + iconColor: theme.colorScheme.outline, + bgColor: Colors.transparent, + ), + ], + ); return Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (videoItem.isPgc == true && videoItem.bangumi != null) ...[ + if (isPgc) ...[ Text( videoItem.bangumi!.season!.title!, style: TextStyle( @@ -205,10 +226,7 @@ class VideoCardHLater extends StatelessWidget { overflow: TextOverflow.ellipsis, ), const Spacer(), - StatWidget( - type: StatType.play, - value: videoItem.stat?.view, - ), + bottom, ] else ...[ Expanded( child: Text( @@ -233,30 +251,7 @@ class VideoCardHLater extends StatelessWidget { ), ), const SizedBox(height: 3), - Row( - spacing: 8, - children: [ - StatWidget( - type: StatType.play, - value: videoItem.stat?.view, - ), - StatWidget( - type: StatType.danmaku, - value: videoItem.stat?.danmaku, - ), - if (onRemove != null) ...[ - const Spacer(), - iconButton( - tooltip: '移除', - context: context, - onPressed: onRemove, - icon: Icons.clear, - iconColor: theme.colorScheme.outline, - bgColor: Colors.transparent, - ), - ], - ], - ), + bottom, ], ], ), diff --git a/lib/pages/later_search/controller.dart b/lib/pages/later_search/controller.dart index 05da9105..57f1304f 100644 --- a/lib/pages/later_search/controller.dart +++ b/lib/pages/later_search/controller.dart @@ -5,13 +5,16 @@ import 'package:PiliPlus/models_new/later/data.dart'; import 'package:PiliPlus/models_new/later/list.dart'; import 'package:PiliPlus/pages/common/multi_select/base.dart'; import 'package:PiliPlus/pages/common/search/common_search_controller.dart'; -import 'package:flutter/material.dart'; +import 'package:PiliPlus/pages/later/controller.dart' show BaseLaterController; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; class LaterSearchController extends CommonSearchController - with CommonMultiSelectMixin, DeleteItemMixin { + with + CommonMultiSelectMixin, + DeleteItemMixin, + BaseLaterController { dynamic mid = Get.arguments['mid']; dynamic count = Get.arguments['count']; @@ -26,15 +29,6 @@ class LaterSearchController return response.list; } - Future toViewDel(BuildContext context, int index, int aid) async { - var res = await UserHttp.toViewDel(aids: aid.toString()); - if (res['status']) { - loadingState.value.data!.removeAt(index); - loadingState.refresh(); - } - SmartDialog.showToast(res['msg']); - } - @override void onRemove() { showConfirmDialog( diff --git a/lib/pages/later_search/view.dart b/lib/pages/later_search/view.dart index 324f10b2..e41d0cf2 100644 --- a/lib/pages/later_search/view.dart +++ b/lib/pages/later_search/view.dart @@ -37,9 +37,9 @@ class _LaterSearchPageState controller.onLoadMore(); } final item = list[index]; - final enableMultiSelect = controller.enableMultiSelect.value; return VideoCardHLater( videoItem: item, + ctr: controller, onViewLater: (cid) { PageUtils.toVideoPage( bvid: item.bvid, @@ -62,13 +62,6 @@ class _LaterSearchPageState index, item.aid!, ), - onTap: !enableMultiSelect ? null : () => controller.onSelect(item), - onLongPress: enableMultiSelect - ? null - : () { - controller.enableMultiSelect.value = true; - controller.onSelect(item); - }, ); }), );