Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-08-16 10:52:39 +08:00
parent 2090fd2312
commit 55733d30c5
86 changed files with 1359 additions and 1740 deletions

View File

@@ -61,6 +61,7 @@ class _AiDetailState extends CommonCollapseSlidePageState<AiConclusionPanel> {
@override
Widget buildList(ThemeData theme) {
return CustomScrollView(
key: const PageStorageKey('ai_detail'),
controller: _controller,
physics: const AlwaysScrollableScrollPhysics(),
slivers: [

View File

@@ -99,6 +99,7 @@ class _IntroDetailState extends CommonCollapseSlidePageState<PgcIntroPanel> {
);
return SelectionArea(
child: ListView(
key: const PageStorageKey('pgc_intro'),
controller: _controller,
physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.only(

View File

@@ -136,6 +136,7 @@ class _PagesPanelState extends State<PagesPanel> {
SizedBox(
height: 35,
child: ListView.builder(
key: PageStorageKey(hashCode),
controller: _scrollController,
scrollDirection: Axis.horizontal,
itemCount: pages.length,

View File

@@ -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<T extends StatefulWidget> extends State<T>
} else if (_timer != null && _timer!.tick == 0) {
_cancelTimer();
if (isTapUp) {
feedBack();
introController.actionLikeVideo();
}
}

View File

@@ -49,14 +49,20 @@ class MediaListPanel extends CommonCollapseSlidePage {
class _MediaListPanelState
extends CommonCollapseSlidePageState<MediaListPanel> {
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,

View File

@@ -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<HorizontalMemberPage> createState() => _HorizontalMemberPageState();
}
class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
class _HorizontalMemberPageState extends State<HorizontalMemberPage>
with GridMixin {
late final HorizontalMemberPageController _controller;
AccountService accountService = Get.find<AccountService>();
dynamic _bvid;
@@ -173,46 +173,36 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
LoadingState<List<SpaceArchiveItem>?> 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),

View File

@@ -173,9 +173,7 @@ class _NoteListPageState extends CommonSlidePageState<NoteListPage> {
child: ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return const VideoReplySkeleton();
},
itemBuilder: (context, index) => const VideoReplySkeleton(),
itemCount: 8,
),
),

View File

@@ -112,6 +112,7 @@ class _PostPanelState extends CommonCollapseSlidePageState<PostPanel> {
clipBehavior: Clip.none,
children: [
SingleChildScrollView(
key: const PageStorageKey('segment_list'),
controller: _controller,
physics: const AlwaysScrollableScrollPhysics(),
padding: EdgeInsets.only(bottom: 88 + bottom),

View File

@@ -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<RelatedVideoPanel>
with AutomaticKeepAliveClientMixin {
with AutomaticKeepAliveClientMixin, GridMixin {
late final RelatedController _relatedController = Get.put(
RelatedController(),
tag: widget.heroTag,
@@ -39,30 +38,20 @@ class _RelatedVideoPanelState extends State<RelatedVideoPanel>
Widget _buildBody(LoadingState<List<HotVideoItemModel>?> 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(

View File

@@ -188,9 +188,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
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) =>

View File

@@ -296,17 +296,18 @@ class _ReplyPageState extends CommonRichTextPubPageState<ReplyPage> {
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 {

View File

@@ -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,
),
),

View File

@@ -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<ReplySearchChildPage>
with AutomaticKeepAliveClientMixin {
with AutomaticKeepAliveClientMixin, GridMixin {
ReplySearchChildController get _controller => widget.controller;
@override
@@ -50,37 +49,23 @@ class _ReplySearchChildPageState extends State<ReplySearchChildPage>
);
}
Widget get _buildLoading {
return SliverGrid(
gridDelegate: Grid.videoCardHDelegate(context),
delegate: SliverChildBuilderDelegate(
(context, index) {
return const VideoCardHSkeleton();
},
childCount: 10,
),
);
}
Widget _buildBody(LoadingState<List<SearchItem>?> 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(

View File

@@ -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,
);
}