import 'dart:async'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; abstract mixin class ScrollOrRefreshMixin { ScrollController get scrollController; void animateToTop() => scrollController.animToTop(); Future onRefresh(); void toTopOrRefresh() { if (scrollController.hasClients) { if (scrollController.position.pixels == 0) { EasyThrottle.throttle('topOrRefresh', const Duration(milliseconds: 500), () { onRefresh(); }); } else { animateToTop(); } } } } abstract class CommonController extends GetxController with ScrollOrRefreshMixin { @override final ScrollController scrollController = ScrollController(); late int currentPage = 1; bool isLoading = false; late bool isEnd = false; Rx loadingState = LoadingState.loading().obs; Future customGetData(); void handleListResponse(List dataList) {} bool customHandleResponse(Success response) { return false; } bool handleError(String? errMsg) { return false; } Future queryData([bool isRefresh = true]) async { if (isLoading || (isRefresh.not && isEnd)) return; isLoading = true; LoadingState response = await customGetData(); if (response is Success) { if (!customHandleResponse(response)) { List? dataList = response.response; if (dataList.isNullOrEmpty) { isEnd = true; if (isRefresh) { loadingState.value = response; } return; } handleListResponse(dataList!); if (isRefresh) { loadingState.value = LoadingState.success(dataList); } else if (loadingState.value is Success) { List currentList = (loadingState.value as Success).response ?? []; currentList.addAll(dataList); loadingState.value = LoadingState.success(currentList); } } currentPage++; } else { if (isRefresh && handleError(response is Error ? response.errMsg : null).not) { loadingState.value = response; } } isLoading = false; } @override Future onRefresh() async { currentPage = 1; isEnd = false; await queryData(); } Future onLoadMore() async { await queryData(false); } Future onReload() async { loadingState.value = LoadingState.loading(); await onRefresh(); } @override void onClose() { scrollController.dispose(); super.onClose(); } }