mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
refactor: subscription
opt: pages Closes #58 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -1,48 +1,30 @@
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:PiliPalaX/pages/common/common_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:PiliPalaX/http/user.dart';
|
||||
import 'package:PiliPalaX/models/user/info.dart';
|
||||
import 'package:PiliPalaX/utils/storage.dart';
|
||||
|
||||
import '../../models/user/sub_folder.dart';
|
||||
|
||||
class SubController extends GetxController {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
Rx<SubFolderModelData> subFolderData = SubFolderModelData().obs;
|
||||
UserInfoData? userInfo;
|
||||
int currentPage = 1;
|
||||
int pageSize = 20;
|
||||
RxBool hasMore = true.obs;
|
||||
class SubController extends CommonController {
|
||||
dynamic mid;
|
||||
|
||||
Future<dynamic> querySubFolder({type = 'init'}) async {
|
||||
userInfo = GStorage.userInfo.get('userInfoCache');
|
||||
if (userInfo == null) {
|
||||
return {'status': false, 'msg': '账号未登录'};
|
||||
}
|
||||
var res = await UserHttp.userSubFolder(
|
||||
pn: currentPage,
|
||||
ps: pageSize,
|
||||
mid: userInfo!.mid!,
|
||||
);
|
||||
if (res['status']) {
|
||||
if (type == 'init') {
|
||||
subFolderData.value = res['data'];
|
||||
} else {
|
||||
if (res['data'].list.isNotEmpty) {
|
||||
subFolderData.value.list!.addAll(res['data'].list);
|
||||
subFolderData.update((val) {});
|
||||
}
|
||||
}
|
||||
currentPage++;
|
||||
} else {
|
||||
SmartDialog.showToast(res['msg']);
|
||||
}
|
||||
return res;
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
mid = GStorage.userInfo.get('userInfoCache')?.mid;
|
||||
queryData();
|
||||
}
|
||||
|
||||
Future onLoad() async {
|
||||
querySubFolder(type: 'onload');
|
||||
@override
|
||||
Future queryData([bool isRefresh = true]) {
|
||||
if (mid == null) {
|
||||
loadingState.value = LoadingState.error('账号未登录');
|
||||
return Future.value();
|
||||
}
|
||||
return super.queryData(isRefresh);
|
||||
}
|
||||
|
||||
// 取消订阅
|
||||
@@ -67,8 +49,9 @@ class SubController extends GetxController {
|
||||
var res = await UserHttp.cancelSub(
|
||||
id: subFolderItem.id!, type: subFolderItem.type!);
|
||||
if (res['status']) {
|
||||
subFolderData.value.list!.remove(subFolderItem);
|
||||
subFolderData.update((val) {});
|
||||
List list = (loadingState.value as Success).response;
|
||||
list.remove(subFolderItem);
|
||||
loadingState.value = LoadingState.success(list);
|
||||
SmartDialog.showToast('取消订阅成功');
|
||||
} else {
|
||||
SmartDialog.showToast(res['msg']);
|
||||
@@ -83,8 +66,9 @@ class SubController extends GetxController {
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
scrollController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
Future<LoadingState> customGetData() => UserHttp.userSubFolder(
|
||||
pn: currentPage,
|
||||
ps: 20,
|
||||
mid: mid,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:PiliPalaX/common/constants.dart';
|
||||
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
||||
import 'package:PiliPalaX/http/loading_state.dart';
|
||||
import 'package:PiliPalaX/pages/subscription/widgets/item.dart';
|
||||
import 'package:PiliPalaX/utils/grid.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||
import '../../common/constants.dart';
|
||||
import '../../utils/grid.dart';
|
||||
import 'controller.dart';
|
||||
import 'widgets/item.dart';
|
||||
|
||||
class SubPage extends StatefulWidget {
|
||||
const SubPage({super.key});
|
||||
@@ -16,81 +17,73 @@ class SubPage extends StatefulWidget {
|
||||
|
||||
class _SubPageState extends State<SubPage> {
|
||||
final SubController _subController = Get.put(SubController());
|
||||
late Future _futureBuilderFuture;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_subController.scrollController.removeListener(() {});
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_futureBuilderFuture = _subController.querySubFolder();
|
||||
_subController.scrollController.addListener(
|
||||
() {
|
||||
if (_subController.scrollController.position.pixels >=
|
||||
_subController.scrollController.position.maxScrollExtent - 300) {
|
||||
EasyThrottle.throttle('history', const Duration(seconds: 1), () {
|
||||
_subController.onLoad();
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text('我的订阅')),
|
||||
body: FutureBuilder(
|
||||
future: _futureBuilderFuture,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
// TODO: refactor
|
||||
Map? data = snapshot.data;
|
||||
if (data != null && data['status']) {
|
||||
return Obx(() => CustomScrollView(
|
||||
controller: _subController.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
slivers: [
|
||||
SliverGrid(
|
||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||
mainAxisSpacing: StyleString.cardSpace,
|
||||
crossAxisSpacing: StyleString.safeSpace,
|
||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||
mainAxisExtent: 0),
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
childCount:
|
||||
_subController.subFolderData.value.list!.length,
|
||||
(BuildContext context, int index) {
|
||||
return SubItem(
|
||||
subFolderItem: _subController
|
||||
.subFolderData.value.list![index],
|
||||
cancelSub: _subController.cancelSub);
|
||||
},
|
||||
),
|
||||
)
|
||||
]));
|
||||
} else {
|
||||
return CustomScrollView(
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
slivers: [
|
||||
HttpError(
|
||||
errMsg: data?['msg'],
|
||||
callback: () => setState(() {}),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 骨架屏
|
||||
return const Text('请求中');
|
||||
}
|
||||
},
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
Obx(() => _buildBody(_subController.loadingState.value)),
|
||||
SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: MediaQuery.of(context).padding.bottom + 10,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody(LoadingState loadingState) {
|
||||
return switch (loadingState) {
|
||||
Loading() => SliverPadding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: StyleString.safeSpace),
|
||||
sliver: SliverGrid(
|
||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||
mainAxisSpacing: StyleString.cardSpace,
|
||||
crossAxisSpacing: StyleString.safeSpace,
|
||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||
mainAxisExtent: 0,
|
||||
),
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) => const VideoCardHSkeleton(),
|
||||
childCount: 10,
|
||||
),
|
||||
),
|
||||
),
|
||||
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||
? SliverGrid(
|
||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||
mainAxisSpacing: StyleString.cardSpace,
|
||||
crossAxisSpacing: StyleString.safeSpace,
|
||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||
mainAxisExtent: 0,
|
||||
),
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
childCount: loadingState.response.length,
|
||||
(BuildContext context, int index) {
|
||||
if (index == loadingState.response.length - 1) {
|
||||
_subController.onLoadMore();
|
||||
}
|
||||
return SubItem(
|
||||
subFolderItem: loadingState.response[index],
|
||||
cancelSub: _subController.cancelSub,
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
: HttpError(
|
||||
callback: _subController.onReload,
|
||||
),
|
||||
Error() => HttpError(
|
||||
errMsg: loadingState.errMsg,
|
||||
callback: _subController.onReload,
|
||||
),
|
||||
LoadingState() => throw UnimplementedError(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user