diff --git a/lib/screens/home/home.dart b/lib/screens/home/home.dart index fdb9d79a..4b55a8e6 100644 --- a/lib/screens/home/home.dart +++ b/lib/screens/home/home.dart @@ -122,7 +122,9 @@ class _HomeState extends State { TopSection( homeStore: _homeStore, ), - const Search(), + Search( + scrollController: _homeStore.searchScrollController, + ), ], ), ), diff --git a/lib/screens/home/search/search.dart b/lib/screens/home/search/search.dart index 7fa4c60c..0b2117ce 100644 --- a/lib/screens/home/search/search.dart +++ b/lib/screens/home/search/search.dart @@ -10,8 +10,15 @@ import 'package:frosty/widgets/alert_message.dart'; import 'package:frosty/widgets/section_header.dart'; import 'package:provider/provider.dart'; +/// The search section that contians search history and search results for channels and categories. class Search extends StatefulWidget { - const Search({Key? key}) : super(key: key); + // The scroll controller for handling scroll to top functionality. + final ScrollController scrollController; + + const Search({ + Key? key, + required this.scrollController, + }) : super(key: key); @override State createState() => _SearchState(); @@ -77,6 +84,7 @@ class _SearchState extends State { ), Expanded( child: ListView( + controller: widget.scrollController, children: _searchStore.searchHistory .mapIndexed( (index, searchTerm) => ListTile( @@ -104,6 +112,7 @@ class _SearchState extends State { ); } return CustomScrollView( + controller: widget.scrollController, slivers: [ const SliverToBoxAdapter( child: SectionHeader( diff --git a/lib/screens/home/stores/home_store.dart b/lib/screens/home/stores/home_store.dart index e2c4d959..16e1a4cc 100644 --- a/lib/screens/home/stores/home_store.dart +++ b/lib/screens/home/stores/home_store.dart @@ -21,6 +21,9 @@ abstract class HomeStoreBase with Store { ScrollController(), ]; + /// The scroll controller for controlling the scroll to top on the search section. + final searchScrollController = ScrollController(); + /// The current index of the top section tab. Changes when switching between the streams and categories tabs. var topSectionCurrentIndex = 0; @@ -44,20 +47,48 @@ abstract class HomeStoreBase with Store { if (index != _selectedIndex) { _selectedIndex = index; } else { - if (index == 0 && authStore.isLoggedIn) { - // If on the followed tab and tapping the followed button, scroll to the top. - followedScrollController.animateTo( - 0.0, - duration: const Duration(milliseconds: 200), - curve: Curves.easeOutCubic, - ); + const duration = Duration(milliseconds: 500); + + // Use different logic if logged in/out since there will be one less tab when logged out. + if (authStore.isLoggedIn) { + if (index == 0) { + // If on the followed tab and tapping the followed tab, scroll to the top. + followedScrollController.animateTo( + 0.0, + duration: duration, + curve: Curves.easeOutCubic, + ); + } else if (index == 1) { + // If on the top section, scroll to the top of the tab based on the current top tab. + topSectionScrollControllers[topSectionCurrentIndex].animateTo( + 0.0, + duration: duration, + curve: Curves.easeOutCubic, + ); + } else { + // If on the search tab and tapping the search tab, scroll to the top. + searchScrollController.animateTo( + 0.0, + duration: duration, + curve: Curves.easeOutCubic, + ); + } } else { - // If on the top section, scroll to the top of the tab based on the current top tab. - topSectionScrollControllers[topSectionCurrentIndex].animateTo( - 0.0, - duration: const Duration(milliseconds: 200), - curve: Curves.easeOutCubic, - ); + if (index == 0) { + // If on the top section, scroll to the top of the tab based on the current top tab. + topSectionScrollControllers[topSectionCurrentIndex].animateTo( + 0.0, + duration: duration, + curve: Curves.easeOutCubic, + ); + } else { + // If on the search tab and tapping the search tab, scroll to the top. + searchScrollController.animateTo( + 0.0, + duration: duration, + curve: Curves.easeOutCubic, + ); + } } } }