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;
List<Tab2>? tab2;
RxInt contributeInitialIndex = 0.obs;
double? top;
@override
void onInit() {

View File

@@ -30,8 +30,6 @@ class _MemberPageNewState extends State<MemberPageNew>
String? _heroTag;
late final MemberControllerNew _userController;
late double _top;
@override
void initState() {
super.initState();
@@ -49,75 +47,76 @@ class _MemberPageNewState extends State<MemberPageNew>
@override
Widget build(BuildContext context) {
_top = MediaQuery.of(context).padding.top;
return MediaQuery.removePadding(
context: context,
removeTop: true,
child: Scaffold(
resizeToAvoidBottomInset: false,
body: Obx(
() => _userController.loadingState.value is Success
? LayoutBuilder(
builder: (_, constraints) {
if (constraints.maxHeight > constraints.maxWidth) {
return ExtendedNestedScrollView(
controller: _userController.scrollController,
onlyOneScrollInBody: true,
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
SliverOverlapAbsorber(
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),
],
),
_userController.top ??= MediaQuery.of(context).padding.top;
return Scaffold(
resizeToAvoidBottomInset: false,
body: Obx(
() => _userController.loadingState.value is Success
? LayoutBuilder(
builder: (_, constraints) {
if (constraints.maxHeight > constraints.maxWidth) {
return ExtendedNestedScrollView(
controller: _userController.scrollController,
onlyOneScrollInBody: true,
headerSliverBuilder: (context, innerBoxIsScrolled) {
return [
SliverOverlapAbsorber(
handle: ExtendedNestedScrollView
.sliverOverlapAbsorberHandleFor(context),
sliver: _buildAppBar(),
),
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(
children: [
SizedBox(height: _top),
SizedBox(height: _userController.top),
_buildTab,
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(),
);
Widget _buildAppBar([bool needTab = true]) => DynamicSliverAppBar(
leading: Padding(
padding: EdgeInsets.only(top: _top),
child: const BackButton(),
Widget _buildAppBar([bool needTab = true]) => MediaQuery.removePadding(
context: context,
removeTop: true,
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) {
@@ -271,11 +275,12 @@ class _MemberPageNewState extends State<MemberPageNew>
shrinkWrap: true,
slivers: [
HttpError(
errMsg: msg,
fn: () {
_userController.loadingState.value = LoadingState.loading();
_userController.onRefresh();
})
errMsg: msg,
fn: () {
_userController.loadingState.value = LoadingState.loading();
_userController.onRefresh();
},
)
],
);
}

View File

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

View File

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

View File

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