mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-01 00:28:18 +08:00
feat: add copy/move support to fav/later search results (#1822)
* feat: add copy/move support to fav/later search results * update Signed-off-by: dom <githubaccount56556@proton.me> --------- Co-authored-by: dom <githubaccount56556@proton.me>
This commit is contained in:
@@ -6,7 +6,6 @@ import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
|||||||
import 'package:PiliPlus/http/fav.dart';
|
import 'package:PiliPlus/http/fav.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models/common/fav_order_type.dart';
|
import 'package:PiliPlus/models/common/fav_order_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_detail/media.dart';
|
||||||
import 'package:PiliPlus/models_new/fav/fav_folder/list.dart';
|
import 'package:PiliPlus/models_new/fav/fav_folder/list.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics_repost/view.dart';
|
import 'package:PiliPlus/pages/dynamics_repost/view.dart';
|
||||||
@@ -305,56 +304,39 @@ class _FavDetailPageState extends State<FavDetailPage> with GridMixin {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _selectActions(ThemeData theme) => [
|
List<Widget> _selectActions(ThemeData theme) {
|
||||||
|
final btnStyle = TextButton.styleFrom(visualDensity: .compact);
|
||||||
|
final textStyle = TextStyle(color: theme.colorScheme.onSurfaceVariant);
|
||||||
|
return [
|
||||||
TextButton(
|
TextButton(
|
||||||
style: TextButton.styleFrom(
|
style: btnStyle,
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
),
|
|
||||||
onPressed: () => _favDetailController.handleSelect(checked: true),
|
onPressed: () => _favDetailController.handleSelect(checked: true),
|
||||||
child: const Text('全选'),
|
child: const Text('全选'),
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
style: TextButton.styleFrom(
|
style: btnStyle,
|
||||||
visualDensity: VisualDensity.compact,
|
onPressed: () => RequestUtils.onCopyOrMove<FavDetailItemModel>(
|
||||||
),
|
|
||||||
onPressed: () =>
|
|
||||||
RequestUtils.onCopyOrMove<FavDetailData, FavDetailItemModel>(
|
|
||||||
context: context,
|
context: context,
|
||||||
isCopy: true,
|
isCopy: true,
|
||||||
ctr: _favDetailController,
|
ctr: _favDetailController,
|
||||||
mediaId: _favDetailController.mediaId,
|
mediaId: _favDetailController.mediaId,
|
||||||
mid: _favDetailController.account.mid,
|
mid: _favDetailController.account.mid,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text('复制', style: textStyle),
|
||||||
'复制',
|
|
||||||
style: TextStyle(
|
|
||||||
color: theme.colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
style: TextButton.styleFrom(
|
style: btnStyle,
|
||||||
visualDensity: VisualDensity.compact,
|
onPressed: () => RequestUtils.onCopyOrMove<FavDetailItemModel>(
|
||||||
),
|
|
||||||
onPressed: () =>
|
|
||||||
RequestUtils.onCopyOrMove<FavDetailData, FavDetailItemModel>(
|
|
||||||
context: context,
|
context: context,
|
||||||
isCopy: false,
|
isCopy: false,
|
||||||
ctr: _favDetailController,
|
ctr: _favDetailController,
|
||||||
mediaId: _favDetailController.mediaId,
|
mediaId: _favDetailController.mediaId,
|
||||||
mid: _favDetailController.account.mid,
|
mid: _favDetailController.account.mid,
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text('移动', style: textStyle),
|
||||||
'移动',
|
|
||||||
style: TextStyle(
|
|
||||||
color: theme.colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
style: TextButton.styleFrom(
|
style: btnStyle,
|
||||||
visualDensity: VisualDensity.compact,
|
|
||||||
),
|
|
||||||
onPressed: _favDetailController.onRemove,
|
onPressed: _favDetailController.onRemove,
|
||||||
child: Text(
|
child: Text(
|
||||||
'删除',
|
'删除',
|
||||||
@@ -363,6 +345,7 @@ class _FavDetailPageState extends State<FavDetailPage> with GridMixin {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
Widget _flexibleSpace(ThemeData theme) {
|
Widget _flexibleSpace(ThemeData theme) {
|
||||||
final style = TextStyle(
|
final style = TextStyle(
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import 'package:PiliPlus/models_new/fav/fav_detail/media.dart';
|
|||||||
import 'package:PiliPlus/pages/common/search/common_search_page.dart';
|
import 'package:PiliPlus/pages/common/search/common_search_page.dart';
|
||||||
import 'package:PiliPlus/pages/fav_detail/widget/fav_video_card.dart';
|
import 'package:PiliPlus/pages/fav_detail/widget/fav_video_card.dart';
|
||||||
import 'package:PiliPlus/pages/fav_search/controller.dart';
|
import 'package:PiliPlus/pages/fav_search/controller.dart';
|
||||||
|
import 'package:PiliPlus/utils/accounts.dart';
|
||||||
import 'package:PiliPlus/utils/grid.dart';
|
import 'package:PiliPlus/utils/grid.dart';
|
||||||
|
import 'package:PiliPlus/utils/request_utils.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -29,6 +31,38 @@ class _FavSearchPageState
|
|||||||
tag: Utils.generateRandomString(8),
|
tag: Utils.generateRandomString(8),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Widget>? get multiSelectActions {
|
||||||
|
final btnStyle = TextButton.styleFrom(visualDensity: .compact);
|
||||||
|
final textStyle = TextStyle(
|
||||||
|
color: ColorScheme.of(context).onSurfaceVariant,
|
||||||
|
);
|
||||||
|
return [
|
||||||
|
TextButton(
|
||||||
|
style: btnStyle,
|
||||||
|
onPressed: () => RequestUtils.onCopyOrMove<FavDetailItemModel>(
|
||||||
|
context: context,
|
||||||
|
isCopy: true,
|
||||||
|
ctr: controller,
|
||||||
|
mediaId: controller.mediaId,
|
||||||
|
mid: Accounts.main.mid,
|
||||||
|
),
|
||||||
|
child: Text('复制', style: textStyle),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
style: btnStyle,
|
||||||
|
onPressed: () => RequestUtils.onCopyOrMove<FavDetailItemModel>(
|
||||||
|
context: context,
|
||||||
|
isCopy: false,
|
||||||
|
ctr: controller,
|
||||||
|
mediaId: controller.mediaId,
|
||||||
|
mid: Accounts.main.mid,
|
||||||
|
),
|
||||||
|
child: Text('移动', style: textStyle),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Widget>? get extraActions => [
|
List<Widget>? get extraActions => [
|
||||||
Obx(
|
Obx(
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import 'package:PiliPlus/common/widgets/gesture/horizontal_drag_gesture_recogniz
|
|||||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||||
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
|
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
|
||||||
import 'package:PiliPlus/models/common/later_view_type.dart';
|
import 'package:PiliPlus/models/common/later_view_type.dart';
|
||||||
import 'package:PiliPlus/models_new/later/data.dart';
|
|
||||||
import 'package:PiliPlus/models_new/later/list.dart';
|
import 'package:PiliPlus/models_new/later/list.dart';
|
||||||
import 'package:PiliPlus/pages/fav_detail/view.dart';
|
import 'package:PiliPlus/pages/fav_detail/view.dart';
|
||||||
import 'package:PiliPlus/pages/later/base_controller.dart';
|
import 'package:PiliPlus/pages/later/base_controller.dart';
|
||||||
@@ -154,16 +153,17 @@ class _LaterPageState extends State<LaterPage>
|
|||||||
PreferredSizeWidget _buildAppbar(bool enableMultiSelect) {
|
PreferredSizeWidget _buildAppbar(bool enableMultiSelect) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
Color color = theme.colorScheme.secondary;
|
Color color = theme.colorScheme.secondary;
|
||||||
|
final btnStyle = TextButton.styleFrom(visualDensity: .compact);
|
||||||
|
final textStyle = TextStyle(color: theme.colorScheme.onSurfaceVariant);
|
||||||
return MultiSelectAppBarWidget(
|
return MultiSelectAppBarWidget(
|
||||||
visible: enableMultiSelect,
|
visible: enableMultiSelect,
|
||||||
ctr: currCtr(),
|
ctr: currCtr(),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
style: TextButton.styleFrom(visualDensity: .compact),
|
style: btnStyle,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final ctr = currCtr();
|
final ctr = currCtr();
|
||||||
RequestUtils.onCopyOrMove<LaterData, LaterItemModel>(
|
RequestUtils.onCopyOrMove<LaterItemModel>(
|
||||||
context: context,
|
context: context,
|
||||||
isCopy: true,
|
isCopy: true,
|
||||||
ctr: ctr,
|
ctr: ctr,
|
||||||
@@ -171,16 +171,13 @@ class _LaterPageState extends State<LaterPage>
|
|||||||
mid: ctr.mid,
|
mid: ctr.mid,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text('复制', style: textStyle),
|
||||||
'复制',
|
|
||||||
style: TextStyle(color: theme.colorScheme.onSurfaceVariant),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
style: TextButton.styleFrom(visualDensity: .compact),
|
style: btnStyle,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final ctr = currCtr();
|
final ctr = currCtr();
|
||||||
RequestUtils.onCopyOrMove<LaterData, LaterItemModel>(
|
RequestUtils.onCopyOrMove<LaterItemModel>(
|
||||||
context: context,
|
context: context,
|
||||||
isCopy: false,
|
isCopy: false,
|
||||||
ctr: ctr,
|
ctr: ctr,
|
||||||
@@ -188,10 +185,7 @@ class _LaterPageState extends State<LaterPage>
|
|||||||
mid: ctr.mid,
|
mid: ctr.mid,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text('移动', style: textStyle),
|
||||||
'移动',
|
|
||||||
style: TextStyle(color: theme.colorScheme.onSurfaceVariant),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: AppBar(
|
child: AppBar(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'package:PiliPlus/pages/later/widgets/video_card_h_later.dart';
|
|||||||
import 'package:PiliPlus/pages/later_search/controller.dart';
|
import 'package:PiliPlus/pages/later_search/controller.dart';
|
||||||
import 'package:PiliPlus/utils/grid.dart';
|
import 'package:PiliPlus/utils/grid.dart';
|
||||||
import 'package:PiliPlus/utils/page_utils.dart';
|
import 'package:PiliPlus/utils/page_utils.dart';
|
||||||
|
import 'package:PiliPlus/utils/request_utils.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -25,6 +26,38 @@ class _LaterSearchPageState
|
|||||||
tag: Utils.generateRandomString(8),
|
tag: Utils.generateRandomString(8),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Widget>? get multiSelectActions {
|
||||||
|
final btnStyle = TextButton.styleFrom(visualDensity: .compact);
|
||||||
|
final textStyle = TextStyle(
|
||||||
|
color: ColorScheme.of(context).onSurfaceVariant,
|
||||||
|
);
|
||||||
|
return [
|
||||||
|
TextButton(
|
||||||
|
style: btnStyle,
|
||||||
|
onPressed: () => RequestUtils.onCopyOrMove<LaterItemModel>(
|
||||||
|
context: context,
|
||||||
|
isCopy: true,
|
||||||
|
ctr: controller,
|
||||||
|
mediaId: null,
|
||||||
|
mid: controller.mid,
|
||||||
|
),
|
||||||
|
child: Text('复制', style: textStyle),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
style: btnStyle,
|
||||||
|
onPressed: () => RequestUtils.onCopyOrMove<LaterItemModel>(
|
||||||
|
context: context,
|
||||||
|
isCopy: false,
|
||||||
|
ctr: controller,
|
||||||
|
mediaId: null,
|
||||||
|
mid: controller.mid,
|
||||||
|
),
|
||||||
|
child: Text('移动', style: textStyle),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
late final gridDelegate = Grid.videoCardHDelegate(context, minHeight: 110);
|
late final gridDelegate = Grid.videoCardHDelegate(context, minHeight: 110);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -16,11 +16,13 @@ import 'package:PiliPlus/http/validate.dart';
|
|||||||
import 'package:PiliPlus/http/video.dart';
|
import 'package:PiliPlus/http/video.dart';
|
||||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||||
import 'package:PiliPlus/models/login/model.dart';
|
import 'package:PiliPlus/models/login/model.dart';
|
||||||
|
import 'package:PiliPlus/models_new/fav/fav_detail/media.dart';
|
||||||
|
import 'package:PiliPlus/models_new/later/list.dart';
|
||||||
import 'package:PiliPlus/pages/common/multi_select/base.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/dynamics_tab/controller.dart';
|
import 'package:PiliPlus/pages/dynamics_tab/controller.dart';
|
||||||
|
import 'package:PiliPlus/pages/fav_detail/controller.dart'
|
||||||
|
show BaseFavController;
|
||||||
import 'package:PiliPlus/pages/group_panel/view.dart';
|
import 'package:PiliPlus/pages/group_panel/view.dart';
|
||||||
import 'package:PiliPlus/pages/later/controller.dart';
|
|
||||||
import 'package:PiliPlus/pages/login/geetest/geetest_webview_dialog.dart';
|
import 'package:PiliPlus/pages/login/geetest/geetest_webview_dialog.dart';
|
||||||
import 'package:PiliPlus/utils/accounts.dart';
|
import 'package:PiliPlus/utils/accounts.dart';
|
||||||
import 'package:PiliPlus/utils/extension/context_ext.dart';
|
import 'package:PiliPlus/utils/extension/context_ext.dart';
|
||||||
@@ -387,10 +389,10 @@ abstract final class RequestUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onCopyOrMove<R, T extends MultiSelectData>({
|
static void onCopyOrMove<T extends MultiSelectData>({
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
required bool isCopy,
|
required bool isCopy,
|
||||||
required MultiSelectController<R, T> ctr,
|
required CommonMultiSelectMixin<T> ctr,
|
||||||
required dynamic mediaId,
|
required dynamic mediaId,
|
||||||
required dynamic mid,
|
required dynamic mid,
|
||||||
}) {
|
}) {
|
||||||
@@ -437,18 +439,20 @@ abstract final class RequestUtils {
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (checkedId != null) {
|
if (checkedId != null) {
|
||||||
Set removeList = ctr.allChecked.toSet();
|
final removeList = ctr.allChecked.toSet();
|
||||||
SmartDialog.showLoading();
|
SmartDialog.showLoading();
|
||||||
FavHttp.copyOrMoveFav(
|
FavHttp.copyOrMoveFav(
|
||||||
isCopy: isCopy,
|
isCopy: isCopy,
|
||||||
isFav: ctr is! LaterController,
|
isFav: ctr is BaseFavController,
|
||||||
srcMediaId: mediaId,
|
srcMediaId: mediaId,
|
||||||
tarMediaId: checkedId,
|
tarMediaId: checkedId,
|
||||||
resources: removeList
|
resources: removeList
|
||||||
.map(
|
.map(
|
||||||
(item) => ctr is LaterController
|
(e) => switch (e) {
|
||||||
? item.aid
|
LaterItemModel _ => e.aid,
|
||||||
: '${item.id}:${item.type}',
|
FavDetailItemModel _ => '${e.id}:${e.type}',
|
||||||
|
_ => throw UnsupportedError(e.toString()),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.join(','),
|
.join(','),
|
||||||
mid: isCopy ? mid : null,
|
mid: isCopy ? mid : null,
|
||||||
|
|||||||
Reference in New Issue
Block a user