import 'dart:async'; import 'package:PiliPlus/http/dynamics.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models/common/dynamic/dynamics_type.dart'; import 'package:PiliPlus/models/dynamics/up.dart'; import 'package:PiliPlus/pages/common/common_data_controller.dart'; import 'package:PiliPlus/pages/dynamics_tab/controller.dart'; import 'package:PiliPlus/services/account_service.dart'; import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart'; import 'package:PiliPlus/utils/extension/string_ext.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; class DynamicsController extends CommonDataController with GetSingleTickerProviderStateMixin, AccountMixin { late final TabController tabController; final Set tempBannedList = {}; String? _offset; late int _page = 1; late bool _isEnd = false; Set? _cacheUpList; late int hostMid = -1, currentMid = -1; late bool showLiveUp = Pref.expandDynLivePanel; late final _showAllUp = Pref.dynamicsShowAllFollowedUp; final upPanelPosition = Pref.upPanelPosition; @override final AccountService accountService = Get.find(); DynamicsTabController? get controller { try { return Get.find( tag: DynamicsTabType.values[tabController.index].name, ); } catch (_) { return null; } } @override void onInit() { super.onInit(); tabController = TabController( vsync: this, length: DynamicsTabType.values.length, initialIndex: Pref.defaultDynamicTypeIndex, ); queryData(); } void _jumpToTab(int mid) { tabController.index = mid == -1 ? 0 : 4; } void onSelectUp(int mid) { if (currentMid == mid) { _jumpToTab(mid); if (mid == -1) { singleRefresh(); } controller?.onReload(); return; } if (mid != -1) { hostMid = mid; try { Get.find( tag: DynamicsTabType.up.name, ).onReload(); } catch (_) {} } currentMid = mid; _jumpToTab(mid); } Future singleRefresh() { if (_showAllUp) { _page = 1; _cacheUpList = null; } _offset = null; _isEnd = false; return super.onRefresh(); } @override Future onRefresh() { singleRefresh(); return controller!.onRefresh(); } @override void animateToTop() { controller?.animateToTop(); scrollController.animToTop(); } @override void toTopOrRefresh() { final ctr = controller; if (ctr?.scrollController.hasClients == true) { if (ctr!.scrollController.position.pixels == 0) { if (scrollController.hasClients && scrollController.position.pixels != 0) { scrollController.animToTop(); } EasyThrottle.throttle( 'topOrRefresh', const Duration(milliseconds: 500), onRefresh, ); } else { animateToTop(); } } else { super.toTopOrRefresh(); } } @override void onClose() { tabController.dispose(); super.onClose(); } @override void onChangeAccount(bool isLogin) => onReload(); @override Future> customGetData() { if (_offset == null) { return DynamicsHttp.followUp(); } if (_showAllUp) { return DynamicsHttp.followings( vmid: Accounts.main.mid, pn: _page, orderType: 'attention', ps: 50, ); } else { return DynamicsHttp.dynUpList(_offset); } } @override Future queryData([bool isRefresh = true]) { if (!isRefresh && _isEnd) return Future.value(); return super.queryData(isRefresh); } @override bool customHandleResponse(bool isRefresh, Success response) { final res = response.response; if (_showAllUp) { if (res.upList?.isNotEmpty != true) { _isEnd = true; } } else { _offset = res.offset; if (res.hasMore != true || _offset.isNullOrEmpty) { _isEnd = true; } } if (isRefresh) { if (_showAllUp) { _offset = ''; _cacheUpList = res.upList?.toSet(); } loadingState.value = response; } else { if (_showAllUp) { _page++; } if (res.upList case final upList? when upList.isNotEmpty) { if (_showAllUp && _cacheUpList != null) { upList.removeWhere(_cacheUpList!.contains); } loadingState ..value.data.addAllUpList(upList) ..refresh(); } } return true; } }