mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-08-04 17:50:13 +08:00
@@ -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: [
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user