diff --git a/lib/http/api.dart b/lib/http/api.dart index b0f7762b6..e0868f00e 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -102,11 +102,9 @@ class Api { // csrf str CSRF Token(位于cookie) Cookie方式必要 // https://api.bilibili.com/medialist/gateway/coll/resource/deal // https://api.bilibili.com/x/v3/fav/resource/deal - static const String favVideo = '/x/v3/fav/resource/deal'; + static const String favVideo = '/x/v3/fav/resource/batch-deal'; - // static const String favBangumi = '/x/v3/fav/resource/batch-deal'; - - static const String delFav = '/x/v3/fav/resource/batch-del'; + static const String unfavAll = '/x/v3/fav/resource/unfav-all'; static const String copyFav = '/x/v3/fav/resource/copy'; diff --git a/lib/http/fav.dart b/lib/http/fav.dart index bbddb5e0d..31099b7c1 100644 --- a/lib/http/fav.dart +++ b/lib/http/fav.dart @@ -593,16 +593,17 @@ class FavHttp { } // (取消)收藏 - static Future delFav({ - List? ids, + static Future favVideo({ + required String resources, + String? addIds, String? delIds, }) async { var res = await Request().post( - Api.delFav, + Api.favVideo, data: { - 'resources': ids?.join(','), - 'media_id': delIds, - 'platform': 'web', + 'resources': resources, + 'add_media_ids': addIds ?? '', + 'del_media_ids': delIds ?? '', 'csrf': Accounts.main.csrf, }, options: Options(contentType: Headers.formUrlEncodedContentType), @@ -615,19 +616,15 @@ class FavHttp { } // (取消)收藏 - static Future favVideo({ - int? aid, - String? addIds, - String? delIds, - int? type, + static Future unfavAll({ + required rid, + required type, }) async { var res = await Request().post( - Api.favVideo, + Api.unfavAll, data: { - 'rid': aid, - 'type': type ?? 2, - 'add_media_ids': addIds ?? '', - 'del_media_ids': delIds ?? '', + 'rid': rid, + 'type': type, 'csrf': Accounts.main.csrf, }, options: Options(contentType: Headers.formUrlEncodedContentType), diff --git a/lib/pages/common/common_intro_controller.dart b/lib/pages/common/common_intro_controller.dart index 607cd437d..2a2ec92ca 100644 --- a/lib/pages/common/common_intro_controller.dart +++ b/lib/pages/common/common_intro_controller.dart @@ -1,8 +1,11 @@ import 'package:PiliPlus/http/user.dart'; import 'package:PiliPlus/models_new/fav/fav_folder/data.dart'; +import 'package:PiliPlus/models_new/fav/fav_folder/list.dart'; import 'package:PiliPlus/models_new/video/video_tag/data.dart'; import 'package:PiliPlus/services/account_service.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/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; @@ -32,6 +35,21 @@ abstract class CommonIntroController extends GetxController { Future actionFavVideo({String type = 'choose'}); late final enableQuickFav = Pref.enableQuickFav; + late int? quickFavId = Pref.quickFavId; + + FavFolderInfo get favFolderInfo { + final list = favFolderData.value.list!; + if (quickFavId != null) { + final folderInfo = list.firstWhereOrNull((e) => e.id == quickFavId); + if (folderInfo != null) { + return folderInfo; + } else { + quickFavId = null; + GStorage.setting.delete(SettingBoxKey.quickFavId); + } + } + return list.first; + } // 收藏 void showFavBottomSheet(BuildContext context, {type = 'tap'}) { diff --git a/lib/pages/fav_detail/controller.dart b/lib/pages/fav_detail/controller.dart index a43a04f87..e623b1c39 100644 --- a/lib/pages/fav_detail/controller.dart +++ b/lib/pages/fav_detail/controller.dart @@ -63,8 +63,8 @@ class FavDetailController } Future onCancelFav(int index, int id, int type) async { - var result = await FavHttp.delFav( - ids: ['$id:$type'], + var result = await FavHttp.favVideo( + resources: '$id:$type', delIds: mediaId.toString(), ); if (result['status']) { @@ -112,8 +112,10 @@ class FavDetailController List list = loadingState.value.data! .where((e) => e.checked == true) .toList(); - var result = await FavHttp.delFav( - ids: list.map((item) => '${item.id}:${item.type}').toList(), + var result = await FavHttp.favVideo( + resources: list + .map((item) => '${item.id}:${item.type}') + .join(','), delIds: mediaId.toString(), ); if (result['status']) { diff --git a/lib/pages/fav_search/controller.dart b/lib/pages/fav_search/controller.dart index fabb68cf8..f6c576b3b 100644 --- a/lib/pages/fav_search/controller.dart +++ b/lib/pages/fav_search/controller.dart @@ -38,10 +38,9 @@ class FavSearchController Future onCancelFav(int index, int id, int? type) async { var result = await FavHttp.favVideo( - aid: id, + resources: '$id:$type', addIds: '', delIds: mediaId.toString(), - type: type, ); if (result['status']) { loadingState diff --git a/lib/pages/setting/models/extra_settings.dart b/lib/pages/setting/models/extra_settings.dart index 1002614c6..472c33c56 100644 --- a/lib/pages/setting/models/extra_settings.dart +++ b/lib/pages/setting/models/extra_settings.dart @@ -3,8 +3,10 @@ import 'dart:math' show pi, max; import 'package:PiliPlus/common/widgets/image/image_view.dart'; import 'package:PiliPlus/common/widgets/pendant_avatar.dart'; +import 'package:PiliPlus/common/widgets/radio_widget.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/grpc/reply.dart'; +import 'package:PiliPlus/http/fav.dart'; import 'package:PiliPlus/models/common/audio_normalization.dart'; import 'package:PiliPlus/models/common/dynamic/dynamics_type.dart'; import 'package:PiliPlus/models/common/member/tab_type.dart'; @@ -12,6 +14,7 @@ import 'package:PiliPlus/models/common/reply/reply_sort_type.dart'; import 'package:PiliPlus/models/common/settings_type.dart'; import 'package:PiliPlus/models/common/super_resolution_type.dart'; import 'package:PiliPlus/models/dynamics/result.dart'; +import 'package:PiliPlus/models_new/fav/fav_folder/data.dart'; import 'package:PiliPlus/pages/common/common_slide_page.dart'; import 'package:PiliPlus/pages/home/controller.dart'; import 'package:PiliPlus/pages/hot/controller.dart'; @@ -20,7 +23,9 @@ import 'package:PiliPlus/pages/setting/models/model.dart'; import 'package:PiliPlus/pages/setting/widgets/select_dialog.dart'; import 'package:PiliPlus/pages/setting/widgets/slide_dialog.dart'; import 'package:PiliPlus/pages/video/reply/widgets/reply_item_grpc.dart'; +import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/cache_manage.dart'; +import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/feed_back.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_key.dart'; @@ -774,9 +779,51 @@ List get extraSettings => [ SettingsModel( settingsType: SettingsType.sw1tch, title: '快速收藏', - subtitle: '点按收藏至默认,长按选择文件夹', + subtitle: '点击设置默认收藏夹\n点按收藏至默认,长按选择文件夹', leading: const Icon(Icons.bookmark_add_outlined), setKey: SettingBoxKey.enableQuickFav, + onTap: () async { + if (Accounts.main.isLogin) { + final res = await FavHttp.allFavFolders(Accounts.main.mid); + if (res['status']) { + final FavFolderData data = res['data']; + final list = data.list; + if (list.isNullOrEmpty) { + return; + } + final quickFavId = Pref.quickFavId; + Get.dialog( + AlertDialog( + clipBehavior: Clip.hardEdge, + title: const Text('选择默认收藏夹'), + contentPadding: const EdgeInsets.only(top: 5, bottom: 18), + content: SingleChildScrollView( + child: Builder( + builder: (context) => Column( + children: List.generate(list!.length, (index) { + final item = list[index]; + return RadioWidget( + padding: const EdgeInsets.only(left: 14), + title: item.title, + groupValue: quickFavId, + value: item.id, + onChanged: (value) { + Get.back(); + GStorage.setting.put(SettingBoxKey.quickFavId, value); + SmartDialog.showToast('设置成功'); + }, + ); + }), + ), + ), + ), + ), + ); + } else { + SmartDialog.showToast('${res['msg']}'); + } + } + }, defaultVal: false, ), SettingsModel( diff --git a/lib/pages/video/controller.dart b/lib/pages/video/controller.dart index ce3b3fdfa..652e4137b 100644 --- a/lib/pages/video/controller.dart +++ b/lib/pages/video/controller.dart @@ -406,8 +406,8 @@ class VideoDetailController extends GetxController } SmartDialog.showToast(res['msg']); } else { - var res = await FavHttp.delFav( - ids: ['${item.aid}:${item.type}'], + var res = await FavHttp.favVideo( + resources: '${item.aid}:${item.type}', delIds: '${Get.arguments?['mediaId']}', ); if (res['status']) { diff --git a/lib/pages/video/introduction/pgc/controller.dart b/lib/pages/video/introduction/pgc/controller.dart index e7fc1d1f7..045b775f6 100644 --- a/lib/pages/video/introduction/pgc/controller.dart +++ b/lib/pages/video/introduction/pgc/controller.dart @@ -130,19 +130,18 @@ class PgcIntroController extends CommonIntroController { SmartDialog.showLoading(msg: '请求中'); queryVideoInFolder().then((res) async { if (res['status']) { - int defaultFolderId = favFolderData.value.list!.first.id; - int favStatus = favFolderData.value.list!.first.favState!; - var result = await FavHttp.favVideo( - aid: epId, - type: 24, - addIds: favStatus == 0 ? '$defaultFolderId' : '', - delIds: favStatus == 1 ? '$defaultFolderId' : '', - ); + final favFolderInfo = this.favFolderInfo; + final defaultFolderId = favFolderInfo.id; + final isFav = favFolderInfo.favState == 1; + var result = isFav + ? await FavHttp.unfavAll(rid: epId, type: 24) + : await FavHttp.favVideo( + resources: '$epId:24', + addIds: defaultFolderId.toString(), + ); SmartDialog.dismiss(); if (result['status']) { - // 重新获取收藏状态 - await Future.delayed(const Duration(milliseconds: 255)); - await queryPgcLikeCoinFav(); + hasFav.value = !isFav; SmartDialog.showToast('✅ 快速收藏/取消收藏成功'); } else { SmartDialog.showToast(result['msg']); @@ -171,17 +170,15 @@ class PgcIntroController extends CommonIntroController { } } catch (_) {} var result = await FavHttp.favVideo( - aid: epId, - type: 24, + resources: '$epId:24', addIds: addMediaIdsNew.join(','), delIds: delMediaIdsNew.join(','), ); if (result['status']) { SmartDialog.showToast('操作成功'); Get.back(); - Future.delayed(const Duration(milliseconds: 255), () { - queryPgcLikeCoinFav(); - }); + hasFav.value = + addMediaIdsNew.isNotEmpty || favIds?.length != delMediaIdsNew.length; } else { SmartDialog.showToast(result['msg']); } diff --git a/lib/pages/video/introduction/ugc/controller.dart b/lib/pages/video/introduction/ugc/controller.dart index f352a102b..9f351e43a 100644 --- a/lib/pages/video/introduction/ugc/controller.dart +++ b/lib/pages/video/introduction/ugc/controller.dart @@ -348,19 +348,18 @@ class VideoIntroController extends CommonIntroController with ReloadMixin { SmartDialog.showLoading(msg: '请求中'); queryVideoInFolder().then((res) async { if (res['status']) { - final first = favFolderData.value.list!.first; - int defaultFolderId = first.id; - bool notInDefFolder = first.favState! == 0; - var result = await FavHttp.favVideo( - aid: IdUtils.bv2av(bvid), - addIds: notInDefFolder ? '$defaultFolderId' : '', - delIds: !notInDefFolder ? '$defaultFolderId' : '', - ); + final favFolderInfo = this.favFolderInfo; + final defaultFolderId = favFolderInfo.id; + final isFav = favFolderInfo.favState == 1; + var result = isFav + ? await FavHttp.unfavAll(rid: IdUtils.bv2av(bvid), type: 2) + : await FavHttp.favVideo( + resources: '${IdUtils.bv2av(bvid)}:2', + addIds: defaultFolderId.toString(), + ); SmartDialog.dismiss(); if (result['status']) { - hasFav.value = !hasFav.value || (hasFav.value && notInDefFolder); - // 重新获取收藏状态 - // await queryHasFavVideo(); + hasFav.value = !isFav; SmartDialog.showToast('✅ 快速收藏/取消收藏成功'); } else { SmartDialog.showToast(result['msg']); @@ -392,7 +391,7 @@ class VideoIntroController extends CommonIntroController with ReloadMixin { } SmartDialog.showLoading(msg: '请求中'); var result = await FavHttp.favVideo( - aid: IdUtils.bv2av(bvid), + resources: '${IdUtils.bv2av(bvid)}:2', addIds: addMediaIdsNew.join(','), delIds: delMediaIdsNew.join(','), ); diff --git a/lib/utils/storage_key.dart b/lib/utils/storage_key.dart index ef7470e00..4efff6283 100644 --- a/lib/utils/storage_key.dart +++ b/lib/utils/storage_key.dart @@ -131,7 +131,8 @@ class SettingBoxKey { enableLog = 'enableLog', memberTab = 'memberTab', dynamicDetailRatio = 'dynamicDetailRatio', - directExitOnBack = 'directExitOnBack'; + directExitOnBack = 'directExitOnBack', + quickFavId = 'quickFavId'; static const String subtitlePreference = 'subtitlePreference', enableDragSubtitle = 'enableDragSubtitle', diff --git a/lib/utils/storage_pref.dart b/lib/utils/storage_pref.dart index 66c56605a..3d65a6eef 100644 --- a/lib/utils/storage_pref.dart +++ b/lib/utils/storage_pref.dart @@ -774,4 +774,6 @@ class Pref { static bool get historyPause => _localCache.get(LocalCacheKey.historyPause, defaultValue: false); + + static int? get quickFavId => _setting.get(SettingBoxKey.quickFavId); }