Files
PiliPlus/lib/pages/fav_detail/controller.dart
bggRGjQaUbCoE 041af37bb0 tweaks
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
2026-01-02 12:06:09 +08:00

236 lines
6.4 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
import 'package:PiliPlus/http/fav.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/common/fav_order_type.dart';
import 'package:PiliPlus/models/common/video/source_type.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_folder/list.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart';
import 'package:PiliPlus/pages/common/multi_select/base.dart';
import 'package:PiliPlus/pages/common/multi_select/multi_select_controller.dart';
import 'package:PiliPlus/pages/fav_sort/view.dart';
import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/storage_key.dart';
import 'package:PiliPlus/utils/storage_pref.dart';
import 'package:flutter/services.dart' show ValueChanged;
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
mixin BaseFavController
on
CommonListController<FavDetailData, FavDetailItemModel>,
DeleteItemMixin<FavDetailData, FavDetailItemModel> {
bool get isOwner;
int get mediaId;
ValueChanged<int>? updateCount;
void onViewFav(FavDetailItemModel item, int? index);
Future<void> onCancelFav(int index, int id, int type) async {
final res = await FavHttp.favVideo(
resources: '$id:$type',
delIds: mediaId.toString(),
);
if (res.isSuccess) {
loadingState
..value.data!.removeAt(index)
..refresh();
updateCount?.call(1);
SmartDialog.showToast('取消收藏');
} else {
res.toast();
}
}
@override
void onRemove() {
showConfirmDialog(
context: Get.context!,
content: '确认删除所选收藏吗?',
title: '提示',
onConfirm: () async {
final removeList = allChecked.toSet();
final res = await FavHttp.favVideo(
resources: removeList
.map((item) => '${item.id}:${item.type}')
.join(','),
delIds: mediaId.toString(),
);
if (res.isSuccess) {
updateCount?.call(removeList.length);
afterDelete(removeList);
SmartDialog.showToast('取消收藏');
} else {
res.toast();
}
},
);
}
}
class FavDetailController
extends MultiSelectController<FavDetailData, FavDetailItemModel>
with BaseFavController {
@override
late int mediaId;
late String heroTag;
final Rx<FavFolderInfo> folderInfo = FavFolderInfo().obs;
final Rx<bool?> _isOwner = Rx<bool?>(null);
final Rx<FavOrderType> order = FavOrderType.mtime.obs;
@override
bool get isOwner => _isOwner.value ?? false;
late final account = Accounts.main;
late double dx = 0;
late final RxBool isPlayAll = Pref.enablePlayAll.obs;
void setIsPlayAll(bool isPlayAll) {
if (this.isPlayAll.value == isPlayAll) return;
this.isPlayAll.value = isPlayAll;
GStorage.setting.put(SettingBoxKey.enablePlayAll, isPlayAll);
}
@override
void onInit() {
super.onInit();
mediaId = int.parse(Get.parameters['mediaId']!);
heroTag = Get.parameters['heroTag']!;
queryData();
}
@override
bool? get hasFooter => true;
@override
List<FavDetailItemModel>? getDataList(FavDetailData response) {
if (response.hasMore == false) {
isEnd = true;
}
return response.medias;
}
@override
void checkIsEnd(int length) {
if (length >= folderInfo.value.mediaCount) {
isEnd = true;
}
}
@override
bool customHandleResponse(bool isRefresh, Success<FavDetailData> response) {
if (isRefresh) {
FavDetailData data = response.response;
folderInfo.value = data.info!;
_isOwner.value = data.info?.mid == account.mid;
}
return false;
}
@override
ValueChanged<int>? get updateCount =>
(count) => folderInfo
..value.mediaCount -= count
..refresh();
@override
Future<LoadingState<FavDetailData>> customGetData() =>
FavHttp.userFavFolderDetail(
pn: page,
ps: 20,
mediaId: mediaId,
order: order.value,
);
void toViewPlayAll() {
if (loadingState.value case Success(:final response)) {
if (response == null || response.isEmpty) return;
for (FavDetailItemModel element in response) {
if (element.ugc?.firstCid == null) {
continue;
} else {
onViewFav(element, null);
break;
}
}
}
}
@override
Future<void> onReload() {
scrollController.jumpToTop();
return super.onReload();
}
Future<void> onFav(bool isFav) async {
if (!account.isLogin) {
SmartDialog.showToast('账号未登录');
return;
}
final res = isFav
? await FavHttp.unfavFavFolder(mediaId)
: await FavHttp.favFavFolder(mediaId);
if (res.isSuccess) {
folderInfo
..value.favState = isFav ? 0 : 1
..refresh();
}
res.toast();
}
Future<void> cleanFav() async {
final res = await FavHttp.cleanFav(mediaId: mediaId);
if (res.isSuccess) {
SmartDialog.showToast('清除成功');
Future.delayed(const Duration(milliseconds: 200), onReload);
} else {
res.toast();
}
}
void onSort() {
if (loadingState.value case Success(:final response)) {
if (response != null && response.isNotEmpty) {
if (folderInfo.value.mediaCount > 1000) {
SmartDialog.showToast('内容太多啦超过1000不支持排序');
return;
}
Get.to(FavSortPage(favDetailController: this));
}
}
}
@override
void onViewFav(FavDetailItemModel item, int? index) {
final folder = folderInfo.value;
PageUtils.toVideoPage(
bvid: item.bvid,
cid: item.ugc!.firstCid!,
cover: item.cover,
title: item.title,
extraArguments: isPlayAll.value
? {
'sourceType': SourceType.fav,
'mediaId': folder.id,
'oid': item.id,
'favTitle': folder.title,
'count': folder.mediaCount,
'desc': true,
if (index != null) 'isContinuePlaying': index != 0,
'isOwner': isOwner,
}
: null,
);
}
}