From af7cc8dab062db322e5e3ee25bafb2b0f1217a2c Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Thu, 10 Oct 2024 23:36:07 +0800 Subject: [PATCH] :lipstick: Optimize the explore page app bar behavior --- lib/controllers/post_list_controller.dart | 17 ++- lib/providers/content/posts.dart | 8 +- lib/screens/dashboard.dart | 10 +- lib/screens/explore.dart | 131 +++++++++++++--------- lib/screens/posts/post_editor.dart | 1 - 5 files changed, 101 insertions(+), 66 deletions(-) diff --git a/lib/controllers/post_list_controller.dart b/lib/controllers/post_list_controller.dart index 151b23c..613984b 100644 --- a/lib/controllers/post_list_controller.dart +++ b/lib/controllers/post_list_controller.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:math'; import 'package:get/get.dart'; @@ -33,9 +34,18 @@ class PostListController extends GetxController { pagingController.addPageRequestListener(_onPagingControllerRequest); } + Completer? _pagingLoadCompleter; + Future _onPagingControllerRequest(int pageKey) async { try { + if (_pagingLoadCompleter != null) { + await _pagingLoadCompleter!.future; + return; + } + _pagingLoadCompleter = Completer(); final result = await loadMore(); + _pagingLoadCompleter!.complete(); + _pagingLoadCompleter = null; if (result != null && hasMore.value) { pagingController.appendPage(result, nextPageKey.value); @@ -99,9 +109,6 @@ class PostListController extends GetxController { hasMore.value = false; } - final idx = {}; - postList.retainWhere((x) => idx.add(x.id)); - if (postList.isNotEmpty) { var lastId = postList.map((x) => x.id).reduce(max); Get.find().feedLastReadAt = lastId; @@ -121,6 +128,7 @@ class PostListController extends GetxController { resp = await posts.listPost( pageKey, author: author, + take: 10, ); } else { switch (mode.value) { @@ -129,6 +137,7 @@ class PostListController extends GetxController { pageKey, channel: 'shuffle', realm: realm, + take: 10, ); break; case 1: @@ -136,12 +145,14 @@ class PostListController extends GetxController { pageKey, channel: 'friends', realm: realm, + take: 10, ); break; default: resp = await posts.listRecommendations( pageKey, realm: realm, + take: 10, ); break; } diff --git a/lib/providers/content/posts.dart b/lib/providers/content/posts.dart index bd9ecb0..c22e481 100644 --- a/lib/providers/content/posts.dart +++ b/lib/providers/content/posts.dart @@ -28,11 +28,11 @@ class PostProvider extends GetConnect { } Future listRecommendations(int page, - {String? realm, String? channel}) async { + {String? realm, String? channel, int take = 10}) async { GetConnect client; final AuthProvider auth = Get.find(); final queries = [ - 'take=${10}', + 'take=$take', 'offset=$page', if (realm != null) 'realm=$realm', ]; @@ -71,9 +71,9 @@ class PostProvider extends GetConnect { } Future listPost(int page, - {String? realm, String? author, tag, category}) async { + {String? realm, String? author, tag, category, int take = 10}) async { final queries = [ - 'take=${10}', + 'take=$take', 'offset=$page', if (tag != null) 'tag=$tag', if (category != null) 'category=$category', diff --git a/lib/screens/dashboard.dart b/lib/screens/dashboard.dart index 971dd5b..3e54219 100644 --- a/lib/screens/dashboard.dart +++ b/lib/screens/dashboard.dart @@ -75,10 +75,12 @@ class _DashboardScreenState extends State { final src = Get.find(); final out = await src.getWhatsNewEvents(_lastRead.messagesLastReadAt!); if (out == null) return; - setState(() { - _currentMessages = out.$1; - _currentMessagesCount = out.$2; - }); + if (mounted) { + setState(() { + _currentMessages = out.$1; + _currentMessagesCount = out.$2; + }); + } } bool _signingDaily = true; diff --git a/lib/screens/explore.dart b/lib/screens/explore.dart index c5e404b..ce6bff3 100644 --- a/lib/screens/explore.dart +++ b/lib/screens/explore.dart @@ -80,62 +80,85 @@ class _ExploreScreenState extends State body: NestedScrollView( headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [ - SliverAppBar( - flexibleSpace: SizedBox( - height: 48, - child: const Row( - children: [ - RealmSwitcher(), + SliverLayoutBuilder( + builder: (context, constraints) { + final scrollOffset = constraints.scrollOffset; + final colorChangeOffset = 120; + + final scrollProgress = + (scrollOffset / colorChangeOffset).clamp(0.0, 1.0); + final backgroundColor = Color.lerp( + Theme.of(context) + .colorScheme + .surfaceContainerLow + .withOpacity(0), + Theme.of(context) + .colorScheme + .surfaceContainerLow + .withOpacity(0.9), + scrollProgress, + ); + + return SliverAppBar( + backgroundColor: backgroundColor, + flexibleSpace: SizedBox( + height: 48, + child: const Row( + children: [ + RealmSwitcher(), + ], + ).paddingSymmetric(horizontal: 8), + ).paddingOnly(top: MediaQuery.of(context).padding.top), + snap: true, + floating: true, + toolbarHeight: AppTheme.toolbarHeight(context), + leading: AppBarLeadingButton.adaptive(context), + actions: [ + const BackgroundStateWidget(), + const NotificationButton(), + SizedBox( + width: AppTheme.isLargeScreen(context) ? 8 : 16, + ), ], - ).paddingSymmetric(horizontal: 8), - ).paddingOnly(top: MediaQuery.of(context).padding.top), - floating: true, - toolbarHeight: AppTheme.toolbarHeight(context), - leading: AppBarLeadingButton.adaptive(context), - actions: [ - const BackgroundStateWidget(), - const NotificationButton(), - SizedBox( - width: AppTheme.isLargeScreen(context) ? 8 : 16, - ), - ], - bottom: TabBar( - controller: _tabController, - dividerHeight: 0.3, - tabAlignment: TabAlignment.fill, - tabs: [ - Tab( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon(Icons.feed, size: 20), - const Gap(8), - Text('postListNews'.tr), - ], - ), + bottom: TabBar( + controller: _tabController, + dividerHeight: 0.3, + tabAlignment: TabAlignment.fill, + tabs: [ + Tab( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.feed, size: 20), + const Gap(8), + Text('postListNews'.tr), + ], + ), + ), + Tab( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.people, size: 20), + const Gap(8), + Text('postListFriends'.tr), + ], + ), + ), + Tab( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.shuffle_on_outlined, size: 20), + const Gap(8), + Text('postListShuffle'.tr), + ], + ), + ), + ], ), - Tab( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon(Icons.people, size: 20), - const Gap(8), - Text('postListFriends'.tr), - ], - ), - ), - Tab( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon(Icons.shuffle_on_outlined, size: 20), - const Gap(8), - Text('postListShuffle'.tr), - ], - ), - ), - ], - ), + ); + }, ) ]; }, diff --git a/lib/screens/posts/post_editor.dart b/lib/screens/posts/post_editor.dart index db4c869..04d1d5e 100644 --- a/lib/screens/posts/post_editor.dart +++ b/lib/screens/posts/post_editor.dart @@ -546,7 +546,6 @@ class _PostEditorTextField extends StatelessWidget { final Function onUpdate; const _PostEditorTextField({ - super.key, required this.focusNode, required this.controller, required this.onUpdate,