From 27b251b06e20e370da68f7d1428f4d446ed94435 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Tue, 15 Apr 2025 10:05:22 +0800 Subject: [PATCH] opt: member page Signed-off-by: bggRGjQaUbCoE --- lib/common/widgets/dynamic_sliver_appbar.dart | 30 +- lib/pages/member/new/controller.dart | 2 +- lib/pages/member/new/member_page.dart | 265 ++++++++---------- .../member/new/widget/user_info_card.dart | 12 +- 4 files changed, 132 insertions(+), 177 deletions(-) diff --git a/lib/common/widgets/dynamic_sliver_appbar.dart b/lib/common/widgets/dynamic_sliver_appbar.dart index cc5a4305..5fdc2fae 100644 --- a/lib/common/widgets/dynamic_sliver_appbar.dart +++ b/lib/common/widgets/dynamic_sliver_appbar.dart @@ -35,7 +35,7 @@ class DynamicSliverAppBar extends StatefulWidget { this.stretchTriggerOffset = 100.0, this.onStretchTrigger, this.shape, - this.toolbarHeight = kToolbarHeight + 20, + this.toolbarHeight = kToolbarHeight, this.leadingWidth, this.toolbarTextStyle, this.titleTextStyle, @@ -43,8 +43,10 @@ class DynamicSliverAppBar extends StatefulWidget { this.forceMaterialTransparency = false, this.clipBehavior, this.appBarClipper, + this.hasTabBar = false, }); + final bool hasTabBar; final Widget? flexibleSpace; final Widget? leading; final bool automaticallyImplyLeading; @@ -95,7 +97,6 @@ class _DynamicSliverAppBarState extends State { // 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 double _height = 0; - Orientation? _orientation; @override void initState() { @@ -103,13 +104,6 @@ class _DynamicSliverAppBarState extends State { _updateHeight(); } - @override - void didUpdateWidget(covariant DynamicSliverAppBar oldWidget) { - super.didUpdateWidget(oldWidget); - - _updateHeight(); - } - void _updateHeight() { // 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 @@ -123,23 +117,27 @@ class _DynamicSliverAppBarState extends State { }); } + @override + void didChangeDependencies() { + _height = 0; + _updateHeight(); + super.didChangeDependencies(); + } + @override Widget build(BuildContext context) { //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) { return SliverToBoxAdapter( - child: Container( + child: SizedBox( key: _childKey, child: widget.flexibleSpace ?? SizedBox(height: kToolbarHeight), ), ); } + MediaQuery.orientationOf(context); + return SliverAppBar( leading: widget.leading, automaticallyImplyLeading: widget.automaticallyImplyLeading, @@ -168,7 +166,7 @@ class _DynamicSliverAppBarState extends State { onStretchTrigger: widget.onStretchTrigger, shape: widget.shape, toolbarHeight: widget.toolbarHeight, - expandedHeight: _height, + expandedHeight: _height + (widget.hasTabBar ? 48 : 0), leadingWidth: widget.leadingWidth, toolbarTextStyle: widget.toolbarTextStyle, titleTextStyle: widget.titleTextStyle, diff --git a/lib/pages/member/new/controller.dart b/lib/pages/member/new/controller.dart index fce40be5..dc6f5320 100644 --- a/lib/pages/member/new/controller.dart +++ b/lib/pages/member/new/controller.dart @@ -33,7 +33,7 @@ class MemberControllerNew extends CommonDataController late List tabs; List? tab2; RxInt contributeInitialIndex = 0.obs; - double? top; + double top = 0; bool? hasSeasonOrSeries; final fromViewAid = Get.parameters['from_view_aid']; diff --git a/lib/pages/member/new/member_page.dart b/lib/pages/member/new/member_page.dart index a9fccc8f..ea9cfcb4 100644 --- a/lib/pages/member/new/member_page.dart +++ b/lib/pages/member/new/member_page.dart @@ -55,7 +55,7 @@ class _MemberPageNewState extends State { @override Widget build(BuildContext context) { - if (_userController.top == null || _userController.top == 0) { + if (_userController.top == 0) { _userController.top = MediaQuery.of(context).padding.top; } return Scaffold( @@ -64,7 +64,6 @@ class _MemberPageNewState extends State { () => _userController.loadingState.value is Success ? LayoutBuilder( builder: (context, constraints) { - // if (constraints.maxHeight > constraints.maxWidth) { return ExtendedNestedScrollView( key: _key, controller: _userController.scrollController, @@ -97,41 +96,6 @@ class _MemberPageNewState extends State { ) : 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( @@ -186,120 +150,117 @@ class _MemberPageNewState extends State { ); Widget _buildAppBar({bool needTab = true, bool isV = true}) => - MediaQuery.removePadding( - context: context, - removeTop: true, - // removeRight: true, - child: DynamicSliverAppBar( - leading: Padding( - padding: EdgeInsets.only(top: _userController.top ?? 0), - child: const BackButton(), - ), - title: IgnorePointer( - child: Obx(() => _userController.showUname.value && - _userController.username != null - ? Padding( - padding: EdgeInsets.only(top: _userController.top ?? 0), - 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, + DynamicSliverAppBar( + primary: false, + leading: Padding( + padding: EdgeInsets.only(top: _userController.top), + child: const BackButton(), + ), + hasTabBar: (_userController.tab2?.length ?? 0) > 1, + toolbarHeight: kToolbarHeight + _userController.top, + title: IgnorePointer( + child: Obx(() => _userController.showUname.value && + _userController.username != null + ? Padding( + padding: EdgeInsets.only(top: _userController.top), + child: Text(_userController.username!), ) - : null, - actions: [ - Padding( - padding: EdgeInsets.only(top: _userController.top ?? 0), - child: IconButton( - tooltip: '搜索', - onPressed: () => Get.toNamed( - '/memberSearch?mid=$_mid&uname=${_userController.username}'), - icon: const Icon(Icons.search_outlined), - ), + : 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, + 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), - child: PopupMenuButton( - icon: const Icon(Icons.more_vert), - itemBuilder: (BuildContext context) => [ - if (_userController.ownerMid != _mid) ...[ - PopupMenuItem( - 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 - ? '加入黑名单' - : '移除黑名单'), - ], - ), - ) - ], + ), + Padding( + padding: EdgeInsets.only(top: _userController.top), + child: PopupMenuButton( + icon: const Icon(Icons.more_vert), + itemBuilder: (BuildContext context) => [ + if (_userController.ownerMid != _mid) ...[ PopupMenuItem( - onTap: () => _userController.shareUser(), + onTap: () => _userController.blockUser(context), child: Row( mainAxisSize: MainAxisSize.min, children: [ - const Icon(Icons.share_outlined, size: 19), + const Icon(Icons.block, size: 19), const SizedBox(width: 10), - Text(_userController.ownerMid != _mid - ? '分享UP主' - : '分享我的主页'), + Text(_userController.relation.value != -1 + ? '加入黑名单' + : '移除黑名单'), + ], + ), + ) + ], + 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) { @@ -314,21 +275,17 @@ class _MemberPageNewState extends State { Loading() => const CircularProgressIndicator(), Success() => userState.response is Data ? Obx( - () => Padding( - padding: EdgeInsets.only( - bottom: (_userController.tab2?.length ?? 0) > 1 ? 48 : 0), - child: UserInfoCard( - isV: isV, - isOwner: _userController.mid == _userController.ownerMid, - relation: _userController.relation.value, - isFollow: _userController.isFollow.value, - card: userState.response.card, - images: userState.response.images, - onFollow: () => _userController.onFollow(context), - live: _userController.live, - silence: _userController.silence, - endTime: _userController.endTime, - ), + () => UserInfoCard( + isV: isV, + isOwner: _userController.mid == _userController.ownerMid, + relation: _userController.relation.value, + isFollow: _userController.isFollow.value, + card: userState.response.card, + images: userState.response.images, + onFollow: () => _userController.onFollow(context), + live: _userController.live, + silence: _userController.silence, + endTime: _userController.endTime, ), ) : GestureDetector( diff --git a/lib/pages/member/new/widget/user_info_card.dart b/lib/pages/member/new/widget/user_info_card.dart index d58d057b..8315b5f1 100644 --- a/lib/pages/member/new/widget/user_info_card.dart +++ b/lib/pages/member/new/widget/user_info_card.dart @@ -436,13 +436,13 @@ class UserInfoCard extends StatelessWidget { child: card.officialVerify?.icon?.isNotEmpty == true ? CachedNetworkImage( imageUrl: card.officialVerify!.icon!.http2https, - width: 24, - height: 24, + width: 22, + height: 22, ) : Image.asset( 'assets/images/big-vip.png', - width: 24, - height: 24, + width: 22, + height: 22, ), ), ); @@ -508,8 +508,8 @@ class UserInfoCard extends StatelessWidget { if (card.officialVerify?.icon?.isNotEmpty == true || (card.vip?.vipStatus ?? -1) > 0) Positioned( - top: 170, - left: 80, + top: 172, + left: 82, child: _buildBadge(context), ), if (live is Map && ((live['liveStatus'] as int?) ?? 0) == 1)