This commit is contained in:
bggRGjQaUbCoE
2024-10-17 10:20:55 +08:00
parent 45be8f558c
commit 2aa4fd49b1
5 changed files with 194 additions and 182 deletions

View File

@@ -22,6 +22,7 @@ class MemberControllerNew extends CommonController
late final List<Tab> tabs; late final List<Tab> tabs;
List<Tab2>? tab2; List<Tab2>? tab2;
RxInt contributeInitialIndex = 0.obs; RxInt contributeInitialIndex = 0.obs;
double? top;
@override @override
void onInit() { void onInit() {

View File

@@ -30,8 +30,6 @@ class _MemberPageNewState extends State<MemberPageNew>
String? _heroTag; String? _heroTag;
late final MemberControllerNew _userController; late final MemberControllerNew _userController;
late double _top;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@@ -49,75 +47,76 @@ class _MemberPageNewState extends State<MemberPageNew>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_top = MediaQuery.of(context).padding.top; _userController.top ??= MediaQuery.of(context).padding.top;
return MediaQuery.removePadding( return Scaffold(
context: context, resizeToAvoidBottomInset: false,
removeTop: true, body: Obx(
child: Scaffold( () => _userController.loadingState.value is Success
resizeToAvoidBottomInset: false, ? LayoutBuilder(
body: Obx( builder: (_, constraints) {
() => _userController.loadingState.value is Success if (constraints.maxHeight > constraints.maxWidth) {
? LayoutBuilder( return ExtendedNestedScrollView(
builder: (_, constraints) { controller: _userController.scrollController,
if (constraints.maxHeight > constraints.maxWidth) { onlyOneScrollInBody: true,
return ExtendedNestedScrollView( headerSliverBuilder: (context, innerBoxIsScrolled) {
controller: _userController.scrollController, return [
onlyOneScrollInBody: true, SliverOverlapAbsorber(
headerSliverBuilder: (context, innerBoxIsScrolled) { handle: ExtendedNestedScrollView
return [ .sliverOverlapAbsorberHandleFor(context),
SliverOverlapAbsorber( sliver: _buildAppBar(),
handle: ExtendedNestedScrollView
.sliverOverlapAbsorberHandleFor(context),
sliver: _buildAppBar(),
),
];
},
body: _userController.tab2 != null &&
_userController.tab2!.isNotEmpty
? LayoutBuilder(
builder: (context, _) {
return Padding(
padding: EdgeInsets.only(
top: ExtendedNestedScrollView
.sliverOverlapAbsorberHandleFor(
context)
.layoutExtent ??
0,
),
child: _buildBody,
);
},
)
: Center(child: const Text('EMPTY')),
);
} else {
return Row(
children: [
Expanded(
child: CustomScrollView(
slivers: [
_buildAppBar(false),
],
),
), ),
Expanded( ];
},
body: _userController.tab2 != null &&
_userController.tab2!.isNotEmpty
? LayoutBuilder(
builder: (context, _) {
return Padding(
padding: EdgeInsets.only(
top: ExtendedNestedScrollView
.sliverOverlapAbsorberHandleFor(
context)
.layoutExtent ??
0,
),
child: _buildBody,
);
},
)
: 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( child: Column(
children: [ children: [
SizedBox(height: _top), SizedBox(height: _userController.top),
_buildTab, _buildTab,
Expanded(child: _buildBody), Expanded(child: _buildBody),
], ],
), ),
), ),
], ),
); ],
} );
}, }
) },
: Center( )
child: _buildUserInfo(_userController.loadingState.value), : Center(
), child: _buildUserInfo(_userController.loadingState.value),
), ),
), ),
); );
} }
@@ -154,116 +153,121 @@ class _MemberPageNewState extends State<MemberPageNew>
}).toList(), }).toList(),
); );
Widget _buildAppBar([bool needTab = true]) => DynamicSliverAppBar( Widget _buildAppBar([bool needTab = true]) => MediaQuery.removePadding(
leading: Padding( context: context,
padding: EdgeInsets.only(top: _top), removeTop: true,
child: const BackButton(), removeRight: true,
child: DynamicSliverAppBar(
leading: Padding(
padding: EdgeInsets.only(top: _userController.top ?? 0),
child: const BackButton(),
),
title: Obx(() => _userController.scrollRatio.value == 1 &&
_userController.username != null
? Padding(
padding: EdgeInsets.only(top: _userController.top ?? 0),
child: Text(_userController.username!),
)
: const SizedBox.shrink()),
pinned: true,
scrolledUnderElevation: 0,
flexibleSpace: _buildUserInfo(_userController.loadingState.value),
bottom: needTab &&
_userController.tab2 != null &&
_userController.tab2!.isNotEmpty
? PreferredSize(
preferredSize: Size.fromHeight(48),
child: Material(
child: _buildTab,
),
)
: 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),
),
),
Padding(
padding: EdgeInsets.only(top: _userController.top ?? 0),
child: PopupMenuButton(
icon: const Icon(Icons.more_vert),
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
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
? '加入黑名单'
: '移除黑名单'),
],
),
)
],
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) ...[
const PopupMenuDivider(),
PopupMenuItem(
onTap: () {
showDialog(
context: context,
builder: (_) => 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),
],
), ),
title: Obx(() => _userController.scrollRatio.value == 1 &&
_userController.username != null
? Padding(
padding: EdgeInsets.only(top: _top),
child: Text(_userController.username!),
)
: const SizedBox.shrink()),
pinned: true,
scrolledUnderElevation: 0,
flexibleSpace: _buildUserInfo(_userController.loadingState.value),
bottom: needTab &&
_userController.tab2 != null &&
_userController.tab2!.isNotEmpty
? PreferredSize(
preferredSize: Size.fromHeight(48),
child: Material(
child: _buildTab,
),
)
: null,
actions: [
Padding(
padding: EdgeInsets.only(top: _top),
child: IconButton(
tooltip: '搜索',
onPressed: () => Get.toNamed(
'/memberSearch?mid=$_mid&uname=${_userController.username}'),
icon: const Icon(Icons.search_outlined),
),
),
Padding(
padding: EdgeInsets.only(top: _top),
child: PopupMenuButton(
icon: const Icon(Icons.more_vert),
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
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
? '加入黑名单'
: '移除黑名单'),
],
),
)
],
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) ...[
const PopupMenuDivider(),
PopupMenuItem(
onTap: () {
showDialog(
context: context,
builder: (_) => 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),
],
); );
Widget _errorWidget(msg) { Widget _errorWidget(msg) {
@@ -271,11 +275,12 @@ class _MemberPageNewState extends State<MemberPageNew>
shrinkWrap: true, shrinkWrap: true,
slivers: [ slivers: [
HttpError( HttpError(
errMsg: msg, errMsg: msg,
fn: () { fn: () {
_userController.loadingState.value = LoadingState.loading(); _userController.loadingState.value = LoadingState.loading();
_userController.onRefresh(); _userController.onRefresh();
}) },
)
], ],
); );
} }

