diff --git a/lib/pages/follow/child/child_view.dart b/lib/pages/follow/child/child_view.dart index ff09c34eb..e1f8f9c67 100644 --- a/lib/pages/follow/child/child_view.dart +++ b/lib/pages/follow/child/child_view.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:PiliPlus/common/skeleton/msg_feed_top.dart'; import 'package:PiliPlus/common/widgets/button/more_btn.dart'; import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart'; @@ -46,37 +48,29 @@ class _FollowChildPageState extends State super.build(context); final colorScheme = ColorScheme.of(context); final padding = MediaQuery.viewPaddingOf(context); - Widget sliver = Obx( - () => _buildBody(_followController.loadingState.value), - ); - if (_followController.loadSameFollow) { - sliver = SliverMainAxisGroup( - slivers: [ - Obx( - () => _buildSameFollowing( - colorScheme, - _followController.sameState.value, + Widget child = Padding( + padding: EdgeInsets.only(left: padding.left, right: padding.right), + child: refreshIndicator( + onRefresh: _followController.onRefresh, + child: CustomScrollView( + controller: _followController.scrollController, + physics: const AlwaysScrollableScrollPhysics(), + slivers: [ + if (_followController.loadSameFollow) + Obx( + () => _buildSameFollowing( + colorScheme, + _followController.sameState.value, + ), + ), + SliverPadding( + padding: EdgeInsets.only(bottom: padding.bottom + 100), + sliver: Obx( + () => _buildBody(_followController.loadingState.value), + ), ), - ), - sliver, - ], - ); - } - Widget child = refreshIndicator( - onRefresh: _followController.onRefresh, - child: CustomScrollView( - controller: _followController.scrollController, - physics: const AlwaysScrollableScrollPhysics(), - slivers: [ - SliverPadding( - padding: EdgeInsets.only( - left: padding.left, - right: padding.right, - bottom: padding.bottom + 100, - ), - sliver: sliver, - ), - ], + ], + ), ), ); if (widget.onSelect != null || @@ -176,7 +170,7 @@ class _FollowChildPageState extends State ), ), SliverList.builder( - itemCount: response!.length, + itemCount: min(3, response!.length), itemBuilder: (_, index) => FollowItem(item: response[index]), ), diff --git a/lib/pages/member/widget/user_info_card.dart b/lib/pages/member/widget/user_info_card.dart index 1ee78d3eb..953c5588a 100644 --- a/lib/pages/member/widget/user_info_card.dart +++ b/lib/pages/member/widget/user_info_card.dart @@ -24,6 +24,18 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart' hide ContextExtensionss; +enum _UserInfoType { + fan('粉丝', .centerLeft), + follow('关注', .center), + like('获赞', .centerRight), + ; + + final String title; + final Alignment alignment; + + const _UserInfoType(this.title, this.alignment); +} + class UserInfoCard extends StatelessWidget { const UserInfoCard({ super.key, @@ -59,29 +71,49 @@ class UserInfoCard extends StatelessWidget { Widget _countWidget({ required ColorScheme colorScheme, - required String title, - required int? count, - required VoidCallback onTap, + required _UserInfoType type, }) { + int? count; + VoidCallback? onTap; + switch (type) { + case _UserInfoType.fan: + count = card.fans; + onTap = () => FansPage.toFansPage( + mid: card.mid, + name: card.name, + ); + case _UserInfoType.follow: + count = card.attention; + onTap = () => FollowPage.toFollowPage( + mid: card.mid, + name: card.name, + ); + case _UserInfoType.like: + count = card.likes?.likeNum; + } return GestureDetector( + behavior: .opaque, onTap: onTap, - behavior: HitTestBehavior.opaque, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - NumUtils.numFormat(count), - style: const TextStyle(fontSize: 14), - ), - Text( - title, - style: TextStyle( - height: 1.2, - fontSize: 12, - color: colorScheme.outline, + child: Align( + alignment: type.alignment, + widthFactor: 1.0, + child: Column( + mainAxisSize: .min, + children: [ + Text( + NumUtils.numFormat(count), + style: const TextStyle(fontSize: 14), ), - ), - ], + Text( + type.title, + style: TextStyle( + height: 1.2, + fontSize: 12, + color: colorScheme.outline, + ), + ), + ], + ), ), ); } @@ -320,33 +352,25 @@ class UserInfoCard extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Row( - children: List.generate( - 5, - (index) => index.isEven - ? _countWidget( + children: _UserInfoType.values + .map( + (e) => Expanded( + child: _countWidget( colorScheme: colorScheme, - title: ['粉丝', '关注', '获赞'][index ~/ 2], - count: index == 0 - ? card.fans - : index == 2 - ? card.attention - : card.likes?.likeNum, - onTap: () { - if (index == 0) { - FansPage.toFansPage(mid: card.mid, name: card.name); - } else if (index == 2) { - FollowPage.toFollowPage(mid: card.mid, name: card.name); - } - }, - ) - : const Expanded( - child: SizedBox( - height: 15, - width: 1, - child: VerticalDivider(), - ), + type: e, ), - ), + ), + ) + .expand((child) sync* { + yield const SizedBox( + height: 15, + width: 1, + child: VerticalDivider(), + ); + yield child; + }) + .skip(1) + .toList(), ), const SizedBox(height: 5), Row( diff --git a/lib/pages/popular_series/controller.dart b/lib/pages/popular_series/controller.dart index 265de8bd9..4f78fced5 100644 --- a/lib/pages/popular_series/controller.dart +++ b/lib/pages/popular_series/controller.dart @@ -1,3 +1,4 @@ +import 'package:PiliPlus/common/widgets/scroll_physics.dart' show ReloadMixin; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/video.dart'; import 'package:PiliPlus/models/model_hot_video_item.dart'; @@ -9,7 +10,8 @@ import 'package:PiliPlus/utils/extension.dart'; import 'package:get/get.dart'; class PopularSeriesController - extends CommonListController { + extends CommonListController + with ReloadMixin { late int number; final Rx config = Rx(null); @@ -54,6 +56,7 @@ class PopularSeriesController if (seriesList.isNullOrEmpty) { return _getSeriesList(); } + reload = true; return super.onReload(); } } diff --git a/lib/pages/popular_series/view.dart b/lib/pages/popular_series/view.dart index faaf81658..a335b2192 100644 --- a/lib/pages/popular_series/view.dart +++ b/lib/pages/popular_series/view.dart @@ -1,7 +1,9 @@ import 'dart:math'; +import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart'; import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; +import 'package:PiliPlus/common/widgets/scroll_physics.dart'; import 'package:PiliPlus/common/widgets/video_card/video_card_h.dart'; import 'package:PiliPlus/common/widgets/view_sliver_safe_area.dart'; import 'package:PiliPlus/http/loading_state.dart'; @@ -40,7 +42,7 @@ class _PopularSeriesPageState extends State with GridMixin { body: refreshIndicator( onRefresh: _controller.onRefresh, child: CustomScrollView( - physics: const AlwaysScrollableScrollPhysics(), + physics: ReloadScrollPhysics(controller: _controller), slivers: [ ViewSliverSafeArea( sliver: Obx(() => _buildBody(_controller.loadingState.value)), @@ -205,10 +207,17 @@ class _PopularSeriesPageState extends State with GridMixin { ], ); } - return SliverToBoxAdapter( - child: Padding( - padding: const EdgeInsets.only(left: 14, bottom: 7), - child: child, + final height = MediaQuery.textScalerOf(context).scale(27); + return SliverPersistentHeader( + floating: true, + delegate: CustomSliverPersistentHeaderDelegate( + extent: height, + child: Container( + height: height, + padding: const EdgeInsets.only(left: 14, bottom: 7), + child: child, + ), + bgColor: colorScheme.surface, ), ); }