diff --git a/lib/common/widgets/video_card/video_card_h.dart b/lib/common/widgets/video_card/video_card_h.dart index 17023e2e5..15149f3be 100644 --- a/lib/common/widgets/video_card/video_card_h.dart +++ b/lib/common/widgets/video_card/video_card_h.dart @@ -51,7 +51,9 @@ class VideoCardH extends StatelessWidget { badge = '合作'; } } else if (videoItem case HotVideoItemModel item) { - if (item.isCooperation == 1) { + if (item.isCharging == true) { + badge = '充电专属'; + } else if (item.isCooperation == 1) { badge = '合作'; } else { badge = item.pgcLabel; @@ -147,6 +149,10 @@ class VideoCardH extends StatelessWidget { text: badge, top: 6.0, right: 6.0, + type: switch (badge) { + '充电专属' => PBadgeType.error, + _ => PBadgeType.primary, + }, ), if (progress != null && progress != 0) ...[ PBadge( diff --git a/lib/models/model_hot_video_item.dart b/lib/models/model_hot_video_item.dart index 82aa33027..4c0a81dae 100644 --- a/lib/models/model_hot_video_item.dart +++ b/lib/models/model_hot_video_item.dart @@ -18,6 +18,7 @@ class HotVideoItemModel extends BaseRecVideoItemModel with MultiSelectData { String? redirectUrl; num? progress; int? isCooperation; + bool? isCharging; HotVideoItemModel.fromJson(Map json) { aid = json["aid"]; @@ -47,6 +48,7 @@ class HotVideoItemModel extends BaseRecVideoItemModel with MultiSelectData { // uri = json['uri']; // 仅在稍后再看存在 progress = json['progress']; isCooperation = json['rights']?['is_cooperation']; + isCharging = json['charging_pay']?['level'] != null; } // @override diff --git a/lib/pages/article/view.dart b/lib/pages/article/view.dart index cddb12d7a..c0b947c9e 100644 --- a/lib/pages/article/view.dart +++ b/lib/pages/article/view.dart @@ -427,9 +427,7 @@ class _ArticlePageState extends CommonDynPageState { return switch (loadingState) { Loading() => SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const VideoReplySkeleton(); - }, + itemBuilder: (context, index) => const VideoReplySkeleton(), ), Success(:var response) => response?.isNotEmpty == true diff --git a/lib/pages/article_list/view.dart b/lib/pages/article_list/view.dart index 14fcf0326..99b9ead51 100644 --- a/lib/pages/article_list/view.dart +++ b/lib/pages/article_list/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; @@ -24,7 +23,7 @@ class ArticleListPage extends StatefulWidget { State createState() => _ArticleListPageState(); } -class _ArticleListPageState extends State { +class _ArticleListPageState extends State with GridMixin { final _controller = Get.put( ArticleListController(), tag: Utils.generateRandomString(8), @@ -58,37 +57,27 @@ class _ArticleListPageState extends State { ); } + @override + Widget get gridSkeleton => SliverPadding( + padding: EdgeInsets.only( + top: MediaQuery.paddingOf(context).top + kToolbarHeight + 120, + ), + sliver: super.gridSkeleton, + ); + Widget _buildBody( ThemeData theme, LoadingState?> loadingState, ) { return switch (loadingState) { - Loading() => SliverPadding( - padding: EdgeInsets.only( - top: MediaQuery.paddingOf(context).top + kToolbarHeight + 120, - ), - sliver: SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return ArticleListItem( - item: response[index], - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) => + ArticleListItem(item: response[index]), + itemCount: response!.length, ) : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/blacklist/view.dart b/lib/pages/blacklist/view.dart index d6573d88f..bfc7beadf 100644 --- a/lib/pages/blacklist/view.dart +++ b/lib/pages/blacklist/view.dart @@ -71,9 +71,7 @@ class _BlackListPageState extends State { return switch (loadingState) { Loading() => SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const MsgFeedTopSkeleton(); - }, + itemBuilder: (context, index) => const MsgFeedTopSkeleton(), ), Success(:var response) => response?.isNotEmpty == true diff --git a/lib/pages/common/dyn/common_dyn_page.dart b/lib/pages/common/dyn/common_dyn_page.dart index a5149f5fd..dbed3ee65 100644 --- a/lib/pages/common/dyn/common_dyn_page.dart +++ b/lib/pages/common/dyn/common_dyn_page.dart @@ -98,9 +98,7 @@ abstract class CommonDynPageState extends State return switch (loadingState) { Loading() => SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const VideoReplySkeleton(); - }, + itemBuilder: (context, index) => const VideoReplySkeleton(), ), Success(:var response) => response?.isNotEmpty == true @@ -149,7 +147,10 @@ abstract class CommonDynPageState extends State } }, ) - : HttpError(onReload: controller.onReload), + : HttpError( + errMsg: '还没有评论', + onReload: controller.onReload, + ), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: controller.onReload, diff --git a/lib/pages/common/search/common_search_page.dart b/lib/pages/common/search/common_search_page.dart index 5d8b66de4..584a181b2 100644 --- a/lib/pages/common/search/common_search_page.dart +++ b/lib/pages/common/search/common_search_page.dart @@ -1,8 +1,8 @@ import 'package:PiliPlus/common/widgets/appbar/appbar.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/http/loading_state.dart'; -import 'package:PiliPlus/pages/common/search/common_search_controller.dart'; import 'package:PiliPlus/pages/common/multi_select/base.dart'; +import 'package:PiliPlus/pages/common/search/common_search_controller.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -108,9 +108,7 @@ abstract class CommonSearchPageState Success(:var response) => response?.isNotEmpty == true ? buildList(response!) - : HttpError( - onReload: controller.onReload, - ), + : HttpError(onReload: controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: controller.onReload, diff --git a/lib/pages/common/slide/common_collapse_slide_page.dart b/lib/pages/common/slide/common_collapse_slide_page.dart index f684bc78a..0554e54d0 100644 --- a/lib/pages/common/slide/common_collapse_slide_page.dart +++ b/lib/pages/common/slide/common_collapse_slide_page.dart @@ -9,30 +9,31 @@ abstract class CommonCollapseSlidePageState extends CommonSlidePageState { late bool isInit = true; - void init() { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (mounted) { - setState(() { - isInit = false; - }); - } - }); - } - @override void initState() { super.initState(); init(); } + void init() { + WidgetsBinding.instance.addPostFrameCallback((_) { + isInit = false; + }); + } + @override Widget build(BuildContext context) { + Widget child = super.build(context); if (isInit) { - return const CustomScrollView( - physics: NeverScrollableScrollPhysics(), + return Stack( + children: [ + const CustomScrollView( + physics: NeverScrollableScrollPhysics(), + ), + child, + ], ); } - - return super.build(context); + return child; } } diff --git a/lib/pages/dynamics_create/view.dart b/lib/pages/dynamics_create/view.dart index 9dbdf31d2..254250bb8 100644 --- a/lib/pages/dynamics_create/view.dart +++ b/lib/pages/dynamics_create/view.dart @@ -590,17 +590,18 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { } final color = theme.colorScheme.onSurfaceVariant; + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + maxCrossAxisExtent: 65, + mainAxisSpacing: 12, + crossAxisSpacing: 12, + mainAxisExtent: 25, + ); return SizedBox( height: height, child: GridView( padding: const EdgeInsets.only(left: 12, bottom: 12, right: 12), - gridDelegate: SliverGridDelegateWithExtentAndRatio( - maxCrossAxisExtent: 65, - mainAxisSpacing: 12, - crossAxisSpacing: 12, - mainAxisExtent: 25, - ), + gridDelegate: gridDelegate, children: [ item( onTap: _onReserve, diff --git a/lib/pages/dynamics_tab/view.dart b/lib/pages/dynamics_tab/view.dart index baae7b24c..acef254fd 100644 --- a/lib/pages/dynamics_tab/view.dart +++ b/lib/pages/dynamics_tab/view.dart @@ -105,7 +105,7 @@ class _DynamicsTabPageState response?.isNotEmpty == true ? GlobalData().dynamicsWaterfallFlow ? SliverWaterfallFlow( - gridDelegate: gridDelegate, + gridDelegate: dynGridDelegate, delegate: SliverChildBuilderDelegate( (_, index) { if (index == response.length - 1) { @@ -147,9 +147,7 @@ class _DynamicsTabPageState const SliverFillRemaining(), ], ) - : HttpError( - onReload: controller.onReload, - ), + : HttpError(onReload: controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: controller.onReload, diff --git a/lib/pages/dynamics_topic/view.dart b/lib/pages/dynamics_topic/view.dart index 321d6b6f8..68a3058ef 100644 --- a/lib/pages/dynamics_topic/view.dart +++ b/lib/pages/dynamics_topic/view.dart @@ -351,7 +351,7 @@ class _DynTopicPageState extends State with DynMixin { response?.isNotEmpty == true ? GlobalData().dynamicsWaterfallFlow ? SliverWaterfallFlow( - gridDelegate: gridDelegate, + gridDelegate: dynGridDelegate, delegate: SliverChildBuilderDelegate( (_, index) { if (index == response.length - 1) { diff --git a/lib/pages/episode_panel/view.dart b/lib/pages/episode_panel/view.dart index 5de77d300..45f36027e 100644 --- a/lib/pages/episode_panel/view.dart +++ b/lib/pages/episode_panel/view.dart @@ -168,6 +168,18 @@ class _EpisodePanelState extends CommonCollapseSlidePageState { _currentItemIndex = _findCurrentItemIndex; } + @override + void init() { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) { + isInit = false; + _itemScrollController[widget.initialTabIndex].jumpTo( + index: _currentItemIndex, + ); + } + }); + } + @override void dispose() { _tabController @@ -249,51 +261,49 @@ class _EpisodePanelState extends CommonCollapseSlidePageState { final isCurrTab = tabIndex == widget.initialTabIndex; return KeepAliveWrapper( builder: (context) => ScrollablePositionedList.separated( + key: PageStorageKey(tabIndex), padding: EdgeInsets.only( top: 7, bottom: MediaQuery.paddingOf(context).bottom + 80, ), reverse: _isReversed[tabIndex], itemCount: episodes.length, - initialScrollIndex: isCurrTab ? _currentItemIndex : 0, physics: const AlwaysScrollableScrollPhysics(), itemBuilder: (BuildContext context, int itemIndex) { final episode = episodes[itemIndex]; + final isCurrItem = isCurrTab ? itemIndex == _currentItemIndex : false; Widget episodeItem = _buildEpisodeItem( theme: theme, episode: episode, index: itemIndex, length: episodes.length, - isCurrentIndex: isCurrTab ? itemIndex == _currentItemIndex : false, + isCurrentIndex: isCurrItem, ); - return widget.type == EpisodeType.season && - widget.showTitle && - episode.pages.length > 1 - ? Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - episodeItem, - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 5, - ), - child: PagesPanel( - list: - widget.initialTabIndex == _currentTabIndex.value && - itemIndex == _currentItemIndex - ? null - : episode.pages, - cover: episode.arc?.pic, - heroTag: widget.heroTag, - ugcIntroController: widget.ugcIntroController!, - bvid: IdUtils.av2bv(episode.aid), - ), - ), - ], - ) - : episodeItem; + if (widget.type == EpisodeType.season && + widget.showTitle && + episode.pages.length > 1) { + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + episodeItem, + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 5, + ), + child: PagesPanel( + list: isCurrTab && isCurrItem ? null : episode.pages, + cover: episode.arc?.pic, + heroTag: widget.heroTag, + ugcIntroController: widget.ugcIntroController!, + bvid: IdUtils.av2bv(episode.aid), + ), + ), + ], + ); + } + return episodeItem; }, itemScrollController: _itemScrollController[tabIndex], separatorBuilder: (context, index) => const SizedBox(height: 2), diff --git a/lib/pages/fan/view.dart b/lib/pages/fan/view.dart index 9bc746dac..dfafb685e 100644 --- a/lib/pages/fan/view.dart +++ b/lib/pages/fan/view.dart @@ -77,82 +77,73 @@ class _FansPageState extends State { ); } + late final gridDelegate = SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: Grid.smallCardWidth * 2, + mainAxisExtent: 66, + ); + Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: Grid.smallCardWidth * 2, - mainAxisExtent: 66, - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const MsgFeedTopSkeleton(); - }, - childCount: 16, - ), + Loading() => SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) => const MsgFeedTopSkeleton(), + itemCount: 16, ), Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: Grid.smallCardWidth * 2, - mainAxisExtent: 66, - ), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - if (index == response.length - 1) { - _fansController.onLoadMore(); - } - final item = response[index]; - return ListTile( - onTap: () { - if (widget.onSelect != null) { - widget.onSelect!( - UserModel( - mid: item.mid!, - name: item.uname!, - avatar: item.face!, - ), - ); - return; - } - Get.toNamed('/member?mid=${item.mid}'); - }, - onLongPress: widget.onSelect != null - ? null - : isOwner - ? () => showConfirmDialog( - context: context, - title: '确定移除 ${item.uname} ?', - onConfirm: () => - _fansController.onRemoveFan(index, item.mid!), - ) - : null, - leading: NetworkImgLayer( - width: 45, - height: 45, - type: ImageType.avatar, - src: item.face, - ), - title: Text( - item.uname!, - style: const TextStyle(fontSize: 14), - ), - subtitle: Text( - item.sign ?? '', - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - dense: true, - trailing: const SizedBox(width: 6), - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _fansController.onLoadMore(); + } + final item = response[index]; + return ListTile( + onTap: () { + if (widget.onSelect != null) { + widget.onSelect!( + UserModel( + mid: item.mid!, + name: item.uname!, + avatar: item.face!, + ), + ); + return; + } + Get.toNamed('/member?mid=${item.mid}'); + }, + onLongPress: widget.onSelect != null + ? null + : isOwner + ? () => showConfirmDialog( + context: context, + title: '确定移除 ${item.uname} ?', + onConfirm: () => + _fansController.onRemoveFan(index, item.mid!), + ) + : null, + leading: NetworkImgLayer( + width: 45, + height: 45, + type: ImageType.avatar, + src: item.face, + ), + title: Text( + item.uname!, + style: const TextStyle(fontSize: 14), + ), + subtitle: Text( + item.sign ?? '', + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + dense: true, + trailing: const SizedBox(width: 6), + ); + }, + itemCount: response!.length, ) - : HttpError( - onReload: _fansController.onReload, - ), + : HttpError(onReload: _fansController.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _fansController.onReload, diff --git a/lib/pages/fav/article/view.dart b/lib/pages/fav/article/view.dart index c6f7a9269..ec6bde068 100644 --- a/lib/pages/fav/article/view.dart +++ b/lib/pages/fav/article/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/dialog/dialog.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; @@ -18,7 +17,7 @@ class FavArticlePage extends StatefulWidget { } class _FavArticlePageState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { final FavArticleController _favArticleController = Get.put( FavArticleController(), ); @@ -51,37 +50,27 @@ class _FavArticlePageState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _favArticleController.onLoadMore(); - } - final item = response[index]; - return FavArticleItem( - item: item, - onDelete: () => showConfirmDialog( - context: context, - title: '确定取消收藏?', - onConfirm: () => - _favArticleController.onRemove(index, item.opusId), - ), - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _favArticleController.onLoadMore(); + } + final item = response[index]; + return FavArticleItem( + item: item, + onDelete: () => showConfirmDialog( + context: context, + title: '确定取消收藏?', + onConfirm: () => + _favArticleController.onRemove(index, item.opusId), + ), + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _favArticleController.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/fav/cheese/view.dart b/lib/pages/fav/cheese/view.dart index 28a2baf71..ebfe6f43b 100644 --- a/lib/pages/fav/cheese/view.dart +++ b/lib/pages/fav/cheese/view.dart @@ -1,6 +1,5 @@ import 'package:PiliPlus/common/widgets/dialog/dialog.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; -import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models_new/space/space_cheese/item.dart'; @@ -18,7 +17,7 @@ class FavCheesePage extends StatefulWidget { } class _FavCheesePageState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { final FavCheeseController _controller = Get.put(FavCheeseController()); @override @@ -53,29 +52,27 @@ class _FavCheesePageState extends State LoadingState?> loadingState, ) { return switch (loadingState) { - Loading() => linearLoading, + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - final item = response[index]; - return MemberCheeseItem( - item: item, - onRemove: () => showConfirmDialog( - context: context, - title: '确定取消收藏该课堂?', - onConfirm: () => - _controller.onRemove(index, item.seasonId), - ), - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + final item = response[index]; + return MemberCheeseItem( + item: item, + onRemove: () => showConfirmDialog( + context: context, + title: '确定取消收藏该课堂?', + onConfirm: () => + _controller.onRemove(index, item.seasonId), + ), + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/fav/note/child_view.dart b/lib/pages/fav/note/child_view.dart index 3b662f0da..64c43cf92 100644 --- a/lib/pages/fav/note/child_view.dart +++ b/lib/pages/fav/note/child_view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/button/icon_button.dart'; import 'package:PiliPlus/common/widgets/dialog/dialog.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; @@ -21,7 +20,7 @@ class FavNoteChildPage extends StatefulWidget { } class _FavNoteChildPageState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { late final FavNoteController _favNoteController = Get.put( FavNoteController(widget.isPublish), tag: '${widget.isPublish}', @@ -141,33 +140,23 @@ class _FavNoteChildPageState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _favNoteController.onLoadMore(); - } - final item = response[index]; - return FavNoteItem( - item: item, - ctr: _favNoteController, - onSelect: () => _favNoteController.onSelect(item), - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _favNoteController.onLoadMore(); + } + final item = response[index]; + return FavNoteItem( + item: item, + ctr: _favNoteController, + onSelect: () => _favNoteController.onSelect(item), + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _favNoteController.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/fav/pgc/child_view.dart b/lib/pages/fav/pgc/child_view.dart index a1a5ab46b..9963db461 100644 --- a/lib/pages/fav/pgc/child_view.dart +++ b/lib/pages/fav/pgc/child_view.dart @@ -26,7 +26,7 @@ class FavPgcChildPage extends StatefulWidget { } class _FavPgcChildPageState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { late final FavPgcController _favPgcController = Get.put( FavPgcController(widget.type, widget.followStatus), tag: '${widget.type}${widget.followStatus}', @@ -165,52 +165,46 @@ class _FavPgcChildPageState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const FavPgcItemSkeleton(); - }, - childCount: 10, - ), + Loading() => SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) => const FavPgcItemSkeleton(), + itemCount: 10, ), Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _favPgcController.onLoadMore(); - } - final item = response[index]; - return FavPgcItem( - item: item, - ctr: _favPgcController, - onSelect: () => _favPgcController.onSelect(item), - onUpdateStatus: () => showPgcFollowDialog( - context: context, - type: widget.type == 0 ? '追番' : '追剧', - followStatus: widget.followStatus, - onUpdateStatus: (followStatus) { - if (followStatus == -1) { - _favPgcController.pgcDel( - index, - item.seasonId, - ); - } else { - _favPgcController.onUpdate( - index, - followStatus, - item.seasonId, - ); - } - }, - ), - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _favPgcController.onLoadMore(); + } + final item = response[index]; + return FavPgcItem( + item: item, + ctr: _favPgcController, + onSelect: () => _favPgcController.onSelect(item), + onUpdateStatus: () => showPgcFollowDialog( + context: context, + type: widget.type == 0 ? '追番' : '追剧', + followStatus: widget.followStatus, + onUpdateStatus: (followStatus) { + if (followStatus == -1) { + _favPgcController.pgcDel( + index, + item.seasonId, + ); + } else { + _favPgcController.onUpdate( + index, + followStatus, + item.seasonId, + ); + } + }, + ), + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _favPgcController.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/fav/topic/view.dart b/lib/pages/fav/topic/view.dart index a5860ee7c..adfb04605 100644 --- a/lib/pages/fav/topic/view.dart +++ b/lib/pages/fav/topic/view.dart @@ -49,6 +49,13 @@ class _FavTopicPageState extends State ); } + late final gridDelegate = SliverGridDelegateWithMaxCrossAxisExtent( + mainAxisSpacing: 12, + crossAxisSpacing: 12, + maxCrossAxisExtent: Grid.smallCardWidth, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(30), + ); + Widget _buildBody( ThemeData theme, LoadingState?> loadingState, @@ -64,61 +71,54 @@ class _FavTopicPageState extends State ), Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - mainAxisSpacing: 12, - crossAxisSpacing: 12, - maxCrossAxisExtent: Grid.smallCardWidth, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(30), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - final item = response[index]; - return Material( - color: theme.colorScheme.onInverseSurface, - borderRadius: const BorderRadius.all(Radius.circular(6)), - child: InkWell( - onTap: () => Get.toNamed( - '/dynTopic', - parameters: { - 'id': item.id!.toString(), - 'name': item.name!, - }, + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + final item = response[index]; + return Material( + color: theme.colorScheme.onInverseSurface, + borderRadius: const BorderRadius.all(Radius.circular(6)), + child: InkWell( + onTap: () => Get.toNamed( + '/dynTopic', + parameters: { + 'id': item.id!.toString(), + 'name': item.name!, + }, + ), + onLongPress: () => showConfirmDialog( + context: context, + title: '确定取消收藏?', + onConfirm: () { + _controller.onRemove(index, item.id); + }, + ), + borderRadius: const BorderRadius.all( + Radius.circular(6), + ), + child: Container( + alignment: Alignment.centerLeft, + padding: const EdgeInsets.symmetric( + horizontal: 11, + vertical: 5, ), - onLongPress: () => showConfirmDialog( - context: context, - title: '确定取消收藏?', - onConfirm: () { - _controller.onRemove(index, item.id); - }, - ), - borderRadius: const BorderRadius.all( - Radius.circular(6), - ), - child: Container( - alignment: Alignment.centerLeft, - padding: const EdgeInsets.symmetric( - horizontal: 11, - vertical: 5, - ), - child: Text( - '# ${item.name}', - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - fontSize: 14, - color: theme.colorScheme.onSurfaceVariant, - ), + child: Text( + '# ${item.name}', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 14, + color: theme.colorScheme.onSurfaceVariant, ), ), ), - ); - }, - childCount: response!.length, - ), + ), + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/fav/video/view.dart b/lib/pages/fav/video/view.dart index 372706b9a..9fff2b95e 100644 --- a/lib/pages/fav/video/view.dart +++ b/lib/pages/fav/video/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; @@ -18,7 +17,7 @@ class FavVideoPage extends StatefulWidget { } class _FavVideoPageState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { final FavController _favController = Get.find(); @override @@ -49,52 +48,40 @@ class _FavVideoPageState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - childCount: response!.length, - (BuildContext context, int index) { - if (index == response.length - 1) { - _favController.onLoadMore(); - } - final item = response[index]; - String heroTag = Utils.makeHeroTag(item.fid); - return FavVideoItem( - heroTag: heroTag, - item: item, - onTap: () async { - var res = await Get.toNamed( - '/favDetail', - arguments: item, - parameters: { - 'heroTag': heroTag, - 'mediaId': item.id.toString(), - }, - ); - if (res == true) { - _favController.loadingState - ..value.data!.removeAt(index) - ..refresh(); - } - }, - ); - }, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (BuildContext context, int index) { + if (index == response.length - 1) { + _favController.onLoadMore(); + } + final item = response[index]; + String heroTag = Utils.makeHeroTag(item.fid); + return FavVideoItem( + heroTag: heroTag, + item: item, + onTap: () async { + var res = await Get.toNamed( + '/favDetail', + arguments: item, + parameters: { + 'heroTag': heroTag, + 'mediaId': item.id.toString(), + }, + ); + if (res == true) { + _favController.loadingState + ..value.data!.removeAt(index) + ..refresh(); + } + }, + ); + }, + itemCount: response!.length, ) - : HttpError( - onReload: _favController.onReload, - ), + : HttpError(onReload: _favController.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _favController.onReload, diff --git a/lib/pages/fav_detail/view.dart b/lib/pages/fav_detail/view.dart index 45d91c4f6..a3f44651c 100644 --- a/lib/pages/fav_detail/view.dart +++ b/lib/pages/fav_detail/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/button/icon_button.dart'; import 'package:PiliPlus/common/widgets/dialog/dialog.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; @@ -28,7 +27,7 @@ class FavDetailPage extends StatefulWidget { State createState() => _FavDetailPageState(); } -class _FavDetailPageState extends State { +class _FavDetailPageState extends State with GridMixin { late final FavDetailController _favDetailController = Get.put( FavDetailController(), tag: Utils.makeHeroTag(mediaId), @@ -335,6 +334,7 @@ class _FavDetailPageState extends State { Widget _flexibleSpace(ThemeData theme) { final style = TextStyle( + height: 1, fontSize: 12.5, color: theme.colorScheme.outline, ); @@ -397,14 +397,15 @@ class _FavDetailPageState extends State { if (folderInfo.title.isNotEmpty) Expanded( child: Column( - spacing: 4, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - folderInfo.title, - style: TextStyle( - fontSize: theme.textTheme.titleMedium!.fontSize, - fontWeight: FontWeight.bold, + Expanded( + child: Text( + folderInfo.title, + style: TextStyle( + fontSize: theme.textTheme.titleMedium!.fontSize, + fontWeight: FontWeight.bold, + ), ), ), GestureDetector( @@ -418,22 +419,20 @@ class _FavDetailPageState extends State { ), ), ), - if (folderInfo.intro?.isNotEmpty == true) + const SizedBox(height: 4), + if (folderInfo.intro?.isNotEmpty == true) ...[ Text( folderInfo.intro!, style: style, maxLines: 2, overflow: TextOverflow.ellipsis, ), - Expanded( - child: Align( - alignment: Alignment.bottomLeft, - child: Text( - '共${folderInfo.mediaCount}条视频 · ${FavUtil.isPublicFavText(folderInfo.attr)}', - textAlign: TextAlign.end, - style: style, - ), - ), + const SizedBox(height: 4), + ], + Text( + '共${folderInfo.mediaCount}条视频 · ' + '${FavUtil.isPublicFavText(folderInfo.attr)}', + style: style, ), ], ), @@ -453,48 +452,36 @@ class _FavDetailPageState extends State { LoadingState?> loadingState, ) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length) { - _favDetailController.onLoadMore(); - return Container( - height: 60, - alignment: Alignment.center, - child: Text( - _favDetailController.isEnd ? '没有更多了' : '加载中...', - style: TextStyle( - color: theme.colorScheme.outline, - fontSize: 13, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length) { + _favDetailController.onLoadMore(); + return Container( + height: 60, + alignment: Alignment.center, + child: Text( + _favDetailController.isEnd ? '没有更多了' : '加载中...', + style: TextStyle( + color: theme.colorScheme.outline, + fontSize: 13, ), - ); - } - FavDetailItemModel item = response[index]; - return FavVideoCardH( - item: item, - index: index, - ctr: _favDetailController, + ), ); - }, - childCount: response!.length + 1, - ), + } + FavDetailItemModel item = response[index]; + return FavVideoCardH( + item: item, + index: index, + ctr: _favDetailController, + ); + }, + itemCount: response!.length + 1, ) - : HttpError( - onReload: _favDetailController.onReload, - ), + : HttpError(onReload: _favDetailController.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _favDetailController.onReload, diff --git a/lib/pages/fav_search/view.dart b/lib/pages/fav_search/view.dart index 759a851fe..09b86fc81 100644 --- a/lib/pages/fav_search/view.dart +++ b/lib/pages/fav_search/view.dart @@ -54,24 +54,24 @@ class _FavSearchPageState ), ]; + late final gridDelegate = Grid.videoCardHDelegate(context, minHeight: 110); + @override Widget buildList(List list) { - return SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context, minHeight: 110), - delegate: SliverChildBuilderDelegate( - childCount: list.length, - (context, index) { - if (index == list.length - 1) { - controller.onLoadMore(); - } - final item = list[index]; - return FavVideoCardH( - item: item, - index: index, - ctr: controller, - ); - }, - ), + return SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == list.length - 1) { + controller.onLoadMore(); + } + final item = list[index]; + return FavVideoCardH( + item: item, + index: index, + ctr: controller, + ); + }, + itemCount: list.length, ); } } diff --git a/lib/pages/follow/child/child_view.dart b/lib/pages/follow/child/child_view.dart index eaf177200..dbc4ed85f 100644 --- a/lib/pages/follow/child/child_view.dart +++ b/lib/pages/follow/child/child_view.dart @@ -88,9 +88,7 @@ class _FollowChildPageState extends State return switch (loadingState) { Loading() => SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const MsgFeedTopSkeleton(); - }, + itemBuilder: (context, index) => const MsgFeedTopSkeleton(), ), Success(:var response) => response?.isNotEmpty == true diff --git a/lib/pages/history/view.dart b/lib/pages/history/view.dart index 32185dbc5..1eb115cce 100644 --- a/lib/pages/history/view.dart +++ b/lib/pages/history/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/appbar/appbar.dart'; import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; @@ -24,7 +23,7 @@ class HistoryPage extends StatefulWidget { } class _HistoryPageState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { late final _historyController = Get.put( HistoryController(widget.type), tag: widget.type ?? 'all', @@ -217,34 +216,24 @@ class _HistoryPageState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _historyController.onLoadMore(); - } - final item = response[index]; - return HistoryItem( - item: item, - ctr: _historyController, - onDelete: (kid, business) => - _historyController.delHistory(item), - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _historyController.onLoadMore(); + } + final item = response[index]; + return HistoryItem( + item: item, + ctr: _historyController, + onDelete: (kid, business) => + _historyController.delHistory(item), + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _historyController.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/history_search/view.dart b/lib/pages/history_search/view.dart index 8b44c5b95..e7b4a78fd 100644 --- a/lib/pages/history_search/view.dart +++ b/lib/pages/history_search/view.dart @@ -28,25 +28,25 @@ class _HistorySearchPageState tag: Utils.generateRandomString(8), ); + late final gridDelegate = Grid.videoCardHDelegate(context, minHeight: 110); + @override Widget buildList(List list) { - return SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context, minHeight: 110), - delegate: SliverChildBuilderDelegate( - childCount: list.length, - (context, index) { - if (index == list.length - 1) { - controller.onLoadMore(); - } - final item = list[index]; - return HistoryItem( - item: item, - ctr: controller, - onDelete: (kid, business) => - controller.onDelHistory(index, kid, business), - ); - }, - ), + return SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == list.length - 1) { + controller.onLoadMore(); + } + final item = list[index]; + return HistoryItem( + item: item, + ctr: controller, + onDelete: (kid, business) => + controller.onDelHistory(index, kid, business), + ); + }, + itemCount: list.length, ); } } diff --git a/lib/pages/hot/view.dart b/lib/pages/hot/view.dart index 1d8652f80..d5de2b462 100644 --- a/lib/pages/hot/view.dart +++ b/lib/pages/hot/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/common/widgets/video_card/video_card_h.dart'; @@ -23,7 +22,7 @@ class HotPage extends CommonPage { } class _HotPageState extends CommonPageState - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { @override HotController controller = Get.put(HotController()); @@ -149,43 +148,27 @@ class _HotPageState extends CommonPageState ); } - Widget _buildSkeleton() { - return SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ); - } - Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => _buildSkeleton(), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - controller.onLoadMore(); - } - return VideoCardH( - videoItem: response[index], - onRemove: () => controller.loadingState - ..value.data!.removeAt(index) - ..refresh(), - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + controller.onLoadMore(); + } + return VideoCardH( + videoItem: response[index], + onRemove: () => controller.loadingState + ..value.data!.removeAt(index) + ..refresh(), + ); + }, + itemCount: response!.length, ) - : HttpError( - onReload: controller.onReload, - ), + : HttpError(onReload: controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: controller.onReload, diff --git a/lib/pages/later/child_view.dart b/lib/pages/later/child_view.dart index ddca2e23e..eb943e132 100644 --- a/lib/pages/later/child_view.dart +++ b/lib/pages/later/child_view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; @@ -25,7 +24,7 @@ class LaterViewChildPage extends StatefulWidget { } class _LaterViewChildPageState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { late final LaterController _laterController = Get.put( LaterController(widget.laterViewType), tag: widget.laterViewType.type.toString(), @@ -56,56 +55,44 @@ class _LaterViewChildPageState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _laterController.onLoadMore(); - } - var videoItem = response[index]; - return VideoCardHLater( - index: index, - videoItem: videoItem, - ctr: _laterController, - onViewLater: (cid) { - PageUtils.toVideoPage( - bvid: videoItem.bvid, - cid: cid, - cover: videoItem.pic, - title: videoItem.title, - extraArguments: { - 'oid': videoItem.aid, - 'sourceType': SourceType.watchLater, - 'count': _laterController - .baseCtr - .counts[LaterViewType.all], - 'favTitle': '稍后再看', - 'mediaId': _laterController.accountService.mid, - 'desc': false, - 'isContinuePlaying': index != 0, - }, - ); - }, - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _laterController.onLoadMore(); + } + var videoItem = response[index]; + return VideoCardHLater( + index: index, + videoItem: videoItem, + ctr: _laterController, + onViewLater: (cid) { + PageUtils.toVideoPage( + bvid: videoItem.bvid, + cid: cid, + cover: videoItem.pic, + title: videoItem.title, + extraArguments: { + 'oid': videoItem.aid, + 'sourceType': SourceType.watchLater, + 'count': _laterController + .baseCtr + .counts[LaterViewType.all], + 'favTitle': '稍后再看', + 'mediaId': _laterController.accountService.mid, + 'desc': false, + 'isContinuePlaying': index != 0, + }, + ); + }, + ); + }, + itemCount: response!.length, ) - : HttpError( - onReload: _laterController.onReload, - ), + : HttpError(onReload: _laterController.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _laterController.onReload, diff --git a/lib/pages/later_search/view.dart b/lib/pages/later_search/view.dart index 27beb1da7..772e27721 100644 --- a/lib/pages/later_search/view.dart +++ b/lib/pages/later_search/view.dart @@ -25,14 +25,13 @@ class _LaterSearchPageState tag: Utils.generateRandomString(8), ); + late final gridDelegate = Grid.videoCardHDelegate(context, minHeight: 110); + @override Widget buildList(List list) { - return SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context, minHeight: 110), - delegate: SliverChildBuilderDelegate(childCount: list.length, ( - context, - index, - ) { + return SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { if (index == list.length - 1) { controller.onLoadMore(); } @@ -59,7 +58,8 @@ class _LaterSearchPageState ); }, ); - }), + }, + itemCount: list.length, ); } } diff --git a/lib/pages/live/view.dart b/lib/pages/live/view.dart index 1a844d244..7d008e58d 100644 --- a/lib/pages/live/view.dart +++ b/lib/pages/live/view.dart @@ -138,22 +138,20 @@ class _LivePageState extends CommonPageState ); } + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), + ); + Widget _buildBody(ThemeData theme, LoadingState loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardVSkeleton(); - }, - childCount: 10, - ), + Loading() => SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) => const VideoCardVSkeleton(), + itemCount: 10, ), Success(:var response) => SliverMainAxisGroup( slivers: [ @@ -194,29 +192,21 @@ class _LivePageState extends CommonPageState ), ), response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - controller.onLoadMore(); - } - final item = response[index]; - if (item is LiveCardList) { - return LiveCardVApp( - item: item.cardData!.smallCardV1!, - ); - } - return LiveCardVApp(item: item); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + controller.onLoadMore(); + } + final item = response[index]; + if (item is LiveCardList) { + return LiveCardVApp( + item: item.cardData!.smallCardV1!, + ); + } + return LiveCardVApp(item: item); + }, + itemCount: response!.length, ) : HttpError(onReload: controller.onReload), ], diff --git a/lib/pages/live_area_detail/child/view.dart b/lib/pages/live_area_detail/child/view.dart index 15f983cd3..90a22dc1f 100644 --- a/lib/pages/live_area_detail/child/view.dart +++ b/lib/pages/live_area_detail/child/view.dart @@ -59,25 +59,23 @@ class _LiveAreaChildPageState extends State ); } + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), + ); + Widget _buildBody( ThemeData theme, LoadingState?> loadingState, ) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardVSkeleton(); - }, - childCount: 10, - ), + Loading() => SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) => const VideoCardVSkeleton(), + itemCount: 10, ), Success(:var response) => SliverMainAxisGroup( slivers: [ @@ -120,27 +118,17 @@ class _LiveAreaChildPageState extends State ), ), response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return LiveCardVApp(item: response[index]); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return LiveCardVApp(item: response[index]); + }, + itemCount: response!.length, ) - : HttpError( - onReload: _controller.onReload, - ), + : HttpError(onReload: _controller.onReload), ], ), Error(:var errMsg) => HttpError( diff --git a/lib/pages/live_follow/view.dart b/lib/pages/live_follow/view.dart index afa2554b7..9f7675086 100644 --- a/lib/pages/live_follow/view.dart +++ b/lib/pages/live_follow/view.dart @@ -54,44 +54,34 @@ class _LiveFollowPageState extends State { ); } + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), + ); + Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardVSkeleton(); - }, - childCount: 10, - ), + Loading() => SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) => const VideoCardVSkeleton(), + itemCount: 10, ), Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return LiveCardVFollow( - liveItem: response[index], - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return LiveCardVFollow( + liveItem: response[index], + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/live_search/child/view.dart b/lib/pages/live_search/child/view.dart index eec861a20..e57fe7b0e 100644 --- a/lib/pages/live_search/child/view.dart +++ b/lib/pages/live_search/child/view.dart @@ -54,36 +54,32 @@ class _LiveSearchChildPageState extends State Widget get _buildLoading { return switch (widget.searchType) { - LiveSearchType.room => SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardVSkeleton(); - }, - childCount: 10, - ), + LiveSearchType.room => SliverGrid.builder( + gridDelegate: roomDelegate, + itemBuilder: (context, index) => const VideoCardVSkeleton(), + itemCount: 10, ), - LiveSearchType.user => SliverGrid( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: Grid.smallCardWidth * 2, - mainAxisExtent: 60, - ), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - return const MsgFeedTopSkeleton(); - }, - childCount: 12, - ), + LiveSearchType.user => SliverGrid.builder( + gridDelegate: userDelegate, + itemBuilder: (context, index) => const MsgFeedTopSkeleton(), + itemCount: 12, ), }; } + late final roomDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(60), + ); + + late final userDelegate = SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: Grid.smallCardWidth * 2, + mainAxisExtent: 60, + ); + Widget _buildBody(LoadingState loadingState) { return switch (loadingState) { Loading() => _buildLoading, @@ -92,51 +88,34 @@ class _LiveSearchChildPageState extends State ? Builder( builder: (context) { return switch (widget.searchType) { - LiveSearchType.room => SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf( - context, - ).scale(60), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return LiveCardVSearch( - item: response[index], - ); - }, - childCount: response!.length, - ), + LiveSearchType.room => SliverGrid.builder( + gridDelegate: roomDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return LiveCardVSearch( + item: response[index], + ); + }, + itemCount: response!.length, ), - LiveSearchType.user => SliverGrid( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: Grid.smallCardWidth * 2, - mainAxisExtent: 60, - ), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return LiveSearchUserItem( - item: response[index], - ); - }, - childCount: response!.length, - ), + LiveSearchType.user => SliverGrid.builder( + gridDelegate: userDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return LiveSearchUserItem( + item: response[index], + ); + }, + itemCount: response!.length, ), }; }, ) - : HttpError( - onReload: _controller.onReload, - ), + : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _controller.onReload, diff --git a/lib/pages/member_article/view.dart b/lib/pages/member_article/view.dart index fe937c0f0..ed7a3ec41 100644 --- a/lib/pages/member_article/view.dart +++ b/lib/pages/member_article/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; @@ -24,7 +23,7 @@ class MemberArticle extends StatefulWidget { } class _MemberArticleState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { @override bool get wantKeepAlive => true; @@ -55,34 +54,22 @@ class _MemberArticleState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return MemberArticleItem( - item: response[index], - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return MemberArticleItem( + item: response[index], + ); + }, + itemCount: response!.length, ) - : HttpError( - onReload: _controller.onReload, - ), + : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _controller.onReload, diff --git a/lib/pages/member_audio/view.dart b/lib/pages/member_audio/view.dart index 243ff754c..f5dd0bae0 100644 --- a/lib/pages/member_audio/view.dart +++ b/lib/pages/member_audio/view.dart @@ -53,29 +53,29 @@ class _MemberAudioState extends State @override bool get wantKeepAlive => true; + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: 2, + maxCrossAxisExtent: Grid.smallCardWidth * 2, + childAspectRatio: StyleString.aspectRatio * 2.6, + minHeight: MediaQuery.textScalerOf(context).scale(90), + ); + Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { Loading() => linearLoading, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: 2, - maxCrossAxisExtent: Grid.smallCardWidth * 2, - childAspectRatio: StyleString.aspectRatio * 2.6, - minHeight: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return MemberAudioItem( - item: response[index], - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return MemberAudioItem( + item: response[index], + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/member_cheese/view.dart b/lib/pages/member_cheese/view.dart index 92884e1a1..21c7e1e31 100644 --- a/lib/pages/member_cheese/view.dart +++ b/lib/pages/member_cheese/view.dart @@ -1,5 +1,4 @@ import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; -import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models_new/space/space_cheese/item.dart'; @@ -24,7 +23,7 @@ class MemberCheese extends StatefulWidget { } class _MemberCheeseState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { late final _controller = Get.put( MemberCheeseController(widget.mid), tag: widget.heroTag, @@ -55,20 +54,18 @@ class _MemberCheeseState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => linearLoading, + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return MemberCheeseItem(item: response[index]); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return MemberCheeseItem(item: response[index]); + }, + itemCount: response!.length, ) : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/member_coin_arc/view.dart b/lib/pages/member_coin_arc/view.dart index c8002d613..a3de2fd3c 100644 --- a/lib/pages/member_coin_arc/view.dart +++ b/lib/pages/member_coin_arc/view.dart @@ -66,31 +66,25 @@ class _MemberCoinArcPageState extends State { ); } + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(75), + ); + Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { Loading() => SliverGrid.builder( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), + gridDelegate: gridDelegate, itemCount: 16, - itemBuilder: (context, index) { - return const VideoCardVSkeleton(); - }, + itemBuilder: (context, index) => const VideoCardVSkeleton(), ), Success(:var response) => response?.isNotEmpty == true ? SliverGrid.builder( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(75), - ), + gridDelegate: gridDelegate, itemCount: response!.length, itemBuilder: (context, index) { if (index == response.length - 1) { diff --git a/lib/pages/member_comic/view.dart b/lib/pages/member_comic/view.dart index 7a3fe9062..e49b25560 100644 --- a/lib/pages/member_comic/view.dart +++ b/lib/pages/member_comic/view.dart @@ -1,5 +1,4 @@ import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; -import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models_new/space/space_archive/item.dart'; @@ -24,7 +23,7 @@ class MemberComic extends StatefulWidget { } class _MemberComicState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { late final _controller = Get.put( MemberComicController(widget.mid), tag: widget.heroTag, @@ -51,20 +50,18 @@ class _MemberComicState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => linearLoading, + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return MemberComicItem(item: response[index]); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return MemberComicItem(item: response[index]); + }, + itemCount: response!.length, ) : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/member_dynamics/view.dart b/lib/pages/member_dynamics/view.dart index 2ac71e77f..350d866dc 100644 --- a/lib/pages/member_dynamics/view.dart +++ b/lib/pages/member_dynamics/view.dart @@ -79,7 +79,7 @@ class _MemberDynamicsPageState extends State response?.isNotEmpty == true ? GlobalData().dynamicsWaterfallFlow ? SliverWaterfallFlow( - gridDelegate: gridDelegate, + gridDelegate: dynGridDelegate, delegate: SliverChildBuilderDelegate( (_, index) { if (index == response.length - 1) { @@ -118,9 +118,7 @@ class _MemberDynamicsPageState extends State const SliverFillRemaining(), ], ) - : HttpError( - onReload: _memberDynamicController.onReload, - ), + : HttpError(onReload: _memberDynamicController.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _memberDynamicController.onReload, diff --git a/lib/pages/member_favorite/view.dart b/lib/pages/member_favorite/view.dart index cd1ce0620..d66edadd3 100644 --- a/lib/pages/member_favorite/view.dart +++ b/lib/pages/member_favorite/view.dart @@ -59,14 +59,10 @@ class _MemberFavoriteState extends State return switch (loadingState) { Loading() => SliverPadding( padding: const EdgeInsets.only(top: 7), - sliver: SliverGrid( + sliver: SliverGrid.builder( gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), + itemBuilder: (context, index) => const VideoCardHSkeleton(), + itemCount: 10, ), ), Success(:var response) => @@ -85,9 +81,7 @@ class _MemberFavoriteState extends State ), ], ) - : HttpError( - onReload: _controller.onReload, - ), + : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _controller.onReload, diff --git a/lib/pages/member_home/view.dart b/lib/pages/member_home/view.dart index 312e4971f..86ff14644 100644 --- a/lib/pages/member_home/view.dart +++ b/lib/pages/member_home/view.dart @@ -32,7 +32,7 @@ class MemberHome extends StatefulWidget { } class _MemberHomeState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { @override bool get wantKeepAlive => true; @@ -44,6 +44,29 @@ class _MemberHomeState extends State return _buildBody(_ctr.loadingState.value); } + late final gridDelegateV = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(55), + ); + + late final gridDelegateAudio = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: 2, + maxCrossAxisExtent: Grid.smallCardWidth * 2, + childAspectRatio: StyleString.aspectRatio * 2.6, + minHeight: MediaQuery.textScalerOf(context).scale(90), + ); + + late final gridDelegatePgc = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2, + childAspectRatio: 0.75, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(52), + ); + Widget _buildBody(LoadingState loadingState) { final isVertical = context.isPortrait; final setting = _ctr.spaceSetting; @@ -67,26 +90,16 @@ class _MemberHomeState extends State padding: const EdgeInsets.symmetric( horizontal: StyleString.safeSpace, ), - sliver: SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf( - context, - ).scale(55), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return VideoCardVMemberHome( - videoItem: res.archive!.item![index], - ); - }, - childCount: min( - isVertical ? 4 : 8, - res.archive!.item!.length, - ), + sliver: SliverGrid.builder( + gridDelegate: gridDelegateV, + itemBuilder: (context, index) { + return VideoCardVMemberHome( + videoItem: res.archive!.item![index], + ); + }, + itemCount: min( + isVertical ? 4 : 8, + res.archive!.item!.length, ), ), ), @@ -120,26 +133,16 @@ class _MemberHomeState extends State padding: const EdgeInsets.symmetric( horizontal: StyleString.safeSpace, ), - sliver: SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf( - context, - ).scale(55), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return VideoCardVMemberHome( - videoItem: res.coinArchive!.item![index], - ); - }, - childCount: min( - isVertical ? 2 : 4, - res.coinArchive!.item!.length, - ), + sliver: SliverGrid.builder( + gridDelegate: gridDelegateV, + itemBuilder: (context, index) { + return VideoCardVMemberHome( + videoItem: res.coinArchive!.item![index], + ); + }, + itemCount: min( + isVertical ? 2 : 4, + res.coinArchive!.item!.length, ), ), ), @@ -156,26 +159,16 @@ class _MemberHomeState extends State padding: const EdgeInsets.symmetric( horizontal: StyleString.safeSpace, ), - sliver: SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf( - context, - ).scale(55), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return VideoCardVMemberHome( - videoItem: res.likeArchive!.item![index], - ); - }, - childCount: min( - isVertical ? 2 : 4, - res.likeArchive!.item!.length, - ), + sliver: SliverGrid.builder( + gridDelegate: gridDelegateV, + itemBuilder: (context, index) { + return VideoCardVMemberHome( + videoItem: res.likeArchive!.item![index], + ); + }, + itemCount: min( + isVertical ? 2 : 4, + res.likeArchive!.item!.length, ), ), ), @@ -188,16 +181,14 @@ class _MemberHomeState extends State param1: 'opus', count: res.article!.count!, ), - SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return MemberArticleItem( - item: res.article!.item![index], - ); - }, - childCount: isVertical ? 1 : res.article!.item!.length, - ), + SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + return MemberArticleItem( + item: res.article!.item![index], + ); + }, + itemCount: isVertical ? 1 : res.article!.item!.length, ), ], if (res.audios?.item?.isNotEmpty == true) ...[ @@ -208,21 +199,14 @@ class _MemberHomeState extends State param1: 'audio', count: res.audios!.count!, ), - SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: 2, - maxCrossAxisExtent: Grid.smallCardWidth * 2, - childAspectRatio: StyleString.aspectRatio * 2.6, - minHeight: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return MemberAudioItem( - item: res.audios!.item![index], - ); - }, - childCount: isVertical ? 1 : min(2, res.audios!.count!), - ), + SliverGrid.builder( + gridDelegate: gridDelegateAudio, + itemBuilder: (context, index) { + return MemberAudioItem( + item: res.audios!.item![index], + ); + }, + itemCount: isVertical ? 1 : min(2, res.audios!.count!), ), ], if (res.comic?.item?.isNotEmpty == true) ...[ @@ -233,14 +217,12 @@ class _MemberHomeState extends State param1: 'comic', count: res.comic!.count!, ), - SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return MemberComicItem(item: res.comic!.item![index]); - }, - childCount: isVertical ? 1 : min(2, res.comic!.count!), - ), + SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + return MemberComicItem(item: res.comic!.item![index]); + }, + itemCount: isVertical ? 1 : min(2, res.comic!.count!), ), ], if (res.season?.item?.isNotEmpty == true) ...[ @@ -255,26 +237,16 @@ class _MemberHomeState extends State padding: const EdgeInsets.symmetric( horizontal: StyleString.safeSpace, ), - sliver: SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2, - childAspectRatio: 0.75, - mainAxisExtent: MediaQuery.textScalerOf( - context, - ).scale(52), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return PgcCardVMemberPgc( - item: res.season!.item![index], - ); - }, - childCount: min( - isVertical ? 3 : 6, - res.season!.item!.length, - ), + sliver: SliverGrid.builder( + gridDelegate: gridDelegatePgc, + itemBuilder: (context, index) { + return PgcCardVMemberPgc( + item: res.season!.item![index], + ); + }, + itemCount: min( + isVertical ? 3 : 6, + res.season!.item!.length, ), ), ), diff --git a/lib/pages/member_like_arc/view.dart b/lib/pages/member_like_arc/view.dart index d797f75b5..dd1e88a09 100644 --- a/lib/pages/member_like_arc/view.dart +++ b/lib/pages/member_like_arc/view.dart @@ -66,31 +66,25 @@ class _MemberLikeArcPageState extends State { ); } + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(75), + ); + Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { Loading() => SliverGrid.builder( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), + gridDelegate: gridDelegate, itemCount: 16, - itemBuilder: (context, index) { - return const VideoCardVSkeleton(); - }, + itemBuilder: (context, index) => const VideoCardVSkeleton(), ), Success(:var response) => response?.isNotEmpty == true ? SliverGrid.builder( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(75), - ), + gridDelegate: gridDelegate, itemCount: response!.length, itemBuilder: (context, index) { if (index == response.length - 1) { diff --git a/lib/pages/member_opus/view.dart b/lib/pages/member_opus/view.dart index 4c7584818..e3ccfefcb 100644 --- a/lib/pages/member_opus/view.dart +++ b/lib/pages/member_opus/view.dart @@ -117,22 +117,25 @@ class _MemberOpusState extends State ); } + late final gridDelegate = SliverWaterfallFlowDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: Grid.smallCardWidth, + mainAxisSpacing: StyleString.safeSpace, + crossAxisSpacing: StyleString.safeSpace, + ); + Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverWaterfallFlow.extent( - maxCrossAxisExtent: Grid.smallCardWidth, - mainAxisSpacing: StyleString.safeSpace, - crossAxisSpacing: StyleString.safeSpace, - children: List.generate(10, (_) => const SpaceOpusSkeleton()), + Loading() => SliverWaterfallFlow( + gridDelegate: gridDelegate, + delegate: SliverChildBuilderDelegate( + (context, index) => const SpaceOpusSkeleton(), + childCount: 10, + ), ), Success(:var response) => response?.isNotEmpty == true ? SliverWaterfallFlow( - gridDelegate: SliverWaterfallFlowDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: Grid.smallCardWidth, - mainAxisSpacing: StyleString.safeSpace, - crossAxisSpacing: StyleString.safeSpace, - ), + gridDelegate: gridDelegate, delegate: SliverChildBuilderDelegate( (_, index) { if (index == response.length - 1) { @@ -145,9 +148,7 @@ class _MemberOpusState extends State childCount: response!.length, ), ) - : HttpError( - onReload: _controller.onReload, - ), + : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _controller.onReload, diff --git a/lib/pages/member_pgc/view.dart b/lib/pages/member_pgc/view.dart index f59bd8ef8..d08e718b1 100644 --- a/lib/pages/member_pgc/view.dart +++ b/lib/pages/member_pgc/view.dart @@ -63,30 +63,30 @@ class _MemberBangumiState extends State ); } + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2, + childAspectRatio: 0.75, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(52), + ); + Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { Loading() => const SliverToBoxAdapter(), Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2, - childAspectRatio: 0.75, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(52), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return PgcCardVMemberPgc( - item: response[index], - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return PgcCardVMemberPgc( + item: response[index], + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/member_search/child/view.dart b/lib/pages/member_search/child/view.dart index 1eeba4155..a6d806e83 100644 --- a/lib/pages/member_search/child/view.dart +++ b/lib/pages/member_search/child/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/common/widgets/video_card/video_card_h.dart'; @@ -29,7 +28,7 @@ class MemberSearchChildPage extends StatefulWidget { } class _MemberSearchChildPageState extends State - with AutomaticKeepAliveClientMixin, DynMixin { + with AutomaticKeepAliveClientMixin, DynMixin, GridMixin { MemberSearchChildController get _controller => widget.controller; @override @@ -55,15 +54,7 @@ class _MemberSearchChildPageState extends State Widget get _buildLoading { return switch (widget.searchType) { - MemberSearchType.archive => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), + MemberSearchType.archive => gridSkeleton, MemberSearchType.dynamic => dynSkeleton, }; } @@ -76,24 +67,22 @@ class _MemberSearchChildPageState extends State ? Builder( builder: (context) { return switch (widget.searchType) { - MemberSearchType.archive => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return VideoCardH( - videoItem: response[index], - ); - }, - childCount: response!.length, - ), + MemberSearchType.archive => SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return VideoCardH( + videoItem: response[index], + ); + }, + itemCount: response!.length, ), MemberSearchType.dynamic => GlobalData().dynamicsWaterfallFlow ? SliverWaterfallFlow( - gridDelegate: gridDelegate, + gridDelegate: dynGridDelegate, delegate: SliverChildBuilderDelegate( (_, index) { if (index == response.length - 1) { @@ -131,9 +120,7 @@ class _MemberSearchChildPageState extends State }; }, ) - : HttpError( - onReload: _controller.onReload, - ), + : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _controller.onReload, diff --git a/lib/pages/member_season_series/view.dart b/lib/pages/member_season_series/view.dart index 8098baecc..e10f15169 100644 --- a/lib/pages/member_season_series/view.dart +++ b/lib/pages/member_season_series/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models/common/member/contribute_type.dart'; @@ -26,7 +25,7 @@ class SeasonSeriesPage extends StatefulWidget { } class _SeasonSeriesPageState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { late final _controller = Get.put( SeasonSeriesController(widget.mid), tag: widget.heroTag, @@ -54,58 +53,48 @@ class _SeasonSeriesPageState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - SpaceSsModel item = response[index]; - return SeasonSeriesCard( - item: item, - onTap: () { - bool isSeason = item.meta!.seasonId != null; - dynamic id = isSeason - ? item.meta!.seasonId - : item.meta!.seriesId; - Get.to( - Scaffold( - appBar: AppBar( - title: Text(item.meta!.name!), - ), - body: SafeArea( - top: false, - bottom: false, - child: MemberVideo( - type: isSeason - ? ContributeType.season - : ContributeType.series, - heroTag: widget.heroTag, - mid: widget.mid, - seasonId: isSeason ? id : null, - seriesId: isSeason ? null : id, - title: item.meta!.name, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + SpaceSsModel item = response[index]; + return SeasonSeriesCard( + item: item, + onTap: () { + bool isSeason = item.meta!.seasonId != null; + dynamic id = isSeason + ? item.meta!.seasonId + : item.meta!.seriesId; + Get.to( + Scaffold( + appBar: AppBar( + title: Text(item.meta!.name!), + ), + body: SafeArea( + top: false, + bottom: false, + child: MemberVideo( + type: isSeason + ? ContributeType.season + : ContributeType.series, + heroTag: widget.heroTag, + mid: widget.mid, + seasonId: isSeason ? id : null, + seriesId: isSeason ? null : id, + title: item.meta!.name, ), ), - ); - }, - ); - }, - childCount: response!.length, - ), + ), + ); + }, + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/member_video/view.dart b/lib/pages/member_video/view.dart index f5a8708a4..b91f74235 100644 --- a/lib/pages/member_video/view.dart +++ b/lib/pages/member_video/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; @@ -38,12 +37,10 @@ class MemberVideo extends StatefulWidget { } class _MemberVideoState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { @override bool get wantKeepAlive => true; - late final gridDelegate = Grid.videoCardHDelegate(context); - late final _controller = Get.put( MemberVideoCtr( type: widget.type, @@ -128,25 +125,18 @@ class _MemberVideoState extends State return child; } + @override + Widget get gridSkeleton => SliverPadding( + padding: widget.isSingle ? const EdgeInsets.only(top: 7) : EdgeInsets.zero, + sliver: super.gridSkeleton, + ); + Widget _buildBody( ThemeData theme, LoadingState?> loadingState, ) { return switch (loadingState) { - Loading() => SliverPadding( - padding: widget.isSingle - ? const EdgeInsets.only(top: 7) - : EdgeInsets.zero, - sliver: SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true ? SliverMainAxisGroup( @@ -239,27 +229,23 @@ class _MemberVideoState extends State ), ), ), - SliverGrid( + SliverGrid.builder( gridDelegate: gridDelegate, - delegate: SliverChildBuilderDelegate( - (context, index) { - if (widget.type != ContributeType.season && - index == response.length - 1) { - _controller.onLoadMore(); - } - return VideoCardHMemberVideo( - videoItem: response[index], - fromViewAid: _controller.fromViewAid, - ); - }, - childCount: response!.length, - ), + itemBuilder: (context, index) { + if (widget.type != ContributeType.season && + index == response.length - 1) { + _controller.onLoadMore(); + } + return VideoCardHMemberVideo( + videoItem: response[index], + fromViewAid: _controller.fromViewAid, + ); + }, + itemCount: response!.length, ), ], ) - : HttpError( - onReload: _controller.onReload, - ), + : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _controller.onReload, diff --git a/lib/pages/msg_feed_top/at_me/view.dart b/lib/pages/msg_feed_top/at_me/view.dart index b3fe342f0..c9ae30ac4 100644 --- a/lib/pages/msg_feed_top/at_me/view.dart +++ b/lib/pages/msg_feed_top/at_me/view.dart @@ -79,9 +79,7 @@ class _AtMePageState extends State { return switch (loadingState) { Loading() => SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const MsgFeedTopSkeleton(); - }, + itemBuilder: (context, index) => const MsgFeedTopSkeleton(), ), Success(:var response) => response?.isNotEmpty == true diff --git a/lib/pages/msg_feed_top/like_detail/view.dart b/lib/pages/msg_feed_top/like_detail/view.dart index b95e16d26..472cfb306 100644 --- a/lib/pages/msg_feed_top/like_detail/view.dart +++ b/lib/pages/msg_feed_top/like_detail/view.dart @@ -63,9 +63,7 @@ class _LikeDetailPageState extends State { return switch (loadingState) { Loading() => SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const MsgFeedTopSkeleton(); - }, + itemBuilder: (context, index) => const MsgFeedTopSkeleton(), ), Success(:var response) => SliverMainAxisGroup( slivers: [ diff --git a/lib/pages/msg_feed_top/like_me/view.dart b/lib/pages/msg_feed_top/like_me/view.dart index d1a42798e..a437ad04a 100644 --- a/lib/pages/msg_feed_top/like_me/view.dart +++ b/lib/pages/msg_feed_top/like_me/view.dart @@ -77,9 +77,7 @@ class _LikeMePageState extends State { return switch (loadingState) { Loading() => SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const MsgFeedTopSkeleton(); - }, + itemBuilder: (context, index) => const MsgFeedTopSkeleton(), ), Success(:var response) => Builder( builder: (context) { diff --git a/lib/pages/msg_feed_top/reply_me/view.dart b/lib/pages/msg_feed_top/reply_me/view.dart index 925d770a8..76c9c4308 100644 --- a/lib/pages/msg_feed_top/reply_me/view.dart +++ b/lib/pages/msg_feed_top/reply_me/view.dart @@ -79,9 +79,7 @@ class _ReplyMePageState extends State { return switch (loadingState) { Loading() => SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const MsgFeedTopSkeleton(); - }, + itemBuilder: (context, index) => const MsgFeedTopSkeleton(), ), Success(:var response) => response?.isNotEmpty == true diff --git a/lib/pages/msg_feed_top/sys_msg/view.dart b/lib/pages/msg_feed_top/sys_msg/view.dart index 98675fc44..7cbe034ac 100644 --- a/lib/pages/msg_feed_top/sys_msg/view.dart +++ b/lib/pages/msg_feed_top/sys_msg/view.dart @@ -67,9 +67,7 @@ class _SysMsgPageState extends State { Loading() => SliverSafeArea( sliver: SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const MsgFeedSysMsgSkeleton(); - }, + itemBuilder: (context, index) => const MsgFeedSysMsgSkeleton(), ), ), Success(:var response) => diff --git a/lib/pages/pgc/view.dart b/lib/pages/pgc/view.dart index 588cc5ee9..f9719ee4d 100644 --- a/lib/pages/pgc/view.dart +++ b/lib/pages/pgc/view.dart @@ -314,35 +314,30 @@ class _PgcPageState extends CommonPageState ), ); + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2, + childAspectRatio: 0.75, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(50), + ); + Widget _buildRcmdBody(LoadingState?> loadingState) { return switch (loadingState) { Loading() => const SliverToBoxAdapter(), Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - // 行间距 - mainAxisSpacing: StyleString.cardSpace, - // 列间距 - crossAxisSpacing: StyleString.cardSpace, - // 最大宽度 - maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2, - childAspectRatio: 0.75, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(50), - ), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - if (index == response.length - 1) { - controller.onLoadMore(); - } - return PgcCardVPgcIndex(item: response[index]); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + controller.onLoadMore(); + } + return PgcCardVPgcIndex(item: response[index]); + }, + itemCount: response!.length, ) - : HttpError( - onReload: controller.onReload, - ), + : HttpError(onReload: controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: controller.onReload, diff --git a/lib/pages/pgc_index/view.dart b/lib/pages/pgc_index/view.dart index ea6951470..89d4710cb 100644 --- a/lib/pages/pgc_index/view.dart +++ b/lib/pages/pgc_index/view.dart @@ -211,28 +211,28 @@ class _PgcIndexPageState extends State ], ); + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2, + childAspectRatio: 0.75, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(50), + ); + Widget _buildList(LoadingState?> loadingState) { return switch (loadingState) { Loading() => linearLoading, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth / 3 * 2, - childAspectRatio: 0.75, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(50), - ), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - if (index == response.length - 1) { - _ctr.onLoadMore(); - } - return PgcCardVPgcIndex(item: response[index]); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _ctr.onLoadMore(); + } + return PgcCardVPgcIndex(item: response[index]); + }, + itemCount: response!.length, ) : HttpError(onReload: _ctr.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/pgc_review/child/view.dart b/lib/pages/pgc_review/child/view.dart index 17ee539f0..5236d1781 100644 --- a/lib/pages/pgc_review/child/view.dart +++ b/lib/pages/pgc_review/child/view.dart @@ -36,17 +36,16 @@ class PgcReviewChildPage extends StatefulWidget { class _PgcReviewChildPageState extends State with AutomaticKeepAliveClientMixin { + late final _tag = '${widget.mediaId}${widget.type.name}'; late final _controller = Get.put( PgcReviewController(type: widget.type, mediaId: widget.mediaId), - tag: '${widget.mediaId}${widget.type.name}', + tag: _tag, ); late final isLongReview = widget.type == PgcReviewType.long; @override void dispose() { - Get.delete( - tag: '${widget.mediaId}${widget.type.name}', - ); + Get.delete(tag: _tag); super.dispose(); } @@ -57,6 +56,7 @@ class _PgcReviewChildPageState extends State return refreshIndicator( onRefresh: _controller.onRefresh, child: CustomScrollView( + key: PageStorageKey(_tag), controller: _controller.scrollController, physics: const AlwaysScrollableScrollPhysics(), slivers: [ @@ -87,9 +87,7 @@ class _PgcReviewChildPageState extends State child: ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return const VideoReplySkeleton(); - }, + itemBuilder: (context, index) => const VideoReplySkeleton(), itemCount: 8, ), ), diff --git a/lib/pages/rank/zone/view.dart b/lib/pages/rank/zone/view.dart index 7e799a4e2..3097f97d0 100644 --- a/lib/pages/rank/zone/view.dart +++ b/lib/pages/rank/zone/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/common/widgets/video_card/video_card_h.dart'; @@ -22,7 +21,7 @@ class ZonePage extends CommonPage { } class _ZonePageState extends CommonPageState - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { @override late ZoneController controller = Get.put( ZoneController(rid: widget.rid, seasonType: widget.seasonType), @@ -53,40 +52,26 @@ class _ZonePageState extends CommonPageState ); } - Widget _buildSkeleton() { - return SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ); - } - Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => _buildSkeleton(), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - final item = response[index]; - if (item is HotVideoItemModel) { - return VideoCardH( - videoItem: item, - onRemove: () => controller.loadingState - ..value.data!.removeAt(index) - ..refresh(), - ); - } - return PgcRankItem(item: item); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + final item = response[index]; + if (item is HotVideoItemModel) { + return VideoCardH( + videoItem: item, + onRemove: () => controller.loadingState + ..value.data!.removeAt(index) + ..refresh(), + ); + } + return PgcRankItem(item: item); + }, + itemCount: response!.length, ) : HttpError(onReload: controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/rcmd/view.dart b/lib/pages/rcmd/view.dart index 3adf99ed2..d89e3ad8f 100644 --- a/lib/pages/rcmd/view.dart +++ b/lib/pages/rcmd/view.dart @@ -51,80 +51,80 @@ class _RcmdPageState extends CommonPageState ); } + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: StyleString.cardSpace, + crossAxisSpacing: StyleString.cardSpace, + maxCrossAxisExtent: Grid.smallCardWidth, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), + ); + Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => _buildSkeleton(), + Loading() => _buildSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - if (index == response.length - 1) { - controller.onLoadMore(); - } - if (controller.lastRefreshAt != null) { - if (controller.lastRefreshAt == index) { - return GestureDetector( - onTap: () => controller - ..animateToTop() - ..onRefresh(), - child: Card( - child: Container( - alignment: Alignment.center, - padding: const EdgeInsets.symmetric( - horizontal: 10, - ), - child: Text( - '上次看到这里\n点击刷新', - textAlign: TextAlign.center, - style: TextStyle( - color: Theme.of( - context, - ).colorScheme.onSurfaceVariant, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + controller.onLoadMore(); + } + if (controller.lastRefreshAt != null) { + if (controller.lastRefreshAt == index) { + return GestureDetector( + onTap: () => controller + ..animateToTop() + ..onRefresh(), + child: Card( + child: Container( + alignment: Alignment.center, + padding: const EdgeInsets.symmetric( + horizontal: 10, + ), + child: Text( + '上次看到这里\n点击刷新', + textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of( + context, + ).colorScheme.onSurfaceVariant, ), ), ), - ); - } - int actualIndex = controller.lastRefreshAt == null - ? index - : index > controller.lastRefreshAt! - ? index - 1 - : index; - return VideoCardV( - videoItem: response[actualIndex], - onRemove: () { - if (controller.lastRefreshAt != null && - actualIndex < controller.lastRefreshAt!) { - controller.lastRefreshAt = - controller.lastRefreshAt! - 1; - } - controller.loadingState - ..value.data!.removeAt(actualIndex) - ..refresh(); - }, - ); - } else { - return VideoCardV( - videoItem: response[index], - onRemove: () => controller.loadingState - ..value.data!.removeAt(index) - ..refresh(), + ), ); } - }, - childCount: controller.lastRefreshAt != null - ? response!.length + 1 - : response!.length, - ), + int actualIndex = controller.lastRefreshAt == null + ? index + : index > controller.lastRefreshAt! + ? index - 1 + : index; + return VideoCardV( + videoItem: response[actualIndex], + onRemove: () { + if (controller.lastRefreshAt != null && + actualIndex < controller.lastRefreshAt!) { + controller.lastRefreshAt = + controller.lastRefreshAt! - 1; + } + controller.loadingState + ..value.data!.removeAt(actualIndex) + ..refresh(); + }, + ); + } else { + return VideoCardV( + videoItem: response[index], + onRemove: () => controller.loadingState + ..value.data!.removeAt(index) + ..refresh(), + ); + } + }, + itemCount: controller.lastRefreshAt != null + ? response!.length + 1 + : response!.length, ) : HttpError(onReload: controller.onReload), Error(:var errMsg) => HttpError( @@ -134,21 +134,9 @@ class _RcmdPageState extends CommonPageState }; } - Widget _buildSkeleton() { - return SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardVSkeleton(); - }, - childCount: 10, - ), - ); - } + Widget get _buildSkeleton => SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) => const VideoCardVSkeleton(), + itemCount: 10, + ); } diff --git a/lib/pages/search_panel/all/view.dart b/lib/pages/search_panel/all/view.dart index 5be5f84e6..a3dad1005 100644 --- a/lib/pages/search_panel/all/view.dart +++ b/lib/pages/search_panel/all/view.dart @@ -1,4 +1,5 @@ import 'package:PiliPlus/common/constants.dart'; +import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/video_card/video_card_h.dart'; import 'package:PiliPlus/models/search/result.dart'; import 'package:PiliPlus/pages/search_panel/all/controller.dart'; @@ -94,4 +95,11 @@ class _SearchAllPanelState ), ); } + + @override + Widget get builLoading => SliverGrid.builder( + gridDelegate: Grid.videoCardHDelegate(context), + itemBuilder: (context, index) => const VideoCardHSkeleton(), + itemCount: 10, + ); } diff --git a/lib/pages/search_panel/article/view.dart b/lib/pages/search_panel/article/view.dart index 7f60896d0..c492025cc 100644 --- a/lib/pages/search_panel/article/view.dart +++ b/lib/pages/search_panel/article/view.dart @@ -25,7 +25,8 @@ class _SearchArticlePanelState SearchArticlePanel, SearchArticleData, SearchArticleItemModel - > { + > + with GridMixin { @override late final SearchArticleController controller = Get.put( SearchArticleController( @@ -90,17 +91,18 @@ class _SearchArticlePanelState @override Widget buildList(ThemeData theme, List list) { - return SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - if (index == list.length - 1) { - controller.onLoadMore(); - } - return SearchArticleItem(item: list[index]); - }, - childCount: list.length, - ), + return SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == list.length - 1) { + controller.onLoadMore(); + } + return SearchArticleItem(item: list[index]); + }, + itemCount: list.length, ); } + + @override + Widget get builLoading => gridSkeleton; } diff --git a/lib/pages/search_panel/live/view.dart b/lib/pages/search_panel/live/view.dart index c9ccbc96c..d0f96b1ce 100644 --- a/lib/pages/search_panel/live/view.dart +++ b/lib/pages/search_panel/live/view.dart @@ -1,4 +1,5 @@ import 'package:PiliPlus/common/constants.dart'; +import 'package:PiliPlus/common/skeleton/video_card_v.dart'; import 'package:PiliPlus/models/search/result.dart'; import 'package:PiliPlus/pages/search_panel/controller.dart'; import 'package:PiliPlus/pages/search_panel/live/widgets/item.dart'; @@ -36,6 +37,14 @@ class _SearchLivePanelState tag: widget.searchType.name + widget.tag, ); + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + maxCrossAxisExtent: Grid.smallCardWidth, + crossAxisSpacing: StyleString.cardSpace, + mainAxisSpacing: StyleString.cardSpace, + childAspectRatio: StyleString.aspectRatio, + mainAxisExtent: MediaQuery.textScalerOf(context).scale(80), + ); + @override Widget buildList(ThemeData theme, List list) { return SliverPadding( @@ -43,24 +52,23 @@ class _SearchLivePanelState left: StyleString.safeSpace, right: StyleString.safeSpace, ), - sliver: SliverGrid( - gridDelegate: SliverGridDelegateWithExtentAndRatio( - maxCrossAxisExtent: Grid.smallCardWidth, - crossAxisSpacing: StyleString.safeSpace, - mainAxisSpacing: StyleString.safeSpace, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(80), - ), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == list.length - 1) { - controller.onLoadMore(); - } - return LiveItem(liveItem: list[index]); - }, - childCount: list.length, - ), + sliver: SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == list.length - 1) { + controller.onLoadMore(); + } + return LiveItem(liveItem: list[index]); + }, + itemCount: list.length, ), ); } + + @override + Widget get builLoading => SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) => const VideoCardVSkeleton(), + itemCount: 10, + ); } diff --git a/lib/pages/search_panel/pgc/view.dart b/lib/pages/search_panel/pgc/view.dart index e4e01730f..5ea1331b6 100644 --- a/lib/pages/search_panel/pgc/view.dart +++ b/lib/pages/search_panel/pgc/view.dart @@ -1,3 +1,5 @@ +import 'package:PiliPlus/common/constants.dart'; +import 'package:PiliPlus/common/skeleton/media_bangumi.dart'; import 'package:PiliPlus/models/search/result.dart'; import 'package:PiliPlus/pages/search_panel/controller.dart'; import 'package:PiliPlus/pages/search_panel/pgc/widgets/item.dart'; @@ -35,22 +37,34 @@ class _SearchPgcPanelState tag: widget.searchType.name + widget.tag, ); + late final gridDelegate = SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: Grid.smallCardWidth * 2, + mainAxisExtent: 160, + ); + @override Widget buildList(ThemeData theme, List list) { - return SliverGrid( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: Grid.smallCardWidth * 2, - mainAxisExtent: 160, - ), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - if (index == list.length - 1) { - controller.onLoadMore(); - } - return SearchPgcItem(item: list[index]); - }, - childCount: list.length, - ), + return SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (BuildContext context, int index) { + if (index == list.length - 1) { + controller.onLoadMore(); + } + return SearchPgcItem(item: list[index]); + }, + itemCount: list.length, ); } + + @override + Widget get builLoading => SliverGrid.builder( + gridDelegate: SliverGridDelegateWithExtentAndRatio( + mainAxisSpacing: 2, + maxCrossAxisExtent: Grid.smallCardWidth * 2, + childAspectRatio: StyleString.aspectRatio * 1.5, + minHeight: MediaQuery.textScalerOf(context).scale(155), + ), + itemBuilder: (context, index) => const MediaPgcSkeleton(), + itemCount: 10, + ); } diff --git a/lib/pages/search_panel/user/view.dart b/lib/pages/search_panel/user/view.dart index 680745956..695f246b6 100644 --- a/lib/pages/search_panel/user/view.dart +++ b/lib/pages/search_panel/user/view.dart @@ -1,3 +1,4 @@ +import 'package:PiliPlus/common/skeleton/msg_feed_top.dart'; import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart'; import 'package:PiliPlus/models/search/result.dart'; import 'package:PiliPlus/pages/search_panel/user/controller.dart'; @@ -88,24 +89,31 @@ class _SearchUserPanelState ); } + late final gridDelegate = SliverGridDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: Grid.smallCardWidth * 2, + mainAxisExtent: 66, + ); + @override Widget buildList(ThemeData theme, List list) { - return SliverGrid( - gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: Grid.smallCardWidth * 2, - mainAxisExtent: 66, - ), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - if (index == list.length - 1) { - controller.onLoadMore(); - } - return SearchUserItem( - item: list[index], - ); - }, - childCount: list.length, - ), + return SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (BuildContext context, int index) { + if (index == list.length - 1) { + controller.onLoadMore(); + } + return SearchUserItem( + item: list[index], + ); + }, + itemCount: list.length, ); } + + @override + Widget get builLoading => SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) => const MsgFeedTopSkeleton(), + itemCount: 10, + ); } diff --git a/lib/pages/search_panel/video/view.dart b/lib/pages/search_panel/video/view.dart index 07af03055..481af69b3 100644 --- a/lib/pages/search_panel/video/view.dart +++ b/lib/pages/search_panel/video/view.dart @@ -27,7 +27,8 @@ class _SearchVideoPanelState SearchVideoPanel, SearchVideoData, SearchVideoItemModel - > { + > + with GridMixin { @override late final SearchVideoController controller = Get.put( SearchVideoController( @@ -102,22 +103,23 @@ class _SearchVideoPanelState @override Widget buildList(ThemeData theme, List list) { - return SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == list.length - 1) { - controller.onLoadMore(); - } - return VideoCardH( - videoItem: list[index], - onRemove: () => controller.loadingState - ..value.data!.removeAt(index) - ..refresh(), - ); - }, - childCount: list.length, - ), + return SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == list.length - 1) { + controller.onLoadMore(); + } + return VideoCardH( + videoItem: list[index], + onRemove: () => controller.loadingState + ..value.data!.removeAt(index) + ..refresh(), + ); + }, + itemCount: list.length, ); } + + @override + Widget get builLoading => gridSkeleton; } diff --git a/lib/pages/search_panel/view.dart b/lib/pages/search_panel/view.dart index a81d4403d..ba489b1cc 100644 --- a/lib/pages/search_panel/view.dart +++ b/lib/pages/search_panel/view.dart @@ -1,15 +1,9 @@ -import 'package:PiliPlus/common/constants.dart'; -import 'package:PiliPlus/common/skeleton/media_bangumi.dart'; -import 'package:PiliPlus/common/skeleton/msg_feed_top.dart'; -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; -import 'package:PiliPlus/common/skeleton/video_card_v.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models/common/search/search_type.dart'; import 'package:PiliPlus/models/search/result.dart'; import 'package:PiliPlus/pages/search_panel/controller.dart'; -import 'package:PiliPlus/utils/grid.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -55,59 +49,11 @@ abstract class CommonSearchPanelState< ); } - Widget get _builLoading { - return SliverGrid( - gridDelegate: switch (widget.searchType) { - SearchType.media_bangumi || - SearchType.media_ft => SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: 2, - maxCrossAxisExtent: Grid.smallCardWidth * 2, - childAspectRatio: StyleString.aspectRatio * 1.5, - minHeight: MediaQuery.textScalerOf(context).scale(155), - ), - SearchType.live_room => SliverGridDelegateWithExtentAndRatio( - mainAxisSpacing: StyleString.cardSpace, - crossAxisSpacing: StyleString.cardSpace, - maxCrossAxisExtent: Grid.smallCardWidth, - childAspectRatio: StyleString.aspectRatio, - mainAxisExtent: MediaQuery.textScalerOf(context).scale(90), - ), - SearchType.bili_user => SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: Grid.smallCardWidth * 2, - mainAxisExtent: 66, - ), - _ => Grid.videoCardHDelegate(context), - }, - delegate: SliverChildBuilderDelegate( - (context, index) { - switch (widget.searchType) { - case SearchType.media_bangumi || SearchType.media_ft: - return const MediaPgcSkeleton(); - case SearchType.bili_user: - return const MsgFeedTopSkeleton(); - case SearchType.live_room: - return const VideoCardVSkeleton(); - default: - return const VideoCardHSkeleton(); - } - }, - childCount: 16, - ), - ); - } + Widget get builLoading; Widget _buildBody(ThemeData theme, LoadingState?> loadingState) { return switch (loadingState) { - Loading() => - widget.searchType == SearchType.live_room - ? SliverPadding( - padding: const EdgeInsets.only( - left: StyleString.cardSpace, - right: StyleString.cardSpace, - ), - sliver: _builLoading, - ) - : _builLoading, + Loading() => builLoading, Success(:var response) => response?.isNotEmpty == true ? SliverPadding( @@ -116,9 +62,7 @@ abstract class CommonSearchPanelState< ), sliver: buildList(theme, response!), ) - : HttpError( - onReload: controller.onReload, - ), + : HttpError(onReload: controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: controller.onReload, diff --git a/lib/pages/search_trending/view.dart b/lib/pages/search_trending/view.dart index 7c4566607..98072c913 100644 --- a/lib/pages/search_trending/view.dart +++ b/lib/pages/search_trending/view.dart @@ -225,9 +225,7 @@ class _SearchTrendingPageState extends State { }, separatorBuilder: (context, index) => divider, ) - : HttpError( - onReload: _controller.onReload, - ), + : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _controller.onReload, diff --git a/lib/pages/subscription/view.dart b/lib/pages/subscription/view.dart index 4e152ce24..b1ba202e1 100644 --- a/lib/pages/subscription/view.dart +++ b/lib/pages/subscription/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; @@ -16,7 +15,7 @@ class SubPage extends StatefulWidget { State createState() => _SubPageState(); } -class _SubPageState extends State { +class _SubPageState extends State with GridMixin { final SubController _subController = Get.put(SubController()); @override @@ -46,34 +45,24 @@ class _SubPageState extends State { Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) => const VideoCardHSkeleton(), - childCount: 10, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - childCount: response!.length, - (BuildContext context, int index) { - if (index == response.length - 1) { - _subController.onLoadMore(); - } - final item = response[index]; - return SubItem( - item: item, - cancelSub: () => _subController.cancelSub(item), - ); - }, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _subController.onLoadMore(); + } + final item = response[index]; + return SubItem( + item: item, + cancelSub: () => _subController.cancelSub(item), + ); + }, + itemCount: response!.length, ) - : HttpError( - onReload: _subController.onReload, - ), + : HttpError(onReload: _subController.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _subController.onReload, diff --git a/lib/pages/subscription_detail/view.dart b/lib/pages/subscription_detail/view.dart index 09042de78..50fe7c466 100644 --- a/lib/pages/subscription_detail/view.dart +++ b/lib/pages/subscription_detail/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; @@ -35,7 +34,7 @@ class SubDetailPage extends StatefulWidget { } } -class _SubDetailPageState extends State { +class _SubDetailPageState extends State with GridMixin { late final SubDetailController _subDetailController = Get.put( SubDetailController(), tag: Utils.makeHeroTag(Get.parameters['id']), @@ -74,32 +73,22 @@ class _SubDetailPageState extends State { Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) => const VideoCardHSkeleton(), - childCount: 10, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - childCount: response!.length, - (context, index) { - if (index == response.length - 1) { - _subDetailController.onLoadMore(); - } - return SubVideoCardH( - videoItem: response[index], - ); - }, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _subDetailController.onLoadMore(); + } + return SubVideoCardH( + videoItem: response[index], + ); + }, + itemCount: response!.length, ) - : HttpError( - onReload: _subDetailController.onReload, - ), + : HttpError(onReload: _subDetailController.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _subDetailController.onReload, @@ -124,6 +113,7 @@ class _SubDetailPageState extends State { Widget _buildAppBar(ThemeData theme, EdgeInsets padding, SubItemModel info) { final style = TextStyle( + height: 1, fontSize: 12.5, color: theme.colorScheme.outline, ); @@ -178,29 +168,28 @@ class _SubDetailPageState extends State { cover, Expanded( child: Column( - spacing: 4, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - info.title!, - style: TextStyle( - fontSize: theme.textTheme.titleMedium!.fontSize, - fontWeight: FontWeight.bold, + Expanded( + child: Text( + info.title!, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + ), ), ), GestureDetector( - onTap: () { - Get.toNamed( - '/member?mid=${info.upper!.mid}', - ); - }, + onTap: () => + Get.toNamed('/member?mid=${info.upper!.mid}'), child: Text( info.upper!.name!, style: TextStyle(color: theme.colorScheme.primary), ), ), - const Spacer(), + const SizedBox(height: 4), Text('共${info.mediaCount}条视频', style: style), + const SizedBox(height: 4), Text( '${NumUtil.numFormat(info.viewCount ?? info.cntInfo?.play)}次播放', style: style, diff --git a/lib/pages/video/ai_conclusion/view.dart b/lib/pages/video/ai_conclusion/view.dart index 3a93b72f6..db6020449 100644 --- a/lib/pages/video/ai_conclusion/view.dart +++ b/lib/pages/video/ai_conclusion/view.dart @@ -61,6 +61,7 @@ class _AiDetailState extends CommonCollapseSlidePageState { @override Widget buildList(ThemeData theme) { return CustomScrollView( + key: const PageStorageKey('ai_detail'), controller: _controller, physics: const AlwaysScrollableScrollPhysics(), slivers: [ diff --git a/lib/pages/video/introduction/pgc/widgets/intro_detail.dart b/lib/pages/video/introduction/pgc/widgets/intro_detail.dart index a3f3c023c..985d0218a 100644 --- a/lib/pages/video/introduction/pgc/widgets/intro_detail.dart +++ b/lib/pages/video/introduction/pgc/widgets/intro_detail.dart @@ -99,6 +99,7 @@ class _IntroDetailState extends CommonCollapseSlidePageState { ); return SelectionArea( child: ListView( + key: const PageStorageKey('pgc_intro'), controller: _controller, physics: const AlwaysScrollableScrollPhysics(), padding: EdgeInsets.only( diff --git a/lib/pages/video/introduction/ugc/widgets/page.dart b/lib/pages/video/introduction/ugc/widgets/page.dart index bc8fd6b85..5db2baf5e 100644 --- a/lib/pages/video/introduction/ugc/widgets/page.dart +++ b/lib/pages/video/introduction/ugc/widgets/page.dart @@ -136,6 +136,7 @@ class _PagesPanelState extends State { SizedBox( height: 35, child: ListView.builder( + key: PageStorageKey(hashCode), controller: _scrollController, scrollDirection: Axis.horizontal, itemCount: pages.length, diff --git a/lib/pages/video/introduction/ugc/widgets/triple_state.dart b/lib/pages/video/introduction/ugc/widgets/triple_state.dart index 94cc882df..f475cc417 100644 --- a/lib/pages/video/introduction/ugc/widgets/triple_state.dart +++ b/lib/pages/video/introduction/ugc/widgets/triple_state.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:math' show pi; import 'package:PiliPlus/pages/common/common_intro_controller.dart'; -import 'package:PiliPlus/utils/feed_back.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; @@ -62,7 +61,6 @@ abstract class TripleState extends State } else if (_timer != null && _timer!.tick == 0) { _cancelTimer(); if (isTapUp) { - feedBack(); introController.actionLikeVideo(); } } diff --git a/lib/pages/video/medialist/view.dart b/lib/pages/video/medialist/view.dart index dcaf5e324..e32292f63 100644 --- a/lib/pages/video/medialist/view.dart +++ b/lib/pages/video/medialist/view.dart @@ -49,14 +49,20 @@ class MediaListPanel extends CommonCollapseSlidePage { class _MediaListPanelState extends CommonCollapseSlidePageState { - late final int _index; + final _controller = ItemScrollController(); @override - void initState() { - super.initState(); + void init() { final bvid = widget.getBvId(); final bvIndex = widget.mediaList.indexWhere((item) => item.bvid == bvid); - _index = bvIndex == -1 ? 0 : bvIndex; + if (bvIndex != -1) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) { + isInit = false; + _controller.jumpTo(index: bvIndex); + } + }); + } } @override @@ -116,9 +122,10 @@ class _MediaListPanelState () { final showDelBtn = widget.onDelete != null && widget.mediaList.length > 1; return ScrollablePositionedList.separated( + key: const PageStorageKey('medialist'), + itemScrollController: _controller, physics: const AlwaysScrollableScrollPhysics(), itemCount: widget.mediaList.length, - initialScrollIndex: _index, padding: EdgeInsets.only( top: 7, bottom: MediaQuery.paddingOf(context).bottom + 80, diff --git a/lib/pages/video/member/view.dart b/lib/pages/video/member/view.dart index c484b58f0..3926dcec7 100644 --- a/lib/pages/video/member/view.dart +++ b/lib/pages/video/member/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/button/icon_button.dart'; import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; @@ -42,7 +41,8 @@ class HorizontalMemberPage extends StatefulWidget { State createState() => _HorizontalMemberPageState(); } -class _HorizontalMemberPageState extends State { +class _HorizontalMemberPageState extends State + with GridMixin { late final HorizontalMemberPageController _controller; AccountService accountService = Get.find(); dynamic _bvid; @@ -173,46 +173,36 @@ class _HorizontalMemberPageState extends State { LoadingState?> loadingState, ) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - childCount: 10, - (context, index) { - return const VideoCardHSkeleton(); - }, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true ? SliverPadding( padding: EdgeInsets.only( bottom: MediaQuery.paddingOf(context).bottom + 80, ), - sliver: SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1 && _controller.hasNext) { - _controller.onLoadMore(); - } - final SpaceArchiveItem videoItem = response[index]; - return VideoCardHMemberVideo( - videoItem: videoItem, - bvid: _bvid, - onTap: () { - Get.back(); - widget.ugcIntroController.onChangeEpisode( - BaseEpisodeItem( - bvid: videoItem.bvid, - cid: videoItem.cid, - cover: videoItem.cover, - ), - ); - }, - ); - }, - childCount: response!.length, - ), + sliver: SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1 && _controller.hasNext) { + _controller.onLoadMore(); + } + final SpaceArchiveItem videoItem = response[index]; + return VideoCardHMemberVideo( + videoItem: videoItem, + bvid: _bvid, + onTap: () { + Get.back(); + widget.ugcIntroController.onChangeEpisode( + BaseEpisodeItem( + bvid: videoItem.bvid, + cid: videoItem.cid, + cover: videoItem.cover, + ), + ); + }, + ); + }, + itemCount: response!.length, ), ) : HttpError(onReload: _controller.onReload), diff --git a/lib/pages/video/note/view.dart b/lib/pages/video/note/view.dart index b9f934150..f0d12ba02 100644 --- a/lib/pages/video/note/view.dart +++ b/lib/pages/video/note/view.dart @@ -173,9 +173,7 @@ class _NoteListPageState extends CommonSlidePageState { child: ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return const VideoReplySkeleton(); - }, + itemBuilder: (context, index) => const VideoReplySkeleton(), itemCount: 8, ), ), diff --git a/lib/pages/video/post_panel/view.dart b/lib/pages/video/post_panel/view.dart index 33c6d3090..198d9ed83 100644 --- a/lib/pages/video/post_panel/view.dart +++ b/lib/pages/video/post_panel/view.dart @@ -112,6 +112,7 @@ class _PostPanelState extends CommonCollapseSlidePageState { clipBehavior: Clip.none, children: [ SingleChildScrollView( + key: const PageStorageKey('segment_list'), controller: _controller, physics: const AlwaysScrollableScrollPhysics(), padding: EdgeInsets.only(bottom: 88 + bottom), diff --git a/lib/pages/video/related/view.dart b/lib/pages/video/related/view.dart index e1e101d20..cd278ea1a 100644 --- a/lib/pages/video/related/view.dart +++ b/lib/pages/video/related/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/video_card/video_card_h.dart'; import 'package:PiliPlus/http/loading_state.dart'; @@ -16,7 +15,7 @@ class RelatedVideoPanel extends StatefulWidget { } class _RelatedVideoPanelState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { late final RelatedController _relatedController = Get.put( RelatedController(), tag: widget.heroTag, @@ -39,30 +38,20 @@ class _RelatedVideoPanelState extends State Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 5, - ), - ), + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return VideoCardH( - videoItem: response[index], - onRemove: () => _relatedController.loadingState - ..value.data!.removeAt(index) - ..refresh(), - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + return VideoCardH( + videoItem: response[index], + onRemove: () => _relatedController.loadingState + ..value.data!.removeAt(index) + ..refresh(), + ); + }, + itemCount: response!.length, ) : const SliverToBoxAdapter(), Error(:var errMsg) => HttpError( diff --git a/lib/pages/video/reply/view.dart b/lib/pages/video/reply/view.dart index 840a385d1..34b0de1e2 100644 --- a/lib/pages/video/reply/view.dart +++ b/lib/pages/video/reply/view.dart @@ -188,9 +188,7 @@ class _VideoReplyPanelState extends State Widget _buildBody(ThemeData theme, double bottom, LoadingState loadingState) { return switch (loadingState) { Loading() => SliverList.builder( - itemBuilder: (BuildContext context, index) { - return const VideoReplySkeleton(); - }, + itemBuilder: (context, index) => const VideoReplySkeleton(), itemCount: 5, ), Success(:var response) => diff --git a/lib/pages/video/reply_new/view.dart b/lib/pages/video/reply_new/view.dart index 214b01e27..0a33b2e6d 100644 --- a/lib/pages/video/reply_new/view.dart +++ b/lib/pages/video/reply_new/view.dart @@ -296,17 +296,18 @@ class _ReplyPageState extends CommonRichTextPubPageState { final isRoot = widget.root == 0; final color = themeData.colorScheme.onSurfaceVariant; + late final gridDelegate = SliverGridDelegateWithExtentAndRatio( + maxCrossAxisExtent: 65, + mainAxisSpacing: 12, + crossAxisSpacing: 12, + mainAxisExtent: 25, + ); return SizedBox( height: height, child: GridView( padding: const EdgeInsets.only(left: 12, bottom: 12, right: 12), - gridDelegate: SliverGridDelegateWithExtentAndRatio( - maxCrossAxisExtent: 65, - mainAxisSpacing: 12, - crossAxisSpacing: 12, - mainAxisExtent: 25, - ), + gridDelegate: gridDelegate, children: [ item( onTap: () async { diff --git a/lib/pages/video/reply_reply/view.dart b/lib/pages/video/reply_reply/view.dart index 27d90c7ed..a47ce8841 100644 --- a/lib/pages/video/reply_reply/view.dart +++ b/lib/pages/video/reply_reply/view.dart @@ -296,9 +296,7 @@ class _VideoReplyReplyPanelState child: ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return const VideoReplySkeleton(); - }, + itemBuilder: (context, index) => const VideoReplySkeleton(), itemCount: 8, ), ), diff --git a/lib/pages/video/reply_search_item/child/view.dart b/lib/pages/video/reply_search_item/child/view.dart index 87cc6cecc..c1cdb13c2 100644 --- a/lib/pages/video/reply_search_item/child/view.dart +++ b/lib/pages/video/reply_search_item/child/view.dart @@ -1,4 +1,3 @@ -import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart' @@ -26,7 +25,7 @@ class ReplySearchChildPage extends StatefulWidget { } class _ReplySearchChildPageState extends State - with AutomaticKeepAliveClientMixin { + with AutomaticKeepAliveClientMixin, GridMixin { ReplySearchChildController get _controller => widget.controller; @override @@ -50,37 +49,23 @@ class _ReplySearchChildPageState extends State ); } - Widget get _buildLoading { - return SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - return const VideoCardHSkeleton(); - }, - childCount: 10, - ), - ); - } - Widget _buildBody(LoadingState?> loadingState) { return switch (loadingState) { - Loading() => _buildLoading, + Loading() => gridSkeleton, Success(:var response) => response?.isNotEmpty == true - ? SliverGrid( - gridDelegate: Grid.videoCardHDelegate(context), - delegate: SliverChildBuilderDelegate( - (context, index) { - if (index == response.length - 1) { - _controller.onLoadMore(); - } - return ReplySearchItem( - item: response[index], - type: widget.searchType, - ); - }, - childCount: response!.length, - ), + ? SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (context, index) { + if (index == response.length - 1) { + _controller.onLoadMore(); + } + return ReplySearchItem( + item: response[index], + type: widget.searchType, + ); + }, + itemCount: response!.length, ) : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( diff --git a/lib/pages/video/view_point/view.dart b/lib/pages/video/view_point/view.dart index 3fae121ab..43b929bed 100644 --- a/lib/pages/video/view_point/view.dart +++ b/lib/pages/video/view_point/view.dart @@ -95,14 +95,12 @@ class _ViewPointsPageState @override Widget buildList(ThemeData theme) { - final divider = Divider( - height: 1, - color: theme.dividerColor.withValues(alpha: 0.1), - ); - return ListView.separated( + return ListView.builder( + key: const PageStorageKey('viewpoint'), controller: _controller, physics: const AlwaysScrollableScrollPhysics(), padding: EdgeInsets.only( + top: 7, bottom: MediaQuery.paddingOf(context).bottom + 80, ), itemCount: videoDetailController.viewPointList.length, @@ -119,7 +117,6 @@ class _ViewPointsPageState final isCurr = currentIndex == index; return _buildItem(theme, segment, isCurr); }, - separatorBuilder: (context, index) => divider, ); } diff --git a/lib/pages/whisper/view.dart b/lib/pages/whisper/view.dart index b20c3e417..f201b754f 100644 --- a/lib/pages/whisper/view.dart +++ b/lib/pages/whisper/view.dart @@ -100,9 +100,7 @@ class _WhisperPageState extends State { return switch (loadingState) { Loading() => SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const WhisperItemSkeleton(); - }, + itemBuilder: (context, index) => const WhisperItemSkeleton(), ), Success(:var response) => response?.isNotEmpty == true @@ -125,9 +123,7 @@ class _WhisperPageState extends State { }, separatorBuilder: (context, index) => divider, ) - : HttpError( - onReload: _controller.onReload, - ), + : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _controller.onReload, diff --git a/lib/pages/whisper_detail/view.dart b/lib/pages/whisper_detail/view.dart index 544ccad72..2b3d86c94 100644 --- a/lib/pages/whisper_detail/view.dart +++ b/lib/pages/whisper_detail/view.dart @@ -185,9 +185,7 @@ class _WhisperDetailPageState separatorBuilder: (context, index) => const SizedBox(height: 12), ) - : scrollErrorWidget( - onReload: _whisperDetailController.onReload, - ), + : scrollErrorWidget(onReload: _whisperDetailController.onReload), Error(:var errMsg) => scrollErrorWidget( errMsg: errMsg, onReload: _whisperDetailController.onReload, diff --git a/lib/pages/whisper_secondary/view.dart b/lib/pages/whisper_secondary/view.dart index 434df5fb0..c36e6ca89 100644 --- a/lib/pages/whisper_secondary/view.dart +++ b/lib/pages/whisper_secondary/view.dart @@ -90,9 +90,7 @@ class _WhisperSecPageState extends State { return switch (loadingState) { Loading() => SliverList.builder( itemCount: 12, - itemBuilder: (context, index) { - return const WhisperItemSkeleton(); - }, + itemBuilder: (context, index) => const WhisperItemSkeleton(), ), Success(:var response) => response?.isNotEmpty == true @@ -115,9 +113,7 @@ class _WhisperSecPageState extends State { }, separatorBuilder: (context, index) => divider, ) - : HttpError( - onReload: _controller.onReload, - ), + : HttpError(onReload: _controller.onReload), Error(:var errMsg) => HttpError( errMsg: errMsg, onReload: _controller.onReload, diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 95dc5ad69..ae16b2774 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -1618,9 +1618,6 @@ class PlPlayerController { } if (videoShot case Success success) { final data = success.response; - if (data.index.isNullOrEmpty) { - return; - } if (!showPreview.value) { showPreview.value = true; } @@ -1663,10 +1660,13 @@ class PlPlayerController { ), ); if (res.data['code'] == 0) { - videoShot = Success(VideoShotData.fromJson(res.data['data'])); - } else { - videoShot = const Error(null); + final data = VideoShotData.fromJson(res.data['data']); + if (data.index.isNotEmpty) { + videoShot = Success(data); + return; + } } + videoShot = const Error(null); } catch (e) { videoShot = const Error(null); if (kDebugMode) debugPrint('getVideoShot: $e'); diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index 0cf130622..860dbe5f2 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -1054,24 +1054,25 @@ class _PLVideoPlayerState extends State // Positioned.fill(top: 4, child: widget.danmuWidget!), /// 长按倍速 toast - Obx( - () => Align( + IgnorePointer( + ignoring: true, + child: Align( alignment: Alignment.topCenter, child: FractionalTranslation( - translation: const Offset(0.0, 0.3), // 上下偏移量(负数向上偏移) - child: AnimatedOpacity( - curve: Curves.easeInOut, - opacity: plPlayerController.longPressStatus.value ? 1.0 : 0.0, - duration: const Duration(milliseconds: 150), - child: Container( - alignment: Alignment.center, - decoration: const BoxDecoration( - color: Color(0x88000000), - borderRadius: BorderRadius.all(Radius.circular(16)), - ), - height: 32.0, - width: 70.0, - child: Center( + translation: isFullScreen + ? const Offset(0.0, 1.2) + : const Offset(0.0, 0.8), + child: Obx( + () => AnimatedOpacity( + curve: Curves.easeInOut, + opacity: plPlayerController.longPressStatus.value ? 1.0 : 0.0, + duration: const Duration(milliseconds: 150), + child: Container( + padding: const EdgeInsets.all(6), + decoration: const BoxDecoration( + color: Color(0x88000000), + borderRadius: BorderRadius.all(Radius.circular(16)), + ), child: Obx( () => Text( '${plPlayerController.enableAutoLongPressSpeed ? (plPlayerController.longPressStatus.value ? plPlayerController.lastPlaybackSpeed : plPlayerController.playbackSpeed) * 2 : plPlayerController.longPressSpeed}倍速中', @@ -1094,53 +1095,54 @@ class _PLVideoPlayerState extends State child: Align( alignment: Alignment.topCenter, child: FractionalTranslation( - translation: const Offset(0.0, 0.6), + translation: isFullScreen + ? const Offset(0.0, 1.2) + : const Offset(0.0, 0.8), child: Obx( () => AnimatedOpacity( curve: Curves.easeInOut, opacity: plPlayerController.isSliderMoving.value ? 1.0 : 0.0, duration: const Duration(milliseconds: 150), - child: IntrinsicWidth( - child: Container( - alignment: Alignment.center, - decoration: const BoxDecoration( - color: Color(0x88000000), - borderRadius: BorderRadius.all(Radius.circular(64)), - ), - height: 34.0, - padding: const EdgeInsets.only(left: 10, right: 10), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Obx(() { + child: Container( + decoration: const BoxDecoration( + color: Color(0x88000000), + borderRadius: BorderRadius.all(Radius.circular(64)), + ), + padding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 8, + ), + child: Row( + spacing: 2, + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Obx(() { + return Text( + DurationUtil.formatDuration( + plPlayerController + .sliderTempPosition + .value + .inSeconds, + ), + style: textStyle, + ); + }), + const Text('/', style: textStyle), + Obx( + () { return Text( DurationUtil.formatDuration( plPlayerController - .sliderTempPosition + .durationSeconds .value .inSeconds, ), style: textStyle, ); - }), - const SizedBox(width: 2), - const Text('/', style: textStyle), - const SizedBox(width: 2), - Obx( - () { - return Text( - DurationUtil.formatDuration( - plPlayerController - .durationSeconds - .value - .inSeconds, - ), - style: textStyle, - ); - }, - ), - ], - ), + }, + ), + ], ), ), ), @@ -1553,7 +1555,7 @@ class _PLVideoPlayerState extends State '$name.png已保存到相册/截图', ); } else { - await SmartDialog.showToast( + SmartDialog.showToast( '保存失败,${result.errorMessage}', ); } @@ -1589,7 +1591,7 @@ class _PLVideoPlayerState extends State child: GestureDetector( onTap: plPlayerController.refreshPlayer, child: Container( - padding: const EdgeInsets.all(30), + padding: const EdgeInsets.all(20), decoration: const BoxDecoration( shape: BoxShape.circle, gradient: RadialGradient( @@ -1920,22 +1922,20 @@ class _VideoShotImageState extends State { final imgYSize = _image!.height / 10; final height = widget.height; final width = height * imgXSize / imgYSize; - _size = Size(width, height); _setRect(width, height); widget.onSetSize(imgXSize, imgYSize); } else { - _size = const Size(double.nan, double.nan); _setRect(double.nan, double.nan); } } else { final height = widget.height; final width = height * widget.imgXSize / widget.imgYSize; - _size = Size(width, height); _setRect(width, height); } } void _setRect(double width, double height) { + _size = Size(width, height); _dstRect = Rect.fromLTWH(0, 0, width, height); _rrect = RRect.fromRectAndRadius(_dstRect, const Radius.circular(10)); } diff --git a/lib/utils/grid.dart b/lib/utils/grid.dart index 4998728ff..904bef241 100644 --- a/lib/utils/grid.dart +++ b/lib/utils/grid.dart @@ -1,10 +1,21 @@ import 'dart:math'; import 'package:PiliPlus/common/constants.dart'; +import 'package:PiliPlus/common/skeleton/video_card_h.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; +mixin GridMixin on State { + late final gridDelegate = Grid.videoCardHDelegate(context); + + Widget get gridSkeleton => SliverGrid.builder( + gridDelegate: gridDelegate, + itemBuilder: (_, _) => const VideoCardHSkeleton(), + itemCount: 10, + ); +} + class Grid { static final double smallCardWidth = Pref.smallCardWidth; diff --git a/lib/utils/waterfall.dart b/lib/utils/waterfall.dart index 7aab380b6..a292779d5 100644 --- a/lib/utils/waterfall.dart +++ b/lib/utils/waterfall.dart @@ -10,11 +10,12 @@ import 'package:waterfall_flow/waterfall_flow.dart' mixin DynMixin { late double maxWidth; - late final gridDelegate = SliverWaterfallFlowDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: Grid.smallCardWidth * 2, - crossAxisSpacing: 4, - callback: (value) => maxWidth = value, - ); + late final dynGridDelegate = + SliverWaterfallFlowDelegateWithMaxCrossAxisExtent( + maxCrossAxisExtent: Grid.smallCardWidth * 2, + crossAxisSpacing: 4, + callback: (value) => maxWidth = value, + ); late final skeDelegate = SliverGridDelegateWithExtentAndRatio( crossAxisSpacing: 4, @@ -25,27 +26,25 @@ mixin DynMixin { ); Widget get dynSkeleton { - if (!GlobalData().dynamicsWaterfallFlow) { - return SliverCrossAxisGroup( - slivers: [ - const SliverFillRemaining(), - SliverConstrainedCrossAxis( - maxExtent: Grid.smallCardWidth * 2, - sliver: SliverList.builder( - itemBuilder: (_, _) => const DynamicCardSkeleton(), - itemCount: 10, - ), - ), - const SliverFillRemaining(), - ], + if (GlobalData().dynamicsWaterfallFlow) { + return SliverGrid.builder( + gridDelegate: skeDelegate, + itemBuilder: (_, _) => const DynamicCardSkeleton(), + itemCount: 10, ); } - return SliverGrid( - gridDelegate: skeDelegate, - delegate: SliverChildBuilderDelegate( - (_, _) => const DynamicCardSkeleton(), - childCount: 10, - ), + return SliverCrossAxisGroup( + slivers: [ + const SliverFillRemaining(), + SliverConstrainedCrossAxis( + maxExtent: Grid.smallCardWidth * 2, + sliver: SliverList.builder( + itemBuilder: (_, _) => const DynamicCardSkeleton(), + itemCount: 10, + ), + ), + const SliverFillRemaining(), + ], ); } }