View File

@@ -12,6 +12,15 @@ class MemberDynamicsController extends GetxController {
bool hasMore = true; bool hasMore = true;
RxList<DynamicItemModel> dynamicsList = <DynamicItemModel>[].obs; RxList<DynamicItemModel> dynamicsList = <DynamicItemModel>[].obs;
// TODO: refactor
late Future futureBuilderFuture;
@override
void onInit() async {
super.onInit();
futureBuilderFuture = getMemberDynamic('onRefresh');
}
Future getMemberDynamic(type) async { Future getMemberDynamic(type) async {
if (type == 'onRefresh') { if (type == 'onRefresh') {
offset = ''; offset = '';

View File

@@ -23,7 +23,6 @@ class MemberDynamicsPage extends StatefulWidget {
class _MemberDynamicsPageState extends State<MemberDynamicsPage> class _MemberDynamicsPageState extends State<MemberDynamicsPage>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
late MemberDynamicsController _memberDynamicController; late MemberDynamicsController _memberDynamicController;
late Future _futureBuilderFuture;
late int mid; late int mid;
late bool dynamicsWaterfallFlow; late bool dynamicsWaterfallFlow;
@@ -37,8 +36,6 @@ class _MemberDynamicsPageState extends State<MemberDynamicsPage>
final String heroTag = Utils.makeHeroTag(mid); final String heroTag = Utils.makeHeroTag(mid);
_memberDynamicController = _memberDynamicController =
Get.put(MemberDynamicsController(widget.mid), tag: heroTag); Get.put(MemberDynamicsController(widget.mid), tag: heroTag);
_futureBuilderFuture =
_memberDynamicController.getMemberDynamic('onRefresh');
// _memberDynamicController.scrollController.addListener( // _memberDynamicController.scrollController.addListener(
// () { // () {
// if (_memberDynamicController.scrollController.position.pixels >= // if (_memberDynamicController.scrollController.position.pixels >=
@@ -83,7 +80,7 @@ class _MemberDynamicsPageState extends State<MemberDynamicsPage>
// controller: _memberDynamicController.scrollController, // controller: _memberDynamicController.scrollController,
slivers: [ slivers: [
FutureBuilder( FutureBuilder(
future: _futureBuilderFuture, future: _memberDynamicController.futureBuilderFuture,
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) { if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data != null) { if (snapshot.data != null) {

View File

@@ -37,7 +37,7 @@ class HotKeyword extends StatelessWidget {
message: i.keyword!, message: i.keyword!,
child: Row( child: Row(
children: [ children: [
Expanded( Flexible(
child: Padding( child: Padding(
padding: const EdgeInsets.fromLTRB(6, 5, 0, 5), padding: const EdgeInsets.fromLTRB(6, 5, 0, 5),
child: Text( child: Text(