opt: dynamic up panel

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2024-12-28 21:09:03 +08:00
parent 93560a6fb2
commit d6ed1edc6f
4 changed files with 166 additions and 157 deletions

View File

@@ -317,7 +317,6 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
Expanded( Expanded(
flex: _ratio[0].toInt(), flex: _ratio[0].toInt(),
child: CustomScrollView( child: CustomScrollView(
controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
slivers: [ slivers: [
SliverPadding( SliverPadding(

View File

@@ -123,54 +123,51 @@ class _DynamicsPageState extends State<DynamicsPage>
} }
Widget upPanelPart() { Widget upPanelPart() {
return Padding( return Container(
padding: const EdgeInsets.symmetric(horizontal: 4), //抽屉模式增加底色
child: Container( color: upPanelPosition.index > 1
//抽屉模式增加底色 ? Theme.of(context).colorScheme.surface
color: upPanelPosition.index > 1 : Colors.transparent,
? Theme.of(context).colorScheme.surface width: 64,
: Colors.transparent, child: FutureBuilder(
width: 56, future: _futureBuilderFutureUp,
child: FutureBuilder( builder: (context, snapshot) {
future: _futureBuilderFutureUp, if (snapshot.connectionState == ConnectionState.done) {
builder: (context, snapshot) { if (snapshot.data == null) {
if (snapshot.connectionState == ConnectionState.done) { return nil;
if (snapshot.data == null) { }
return nil; // TODO: refactor
} if (snapshot.data is! Map) {
// TODO: refactor return HttpError(
if (snapshot.data is! Map) { isSliver: false,
return HttpError( callback: () => setState(() {
isSliver: false, _futureBuilderFutureUp = _dynamicsController.queryFollowUp();
callback: () => setState(() { }),
);
}
Map data = snapshot.data;
if (data['status']) {
return Obx(() => UpPanel(_dynamicsController.upData.value,
_dynamicsController.scrollController));
} else {
return Center(
child: IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
setState(() {
_futureBuilderFutureUp = _futureBuilderFutureUp =
_dynamicsController.queryFollowUp(); _dynamicsController.queryFollowUp();
}), });
); },
} ),
Map data = snapshot.data; );
if (data['status']) { }
return Obx(() => UpPanel(_dynamicsController.upData.value, } else {
_dynamicsController.scrollController)); return nil;
} else { }
return Center( },
child: IconButton( ),
icon: Icon(Icons.refresh), );
onPressed: () {
setState(() {
_futureBuilderFutureUp =
_dynamicsController.queryFollowUp();
});
},
),
);
}
} else {
return nil;
}
},
),
));
} }
@override @override

View File

@@ -38,79 +38,78 @@ class _UpPanelState extends State<UpPanel> {
liveList = widget.upData!.liveUsers?.items ?? []; liveList = widget.upData!.liveUsers?.items ?? [];
// return const SizedBox(); // return const SizedBox();
return CustomScrollView( return CustomScrollView(
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
controller: widget.scrollController, controller: widget.scrollController,
slivers: [ slivers: [
SliverToBoxAdapter( SliverToBoxAdapter(
child: SizedBox( child: SizedBox(
height: 45, height: 45,
child: TextButton( child: TextButton(
style: ButtonStyle( style: TextButton.styleFrom(
padding: WidgetStateProperty.all(const EdgeInsets.only()), padding: EdgeInsets.zero,
), ),
child: Column( child: Column(
children: [ children: [
const Spacer(), const SizedBox(height: 12),
const SizedBox(height: 12), Text(
Text( 'Live(${liveList.length})',
'Live(${liveList.length})', style: const TextStyle(
style: const TextStyle( fontSize: 13,
fontSize: 13,
),
semanticsLabel:
'${_showLiveItems ? '展开' : '收起'}直播中的${liveList.length}个Up',
), ),
Icon(_showLiveItems ? Icons.expand_less : Icons.expand_more, semanticsLabel:
size: 12), '${_showLiveItems ? '展开' : '收起'}直播中的${liveList.length}个Up',
const Spacer(), ),
], Icon(
), _showLiveItems ? Icons.expand_less : Icons.expand_more,
onPressed: () { size: 12,
setState(() { ),
_showLiveItems = !_showLiveItems;
});
},
),
),
),
const SliverToBoxAdapter(
child: SizedBox(
height: 10,
),
),
SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
mainAxisExtent: 76,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
),
delegate: SliverChildListDelegate(
[
if (_showLiveItems && liveList.isNotEmpty) ...[
for (int i = 0; i < liveList.length; i++) ...[
upItemBuild(liveList[i], i)
],
],
upItemBuild(UpItem(face: '', uname: '全部动态', mid: -1), 0),
upItemBuild(
UpItem(
face: userInfo?.face,
uname: '',
mid: userInfo?.mid,
),
1),
for (int i = 0; i < upList.length; i++) ...[
upItemBuild(upList[i], i + 2)
],
], ],
)), ),
const SliverToBoxAdapter( onPressed: () {
child: SizedBox( setState(() {
height: 200, _showLiveItems = !_showLiveItems;
});
},
), ),
), ),
]); ),
const SliverToBoxAdapter(
child: SizedBox(height: 10),
),
SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
mainAxisExtent: 76,
crossAxisSpacing: 0,
mainAxisSpacing: 0,
),
delegate: SliverChildListDelegate(
[
if (_showLiveItems && liveList.isNotEmpty) ...[
for (int i = 0; i < liveList.length; i++) ...[
upItemBuild(liveList[i], i)
],
],
upItemBuild(UpItem(face: '', uname: '全部动态', mid: -1), 0),
upItemBuild(
UpItem(
face: userInfo?.face,
uname: '',
mid: userInfo?.mid,
),
1,
),
for (int i = 0; i < upList.length; i++) ...[
upItemBuild(upList[i], i + 2)
],
],
),
),
const SliverToBoxAdapter(
child: SizedBox(height: 200),
),
],
);
} }
Widget upItemBuild(data, i) { Widget upItemBuild(data, i) {
@@ -172,49 +171,63 @@ class _UpPanelState extends State<UpPanel> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Badge( Stack(
smallSize: 8, clipBehavior: Clip.none,
label: data.type == 'live' ? const Text('Live') : null, children: [
textColor: Theme.of(context).colorScheme.onSecondaryContainer, Padding(
alignment: data.type == 'live' padding: const EdgeInsets.symmetric(horizontal: 4),
? AlignmentDirectional.topCenter child: data.face != ''
: AlignmentDirectional.topEnd, ? NetworkImgLayer(
padding: const EdgeInsets.only(left: 6, right: 6), width: 38,
isLabelVisible: data.type == 'live' || height: 38,
(data.type == 'up' && (data.hasUpdate ?? false)), src: data.face,
backgroundColor: data.type == 'live' type: 'avatar',
? Theme.of(context) )
.colorScheme : const CircleAvatar(
.secondaryContainer radius: 19,
.withOpacity(0.7) backgroundImage: AssetImage(
: Theme.of(context).colorScheme.primary, 'assets/images/logo/logo_android_2.png',
child: data.face != '' ),
? NetworkImgLayer( ),
width: 38, ),
height: 38, Positioned(
src: data.face, top: 0,
type: 'avatar', right: data.type == 'live' ? -6 : 4,
) child: Badge(
: const CircleAvatar( smallSize: 8,
radius: 19, label: data.type == 'live' ? const Text(' Live ') : null,
backgroundImage: AssetImage( textColor:
'assets/images/logo/logo_android_2.png', Theme.of(context).colorScheme.onSecondaryContainer,
), alignment: AlignmentDirectional.topStart,
), isLabelVisible: data.type == 'live' ||
(data.type == 'up' && (data.hasUpdate ?? false)),
backgroundColor: data.type == 'live'
? Theme.of(context)
.colorScheme
.secondaryContainer
.withOpacity(0.7)
: Theme.of(context).colorScheme.primary,
),
),
],
), ),
const SizedBox(height: 3), const SizedBox(height: 3),
Text( Padding(
data.uname, padding: const EdgeInsets.symmetric(horizontal: 4),
overflow: TextOverflow.clip, child: Text(
maxLines: 2, data.uname,
softWrap: true, overflow: TextOverflow.clip,
textAlign: TextAlign.center, maxLines: 2,
style: TextStyle( softWrap: true,
textAlign: TextAlign.center,
style: TextStyle(
color: currentMid == data.mid color: currentMid == data.mid
? Theme.of(context).colorScheme.primary ? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.outline, : Theme.of(context).colorScheme.outline,
height: 1.1, height: 1.1,
fontSize: 12.5), fontSize: 12.5,
),
),
), ),
], ],
), ),

View File

@@ -281,7 +281,7 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
child: CustomScrollView( child: CustomScrollView(
controller: orientation == Orientation.portrait controller: orientation == Orientation.portrait
? _htmlRenderCtr.scrollController ? _htmlRenderCtr.scrollController
: ScrollController(), : null,
slivers: [ slivers: [
SliverPadding( SliverPadding(
padding: orientation == Orientation.portrait padding: orientation == Orientation.portrait
@@ -330,9 +330,9 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
), ),
if (orientation == Orientation.landscape) ...[ if (orientation == Orientation.landscape) ...[
VerticalDivider( VerticalDivider(
thickness: 8, thickness: 8,
color: color: Theme.of(context).dividerColor.withOpacity(0.05),
Theme.of(context).dividerColor.withOpacity(0.05)), ),
Expanded( Expanded(
flex: _ratio[1].toInt(), flex: _ratio[1].toInt(),
child: Scaffold( child: Scaffold(