diff --git a/lib/pages/common/common_controller.dart b/lib/pages/common/common_controller.dart index 183c98c9..bc5695f1 100644 --- a/lib/pages/common/common_controller.dart +++ b/lib/pages/common/common_controller.dart @@ -1,9 +1,31 @@ +import 'dart:async'; + import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -abstract class CommonController extends GetxController { +abstract mixin class ScrollOrRefreshMixin { + ScrollController get scrollController; + + void animateToTop() => scrollController.animToTop(); + + Future onRefresh(); + + FutureOr toTopOrRefresh() { + if (scrollController.hasClients) { + if (scrollController.position.pixels == 0) { + return onRefresh(); + } else { + animateToTop(); + } + } + } +} + +abstract class CommonController extends GetxController + with ScrollOrRefreshMixin { + @override final ScrollController scrollController = ScrollController(); int currentPage = 1; @@ -57,7 +79,8 @@ abstract class CommonController extends GetxController { isLoading = false; } - Future onRefresh() async { + @override + Future onRefresh() async { currentPage = 1; isEnd = false; await queryData(); @@ -67,10 +90,6 @@ abstract class CommonController extends GetxController { await queryData(false); } - void animateToTop() { - scrollController.animToTop(); - } - Future onReload() async { loadingState.value = LoadingState.loading(); await onRefresh(); diff --git a/lib/pages/dynamics/controller.dart b/lib/pages/dynamics/controller.dart index baf0de62..e4e2bf1b 100644 --- a/lib/pages/dynamics/controller.dart +++ b/lib/pages/dynamics/controller.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:PiliPlus/http/follow.dart'; import 'package:PiliPlus/pages/dynamics/tab/controller.dart'; import 'package:PiliPlus/pages/dynamics/tab/view.dart'; @@ -11,11 +13,13 @@ import 'package:PiliPlus/models/dynamics/up.dart'; import 'package:PiliPlus/utils/storage.dart'; import '../../models/follow/result.dart'; +import '../common/common_controller.dart'; class DynamicsController extends GetxController - with GetTickerProviderStateMixin { - String? offset = ''; + with GetTickerProviderStateMixin, ScrollOrRefreshMixin { + @override final ScrollController scrollController = ScrollController(); + String? offset = ''; Rx upData = FollowUpModel().obs; // 默认获取全部动态 RxInt mid = (-1).obs; @@ -36,6 +40,9 @@ class DynamicsController extends GetxController late int currentMid = -1; late bool showLiveItems = GStorage.expandDynLivePanel; + DynamicsTabController get controller => Get.find( + tag: tabsConfig[tabController.index]['tag']); + @override void onInit() { super.onInit(); @@ -160,20 +167,33 @@ class DynamicsController extends GetxController tabController.index = (mid == -1 ? 0 : 4); } + @override onRefresh() async { queryFollowUp(); - await Get.find( - tag: tabsConfig[tabController.index]['tag']) - .onRefresh(); + await controller.onRefresh(); } // 返回顶部并刷新 + @override void animateToTop() async { - Get.find(tag: tabsConfig[tabController.index]['tag']) - .animateToTop(); + controller.animateToTop(); scrollController.animToTop(); } + @override + FutureOr toTopOrRefresh() { + if (scrollController.hasClients && controller.scrollController.hasClients) { + if (scrollController.position.pixels == 0 && + controller.scrollController.position.pixels == 0) { + return onRefresh(); + } else { + animateToTop(); + } + } else { + super.toTopOrRefresh(); + } + } + @override void onClose() { tabController.dispose(); diff --git a/lib/pages/home/controller.dart b/lib/pages/home/controller.dart index 1bf7d963..b1153e83 100644 --- a/lib/pages/home/controller.dart +++ b/lib/pages/home/controller.dart @@ -7,9 +7,11 @@ import 'package:PiliPlus/models/common/tab_type.dart'; import 'package:PiliPlus/utils/storage.dart'; import '../../http/index.dart'; import '../../utils/feed_back.dart'; +import '../common/common_controller.dart'; import '../mine/view.dart'; -class HomeController extends GetxController with GetTickerProviderStateMixin { +class HomeController extends GetxController + with GetTickerProviderStateMixin, ScrollOrRefreshMixin { late RxList tabs = [].obs; late TabController tabController; late List tabsCtrList; @@ -28,6 +30,19 @@ class HomeController extends GetxController with GetTickerProviderStateMixin { late RxString defaultSearch = ''.obs; late int lateCheckSearchAt = 0; + ScrollOrRefreshMixin get controller { + final index = tabController.index; + return tabsCtrList[index]!( + tag: switch (tabs[index]['type']) { + TabType.bangumi => TabType.bangumi.name, + TabType.cinema => TabType.cinema.name, + _ => null, + }); + } + + @override + ScrollController get scrollController => controller.scrollController; + @override void onInit() { super.onInit(); @@ -48,32 +63,9 @@ class HomeController extends GetxController with GetTickerProviderStateMixin { setTabConfig(); } - void onRefresh() { - try { - int index = tabController.index; - var ctr = tabsCtrList[index]; - ctr( - tag: tabs[index]['type'] == TabType.bangumi - ? TabType.bangumi.name - : tabs[index]['type'] == TabType.cinema - ? TabType.cinema.name - : null) - .onRefresh(); - } catch (_) {} - } - - void animateToTop() { - try { - int index = tabController.index; - var ctr = tabsCtrList[index]; - ctr( - tag: tabs[index]['type'] == TabType.bangumi - ? TabType.bangumi.name - : tabs[index]['type'] == TabType.cinema - ? TabType.cinema.name - : null) - .animateToTop(); - } catch (_) {} + @override + Future onRefresh() { + return controller.onRefresh().catchError((e) => debugPrint(e.toString())); } void setTabConfig() async { diff --git a/lib/pages/main/view.dart b/lib/pages/main/view.dart index e952b032..84344e7e 100644 --- a/lib/pages/main/view.dart +++ b/lib/pages/main/view.dart @@ -140,9 +140,9 @@ class _MainAppState extends State dynamic currentPage = _mainController.pages[value]; if (currentPage is HomePage) { - _homeController.animateToTop(); + _homeController.toTopOrRefresh(); } else if (currentPage is DynamicsPage) { - _dynamicController.animateToTop(); + _dynamicController.toTopOrRefresh(); } int now = DateTime.now().millisecondsSinceEpoch; diff --git a/lib/pages/rank/controller.dart b/lib/pages/rank/controller.dart index a8b92ae8..38f4f124 100644 --- a/lib/pages/rank/controller.dart +++ b/lib/pages/rank/controller.dart @@ -1,9 +1,13 @@ +import 'dart:async'; + +import 'package:PiliPlus/pages/common/common_controller.dart'; import 'package:PiliPlus/pages/rank/zone/index.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:PiliPlus/models/common/rank_type.dart'; -class RankController extends GetxController with GetTickerProviderStateMixin { +class RankController extends GetxController + with GetTickerProviderStateMixin, ScrollOrRefreshMixin { bool flag = false; late RxList tabs = [].obs; RxInt initialIndex = 0.obs; @@ -13,6 +17,12 @@ class RankController extends GetxController with GetTickerProviderStateMixin { // StreamController.broadcast(); late bool enableGradientBg; + ZoneController get controller => Get.find( + tag: tabsConfig[tabController.index]['rid'].toString()); + + @override + ScrollController get scrollController => controller.scrollController; + @override void onInit() { super.onInit(); @@ -22,18 +32,6 @@ class RankController extends GetxController with GetTickerProviderStateMixin { setTabConfig(); } - void onRefresh() { - int index = tabController.index; - Get.find(tag: tabsConfig[index]['rid'].toString()) - .onRefresh(); - } - - void animateToTop() { - int index = tabController.index; - Get.find(tag: tabsConfig[index]['rid'].toString()) - .animateToTop(); - } - void setTabConfig() async { tabs.value = tabsConfig; initialIndex.value = 0; @@ -51,4 +49,7 @@ class RankController extends GetxController with GetTickerProviderStateMixin { tabController.dispose(); super.onClose(); } + + @override + Future onRefresh() => controller.onRefresh(); }