mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
opt: member page
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -35,7 +35,7 @@ class DynamicSliverAppBar extends StatefulWidget {
|
|||||||
this.stretchTriggerOffset = 100.0,
|
this.stretchTriggerOffset = 100.0,
|
||||||
this.onStretchTrigger,
|
this.onStretchTrigger,
|
||||||
this.shape,
|
this.shape,
|
||||||
this.toolbarHeight = kToolbarHeight + 20,
|
this.toolbarHeight = kToolbarHeight,
|
||||||
this.leadingWidth,
|
this.leadingWidth,
|
||||||
this.toolbarTextStyle,
|
this.toolbarTextStyle,
|
||||||
this.titleTextStyle,
|
this.titleTextStyle,
|
||||||
@@ -43,8 +43,10 @@ class DynamicSliverAppBar extends StatefulWidget {
|
|||||||
this.forceMaterialTransparency = false,
|
this.forceMaterialTransparency = false,
|
||||||
this.clipBehavior,
|
this.clipBehavior,
|
||||||
this.appBarClipper,
|
this.appBarClipper,
|
||||||
|
this.hasTabBar = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
final bool hasTabBar;
|
||||||
final Widget? flexibleSpace;
|
final Widget? flexibleSpace;
|
||||||
final Widget? leading;
|
final Widget? leading;
|
||||||
final bool automaticallyImplyLeading;
|
final bool automaticallyImplyLeading;
|
||||||
@@ -95,7 +97,6 @@ class _DynamicSliverAppBarState extends State<DynamicSliverAppBar> {
|
|||||||
// As long as the height is 0 instead of the sliver app bar a sliver to box adapter will be used
|
// As long as the height is 0 instead of the sliver app bar a sliver to box adapter will be used
|
||||||
// to calculate dynamically the size for the sliver app bar
|
// to calculate dynamically the size for the sliver app bar
|
||||||
double _height = 0;
|
double _height = 0;
|
||||||
Orientation? _orientation;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -103,13 +104,6 @@ class _DynamicSliverAppBarState extends State<DynamicSliverAppBar> {
|
|||||||
_updateHeight();
|
_updateHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void didUpdateWidget(covariant DynamicSliverAppBar oldWidget) {
|
|
||||||
super.didUpdateWidget(oldWidget);
|
|
||||||
|
|
||||||
_updateHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _updateHeight() {
|
void _updateHeight() {
|
||||||
// Gets the new height and updates the sliver app bar. Needs to be called after the last frame has been rebuild
|
// Gets the new height and updates the sliver app bar. Needs to be called after the last frame has been rebuild
|
||||||
// otherwise this will throw an error
|
// otherwise this will throw an error
|
||||||
@@ -123,23 +117,27 @@ class _DynamicSliverAppBarState extends State<DynamicSliverAppBar> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didChangeDependencies() {
|
||||||
|
_height = 0;
|
||||||
|
_updateHeight();
|
||||||
|
super.didChangeDependencies();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
//Needed to lay out the flexibleSpace the first time, so we can calculate its intrinsic height
|
//Needed to lay out the flexibleSpace the first time, so we can calculate its intrinsic height
|
||||||
Orientation orientation = MediaQuery.orientationOf(context);
|
|
||||||
if (_orientation != orientation) {
|
|
||||||
_orientation = orientation;
|
|
||||||
_height = 0;
|
|
||||||
}
|
|
||||||
if (_height == 0) {
|
if (_height == 0) {
|
||||||
return SliverToBoxAdapter(
|
return SliverToBoxAdapter(
|
||||||
child: Container(
|
child: SizedBox(
|
||||||
key: _childKey,
|
key: _childKey,
|
||||||
child: widget.flexibleSpace ?? SizedBox(height: kToolbarHeight),
|
child: widget.flexibleSpace ?? SizedBox(height: kToolbarHeight),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MediaQuery.orientationOf(context);
|
||||||
|
|
||||||
return SliverAppBar(
|
return SliverAppBar(
|
||||||
leading: widget.leading,
|
leading: widget.leading,
|
||||||
automaticallyImplyLeading: widget.automaticallyImplyLeading,
|
automaticallyImplyLeading: widget.automaticallyImplyLeading,
|
||||||
@@ -168,7 +166,7 @@ class _DynamicSliverAppBarState extends State<DynamicSliverAppBar> {
|
|||||||
onStretchTrigger: widget.onStretchTrigger,
|
onStretchTrigger: widget.onStretchTrigger,
|
||||||
shape: widget.shape,
|
shape: widget.shape,
|
||||||
toolbarHeight: widget.toolbarHeight,
|
toolbarHeight: widget.toolbarHeight,
|
||||||
expandedHeight: _height,
|
expandedHeight: _height + (widget.hasTabBar ? 48 : 0),
|
||||||
leadingWidth: widget.leadingWidth,
|
leadingWidth: widget.leadingWidth,
|
||||||
toolbarTextStyle: widget.toolbarTextStyle,
|
toolbarTextStyle: widget.toolbarTextStyle,
|
||||||
titleTextStyle: widget.titleTextStyle,
|
titleTextStyle: widget.titleTextStyle,
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class MemberControllerNew extends CommonDataController<Data, dynamic>
|
|||||||
late List<Tab> tabs;
|
late List<Tab> tabs;
|
||||||
List<Tab2>? tab2;
|
List<Tab2>? tab2;
|
||||||
RxInt contributeInitialIndex = 0.obs;
|
RxInt contributeInitialIndex = 0.obs;
|
||||||
double? top;
|
double top = 0;
|
||||||
bool? hasSeasonOrSeries;
|
bool? hasSeasonOrSeries;
|
||||||
final fromViewAid = Get.parameters['from_view_aid'];
|
final fromViewAid = Get.parameters['from_view_aid'];
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class _MemberPageNewState extends State<MemberPageNew> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (_userController.top == null || _userController.top == 0) {
|
if (_userController.top == 0) {
|
||||||
_userController.top = MediaQuery.of(context).padding.top;
|
_userController.top = MediaQuery.of(context).padding.top;
|
||||||
}
|
}
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@@ -64,7 +64,6 @@ class _MemberPageNewState extends State<MemberPageNew> {
|
|||||||
() => _userController.loadingState.value is Success
|
() => _userController.loadingState.value is Success
|
||||||
? LayoutBuilder(
|
? LayoutBuilder(
|
||||||
builder: (context, constraints) {
|
builder: (context, constraints) {
|
||||||
// if (constraints.maxHeight > constraints.maxWidth) {
|
|
||||||
return ExtendedNestedScrollView(
|
return ExtendedNestedScrollView(
|
||||||
key: _key,
|
key: _key,
|
||||||
controller: _userController.scrollController,
|
controller: _userController.scrollController,
|
||||||
@@ -97,41 +96,6 @@ class _MemberPageNewState extends State<MemberPageNew> {
|
|||||||
)
|
)
|
||||||
: Center(child: const Text('EMPTY')),
|
: Center(child: const Text('EMPTY')),
|
||||||
);
|
);
|
||||||
// } else {
|
|
||||||
// return Row(
|
|
||||||
// children: [
|
|
||||||
// Expanded(
|
|
||||||
// child: CustomScrollView(
|
|
||||||
// slivers: [
|
|
||||||
// _buildAppBar(false),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// Expanded(
|
|
||||||
// child: SafeArea(
|
|
||||||
// top: false,
|
|
||||||
// left: false,
|
|
||||||
// bottom: false,
|
|
||||||
// child: Column(
|
|
||||||
// children: [
|
|
||||||
// SizedBox(height: _userController.top),
|
|
||||||
// if ((_userController.tab2?.length ?? -1) > 1)
|
|
||||||
// _buildTab,
|
|
||||||
// Expanded(
|
|
||||||
// child:
|
|
||||||
// _userController.tab2?.isNotEmpty == true
|
|
||||||
// ? _buildBody
|
|
||||||
// : Center(
|
|
||||||
// child: const Text('EMPTY'),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: Center(
|
: Center(
|
||||||
@@ -186,120 +150,117 @@ class _MemberPageNewState extends State<MemberPageNew> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildAppBar({bool needTab = true, bool isV = true}) =>
|
Widget _buildAppBar({bool needTab = true, bool isV = true}) =>
|
||||||
MediaQuery.removePadding(
|
DynamicSliverAppBar(
|
||||||
context: context,
|
primary: false,
|
||||||
removeTop: true,
|
leading: Padding(
|
||||||
// removeRight: true,
|
padding: EdgeInsets.only(top: _userController.top),
|
||||||
child: DynamicSliverAppBar(
|
child: const BackButton(),
|
||||||
leading: Padding(
|
),
|
||||||
padding: EdgeInsets.only(top: _userController.top ?? 0),
|
hasTabBar: (_userController.tab2?.length ?? 0) > 1,
|
||||||
child: const BackButton(),
|
toolbarHeight: kToolbarHeight + _userController.top,
|
||||||
),
|
title: IgnorePointer(
|
||||||
title: IgnorePointer(
|
child: Obx(() => _userController.showUname.value &&
|
||||||
child: Obx(() => _userController.showUname.value &&
|
_userController.username != null
|
||||||
_userController.username != null
|
? Padding(
|
||||||
? Padding(
|
padding: EdgeInsets.only(top: _userController.top),
|
||||||
padding: EdgeInsets.only(top: _userController.top ?? 0),
|
child: Text(_userController.username!),
|
||||||
child: Text(_userController.username!),
|
|
||||||
)
|
|
||||||
: const SizedBox.shrink()),
|
|
||||||
),
|
|
||||||
pinned: true,
|
|
||||||
flexibleSpace:
|
|
||||||
_buildUserInfo(_userController.loadingState.value, isV),
|
|
||||||
bottom: needTab && (_userController.tab2?.length ?? -1) > 1
|
|
||||||
? PreferredSize(
|
|
||||||
preferredSize: Size.fromHeight(48),
|
|
||||||
child: _buildTab,
|
|
||||||
)
|
)
|
||||||
: null,
|
: const SizedBox.shrink()),
|
||||||
actions: [
|
),
|
||||||
Padding(
|
pinned: true,
|
||||||
padding: EdgeInsets.only(top: _userController.top ?? 0),
|
flexibleSpace: _buildUserInfo(_userController.loadingState.value, isV),
|
||||||
child: IconButton(
|
bottom: needTab && (_userController.tab2?.length ?? -1) > 1
|
||||||
tooltip: '搜索',
|
? PreferredSize(
|
||||||
onPressed: () => Get.toNamed(
|
preferredSize: Size.fromHeight(48),
|
||||||
'/memberSearch?mid=$_mid&uname=${_userController.username}'),
|
child: _buildTab,
|
||||||
icon: const Icon(Icons.search_outlined),
|
)
|
||||||
),
|
: null,
|
||||||
|
actions: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(top: _userController.top),
|
||||||
|
child: IconButton(
|
||||||
|
tooltip: '搜索',
|
||||||
|
onPressed: () => Get.toNamed(
|
||||||
|
'/memberSearch?mid=$_mid&uname=${_userController.username}'),
|
||||||
|
icon: const Icon(Icons.search_outlined),
|
||||||
),
|
),
|
||||||
Padding(
|
),
|
||||||
padding: EdgeInsets.only(top: _userController.top ?? 0),
|
Padding(
|
||||||
child: PopupMenuButton(
|
padding: EdgeInsets.only(top: _userController.top),
|
||||||
icon: const Icon(Icons.more_vert),
|
child: PopupMenuButton(
|
||||||
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
icon: const Icon(Icons.more_vert),
|
||||||
if (_userController.ownerMid != _mid) ...[
|
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
||||||
PopupMenuItem(
|
if (_userController.ownerMid != _mid) ...[
|
||||||
onTap: () => _userController.blockUser(context),
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
const Icon(Icons.block, size: 19),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Text(_userController.relation.value != -1
|
|
||||||
? '加入黑名单'
|
|
||||||
: '移除黑名单'),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
onTap: () => _userController.shareUser(),
|
onTap: () => _userController.blockUser(context),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.share_outlined, size: 19),
|
const Icon(Icons.block, size: 19),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Text(_userController.ownerMid != _mid
|
Text(_userController.relation.value != -1
|
||||||
? '分享UP主'
|
? '加入黑名单'
|
||||||
: '分享我的主页'),
|
: '移除黑名单'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
PopupMenuItem(
|
||||||
|
onTap: () => _userController.shareUser(),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.share_outlined, size: 19),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Text(_userController.ownerMid != _mid
|
||||||
|
? '分享UP主'
|
||||||
|
: '分享我的主页'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (_userController.ownerMid != null &&
|
||||||
|
_userController.mid != _userController.ownerMid) ...[
|
||||||
|
const PopupMenuDivider(),
|
||||||
|
PopupMenuItem(
|
||||||
|
onTap: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 20,
|
||||||
|
vertical: 16,
|
||||||
|
),
|
||||||
|
content: ReportPanel(
|
||||||
|
name: _userController.username,
|
||||||
|
mid: _mid,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.error_outline,
|
||||||
|
size: 19,
|
||||||
|
color: Theme.of(context).colorScheme.error,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Text(
|
||||||
|
'举报',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.error),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (_userController.ownerMid != null &&
|
|
||||||
_userController.mid != _userController.ownerMid) ...[
|
|
||||||
const PopupMenuDivider(),
|
|
||||||
PopupMenuItem(
|
|
||||||
onTap: () {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) => AlertDialog(
|
|
||||||
clipBehavior: Clip.hardEdge,
|
|
||||||
contentPadding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 20,
|
|
||||||
vertical: 16,
|
|
||||||
),
|
|
||||||
content: ReportPanel(
|
|
||||||
name: _userController.username,
|
|
||||||
mid: _mid,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.error_outline,
|
|
||||||
size: 19,
|
|
||||||
color: Theme.of(context).colorScheme.error,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Text(
|
|
||||||
'举报',
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context).colorScheme.error),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
),
|
||||||
],
|
const SizedBox(width: 4),
|
||||||
),
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _errorWidget(msg) {
|
Widget _errorWidget(msg) {
|
||||||
@@ -314,21 +275,17 @@ class _MemberPageNewState extends State<MemberPageNew> {
|
|||||||
Loading() => const CircularProgressIndicator(),
|
Loading() => const CircularProgressIndicator(),
|
||||||
Success() => userState.response is Data
|
Success() => userState.response is Data
|
||||||
? Obx(
|
? Obx(
|
||||||
() => Padding(
|
() => UserInfoCard(
|
||||||
padding: EdgeInsets.only(
|
isV: isV,
|
||||||
bottom: (_userController.tab2?.length ?? 0) > 1 ? 48 : 0),
|
isOwner: _userController.mid == _userController.ownerMid,
|
||||||
child: UserInfoCard(
|
relation: _userController.relation.value,
|
||||||
isV: isV,
|
isFollow: _userController.isFollow.value,
|
||||||
isOwner: _userController.mid == _userController.ownerMid,
|
card: userState.response.card,
|
||||||
relation: _userController.relation.value,
|
images: userState.response.images,
|
||||||
isFollow: _userController.isFollow.value,
|
onFollow: () => _userController.onFollow(context),
|
||||||
card: userState.response.card,
|
live: _userController.live,
|
||||||
images: userState.response.images,
|
silence: _userController.silence,
|
||||||
onFollow: () => _userController.onFollow(context),
|
endTime: _userController.endTime,
|
||||||
live: _userController.live,
|
|
||||||
silence: _userController.silence,
|
|
||||||
endTime: _userController.endTime,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: GestureDetector(
|
: GestureDetector(
|
||||||
|
|||||||
@@ -436,13 +436,13 @@ class UserInfoCard extends StatelessWidget {
|
|||||||
child: card.officialVerify?.icon?.isNotEmpty == true
|
child: card.officialVerify?.icon?.isNotEmpty == true
|
||||||
? CachedNetworkImage(
|
? CachedNetworkImage(
|
||||||
imageUrl: card.officialVerify!.icon!.http2https,
|
imageUrl: card.officialVerify!.icon!.http2https,
|
||||||
width: 24,
|
width: 22,
|
||||||
height: 24,
|
height: 22,
|
||||||
)
|
)
|
||||||
: Image.asset(
|
: Image.asset(
|
||||||
'assets/images/big-vip.png',
|
'assets/images/big-vip.png',
|
||||||
width: 24,
|
width: 22,
|
||||||
height: 24,
|
height: 22,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -508,8 +508,8 @@ class UserInfoCard extends StatelessWidget {
|
|||||||
if (card.officialVerify?.icon?.isNotEmpty == true ||
|
if (card.officialVerify?.icon?.isNotEmpty == true ||
|
||||||
(card.vip?.vipStatus ?? -1) > 0)
|
(card.vip?.vipStatus ?? -1) > 0)
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 170,
|
top: 172,
|
||||||
left: 80,
|
left: 82,
|
||||||
child: _buildBadge(context),
|
child: _buildBadge(context),
|
||||||
),
|
),
|
||||||
if (live is Map && ((live['liveStatus'] as int?) ?? 0) == 1)
|
if (live is Map && ((live['liveStatus'] as int?) ?? 0) == 1)
|
||||||
|
|||||||
Reference in New Issue
Block a user