refactor: blacklist

This commit is contained in:
bggRGjQaUbCoE
2024-09-26 11:49:39 +08:00
parent 6138dfa51f
commit f73fd8d6a6
2 changed files with 102 additions and 113 deletions

View File

@@ -1,8 +1,11 @@
import 'package:PiliPalaX/http/loading_state.dart';
import 'package:PiliPalaX/utils/extension.dart';
import '../models/user/black.dart'; import '../models/user/black.dart';
import 'index.dart'; import 'index.dart';
class BlackHttp { class BlackHttp {
static Future blackList({required int pn, int? ps}) async { static Future<LoadingState> blackList({required int pn, int? ps}) async {
var res = await Request().get(Api.blackLst, data: { var res = await Request().get(Api.blackLst, data: {
'pn': pn, 'pn': pn,
'ps': ps ?? 50, 'ps': ps ?? 50,
@@ -11,16 +14,14 @@ class BlackHttp {
'csrf': await Request.getCsrf(), 'csrf': await Request.getCsrf(),
}); });
if (res.data['code'] == 0) { if (res.data['code'] == 0) {
return { BlackListDataModel data = BlackListDataModel.fromJson(res.data['data']);
'status': true, if (!data.list.isNullOrEmpty) {
'data': BlackListDataModel.fromJson(res.data['data']) return LoadingState.success(data);
}; } else {
return LoadingState.empty();
}
} else { } else {
return { return LoadingState.error(res.data['message']);
'status': false,
'data': [],
'msg': res.data['message'],
};
} }
} }

View File

@@ -1,3 +1,5 @@
import 'package:PiliPalaX/http/loading_state.dart';
import 'package:PiliPalaX/pages/common/common_controller.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -5,7 +7,6 @@ import 'package:hive/hive.dart';
import 'package:PiliPalaX/common/widgets/http_error.dart'; import 'package:PiliPalaX/common/widgets/http_error.dart';
import 'package:PiliPalaX/common/widgets/network_img_layer.dart'; import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
import 'package:PiliPalaX/http/black.dart'; import 'package:PiliPalaX/http/black.dart';
import 'package:PiliPalaX/models/user/black.dart';
import 'package:PiliPalaX/utils/storage.dart'; import 'package:PiliPalaX/utils/storage.dart';
import 'package:PiliPalaX/utils/utils.dart'; import 'package:PiliPalaX/utils/utils.dart';
@@ -17,26 +18,18 @@ class BlackListPage extends StatefulWidget {
} }
class _BlackListPageState extends State<BlackListPage> { class _BlackListPageState extends State<BlackListPage> {
final BlackListController _blackListController = final _blackListController = Get.put(BlackListController());
Get.put(BlackListController());
final ScrollController scrollController = ScrollController();
Future? _futureBuilderFuture;
bool _isLoadingMore = false;
Box localCache = GStorage.localCache; Box localCache = GStorage.localCache;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_futureBuilderFuture = _blackListController.queryBlacklist(); _blackListController.scrollController.addListener(
scrollController.addListener(
() async { () async {
if (scrollController.position.pixels >= if (_blackListController.scrollController.position.pixels >=
scrollController.position.maxScrollExtent - 200) { _blackListController.scrollController.position.maxScrollExtent -
if (!_isLoadingMore) { 200) {
_isLoadingMore = true; await _blackListController.onLoadMore();
await _blackListController.queryBlacklist(type: 'onLoad');
_isLoadingMore = false;
}
} }
}, },
); );
@@ -44,11 +37,12 @@ class _BlackListPageState extends State<BlackListPage> {
@override @override
void dispose() { void dispose() {
List<int> blackMidsList = List list = _blackListController.loadingState.value is Success
_blackListController.blackList.map<int>((e) => e.mid!).toList(); ? (_blackListController.loadingState.value as Success).response
localCache.put(LocalCacheKey.blackMidsList, blackMidsList); : <int>[];
scrollController.removeListener(() {}); localCache.put(LocalCacheKey.blackMidsList,
scrollController.dispose(); list.isNotEmpty ? list.map<int>((e) => e.mid!).toList() : list);
_blackListController.scrollController.removeListener(() {});
super.dispose(); super.dispose();
} }
@@ -62,110 +56,104 @@ class _BlackListPageState extends State<BlackListPage> {
centerTitle: false, centerTitle: false,
title: Obx( title: Obx(
() => Text( () => Text(
'黑名单管理 - ${_blackListController.total.value}', '黑名单管理: ${_blackListController.total.value}',
style: Theme.of(context).textTheme.titleMedium, style: Theme.of(context).textTheme.titleMedium,
), ),
), ),
), ),
body: RefreshIndicator( body: RefreshIndicator(
onRefresh: () async => await _blackListController.queryBlacklist(), onRefresh: () async => await _blackListController.onRefresh(),
child: FutureBuilder( child: Obx(() => _buildBody(_blackListController.loadingState.value)),
future: _futureBuilderFuture,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
var data = snapshot.data;
if (data['status']) {
List<BlackListItem> list = _blackListController.blackList;
return Obx(
() => list.length == 1
? const SizedBox()
: ListView.builder(
controller: scrollController,
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
onTap: () {},
leading: NetworkImgLayer(
width: 45,
height: 45,
type: 'avatar',
src: list[index].face,
),
title: Text(
list[index].uname!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 14),
),
subtitle: Text(
Utils.dateFormat(list[index].mtime),
maxLines: 1,
style: TextStyle(
color:
Theme.of(context).colorScheme.outline),
overflow: TextOverflow.ellipsis,
),
dense: true,
trailing: TextButton(
onPressed: () => _blackListController
.removeBlack(list[index].mid),
child: const Text('移除'),
),
);
},
),
);
} else {
return CustomScrollView(
slivers: [
HttpError(
errMsg: data['msg'],
fn: () => _blackListController.queryBlacklist(),
)
],
);
}
} else {
// 骨架屏
return const SizedBox();
}
},
),
), ),
); );
} }
Widget _buildBody(LoadingState loadingState) {
return loadingState is Success
? ListView.builder(
controller: _blackListController.scrollController,
itemCount: loadingState.response.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
onTap: () {},
leading: NetworkImgLayer(
width: 45,
height: 45,
type: 'avatar',
src: loadingState.response[index].face,
),
title: Text(
loadingState.response[index].uname!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 14),
),
subtitle: Text(
Utils.dateFormat(loadingState.response[index].mtime),
maxLines: 1,
style:
TextStyle(color: Theme.of(context).colorScheme.outline),
overflow: TextOverflow.ellipsis,
),
dense: true,
trailing: TextButton(
onPressed: () => _blackListController
.removeBlack(loadingState.response[index].mid),
child: const Text('移除'),
),
);
},
)
: loadingState is Error
? CustomScrollView(
slivers: [
HttpError(
errMsg: loadingState.errMsg,
fn: _blackListController.onReload,
)
],
)
: const SizedBox();
}
} }
class BlackListController extends GetxController { class BlackListController extends CommonController {
int currentPage = 1;
int pageSize = 50; int pageSize = 50;
RxInt total = 0.obs; RxInt total = 0.obs;
RxList<BlackListItem> blackList = <BlackListItem>[].obs;
Future queryBlacklist({type = 'init'}) async { @override
if (type == 'init') { void onInit() {
currentPage = 1; super.onInit();
} queryData();
var result = await BlackHttp.blackList(pn: currentPage, ps: pageSize); }
if (result['status']) {
if (type == 'init') {
blackList.value = result['data'].list;
total.value = result['data'].total;
} else {
blackList.addAll(result['data'].list);
}
currentPage += 1; @override
} bool customHandleResponse(Success response) {
return result; total.value = response.response.total;
List currentList = loadingState.value is Success
? (loadingState.value as Success).response
: [];
List dataList = currentPage == 1
? response.response.list
: currentList + response.response.list;
loadingState.value = dataList.isNotEmpty
? LoadingState.success(dataList)
: LoadingState.empty();
return true;
} }
Future removeBlack(mid) async { Future removeBlack(mid) async {
var result = await BlackHttp.removeBlack(fid: mid); var result = await BlackHttp.removeBlack(fid: mid);
if (result['status']) { if (result['status']) {
blackList.removeWhere((e) => e.mid == mid); List list = (loadingState.value as Success).response;
list.removeWhere((e) => e.mid == mid);
total.value = total.value - 1; total.value = total.value - 1;
loadingState.value = LoadingState.success(list);
SmartDialog.showToast(result['msg']); SmartDialog.showToast(result['msg']);
} }
} }
@override
Future<LoadingState> customGetData() =>
BlackHttp.blackList(pn: currentPage, ps: pageSize);
} }