From 51dc5495ec224b6d074d2a1eef4d5f8b9129a3b4 Mon Sep 17 00:00:00 2001 From: rzuasti Date: Thu, 4 Jun 2026 10:12:36 -0400 Subject: [PATCH] Fold scroll-to-top into _fetchPage Replace the _goToPage wrapper with an optional scrollToTop flag on _fetchPage, so there is a single fetch entry point. The pagination bar passes scrollToTop: true; all other callers keep the current behaviour. Co-Authored-By: Claude Opus 4.8 --- frontend/lib/devices/device_list.dart | 26 ++++++++++------------- frontend/lib/home/notifications_list.dart | 14 +++++------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/frontend/lib/devices/device_list.dart b/frontend/lib/devices/device_list.dart index ee53a1c..edd5413 100644 --- a/frontend/lib/devices/device_list.dart +++ b/frontend/lib/devices/device_list.dart @@ -74,19 +74,6 @@ class _DeviceListState extends State with RouteAware { super.dispose(); } - /// Fetches [page] and scrolls back to the top of the list, so changing pages - /// always starts the new page from its first row. - void _goToPage(int page) { - if (_scrollController.hasClients) { - _scrollController.animateTo( - 0, - duration: const Duration(milliseconds: 300), - curve: Curves.easeOut, - ); - } - _fetchPage(page); - } - void _onOwnerChanged() { _ownerDebounce?.cancel(); _ownerDebounce = Timer( @@ -95,7 +82,16 @@ class _DeviceListState extends State with RouteAware { ); } - Future _fetchPage(int page) async { + /// Fetches [page]. When [scrollToTop] is set, the list animates back to its + /// first row, so changing pages always starts the new page from the top. + Future _fetchPage(int page, {bool scrollToTop = false}) async { + if (scrollToTop && _scrollController.hasClients) { + _scrollController.animateTo( + 0, + duration: const Duration(milliseconds: 300), + curve: Curves.easeOut, + ); + } _fetchToken?.cancel(); final token = CancelToken(); _fetchToken = token; @@ -339,7 +335,7 @@ class _DeviceListState extends State with RouteAware { currentPage: _currentPage, hasNextPage: _hasNextPage, isLoading: _isLoading, - onPageChanged: _goToPage, + onPageChanged: (page) => _fetchPage(page, scrollToTop: true), ), ), ], diff --git a/frontend/lib/home/notifications_list.dart b/frontend/lib/home/notifications_list.dart index 298874d..fa38c0c 100644 --- a/frontend/lib/home/notifications_list.dart +++ b/frontend/lib/home/notifications_list.dart @@ -112,20 +112,16 @@ class _NotificationsListState extends State super.dispose(); } - /// Fetches [page] and scrolls back to the top of the list, so changing pages - /// always starts the new page from its first item. - void _goToPage(int page) { - if (_scrollController.hasClients) { + /// Fetches [page]. When [scrollToTop] is set, the list animates back to its + /// first item, so changing pages always starts the new page from the top. + Future _fetchPage(int page, {bool scrollToTop = false}) async { + if (scrollToTop && _scrollController.hasClients) { _scrollController.animateTo( 0, duration: const Duration(milliseconds: 300), curve: Curves.easeOut, ); } - _fetchPage(page); - } - - Future _fetchPage(int page) async { _fetchToken?.cancel(); final token = CancelToken(); _fetchToken = token; @@ -312,7 +308,7 @@ class _NotificationsListState extends State currentPage: _currentPage, hasNextPage: _hasNextPage, isLoading: _isLoading, - onPageChanged: _goToPage, + onPageChanged: (page) => _fetchPage(page, scrollToTop: true), ), ), ];