opt: up主页布局

This commit is contained in:
guozhigq
2024-10-13 01:11:48 +08:00
parent 85f77ed933
commit c1cd024db6
4 changed files with 601 additions and 668 deletions

View File

@ -49,6 +49,8 @@ class MemberController extends GetxController {
if (res['status']) { if (res['status']) {
memberInfo.value = res['data']; memberInfo.value = res['data'];
face.value = res['data'].face; face.value = res['data'].face;
} else {
SmartDialog.showToast('用户信息请求异常:${res['msg']}');
} }
return res; return res;
} }
@ -78,42 +80,10 @@ class MemberController extends GetxController {
return; return;
} }
if (attribute.value == 128) { if (attribute.value == 128) {
blockUser(); modifyRelation('block');
return; } else {
modifyRelation('follow');
} }
SmartDialog.show(
useSystem: true,
animationType: SmartAnimationType.centerFade_otherSlide,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('提示'),
content: Text(memberInfo.value.isFollowed! ? '取消关注UP主?' : '关注UP主?'),
actions: [
TextButton(
onPressed: () => SmartDialog.dismiss(),
child: Text(
'点错了',
style: TextStyle(color: Theme.of(context).colorScheme.outline),
),
),
TextButton(
onPressed: () async {
await VideoHttp.relationMod(
mid: mid,
act: memberInfo.value.isFollowed! ? 2 : 1,
reSrc: 11,
);
memberInfo.value.isFollowed = !memberInfo.value.isFollowed!;
relationSearch();
SmartDialog.dismiss();
memberInfo.update((val) {});
},
child: const Text('确认'),
)
],
);
},
);
} }
// 关系查询 // 关系查询
@ -123,24 +93,15 @@ class MemberController extends GetxController {
var res = await UserHttp.hasFollow(mid); var res = await UserHttp.hasFollow(mid);
if (res['status']) { if (res['status']) {
attribute.value = res['data']['attribute']; attribute.value = res['data']['attribute'];
switch (attribute.value) { final Map<int, String> attributeTextMap = {
case 1: 1: '悄悄关注',
attributeText.value = '悄悄关注'; 2: '关注',
break; 6: '已互关',
case 2: 128: '已拉黑',
attributeText.value = '已关注'; };
break; attributeText.value = attributeTextMap[attribute.value] ?? '关注';
case 6:
attributeText.value = '已互关';
break;
case 128:
attributeText.value = '已拉黑';
break;
default:
attributeText.value = '关注';
}
if (res['data']['special'] == 1) { if (res['data']['special'] == 1) {
attributeText.value += 'SP'; attributeText.value = '特别关注';
} }
} }
} }
@ -151,16 +112,37 @@ class MemberController extends GetxController {
SmartDialog.showToast('账号未登录'); SmartDialog.showToast('账号未登录');
return; return;
} }
SmartDialog.show( modifyRelation('block');
useSystem: true, }
animationType: SmartAnimationType.centerFade_otherSlide,
// 合并关注/取关和拉黑逻辑
Future modifyRelation(String actionType) async {
if (userInfo == null) {
SmartDialog.showToast('账号未登录');
return;
}
String contentText;
int act;
if (actionType == 'follow') {
contentText = memberInfo.value.isFollowed! ? '确定取消关注UP主?' : '确定关注UP主?';
act = memberInfo.value.isFollowed! ? 2 : 1;
} else if (actionType == 'block') {
contentText = attribute.value != 128 ? '确定拉黑UP主?' : '确定从黑名单移除UP主';
act = attribute.value != 128 ? 5 : 6;
} else {
return;
}
showDialog(
context: Get.context!,
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
title: const Text('提示'), title: const Text('提示'),
content: Text(attribute.value != 128 ? '确定拉黑UP主?' : '从黑名单移除UP主'), content: Text(contentText),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => SmartDialog.dismiss(), onPressed: () => Navigator.of(context).pop(),
child: Text( child: Text(
'点错了', '点错了',
style: TextStyle(color: Theme.of(context).colorScheme.outline), style: TextStyle(color: Theme.of(context).colorScheme.outline),
@ -170,19 +152,26 @@ class MemberController extends GetxController {
onPressed: () async { onPressed: () async {
var res = await VideoHttp.relationMod( var res = await VideoHttp.relationMod(
mid: mid, mid: mid,
act: attribute.value != 128 ? 5 : 6, act: act,
reSrc: 11, reSrc: 11,
); );
SmartDialog.dismiss(); SmartDialog.dismiss();
if (res['status']) { if (res['status']) {
attribute.value = attribute.value != 128 ? 128 : 0; if (actionType == 'follow') {
attributeText.value = attribute.value == 128 ? '已拉黑' : '关注'; memberInfo.value.isFollowed = !memberInfo.value.isFollowed!;
memberInfo.value.isFollowed = false; } else if (actionType == 'block') {
attribute.value = attribute.value != 128 ? 128 : 0;
attributeText.value = attribute.value == 128 ? '已拉黑' : '关注';
memberInfo.value.isFollowed = false;
}
relationSearch(); relationSearch();
if (context.mounted) {
Navigator.of(context).pop();
}
memberInfo.update((val) {}); memberInfo.update((val) {});
} }
}, },
child: const Text(''), child: const Text(''),
) )
], ],
); );
@ -228,17 +217,14 @@ class MemberController extends GetxController {
// 跳转查看动态 // 跳转查看动态
void pushDynamicsPage() => Get.toNamed('/memberDynamics?mid=$mid'); void pushDynamicsPage() => Get.toNamed('/memberDynamics?mid=$mid');
// 跳转查看投稿 // 跳转查看投稿
void pushArchivesPage() => Get.toNamed('/memberArchive?mid=$mid'); void pushArchivesPage() => Get.toNamed('/memberArchive?mid=$mid');
// 跳转查看专栏
void pushSeasonsPage() {}
// 跳转查看最近投币 // 跳转查看最近投币
void pushRecentCoinsPage() async { void pushRecentCoinsPage() async {
if (recentCoinsList.isNotEmpty) {} if (recentCoinsList.isNotEmpty) {}
} }
// 跳转查看收藏夹
void pushfavPage() => Get.toNamed('/fav?mid=$mid'); void pushfavPage() => Get.toNamed('/fav?mid=$mid');
// 跳转图文专栏 // 跳转图文专栏
void pushArticlePage() => Get.toNamed('/memberArticle?mid=$mid'); void pushArticlePage() => Get.toNamed('/memberArticle?mid=$mid');

View File

@ -1,13 +1,13 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/models/member/info.dart';
import 'package:pilipala/pages/member/index.dart'; import 'package:pilipala/pages/member/index.dart';
import 'package:pilipala/utils/utils.dart'; import 'package:pilipala/utils/utils.dart';
import 'widgets/commen_widget.dart';
import 'widgets/conis.dart'; import 'widgets/conis.dart';
import 'widgets/like.dart'; import 'widgets/like.dart';
import 'widgets/profile.dart'; import 'widgets/profile.dart';
@ -65,259 +65,233 @@ class _MemberPageState extends State<MemberPage>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
primary: true, appBar: AppBar(
body: Column( title: StreamBuilder(
children: [ stream: appbarStream.stream.distinct(),
AppBar( initialData: false,
title: StreamBuilder( builder: (BuildContext context, AsyncSnapshot snapshot) {
stream: appbarStream.stream.distinct(), return AnimatedOpacity(
initialData: false, opacity: snapshot.data ? 1 : 0,
builder: (BuildContext context, AsyncSnapshot snapshot) { curve: Curves.easeOut,
return AnimatedOpacity( duration: const Duration(milliseconds: 500),
opacity: snapshot.data ? 1 : 0, child: Row(
curve: Curves.easeOut, children: [
duration: const Duration(milliseconds: 500), Obx(
child: Row( () => NetworkImgLayer(
children: [ width: 35,
Row( height: 35,
children: [ type: 'avatar',
Obx( src: _memberController.face.value,
() => NetworkImgLayer( ),
width: 35,
height: 35,
type: 'avatar',
src: _memberController.face.value,
),
),
const SizedBox(width: 10),
Obx(
() => Text(
_memberController.memberInfo.value.name ?? '',
style: TextStyle(
color:
Theme.of(context).colorScheme.onSurface,
fontSize: 14),
),
),
],
)
],
), ),
); const SizedBox(width: 10),
}, Obx(
), () => Text(
actions: [ _memberController.memberInfo.value.name ?? '',
IconButton( style: TextStyle(
onPressed: () => Get.toNamed( color: Theme.of(context).colorScheme.onSurface,
'/memberSearch?mid=$mid&uname=${_memberController.memberInfo.value.name!}'), fontSize: 14),
icon: const Icon(Icons.search_outlined),
),
PopupMenuButton(
icon: const Icon(Icons.more_vert),
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
if (_memberController.ownerMid != _memberController.mid) ...[
PopupMenuItem(
onTap: () => _memberController.blockUser(),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.block, size: 19),
const SizedBox(width: 10),
Text(_memberController.attribute.value != 128
? '加入黑名单'
: '移除黑名单'),
],
),
)
],
PopupMenuItem(
onTap: () => _memberController.shareUser(),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.share_outlined, size: 19),
const SizedBox(width: 10),
Text(_memberController.ownerMid != _memberController.mid
? '分享UP主'
: '分享我的主页'),
],
), ),
), ),
], ],
), ),
const SizedBox(width: 4), );
], },
),
actions: [
IconButton(
onPressed: () => Get.toNamed(
'/memberSearch?mid=$mid&uname=${_memberController.memberInfo.value.name!}'),
icon: const Icon(Icons.search_outlined),
), ),
Expanded( PopupMenuButton(
child: SingleChildScrollView( icon: const Icon(Icons.more_vert),
controller: _extendNestCtr, itemBuilder: (BuildContext context) => <PopupMenuEntry>[
child: Padding( if (_memberController.ownerMid != _memberController.mid) ...[
padding: EdgeInsets.only( PopupMenuItem(
bottom: MediaQuery.of(context).padding.bottom + 20, onTap: () => _memberController.blockUser(),
), child: Row(
child: Column( mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.block, size: 19),
const SizedBox(width: 10),
Text(_memberController.attribute.value != 128
? '加入黑名单'
: '移除黑名单'),
],
),
)
],
PopupMenuItem(
onTap: () => _memberController.shareUser(),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [ children: [
profileWidget(), const Icon(Icons.share_outlined, size: 19),
const SizedBox(width: 10),
/// 动态链接 Text(_memberController.ownerMid != _memberController.mid
Obx( ? '分享UP主'
() => ListTile( : '分享我的主页'),
onTap: _memberController.pushDynamicsPage,
title: Text(
'${_memberController.isOwner.value ? '' : 'Ta'}的动态'),
trailing:
const Icon(Icons.arrow_forward_outlined, size: 19),
),
),
/// 视频
Obx(
() => ListTile(
onTap: _memberController.pushArchivesPage,
title: Text(
'${_memberController.isOwner.value ? '' : 'Ta'}的投稿'),
trailing:
const Icon(Icons.arrow_forward_outlined, size: 19),
),
),
/// 他的收藏夹
Obx(
() => ListTile(
onTap: _memberController.pushfavPage,
title: Text(
'${_memberController.isOwner.value ? '' : 'Ta'}的收藏'),
trailing:
const Icon(Icons.arrow_forward_outlined, size: 19),
),
),
/// 专栏
Obx(
() => ListTile(
onTap: _memberController.pushArticlePage,
title: Text(
'${_memberController.isOwner.value ? '' : 'Ta'}的专栏'),
trailing:
const Icon(Icons.arrow_forward_outlined, size: 19),
),
),
/// 合集
Obx(
() => ListTile(
title: Text(
'${_memberController.isOwner.value ? '' : 'Ta'}的合集')),
),
MediaQuery.removePadding(
removeTop: true,
removeBottom: true,
context: context,
child: FutureBuilder(
future: _memberSeasonsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.done) {
if (snapshot.data == null) {
return const SizedBox();
}
if (snapshot.data['status']) {
Map data = snapshot.data as Map;
if (data['data'].seasonsList.isEmpty) {
return commenWidget('用户没有设置合集');
} else {
return MemberSeasonsPanel(data: data['data']);
}
} else {
// 请求错误
return const SizedBox();
}
} else {
return const SizedBox();
}
},
),
),
/// 追番
/// 最近投币
Obx(
() => _memberController.recentCoinsList.isNotEmpty
? const ListTile(title: Text('最近投币的视频'))
: const SizedBox(),
),
MediaQuery.removePadding(
removeTop: true,
removeBottom: true,
context: context,
child: Padding(
padding: const EdgeInsets.only(
left: StyleString.safeSpace,
right: StyleString.safeSpace,
),
child: FutureBuilder(
future: _memberCoinsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.done) {
if (snapshot.data == null) {
return const SizedBox();
}
if (snapshot.data['status']) {
Map data = snapshot.data as Map;
return MemberCoinsPanel(data: data['data']);
} else {
// 请求错误
return const SizedBox();
}
} else {
return const SizedBox();
}
},
),
),
),
/// 最近点赞
Obx(
() => _memberController.recentLikeList.isNotEmpty
? const ListTile(title: Text('最近点赞的视频'))
: const SizedBox(),
),
MediaQuery.removePadding(
removeTop: true,
removeBottom: true,
context: context,
child: Padding(
padding: const EdgeInsets.only(
left: StyleString.safeSpace,
right: StyleString.safeSpace,
),
child: FutureBuilder(
future: _memberLikeFuture,
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.done) {
if (snapshot.data == null) {
return const SizedBox();
}
if (snapshot.data['status']) {
Map data = snapshot.data as Map;
return MemberLikePanel(data: data['data']);
} else {
// 请求错误
return const SizedBox();
}
} else {
return const SizedBox();
}
},
),
),
),
], ],
), ),
), ),
],
),
const SizedBox(width: 4),
],
),
primary: true,
body: ListView(
controller: _extendNestCtr,
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).padding.bottom + 20,
),
children: [
profileWidget(),
/// 动态链接
Obx(
() => ListTile(
onTap: _memberController.pushDynamicsPage,
title: Text('${_memberController.isOwner.value ? '' : 'Ta'}的动态'),
trailing: const Icon(Icons.arrow_forward_outlined, size: 19),
),
),
/// 视频
Obx(
() => ListTile(
onTap: _memberController.pushArchivesPage,
title: Text('${_memberController.isOwner.value ? '' : 'Ta'}的投稿'),
trailing: const Icon(Icons.arrow_forward_outlined, size: 19),
),
),
/// 他的收藏夹
Obx(
() => ListTile(
onTap: _memberController.pushfavPage,
title: Text('${_memberController.isOwner.value ? '' : 'Ta'}的收藏'),
trailing: const Icon(Icons.arrow_forward_outlined, size: 19),
),
),
/// 专栏
Obx(
() => ListTile(
onTap: _memberController.pushArticlePage,
title: Text('${_memberController.isOwner.value ? '' : 'Ta'}的专栏'),
trailing: const Icon(Icons.arrow_forward_outlined, size: 19),
),
),
/// 合集
Obx(
() => ListTile(
title: Text('${_memberController.isOwner.value ? '' : 'Ta'}的合集'),
),
),
MediaQuery.removePadding(
removeTop: true,
removeBottom: true,
context: context,
child: FutureBuilder(
future: _memberSeasonsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
return const SizedBox();
}
if (snapshot.data['status']) {
Map data = snapshot.data as Map;
if (data['data'].seasonsList.isEmpty) {
return const CommenWidget(msg: '用户没有设置合集');
} else {
return MemberSeasonsPanel(data: data['data']);
}
} else {
// 请求错误
return const SizedBox();
}
} else {
return const SizedBox();
}
},
),
),
/// 追番
/// 最近投币
Obx(
() => _memberController.recentCoinsList.isNotEmpty
? const ListTile(title: Text('最近投币的视频'))
: const SizedBox(),
),
MediaQuery.removePadding(
removeTop: true,
removeBottom: true,
context: context,
child: Padding(
padding: const EdgeInsets.only(
left: StyleString.safeSpace,
right: StyleString.safeSpace,
),
child: FutureBuilder(
future: _memberCoinsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
return const SizedBox();
}
if (snapshot.data['status']) {
Map data = snapshot.data as Map;
return MemberCoinsPanel(data: data['data']);
} else {
// 请求错误
return const SizedBox();
}
} else {
return const SizedBox();
}
},
),
),
),
/// 最近点赞
Obx(
() => _memberController.recentLikeList.isNotEmpty
? const ListTile(title: Text('最近点赞的视频'))
: const SizedBox(),
),
MediaQuery.removePadding(
removeTop: true,
removeBottom: true,
context: context,
child: Padding(
padding: const EdgeInsets.only(
left: StyleString.safeSpace,
right: StyleString.safeSpace,
),
child: FutureBuilder(
future: _memberLikeFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
return const SizedBox();
}
if (snapshot.data['status']) {
Map data = snapshot.data as Map;
return MemberLikePanel(data: data['data']);
} else {
// 请求错误
return const SizedBox();
}
} else {
return const SizedBox();
}
},
),
), ),
), ),
], ],
@ -334,115 +308,90 @@ class _MemberPageState extends State<MemberPage>
if (snapshot.connectionState == ConnectionState.done) { if (snapshot.connectionState == ConnectionState.done) {
Map? data = snapshot.data; Map? data = snapshot.data;
if (data != null && data['status']) { if (data != null && data['status']) {
Rx<MemberInfoModel> memberInfo = _memberController.memberInfo;
return Obx( return Obx(
() => Stack( () => Column(
alignment: AlignmentDirectional.center, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Column( ProfilePanel(ctr: _memberController),
crossAxisAlignment: CrossAxisAlignment.start, const SizedBox(height: 20),
Row(
children: [ children: [
ProfilePanel(ctr: _memberController), Flexible(
const SizedBox(height: 20), child: Text(
Row( memberInfo.value.name!,
children: [ maxLines: 1,
Flexible( overflow: TextOverflow.ellipsis,
child: Text( style: Theme.of(context)
_memberController.memberInfo.value.name!, .textTheme
maxLines: 1, .titleMedium!
overflow: TextOverflow.ellipsis, .copyWith(
style: Theme.of(context) fontWeight: FontWeight.bold,
.textTheme color: memberInfo.value.vip!.nicknameColor !=
.titleMedium! null
.copyWith( ? Color(_memberController
fontWeight: FontWeight.bold, .memberInfo.value.vip!.nicknameColor!)
color: _memberController.memberInfo.value : null),
.vip!.nicknameColor != )),
null const SizedBox(width: 2),
? Color(_memberController.memberInfo if (memberInfo.value.sex == '')
.value.vip!.nicknameColor!) const Icon(
: null), FontAwesomeIcons.venus,
)), size: 14,
const SizedBox(width: 2), color: Colors.pink,
if (_memberController.memberInfo.value.sex == '') ),
const Icon( if (memberInfo.value.sex == '')
FontAwesomeIcons.venus, const Icon(
size: 14, FontAwesomeIcons.mars,
color: Colors.pink, size: 14,
), color: Colors.blue,
if (_memberController.memberInfo.value.sex == '') ),
const Icon( const SizedBox(width: 4),
FontAwesomeIcons.mars, Image.asset(
size: 14, 'assets/images/lv/lv${memberInfo.value.level}.png',
color: Colors.blue, height: 11,
),
const SizedBox(width: 4),
Image.asset(
'assets/images/lv/lv${_memberController.memberInfo.value.level}.png',
height: 11,
),
const SizedBox(width: 6),
if (_memberController
.memberInfo.value.vip!.status ==
1 &&
_memberController.memberInfo.value.vip!
.label!['img_label_uri_hans'] !=
'') ...[
Image.network(
_memberController.memberInfo.value.vip!
.label!['img_label_uri_hans'],
height: 20,
),
] else if (_memberController
.memberInfo.value.vip!.status ==
1 &&
_memberController.memberInfo.value.vip!
.label!['img_label_uri_hans_static'] !=
'') ...[
Image.network(
_memberController.memberInfo.value.vip!
.label!['img_label_uri_hans_static'],
height: 20,
),
]
],
), ),
if (_memberController const SizedBox(width: 6),
.memberInfo.value.official!['title'] != if (memberInfo.value.vip!.status == 1 &&
'') ...[ memberInfo
const SizedBox(height: 6), .value.vip!.label!['img_label_uri_hans'] !=
Text.rich( '') ...[
maxLines: 2, Image.network(
TextSpan( memberInfo.value.vip!.label!['img_label_uri_hans'],
text: _memberController height: 20,
.memberInfo.value.official!['role'] ==
1
? '个人认证:'
: '企业认证:',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
children: [
TextSpan(
text: _memberController
.memberInfo.value.official!['title'],
),
],
),
softWrap: true,
), ),
], ] else if (memberInfo.value.vip!.status == 1 &&
const SizedBox(height: 6), memberInfo.value.vip!
if (_memberController.memberInfo.value.sign != '') .label!['img_label_uri_hans_static'] !=
SelectableText( '') ...[
_memberController.memberInfo.value.sign!, Image.network(
memberInfo
.value.vip!.label!['img_label_uri_hans_static'],
height: 20,
), ),
]
], ],
), ),
if (memberInfo.value.official!['title'] != '') ...[
const SizedBox(height: 6),
Text(
memberInfo.value.official!['role'] == 1
? '个人认证:${memberInfo.value.official!['title']}'
: '企业认证:${memberInfo.value.official!['title']}',
maxLines: 2,
softWrap: true,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
],
const SizedBox(height: 6),
SelectableText(memberInfo.value.sign ?? ''),
], ],
), ),
); );
} else { } else {
return const SizedBox(); return ProfilePanel(ctr: _memberController, loadingStatus: true);
} }
} else { } else {
// 骨架屏 // 骨架屏
@ -452,22 +401,4 @@ class _MemberPageState extends State<MemberPage>
), ),
); );
} }
Widget commenWidget(msg) {
return Padding(
padding: const EdgeInsets.only(
top: 20,
bottom: 30,
),
child: Center(
child: Text(
msg,
style: Theme.of(context)
.textTheme
.labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline),
),
),
);
}
} }

