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(
flex: _ratio[0].toInt(),
child: CustomScrollView(
controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(),
slivers: [
SliverPadding(

View File

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

View File

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

View File

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