top up panel

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-05-15 18:48:31 +08:00
parent e54a0f127f
commit 35bc4a6ece
5 changed files with 115 additions and 85 deletions

View File

@@ -1,10 +1,10 @@
enum UpPanelPosition { enum UpPanelPosition {
leftFixed, top('顶部'),
rightFixed, leftFixed('左侧常驻'),
leftDrawer, rightFixed('右侧常驻'),
rightDrawer, leftDrawer('左侧抽屉'),
} rightDrawer('右侧抽屉');
extension UpPanelPositionExt on UpPanelPosition { final String label;
String get labels => const ['左侧常驻', '右侧常驻', '左侧抽屉', '右侧抽屉'][index]; const UpPanelPosition(this.label);
} }

View File

@@ -39,6 +39,8 @@ class DynamicsController extends GetxController
late int currentMid = -1; late int currentMid = -1;
late bool showLiveItems = GStorage.expandDynLivePanel; late bool showLiveItems = GStorage.expandDynLivePanel;
final upPanelPosition = GStorage.upPanelPosition;
DynamicsTabController? get controller { DynamicsTabController? get controller {
try { try {
return Get.find<DynamicsTabController>( return Get.find<DynamicsTabController>(

View File

@@ -19,20 +19,12 @@ class DynamicsPage extends StatefulWidget {
class _DynamicsPageState extends State<DynamicsPage> class _DynamicsPageState extends State<DynamicsPage>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
final DynamicsController _dynamicsController = Get.put(DynamicsController()); final DynamicsController _dynamicsController = Get.put(DynamicsController());
late UpPanelPosition upPanelPosition; UpPanelPosition get upPanelPosition => _dynamicsController.upPanelPosition;
late ThemeData theme;
@override
void didChangeDependencies() {
super.didChangeDependencies();
theme = Theme.of(context);
}
@override @override
bool get wantKeepAlive => true; bool get wantKeepAlive => true;
Widget _createDynamicBtn([bool isRight = true]) => Center( Widget _createDynamicBtn(ThemeData theme, [bool isRight = true]) => Center(
child: Container( child: Container(
width: 34, width: 34,
height: 34, height: 34,
@@ -68,8 +60,6 @@ class _DynamicsPageState extends State<DynamicsPage>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
upPanelPosition = GStorage.upPanelPosition;
debugPrint('upPanelPosition: $upPanelPosition');
if (GStorage.setting if (GStorage.setting
.get(SettingBoxKey.dynamicsShowAllFollowedUp, defaultValue: false)) { .get(SettingBoxKey.dynamicsShowAllFollowedUp, defaultValue: false)) {
_dynamicsController.scrollController.addListener(listener); _dynamicsController.scrollController.addListener(listener);
@@ -91,33 +81,37 @@ class _DynamicsPageState extends State<DynamicsPage>
super.dispose(); super.dispose();
} }
Widget upPanelPart() { Widget upPanelPart(ThemeData theme) {
return Container( bool isTop = upPanelPosition == UpPanelPosition.top;
return Material(
//抽屉模式增加底色 //抽屉模式增加底色
color: upPanelPosition.index > 1 color: isTop || upPanelPosition.index > 1
? theme.colorScheme.surface ? theme.colorScheme.surface
: Colors.transparent, : Colors.transparent,
width: 64, child: SizedBox(
child: Obx( width: isTop ? null : 64,
() { height: isTop ? 76 : null,
if (_dynamicsController.upData.value.upList == null && child: Obx(
_dynamicsController.upData.value.liveUsers == null) { () {
return const SizedBox.shrink(); if (_dynamicsController.upData.value.upList == null &&
} else if (_dynamicsController.upData.value.errMsg != null) { _dynamicsController.upData.value.liveUsers == null) {
return Center( return const SizedBox.shrink();
child: IconButton( } else if (_dynamicsController.upData.value.errMsg != null) {
icon: const Icon(Icons.refresh), return Center(
onPressed: () { child: IconButton(
_dynamicsController.queryFollowUp(); icon: const Icon(Icons.refresh),
}, onPressed: () {
), _dynamicsController.queryFollowUp();
); },
} else { ),
return UpPanel( );
dynamicsController: _dynamicsController, } else {
); return UpPanel(
} dynamicsController: _dynamicsController,
}, );
}
},
),
), ),
); );
} }
@@ -125,11 +119,12 @@ class _DynamicsPageState extends State<DynamicsPage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
ThemeData theme = Theme.of(context);
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
appBar: AppBar( appBar: AppBar(
leading: upPanelPosition == UpPanelPosition.rightDrawer leading: upPanelPosition == UpPanelPosition.rightDrawer
? _createDynamicBtn(false) ? _createDynamicBtn(theme, false)
: null, : null,
leadingWidth: 50, leadingWidth: 50,
toolbarHeight: 50, toolbarHeight: 50,
@@ -158,26 +153,33 @@ class _DynamicsPageState extends State<DynamicsPage>
), ),
actions: upPanelPosition == UpPanelPosition.rightDrawer actions: upPanelPosition == UpPanelPosition.rightDrawer
? null ? null
: [_createDynamicBtn()], : [_createDynamicBtn(theme)],
), ),
drawer: upPanelPosition == UpPanelPosition.leftDrawer drawer: upPanelPosition == UpPanelPosition.leftDrawer
? SafeArea(child: upPanelPart()) ? SafeArea(child: upPanelPart(theme))
: null, : null,
drawerEnableOpenDragGesture: true, drawerEnableOpenDragGesture: true,
endDrawer: upPanelPosition == UpPanelPosition.rightDrawer endDrawer: upPanelPosition == UpPanelPosition.rightDrawer
? SafeArea(child: upPanelPart()) ? SafeArea(child: upPanelPart(theme))
: null, : null,
endDrawerEnableOpenDragGesture: true, endDrawerEnableOpenDragGesture: true,
body: Row( body: Row(
children: [ children: [
if (upPanelPosition == UpPanelPosition.leftFixed) upPanelPart(), if (upPanelPosition == UpPanelPosition.leftFixed) upPanelPart(theme),
Expanded( Expanded(
child: tabBarView( child: Column(
controller: _dynamicsController.tabController, children: [
children: _dynamicsController.tabsPageList, if (upPanelPosition == UpPanelPosition.top) upPanelPart(theme),
Expanded(
child: tabBarView(
controller: _dynamicsController.tabController,
children: _dynamicsController.tabsPageList,
),
),
],
), ),
), ),
if (upPanelPosition == UpPanelPosition.rightFixed) upPanelPart(), if (upPanelPosition == UpPanelPosition.rightFixed) upPanelPart(theme),
], ],
), ),
); );

View File

@@ -1,4 +1,5 @@
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/dynamic/up_panel_position.dart';
import 'package:PiliPlus/models/common/image_type.dart'; import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/dynamics/up.dart'; import 'package:PiliPlus/models/dynamics/up.dart';
import 'package:PiliPlus/pages/dynamics/controller.dart'; import 'package:PiliPlus/pages/dynamics/controller.dart';
@@ -8,11 +9,11 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class UpPanel extends StatefulWidget { class UpPanel extends StatefulWidget {
final DynamicsController dynamicsController;
const UpPanel({ const UpPanel({
required this.dynamicsController, required this.dynamicsController,
super.key, super.key,
}); });
final DynamicsController dynamicsController;
@override @override
State<UpPanel> createState() => _UpPanelState(); State<UpPanel> createState() => _UpPanelState();
@@ -22,6 +23,8 @@ class _UpPanelState extends State<UpPanel> {
List<UpItem>? get upList => widget.dynamicsController.upData.value.upList; List<UpItem>? get upList => widget.dynamicsController.upData.value.upList;
List<LiveUserItem>? get liveList => List<LiveUserItem>? get liveList =>
widget.dynamicsController.upData.value.liveUsers?.items; widget.dynamicsController.upData.value.liveUsers?.items;
late final isTop =
widget.dynamicsController.upPanelPosition == UpPanelPosition.top;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -30,41 +33,63 @@ class _UpPanelState extends State<UpPanel> {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return CustomScrollView( return CustomScrollView(
scrollDirection: isTop ? Axis.horizontal : Axis.vertical,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
controller: widget.dynamicsController.scrollController, controller: widget.dynamicsController.scrollController,
slivers: [ slivers: [
SliverToBoxAdapter( SliverToBoxAdapter(
child: SizedBox( child: InkWell(
height: 45, onTap: () {
child: TextButton( setState(() {
style: TextButton.styleFrom( widget.dynamicsController.showLiveItems =
padding: EdgeInsets.zero, !widget.dynamicsController.showLiveItems;
});
},
child: Container(
alignment: Alignment.center,
height: isTop ? 76 : 60,
padding: isTop ? const EdgeInsets.symmetric(horizontal: 6) : null,
child: Text.rich(
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: theme.colorScheme.primary,
),
TextSpan(
children: [
TextSpan(
text:
'Live(${widget.dynamicsController.upData.value.liveUsers?.count})',
),
if (!isTop) ...[
const TextSpan(text: '\n'),
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Icon(
widget.dynamicsController.showLiveItems
? Icons.expand_less
: Icons.expand_more,
size: 12,
color: theme.colorScheme.primary,
),
),
] else
WidgetSpan(
alignment: PlaceholderAlignment.middle,
child: Icon(
widget.dynamicsController.showLiveItems
? Icons.keyboard_arrow_right
: Icons.keyboard_arrow_left,
color: theme.colorScheme.primary,
size: 14,
),
),
],
),
), ),
child: Column(
children: [
const SizedBox(height: 12),
Text(
'Live(${widget.dynamicsController.upData.value.liveUsers?.count})',
style: const TextStyle(fontSize: 13),
),
Icon(
widget.dynamicsController.showLiveItems
? Icons.expand_less
: Icons.expand_more,
size: 12,
),
],
),
onPressed: () {
setState(() {
widget.dynamicsController.showLiveItems =
!widget.dynamicsController.showLiveItems;
});
},
), ),
), ),
), ),
const SliverToBoxAdapter(child: SizedBox(height: 10)),
if (widget.dynamicsController.showLiveItems && if (widget.dynamicsController.showLiveItems &&
liveList?.isNotEmpty == true) liveList?.isNotEmpty == true)
SliverList.builder( SliverList.builder(
@@ -93,7 +118,7 @@ class _UpPanelState extends State<UpPanel> {
return upItemBuild(theme, upList![index]); return upItemBuild(theme, upList![index]);
}, },
), ),
const SliverToBoxAdapter(child: SizedBox(height: 200)), if (!isTop) const SliverToBoxAdapter(child: SizedBox(height: 200)),
], ],
); );
} }
@@ -103,6 +128,7 @@ class _UpPanelState extends State<UpPanel> {
widget.dynamicsController.currentMid == -1; widget.dynamicsController.currentMid == -1;
return SizedBox( return SizedBox(
height: 76, height: 76,
width: isTop ? 65 : null,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
feedBack(); feedBack();
@@ -172,13 +198,13 @@ class _UpPanelState extends State<UpPanel> {
), ),
], ],
), ),
const SizedBox(height: 3), const SizedBox(height: 4),
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 4), padding: const EdgeInsets.symmetric(horizontal: 4),
child: Text( child: Text(
data.uname, data.uname,
overflow: TextOverflow.clip, overflow: TextOverflow.clip,
maxLines: 2, maxLines: isTop ? 1 : 2,
softWrap: true, softWrap: true,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(

View File

@@ -283,7 +283,7 @@ List<SettingsModel> get styleSettings => [
settingsType: SettingsType.normal, settingsType: SettingsType.normal,
title: '动态页UP主显示位置', title: '动态页UP主显示位置',
leading: const Icon(Icons.person_outlined), leading: const Icon(Icons.person_outlined),
getSubtitle: () => '当前:${GStorage.upPanelPosition.labels}', getSubtitle: () => '当前:${GStorage.upPanelPosition.label}',
onTap: (setState) async { onTap: (setState) async {
UpPanelPosition? result = await showDialog( UpPanelPosition? result = await showDialog(
context: Get.context!, context: Get.context!,
@@ -292,7 +292,7 @@ List<SettingsModel> get styleSettings => [
title: '动态页UP主显示位置', title: '动态页UP主显示位置',
value: GStorage.upPanelPosition, value: GStorage.upPanelPosition,
values: UpPanelPosition.values.map((e) { values: UpPanelPosition.values.map((e) {
return (e, e.labels); return (e, e.label);
}).toList(), }).toList(),
); );
}, },