View File

@ -0,0 +1,24 @@
import 'package:flutter/material.dart';
class CommenWidget extends StatelessWidget {
final String msg;
const CommenWidget({required this.msg, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 20.0, horizontal: 10.0),
child: Center(
child: Text(
msg,
textAlign: TextAlign.center,
style: Theme.of(context)
.textTheme
.labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline),
),
),
);
}
}

View File

@ -18,253 +18,245 @@ class ProfilePanel extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
MemberInfoModel memberInfo = ctr.memberInfo.value; MemberInfoModel memberInfo = ctr.memberInfo.value;
return Builder( final int? mid = memberInfo.mid;
builder: ((context) { final String? name = memberInfo.name;
return Padding(
padding: Map<String, dynamic> buildStatItem({
EdgeInsets.only(top: MediaQuery.of(context).padding.top - 20), required String label,
child: Row( required String value,
children: [ required VoidCallback onTap,
Hero( }) {
tag: ctr.heroTag!, return {
child: Stack( 'label': label,
children: [ 'value': value,
NetworkImgLayer( 'fn': onTap,
width: 90, };
height: 90, }
type: 'avatar',
src: !loadingStatus ? memberInfo.face : ctr.face.value, final List<Map<String, dynamic>> statList = [
), buildStatItem(
if (!loadingStatus && label: '关注',
memberInfo.liveRoom != null && value: !loadingStatus ? "${ctr.userStat!['following']}" : '-',
memberInfo.liveRoom!.liveStatus == 1) onTap: () {
Positioned( Get.toNamed('/follow?mid=$mid&name=$name');
bottom: 0, },
left: 14, ),
child: GestureDetector( buildStatItem(
onTap: () { label: '粉丝',
LiveItemModel liveItem = LiveItemModel.fromJson({ value: !loadingStatus
'title': memberInfo.liveRoom!.title, ? ctr.userStat!['follower'] != null
'uname': memberInfo.name, ? Utils.numFormat(ctr.userStat!['follower'])
'face': memberInfo.face, : '-'
'roomid': memberInfo.liveRoom!.roomId, : '-',
'watched_show': memberInfo.liveRoom!.watchedShow, onTap: () {
}); Get.toNamed('/fan?mid=$mid&name=$name');
Get.toNamed( },
'/liveRoom?roomid=${memberInfo.liveRoom!.roomId}', ),
arguments: {'liveItem': liveItem}, buildStatItem(
); label: '获赞',
}, value: !loadingStatus
child: Container( ? ctr.userStat!['likes'] != null
padding: const EdgeInsets.fromLTRB(6, 2, 6, 2), ? Utils.numFormat(ctr.userStat!['likes'])
decoration: BoxDecoration( : '-'
color: Theme.of(context).colorScheme.primary, : '-',
borderRadius: onTap: () {},
const BorderRadius.all(Radius.circular(10)), ),
), ];
child: Row(children: [
Image.asset( return Padding(
'assets/images/live.gif', padding: const EdgeInsets.only(top: 30, left: 4),
height: 10, child: Row(
), children: [
Text( Hero(
' 直播中', tag: ctr.heroTag!,
style: TextStyle( child: Stack(
color: Colors.white, children: [
fontSize: Theme.of(context) NetworkImgLayer(
.textTheme width: 90,
.labelSmall! height: 90,
.fontSize), type: 'avatar',
) src: !loadingStatus ? memberInfo.face : ctr.face.value,
]),
),
),
)
],
), ),
), if (!loadingStatus &&
const SizedBox(width: 12), memberInfo.liveRoom != null &&
Expanded( memberInfo.liveRoom!.liveStatus == 1)
child: Column( Positioned(
mainAxisSize: MainAxisSize.min, bottom: 0,
children: [ left: 14,
Padding( child: GestureDetector(
padding: onTap: () {
const EdgeInsets.only(top: 10, left: 10, right: 10), LiveItemModel liveItem = LiveItemModel(
child: Row( title: memberInfo.liveRoom!.title,
mainAxisSize: MainAxisSize.max, uname: memberInfo.name,
mainAxisAlignment: MainAxisAlignment.spaceAround, face: memberInfo.face,
children: [ roomId: memberInfo.liveRoom!.roomId,
InkWell( watchedShow: memberInfo.liveRoom!.watchedShow,
onTap: () { );
Get.toNamed( Get.toNamed(
'/follow?mid=${memberInfo.mid}&name=${memberInfo.name}'); '/liveRoom?roomid=${memberInfo.liveRoom!.roomId}',
}, arguments: {'liveItem': liveItem},
child: Column( );
children: [ },
Text( child: Container(
!loadingStatus padding: const EdgeInsets.fromLTRB(6, 2, 6, 2),
? ctr.userStat!['following'].toString() decoration: BoxDecoration(
: '-', color: Theme.of(context).colorScheme.primary,
style: const TextStyle( borderRadius:
fontWeight: FontWeight.bold), const BorderRadius.all(Radius.circular(10)),
), ),
Text( child: Row(children: [
'关注', Image.asset(
style: TextStyle( 'assets/images/live.gif',
fontSize: Theme.of(context) height: 10,
.textTheme
.labelMedium!
.fontSize),
)
],
),
), ),
InkWell( Text(
onTap: () { ' 直播中',
Get.toNamed( style: TextStyle(
'/fan?mid=${memberInfo.mid}&name=${memberInfo.name}'); color: Colors.white,
}, fontSize: Theme.of(context)
child: Column( .textTheme
children: [ .labelSmall!
Text( .fontSize),
!loadingStatus )
? ctr.userStat!['follower'] != null ]),
? Utils.numFormat(
ctr.userStat!['follower'],
)
: '-'
: '-',
style: const TextStyle(
fontWeight: FontWeight.bold)),
Text(
'粉丝',
style: TextStyle(
fontSize: Theme.of(context)
.textTheme
.labelMedium!
.fontSize),
)
],
),
),
Column(
children: [
Text(
!loadingStatus
? ctr.userStat!['likes'] != null
? Utils.numFormat(
ctr.userStat!['likes'],
)
: '-'
: '-',
style: const TextStyle(
fontWeight: FontWeight.bold)),
Text(
'获赞',
style: TextStyle(
fontSize: Theme.of(context)
.textTheme
.labelMedium!
.fontSize),
)
],
),
],
), ),
), ),
const SizedBox(height: 10), )
if (ctr.ownerMid != ctr.mid && ctr.ownerMid != -1) ...[ ],
Row( ),
children: [
Obx(
() => Expanded(
child: TextButton(
onPressed: () => loadingStatus
? null
: ctr.actionRelationMod(),
style: TextButton.styleFrom(
foregroundColor: ctr.attribute.value == -1
? Colors.transparent
: ctr.attribute.value != 0
? Theme.of(context)
.colorScheme
.outline
: Theme.of(context)
.colorScheme
.onPrimary,
backgroundColor: ctr.attribute.value != 0
? Theme.of(context)
.colorScheme
.onInverseSurface
: Theme.of(context)
.colorScheme
.primary, // 设置按钮背景色
),
child: Obx(() => Text(ctr.attributeText.value)),
),
),
),
const SizedBox(width: 8),
Expanded(
child: TextButton(
onPressed: () {
Get.toNamed(
'/whisperDetail',
parameters: {
'name': memberInfo.name!,
'face': memberInfo.face!,
'mid': memberInfo.mid.toString(),
'heroTag': ctr.heroTag!,
},
);
},
style: TextButton.styleFrom(
backgroundColor: Theme.of(context)
.colorScheme
.onInverseSurface,
),
child: const Text('发消息'),
),
)
],
)
],
if (ctr.ownerMid == ctr.mid && ctr.ownerMid != -1) ...[
TextButton(
onPressed: () {
SmartDialog.showToast('功能开发中 💪');
},
style: TextButton.styleFrom(
padding: const EdgeInsets.only(left: 80, right: 80),
foregroundColor:
Theme.of(context).colorScheme.onPrimary,
backgroundColor:
Theme.of(context).colorScheme.primary,
),
child: const Text('编辑资料'),
)
],
if (ctr.ownerMid == -1) ...[
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
padding: const EdgeInsets.only(left: 80, right: 80),
foregroundColor:
Theme.of(context).colorScheme.outline,
backgroundColor:
Theme.of(context).colorScheme.onInverseSurface,
),
child: const Text('未登录'),
)
]
],
),
),
],
), ),
); const SizedBox(width: 12),
}), Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: statList.map((item) {
return buildStatColumn(
context,
item['label'],
item['value'],
item['fn'],
);
}).toList(),
),
),
const SizedBox(height: 16),
if (ctr.ownerMid != ctr.mid && ctr.ownerMid != -1)
buildActionButtons(context, ctr, memberInfo),
if (ctr.ownerMid == ctr.mid && ctr.ownerMid != -1)
buildEditProfileButton(context),
if (ctr.ownerMid == -1) buildNotLoggedInButton(context),
],
),
),
],
),
);
}
Widget buildStatColumn(
BuildContext context,
String label,
String value,
VoidCallback? onTap,
) {
return InkWell(
onTap: onTap,
child: Column(
children: [
Text(
value,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
Text(
label,
style: TextStyle(
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
),
),
],
),
);
}
Widget buildActionButtons(
BuildContext context,
dynamic ctr,
MemberInfoModel memberInfo,
) {
ColorScheme colorScheme = Theme.of(context).colorScheme;
return Row(
children: [
const SizedBox(width: 20),
Obx(
() => Expanded(
child: TextButton(
onPressed: () => loadingStatus ? null : ctr.actionRelationMod(),
style: TextButton.styleFrom(
foregroundColor: ctr.attribute.value == -1
? Colors.transparent
: ctr.attribute.value != 0
? colorScheme.outline
: colorScheme.onPrimary,
backgroundColor: ctr.attribute.value != 0
? colorScheme.onInverseSurface
: colorScheme.primary,
),
child: Obx(() => Text(ctr.attributeText.value)),
),
),
),
const SizedBox(width: 8),
Expanded(
child: TextButton(
onPressed: () {
Get.toNamed(
'/whisperDetail',
parameters: {
'name': memberInfo.name!,
'face': memberInfo.face!,
'mid': memberInfo.mid.toString(),
'heroTag': ctr.heroTag!,
},
);
},
style: TextButton.styleFrom(
backgroundColor: colorScheme.onInverseSurface,
),
child: const Text('发消息'),
),
),
],
);
}
Widget buildEditProfileButton(BuildContext context) {
return TextButton(
onPressed: () {
SmartDialog.showToast('功能开发中 💪');
},
style: TextButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 80),
foregroundColor: Theme.of(context).colorScheme.onPrimary,
backgroundColor: Theme.of(context).colorScheme.primary,
),
child: const Text('编辑资料'),
);
}
Widget buildNotLoggedInButton(BuildContext context) {
return TextButton(
onPressed: () {},
style: TextButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 80),
foregroundColor: Theme.of(context).colorScheme.outline,
backgroundColor: Theme.of(context).colorScheme.onInverseSurface,
),
child: const Text('未登录'),
); );
} }
} }