mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-17 06:40:13 +08:00
refa persistent header & dynamic sliver appbar
Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import 'dart:math' show pi;
|
||||
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/skeleton/video_reply.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/sliver/sliver_pinned_header.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
|
||||
show ReplyInfo;
|
||||
@@ -103,44 +104,33 @@ abstract class CommonDynPageState<T extends StatefulWidget> extends State<T>
|
||||
|
||||
Widget buildReplyHeader(ThemeData theme) {
|
||||
final secondary = theme.colorScheme.secondary;
|
||||
return SliverPersistentHeader(
|
||||
pinned: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 45,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: Container(
|
||||
height: 45,
|
||||
padding: const EdgeInsets.only(left: 12, right: 6),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final count = controller.count.value;
|
||||
return Text(
|
||||
'${count == -1 ? 0 : NumUtils.numFormat(count)}条回复',
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: 35,
|
||||
child: TextButton.icon(
|
||||
onPressed: controller.queryBySort,
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
color: secondary,
|
||||
),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
controller.sortType.value.label,
|
||||
style: TextStyle(fontSize: 13, color: secondary),
|
||||
),
|
||||
),
|
||||
return SliverPinnedHeader(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const .fromLTRB(12, 2.5, 6, 2.5),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final count = controller.count.value;
|
||||
return Text(
|
||||
'${count == -1 ? 0 : NumUtils.numFormat(count)}条回复',
|
||||
);
|
||||
},
|
||||
),
|
||||
TextButton.icon(
|
||||
style: StyleString.buttonStyle,
|
||||
onPressed: controller.queryBySort,
|
||||
icon: Icon(Icons.sort, size: 16, color: secondary),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
controller.sortType.value.label,
|
||||
style: TextStyle(fontSize: 13, color: secondary),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/draggable_sheet/draggable_scrollable_sheet_topic.dart'
|
||||
as topic_sheet;
|
||||
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/sliver/sliver_pinned_header.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models_new/dynamic/dyn_mention/group.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_mention/controller.dart';
|
||||
@@ -247,18 +247,14 @@ class _DynMentionPanelState
|
||||
}
|
||||
return SliverMainAxisGroup(
|
||||
slivers: [
|
||||
SliverPersistentHeader(
|
||||
pinned: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 40,
|
||||
needRebuild: true,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: Container(
|
||||
height: 40,
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Text(group.groupName!),
|
||||
SliverPinnedHeader(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const .symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 10,
|
||||
),
|
||||
child: Text(group.groupName!),
|
||||
),
|
||||
),
|
||||
SliverList.builder(
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import 'package:PiliPlus/common/widgets/custom_icon.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/dynamic_sliver_appbar_medium.dart';
|
||||
import 'package:PiliPlus/common/widgets/dynamic_sliver_app_bar/dynamic_sliver_app_bar.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.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/pair.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_pinned_header.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/image_type.dart';
|
||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_feed/item.dart';
|
||||
@@ -78,56 +78,49 @@ class _DynTopicPageState extends State<DynTopicPage> with DynMixin {
|
||||
Obx(() {
|
||||
final allSortBy = _controller.topicSortByConf.value?.allSortBy;
|
||||
if (allSortBy != null && allSortBy.isNotEmpty) {
|
||||
return SliverPersistentHeader(
|
||||
pinned: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 36,
|
||||
needRebuild: true,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: Container(
|
||||
height: 36,
|
||||
padding: EdgeInsets.only(
|
||||
left: 12 + padding.left,
|
||||
top: 6,
|
||||
bottom: 6,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return ToggleButtons(
|
||||
fillColor: theme.colorScheme.secondaryContainer,
|
||||
selectedColor:
|
||||
theme.colorScheme.onSecondaryContainer,
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: 54,
|
||||
minHeight: 24,
|
||||
),
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
borderRadius: const .all(.circular(25)),
|
||||
onPressed: (index) {
|
||||
_controller.onSort(allSortBy[index].sortBy!);
|
||||
(context as Element).markNeedsBuild();
|
||||
},
|
||||
isSelected: allSortBy
|
||||
.map((e) => e.sortBy == _controller.sortBy)
|
||||
.toList(),
|
||||
children: allSortBy.map((e) {
|
||||
return Text(
|
||||
e.sortName!,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
height: 1,
|
||||
),
|
||||
strutStyle: const StrutStyle(
|
||||
height: 1,
|
||||
leading: 0,
|
||||
fontSize: 13,
|
||||
),
|
||||
textScaler: TextScaler.noScaling,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
},
|
||||
),
|
||||
return SliverPinnedHeader(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 12 + padding.left,
|
||||
top: 6,
|
||||
bottom: 6,
|
||||
),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return ToggleButtons(
|
||||
fillColor: theme.colorScheme.secondaryContainer,
|
||||
selectedColor: theme.colorScheme.onSecondaryContainer,
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: 54,
|
||||
minHeight: 24,
|
||||
),
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
borderRadius: const .all(.circular(25)),
|
||||
onPressed: (index) {
|
||||
_controller.onSort(allSortBy[index].sortBy!);
|
||||
(context as Element).markNeedsBuild();
|
||||
},
|
||||
isSelected: allSortBy
|
||||
.map((e) => e.sortBy == _controller.sortBy)
|
||||
.toList(),
|
||||
children: allSortBy.map((e) {
|
||||
return Text(
|
||||
e.sortName!,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
height: 1,
|
||||
),
|
||||
strutStyle: const StrutStyle(
|
||||
height: 1,
|
||||
leading: 0,
|
||||
fontSize: 13,
|
||||
),
|
||||
textScaler: TextScaler.noScaling,
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -157,10 +150,9 @@ class _DynTopicPageState extends State<DynTopicPage> with DynMixin {
|
||||
) {
|
||||
return switch (topState) {
|
||||
Loading() => const SliverAppBar(),
|
||||
Success(:final response) when response != null => DynamicSliverAppBarMedium(
|
||||
pinned: true,
|
||||
onPerformLayout: (value) =>
|
||||
_controller.appbarOffset = value - kToolbarHeight - padding.top,
|
||||
Success(:final response) when response != null => DynamicSliverAppBar.medium(
|
||||
onPerformLayout: (value) => _controller.appbarOffset =
|
||||
value.height - kToolbarHeight - padding.top,
|
||||
title: IgnorePointer(child: Text(response.topicItem!.name)),
|
||||
flexibleSpace: Container(
|
||||
decoration: BoxDecoration(
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_pinned_header.dart';
|
||||
import 'package:PiliPlus/models/common/live/live_dm_silent_type.dart';
|
||||
import 'package:PiliPlus/models_new/live/live_dm_block/shield_user_list.dart';
|
||||
import 'package:PiliPlus/pages/live_dm_block/controller.dart';
|
||||
@@ -102,13 +102,7 @@ class _LiveDmBlockPageState extends State<LiveDmBlockPage> {
|
||||
ExtendedNestedScrollView.sliverOverlapAbsorberHandleFor(
|
||||
context,
|
||||
),
|
||||
sliver: SliverPersistentHeader(
|
||||
pinned: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 48,
|
||||
child: tabBar,
|
||||
),
|
||||
),
|
||||
sliver: SliverPinnedHeader(child: tabBar),
|
||||
),
|
||||
];
|
||||
},
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/skeleton/video_reply.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_floating_header.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
|
||||
show ReplyInfo;
|
||||
@@ -15,7 +16,6 @@ import 'package:PiliPlus/utils/num_utils.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart' show ScrollDirection;
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class MainReplyPage extends StatefulWidget {
|
||||
@@ -61,9 +61,9 @@ class _MainReplyPageState extends State<MainReplyPage> {
|
||||
body: NotificationListener<UserScrollNotification>(
|
||||
onNotification: (notification) {
|
||||
final direction = notification.direction;
|
||||
if (direction == ScrollDirection.forward) {
|
||||
if (direction == .forward) {
|
||||
_controller.showFab();
|
||||
} else if (direction == ScrollDirection.reverse) {
|
||||
} else if (direction == .reverse) {
|
||||
_controller.hideFab();
|
||||
}
|
||||
return false;
|
||||
@@ -172,44 +172,33 @@ class _MainReplyPageState extends State<MainReplyPage> {
|
||||
|
||||
Widget buildReplyHeader(ColorScheme colorScheme) {
|
||||
final secondary = colorScheme.secondary;
|
||||
return SliverPersistentHeader(
|
||||
floating: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 45,
|
||||
bgColor: colorScheme.surface,
|
||||
child: Container(
|
||||
height: 45,
|
||||
padding: const EdgeInsets.only(left: 12, right: 6),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final count = _controller.count.value;
|
||||
return Text(
|
||||
'${count == -1 ? 0 : NumUtils.numFormat(count)}条回复',
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: 35,
|
||||
child: TextButton.icon(
|
||||
onPressed: _controller.queryBySort,
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
color: secondary,
|
||||
),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
_controller.sortType.value.label,
|
||||
style: TextStyle(fontSize: 13, color: secondary),
|
||||
),
|
||||
),
|
||||
return SliverFloatingHeaderWidget(
|
||||
backgroundColor: colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const .fromLTRB(12, 2.5, 6, 2.5),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final count = _controller.count.value;
|
||||
return Text(
|
||||
'${count == -1 ? 0 : NumUtils.numFormat(count)}条回复',
|
||||
);
|
||||
},
|
||||
),
|
||||
TextButton.icon(
|
||||
style: StyleString.buttonStyle,
|
||||
onPressed: _controller.queryBySort,
|
||||
icon: Icon(Icons.sort, size: 16, color: secondary),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
_controller.sortType.value.label,
|
||||
style: TextStyle(fontSize: 13, color: secondary),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:PiliPlus/common/widgets/dialog/report_member.dart';
|
||||
import 'package:PiliPlus/common/widgets/dynamic_sliver_appbar_medium.dart';
|
||||
import 'package:PiliPlus/common/widgets/dynamic_sliver_app_bar/dynamic_sliver_app_bar.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
@@ -328,8 +328,7 @@ class _MemberPageState extends State<MemberPage> {
|
||||
return const CircularProgressIndicator();
|
||||
case Success<SpaceData?>(:final response):
|
||||
if (response != null) {
|
||||
return DynamicSliverAppBarMedium(
|
||||
pinned: true,
|
||||
return DynamicSliverAppBar.medium(
|
||||
actions: _actions(theme),
|
||||
title: Text(_userController.username ?? ''),
|
||||
flexibleSpace: Obx(
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_floating_header.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models_new/space/space_audio/item.dart';
|
||||
import 'package:PiliPlus/pages/member_audio/controller.dart';
|
||||
@@ -80,44 +80,36 @@ class _MemberAudioState extends State<MemberAudio>
|
||||
response != null && response.isNotEmpty
|
||||
? SliverMainAxisGroup(
|
||||
slivers: [
|
||||
SliverPersistentHeader(
|
||||
floating: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 40,
|
||||
bgColor: colorScheme.surface,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(width: 8),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6),
|
||||
child: Text(
|
||||
'共${_controller.totalSize ?? 0}首',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
SliverFloatingHeaderWidget(
|
||||
backgroundColor: colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(14, 2.5, 8, 2.5),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
'共${_controller.totalSize ?? 0}首',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6),
|
||||
child: TextButton.icon(
|
||||
style: StyleString.buttonStyle,
|
||||
onPressed: _controller.toViewPlayAll,
|
||||
icon: Icon(
|
||||
Icons.play_circle_outline_rounded,
|
||||
size: 16,
|
||||
color: colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(left: 6),
|
||||
child: TextButton.icon(
|
||||
onPressed: _controller.toViewPlayAll,
|
||||
icon: Icon(
|
||||
Icons.play_circle_outline_rounded,
|
||||
size: 16,
|
||||
label: Text(
|
||||
'播放全部',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: colorScheme.secondary,
|
||||
),
|
||||
label: Text(
|
||||
'播放全部',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -97,13 +97,14 @@ class _MemberContributeState extends State<MemberContribute>
|
||||
}
|
||||
|
||||
Widget _getPageFromType(SpaceTab2Item item) {
|
||||
final isSingle = _controller.tabs == null;
|
||||
return switch (item.param) {
|
||||
'video' => MemberVideo(
|
||||
type: ContributeType.video,
|
||||
heroTag: widget.heroTag,
|
||||
mid: widget.mid,
|
||||
title: item.title,
|
||||
isSingle: _controller.tabs == null,
|
||||
isSingle: isSingle,
|
||||
),
|
||||
'charging_video' => MemberVideo(
|
||||
type: ContributeType.charging,
|
||||
@@ -116,9 +117,9 @@ class _MemberContributeState extends State<MemberContribute>
|
||||
mid: widget.mid,
|
||||
),
|
||||
'opus' => MemberOpus(
|
||||
isSingle: _controller.tabs == null,
|
||||
heroTag: widget.heroTag,
|
||||
mid: widget.mid,
|
||||
isSingle: isSingle,
|
||||
),
|
||||
'audio' => MemberAudio(
|
||||
heroTag: widget.heroTag,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_pinned_header.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models_new/space/space_fav/data.dart';
|
||||
import 'package:PiliPlus/pages/member_favorite/controller.dart';
|
||||
@@ -109,56 +109,51 @@ class _MemberFavoriteState extends State<MemberFavorite>
|
||||
}) {
|
||||
return SliverMainAxisGroup(
|
||||
slivers: [
|
||||
SliverPersistentHeader(
|
||||
pinned: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
child: Material(
|
||||
color: theme.colorScheme.surface,
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
_controller.setExpand(isFav);
|
||||
(context as Element).markNeedsBuild();
|
||||
data.refresh();
|
||||
if (!isEnd.value) {
|
||||
isEnd.refresh();
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
height: 45,
|
||||
alignment: .centerLeft,
|
||||
padding: const .only(left: 12),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: .middle,
|
||||
child: Icon(
|
||||
_controller.isExpand(isFav)
|
||||
? Icons.expand_less
|
||||
: Icons.expand_more,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
SliverPinnedHeader(
|
||||
child: Material(
|
||||
color: theme.colorScheme.surface,
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
_controller.setExpand(isFav);
|
||||
(context as Element).markNeedsBuild();
|
||||
data.refresh();
|
||||
if (!isEnd.value) {
|
||||
isEnd.refresh();
|
||||
}
|
||||
},
|
||||
child: Padding(
|
||||
padding: const .symmetric(horizontal: 12, vertical: 10),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: .middle,
|
||||
child: Icon(
|
||||
_controller.isExpand(isFav)
|
||||
? Icons.expand_less
|
||||
: Icons.expand_more,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
TextSpan(
|
||||
text: ' ${data.value.name}',
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
TextSpan(
|
||||
text: ' ${data.value.name}',
|
||||
style: const TextStyle(fontSize: 14),
|
||||
),
|
||||
TextSpan(
|
||||
text: ' ${data.value.mediaListResponse?.count}',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
TextSpan(
|
||||
text: ' ${data.value.mediaListResponse?.count}',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.outline,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_floating_header.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/member/contribute_type.dart';
|
||||
import 'package:PiliPlus/models_new/space/space_archive/item.dart';
|
||||
@@ -173,91 +174,78 @@ class _MemberVideoState extends State<MemberVideo>
|
||||
response != null && response.isNotEmpty
|
||||
? SliverMainAxisGroup(
|
||||
slivers: [
|
||||
SliverPersistentHeader(
|
||||
pinned: false,
|
||||
floating: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 40,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(width: 8),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 6),
|
||||
child: Obx(
|
||||
() {
|
||||
final count = _controller.count.value;
|
||||
return Text(
|
||||
count != -1 ? '共$count视频' : '',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Obx(
|
||||
() {
|
||||
final episodicButton =
|
||||
_controller.episodicButton.value;
|
||||
return episodicButton.uri?.isNotEmpty == true
|
||||
? Container(
|
||||
height: 35,
|
||||
padding: EdgeInsets.only(
|
||||
left: _controller.count.value != -1
|
||||
? 6
|
||||
: 0,
|
||||
SliverFloatingHeaderWidget(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(14, 2.5, 8, 2.5),
|
||||
child: Row(
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final count = _controller.count.value;
|
||||
return Text(
|
||||
count != -1 ? '共$count视频' : '',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
);
|
||||
},
|
||||
),
|
||||
Obx(
|
||||
() {
|
||||
final episodicButton =
|
||||
_controller.episodicButton.value;
|
||||
return episodicButton.uri?.isNotEmpty == true
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: _controller.count.value != -1
|
||||
? 6
|
||||
: 0,
|
||||
),
|
||||
child: TextButton.icon(
|
||||
style: StyleString.buttonStyle,
|
||||
onPressed: _controller.toViewPlayAll,
|
||||
icon: Icon(
|
||||
Icons.play_circle_outline_rounded,
|
||||
size: 16,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
child: TextButton.icon(
|
||||
onPressed: _controller.toViewPlayAll,
|
||||
icon: Icon(
|
||||
Icons.play_circle_outline_rounded,
|
||||
size: 16,
|
||||
label: Text(
|
||||
episodicButton.text ?? '播放全部',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Text(
|
||||
episodicButton.text ?? '播放全部',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color:
|
||||
theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
const Spacer(),
|
||||
TextButton.icon(
|
||||
style: StyleString.buttonStyle,
|
||||
onPressed: _controller.queryBySort,
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
height: 35,
|
||||
child: TextButton.icon(
|
||||
onPressed: _controller.queryBySort,
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
label: Obx(
|
||||
() => Text(
|
||||
widget.type == ContributeType.video
|
||||
? _controller.order.value == 'pubdate'
|
||||
? '最新发布'
|
||||
: '最多播放'
|
||||
: _controller.sort.value == 'desc'
|
||||
? '默认'
|
||||
: '倒序',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
widget.type == ContributeType.video
|
||||
? _controller.order.value == 'pubdate'
|
||||
? '最新发布'
|
||||
: '最多播放'
|
||||
: _controller.sort.value == 'desc'
|
||||
? '默认'
|
||||
: '倒序',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/skeleton/video_reply.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_icon.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/selectable_text/selectable_text.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/sliver/sliver_floating_header.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/image_type.dart';
|
||||
import 'package:PiliPlus/models/common/pgc_review_type.dart';
|
||||
@@ -383,51 +384,43 @@ class _PgcReviewChildPageState extends State<PgcReviewChildPage>
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHeader(ThemeData theme) => SliverPersistentHeader(
|
||||
pinned: false,
|
||||
floating: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 40,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: Container(
|
||||
height: 40,
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final count = _controller.count.value;
|
||||
return count == null
|
||||
? const SizedBox.shrink()
|
||||
: Text(
|
||||
'${NumUtils.numFormat(count)}条点评',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
);
|
||||
},
|
||||
Widget _buildHeader(ThemeData theme) => SliverFloatingHeaderWidget(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(12, 2.5, 6, 2.5),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final count = _controller.count.value;
|
||||
return count == null
|
||||
? const SizedBox.shrink()
|
||||
: Text(
|
||||
'${NumUtils.numFormat(count)}条点评',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
);
|
||||
},
|
||||
),
|
||||
TextButton.icon(
|
||||
style: StyleString.buttonStyle,
|
||||
onPressed: _controller.queryBySort,
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
SizedBox(
|
||||
height: 35,
|
||||
child: TextButton.icon(
|
||||
onPressed: _controller.queryBySort,
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
label: Obx(
|
||||
() => Text(
|
||||
_controller.sortType.value.label,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
_controller.sortType.value.label,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_floating_header.dart';
|
||||
import 'package:PiliPlus/common/widgets/video_card/video_card_h.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_sliver_safe_area.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
@@ -201,17 +201,11 @@ class _PopularSeriesPageState extends State<PopularSeriesPage> with GridMixin {
|
||||
],
|
||||
);
|
||||
}
|
||||
final height = MediaQuery.textScalerOf(context).scale(27);
|
||||
return SliverPersistentHeader(
|
||||
floating: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: height,
|
||||
child: Container(
|
||||
height: height,
|
||||
padding: const EdgeInsets.only(left: 14, bottom: 7),
|
||||
child: child,
|
||||
),
|
||||
bgColor: colorScheme.surface,
|
||||
return SliverFloatingHeaderWidget(
|
||||
backgroundColor: colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const .only(left: 14, bottom: 7),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_floating_header.dart';
|
||||
import 'package:PiliPlus/models/search/result.dart';
|
||||
import 'package:PiliPlus/pages/search_panel/article/controller.dart';
|
||||
import 'package:PiliPlus/pages/search_panel/article/widgets/item.dart';
|
||||
@@ -45,51 +45,45 @@ class _SearchArticlePanelState
|
||||
|
||||
@override
|
||||
Widget buildHeader(ThemeData theme) {
|
||||
return SliverPersistentHeader(
|
||||
pinned: false,
|
||||
floating: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 40,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: Container(
|
||||
height: 40,
|
||||
padding: const EdgeInsets.only(left: 25, right: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Obx(
|
||||
() => Text(
|
||||
'排序: ${controller.articleOrderType.value.label}',
|
||||
maxLines: 1,
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
return SliverFloatingHeaderWidget(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const .fromLTRB(25, 0, 12, 4),
|
||||
child: Row(
|
||||
children: [
|
||||
Obx(
|
||||
() => Text(
|
||||
'排序: ${controller.articleOrderType.value.label}',
|
||||
maxLines: 1,
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Obx(
|
||||
() => Text(
|
||||
'分区: ${controller.articleZoneType!.value.label}',
|
||||
maxLines: 1,
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: 32,
|
||||
height: 32,
|
||||
child: IconButton(
|
||||
tooltip: '筛选',
|
||||
style: const ButtonStyle(
|
||||
padding: WidgetStatePropertyAll(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => controller.onShowFilterDialog(context),
|
||||
icon: Icon(
|
||||
Icons.filter_list_outlined,
|
||||
size: 18,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Obx(
|
||||
() => Text(
|
||||
'分区: ${controller.articleZoneType!.value.label}',
|
||||
maxLines: 1,
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: 32,
|
||||
height: 32,
|
||||
child: IconButton(
|
||||
tooltip: '筛选',
|
||||
style: const ButtonStyle(
|
||||
padding: WidgetStatePropertyAll(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => controller.onShowFilterDialog(context),
|
||||
icon: Icon(
|
||||
Icons.filter_list_outlined,
|
||||
size: 18,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:PiliPlus/common/skeleton/msg_feed_top.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_floating_header.dart';
|
||||
import 'package:PiliPlus/models/search/result.dart';
|
||||
import 'package:PiliPlus/pages/search_panel/user/controller.dart';
|
||||
import 'package:PiliPlus/pages/search_panel/user/widgets/item.dart';
|
||||
@@ -46,51 +46,45 @@ class _SearchUserPanelState
|
||||
|
||||
@override
|
||||
Widget buildHeader(ThemeData theme) {
|
||||
return SliverPersistentHeader(
|
||||
pinned: false,
|
||||
floating: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 40,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: Container(
|
||||
height: 40,
|
||||
padding: const EdgeInsets.only(left: 25, right: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Obx(
|
||||
() => Text(
|
||||
'排序: ${controller.userOrderType!.value.label}',
|
||||
maxLines: 1,
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
return SliverFloatingHeaderWidget(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const .fromLTRB(25, 0, 12, 4),
|
||||
child: Row(
|
||||
children: [
|
||||
Obx(
|
||||
() => Text(
|
||||
'排序: ${controller.userOrderType!.value.label}',
|
||||
maxLines: 1,
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Obx(
|
||||
() => Text(
|
||||
'用户类型: ${controller.userType!.value.label}',
|
||||
maxLines: 1,
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: 32,
|
||||
height: 32,
|
||||
child: IconButton(
|
||||
tooltip: '筛选',
|
||||
style: const ButtonStyle(
|
||||
padding: WidgetStatePropertyAll(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => controller.onShowFilterDialog(context),
|
||||
icon: Icon(
|
||||
Icons.filter_list_outlined,
|
||||
size: 18,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Obx(
|
||||
() => Text(
|
||||
'用户类型: ${controller.userType!.value.label}',
|
||||
maxLines: 1,
|
||||
style: TextStyle(color: theme.colorScheme.outline),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: 32,
|
||||
height: 32,
|
||||
child: IconButton(
|
||||
tooltip: '筛选',
|
||||
style: const ButtonStyle(
|
||||
padding: WidgetStatePropertyAll(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => controller.onShowFilterDialog(context),
|
||||
icon: Icon(
|
||||
Icons.filter_list_outlined,
|
||||
size: 18,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_floating_header.dart';
|
||||
import 'package:PiliPlus/common/widgets/video_card/video_card_h.dart';
|
||||
import 'package:PiliPlus/models/common/search/video_search_type.dart';
|
||||
import 'package:PiliPlus/models/search/result.dart';
|
||||
@@ -47,61 +47,55 @@ class _SearchVideoPanelState
|
||||
|
||||
@override
|
||||
Widget buildHeader(ThemeData theme) {
|
||||
return SliverPersistentHeader(
|
||||
pinned: false,
|
||||
floating: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 34,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: Container(
|
||||
height: 34,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Wrap(
|
||||
children: [
|
||||
for (final e in ArchiveFilterType.values)
|
||||
Obx(
|
||||
() => SearchText(
|
||||
fontSize: 13,
|
||||
text: e.desc,
|
||||
bgColor: Colors.transparent,
|
||||
textColor: controller.selectedType.value == e
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.outline,
|
||||
onTap: (_) => controller
|
||||
..order = e.name
|
||||
..selectedType.value = e
|
||||
..onSortSearch(getBack: false),
|
||||
),
|
||||
return SliverFloatingHeaderWidget(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const .fromLTRB(12, 0, 12, 4),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Wrap(
|
||||
children: [
|
||||
for (final e in ArchiveFilterType.values)
|
||||
Obx(
|
||||
() => SearchText(
|
||||
fontSize: 13,
|
||||
text: e.desc,
|
||||
bgColor: Colors.transparent,
|
||||
textColor: controller.selectedType.value == e
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.outline,
|
||||
onTap: (_) => controller
|
||||
..order = e.name
|
||||
..selectedType.value = e
|
||||
..onSortSearch(getBack: false),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const VerticalDivider(indent: 7, endIndent: 8),
|
||||
const SizedBox(width: 3),
|
||||
SizedBox(
|
||||
width: 32,
|
||||
height: 32,
|
||||
child: IconButton(
|
||||
tooltip: '筛选',
|
||||
style: const ButtonStyle(
|
||||
padding: WidgetStatePropertyAll(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => controller.onShowFilterDialog(context),
|
||||
icon: Icon(
|
||||
Icons.filter_list_outlined,
|
||||
size: 18,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
const VerticalDivider(indent: 7, endIndent: 8),
|
||||
const SizedBox(width: 3),
|
||||
SizedBox(
|
||||
width: 32,
|
||||
height: 32,
|
||||
child: IconButton(
|
||||
tooltip: '筛选',
|
||||
style: const ButtonStyle(
|
||||
padding: WidgetStatePropertyAll(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => controller.onShowFilterDialog(context),
|
||||
icon: Icon(
|
||||
Icons.filter_list_outlined,
|
||||
size: 18,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/skeleton/video_card_h.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
@@ -136,24 +137,22 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
height: 35,
|
||||
child: TextButton.icon(
|
||||
onPressed: () => _controller
|
||||
..lastAid = widget.videoDetailController.aid.toString()
|
||||
..queryBySort(),
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
_controller.order.value == 'pubdate' ? '最新发布' : '最多播放',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
TextButton.icon(
|
||||
style: StyleString.buttonStyle,
|
||||
onPressed: () => _controller
|
||||
..lastAid = widget.videoDetailController.aid.toString()
|
||||
..queryBySort(),
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
_controller.order.value == 'pubdate' ? '最新发布' : '最多播放',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/skeleton/video_reply.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_floating_header.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
|
||||
show ReplyInfo;
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
@@ -83,47 +84,39 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
: _videoReplyController.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
key: const PageStorageKey(_VideoReplyPanelState),
|
||||
slivers: <Widget>[
|
||||
SliverPersistentHeader(
|
||||
pinned: false,
|
||||
floating: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 40,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: Container(
|
||||
height: 40,
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() => Text(
|
||||
_videoReplyController.sortType.value.title,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
slivers: [
|
||||
SliverFloatingHeaderWidget(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const .fromLTRB(12, 2.5, 6, 2.5),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() => Text(
|
||||
_videoReplyController.sortType.value.title,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
SizedBox(
|
||||
height: 35,
|
||||
child: TextButton.icon(
|
||||
onPressed: _videoReplyController.queryBySort,
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
),
|
||||
TextButton.icon(
|
||||
style: StyleString.buttonStyle,
|
||||
onPressed: _videoReplyController.queryBySort,
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
_videoReplyController.sortType.value.label,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
_videoReplyController.sortType.value.label,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/skeleton/video_reply.dart';
|
||||
import 'package:PiliPlus/common/widgets/colored_box_transition.dart';
|
||||
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_pinned_header.dart';
|
||||
import 'package:PiliPlus/common/widgets/view_safe_area.dart';
|
||||
import 'package:PiliPlus/grpc/bilibili/main/community/reply/v1.pb.dart'
|
||||
show ReplyInfo, Mode;
|
||||
@@ -240,52 +241,43 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel>
|
||||
}
|
||||
|
||||
Widget _sortWidget(ThemeData theme) {
|
||||
return SliverPersistentHeader(
|
||||
pinned: true,
|
||||
delegate: CustomSliverPersistentHeaderDelegate(
|
||||
extent: 40,
|
||||
bgColor: theme.colorScheme.surface,
|
||||
child: Container(
|
||||
height: 40,
|
||||
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final count = _controller.count.value;
|
||||
return count != -1
|
||||
? Text(
|
||||
'相关回复共${NumUtils.numFormat(count)}条',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
)
|
||||
: const SizedBox.shrink();
|
||||
},
|
||||
return SliverPinnedHeader(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(12, 2.5, 6, 2.5),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final count = _controller.count.value;
|
||||
return count != -1
|
||||
? Text(
|
||||
'相关回复共${NumUtils.numFormat(count)}条',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
)
|
||||
: const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
TextButton.icon(
|
||||
style: StyleString.buttonStyle,
|
||||
onPressed: _controller.queryBySort,
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
SizedBox(
|
||||
height: 35,
|
||||
child: TextButton.icon(
|
||||
onPressed: _controller.queryBySort,
|
||||
icon: Icon(
|
||||
Icons.sort,
|
||||
size: 16,
|
||||
label: Obx(
|
||||
() => Text(
|
||||
_controller.mode.value == Mode.MAIN_LIST_HOT ? '按热度' : '按时间',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Obx(
|
||||
() => Text(
|
||||
_controller.mode.value == Mode.MAIN_LIST_HOT
|
||||
? '按热度'
|
||||
: '按时间',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image_viewer/hero_dialog_route.dart';
|
||||
import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
import 'package:PiliPlus/common/widgets/sliver/sliver_pinned_dynamic_header.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/main.dart';
|
||||
import 'package:PiliPlus/models/common/episode_panel_type.dart';
|
||||
@@ -648,14 +649,10 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
||||
? animHeight
|
||||
: videoDetailController.videoHeight;
|
||||
return [
|
||||
SliverAppBar(
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
primary: false,
|
||||
automaticallyImplyLeading: false,
|
||||
pinned: true,
|
||||
expandedHeight: height,
|
||||
flexibleSpace: Stack(
|
||||
SliverPinnedDynamicHeader(
|
||||
minExtent: kToolbarHeight,
|
||||
maxExtent: height,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
SizedBox(
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io' show File;
|
||||
|
||||
import 'package:PiliPlus/common/widgets/chat_list_view.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/report.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/chat_list_view.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/text_field/text_field.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||
|
||||
Reference in New Issue
Block a user