Merge branch 'design'
This commit is contained in:
@ -217,12 +217,13 @@ class Request {
|
|||||||
/*
|
/*
|
||||||
* get请求
|
* get请求
|
||||||
*/
|
*/
|
||||||
get(url, {data, options, cancelToken, extra}) async {
|
get(url, {data, Options? options, cancelToken, extra}) async {
|
||||||
Response response;
|
Response response;
|
||||||
final Options options = Options();
|
options ??= Options(); // 如果 options 为 null,则初始化一个新的 Options 对象
|
||||||
ResponseType resType = ResponseType.json;
|
ResponseType resType = ResponseType.json;
|
||||||
|
|
||||||
if (extra != null) {
|
if (extra != null) {
|
||||||
resType = extra!['resType'] ?? ResponseType.json;
|
resType = extra['resType'] ?? ResponseType.json;
|
||||||
if (extra['ua'] != null) {
|
if (extra['ua'] != null) {
|
||||||
options.headers = {'user-agent': headerUa(type: extra['ua'])};
|
options.headers = {'user-agent': headerUa(type: extra['ua'])};
|
||||||
}
|
}
|
||||||
@ -238,14 +239,11 @@ class Request {
|
|||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
Response errResponse = Response(
|
return Response(
|
||||||
data: {
|
data: {'message': await ApiInterceptor.dioError(e)},
|
||||||
'message': await ApiInterceptor.dioError(e)
|
|
||||||
}, // 将自定义 Map 数据赋值给 Response 的 data 属性
|
|
||||||
statusCode: 200,
|
statusCode: 200,
|
||||||
requestOptions: RequestOptions(),
|
requestOptions: RequestOptions(),
|
||||||
);
|
);
|
||||||
return errResponse;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import 'package:hive/hive.dart';
|
|||||||
import 'package:html/parser.dart';
|
import 'package:html/parser.dart';
|
||||||
import 'package:pilipala/models/member/article.dart';
|
import 'package:pilipala/models/member/article.dart';
|
||||||
import 'package:pilipala/models/member/like.dart';
|
import 'package:pilipala/models/member/like.dart';
|
||||||
|
import 'package:pilipala/utils/global_data_cache.dart';
|
||||||
import '../common/constants.dart';
|
import '../common/constants.dart';
|
||||||
import '../models/dynamics/result.dart';
|
import '../models/dynamics/result.dart';
|
||||||
import '../models/follow/result.dart';
|
import '../models/follow/result.dart';
|
||||||
@ -19,14 +20,20 @@ import 'index.dart';
|
|||||||
|
|
||||||
class MemberHttp {
|
class MemberHttp {
|
||||||
static Future memberInfo({
|
static Future memberInfo({
|
||||||
int? mid,
|
required int mid,
|
||||||
String token = '',
|
String token = '',
|
||||||
}) async {
|
}) async {
|
||||||
|
String? wWebid;
|
||||||
|
if ((await getWWebid(mid: mid))['status']) {
|
||||||
|
wWebid = GlobalDataCache().wWebid;
|
||||||
|
}
|
||||||
|
|
||||||
Map params = await WbiSign().makSign({
|
Map params = await WbiSign().makSign({
|
||||||
'mid': mid,
|
'mid': mid,
|
||||||
'token': token,
|
'token': token,
|
||||||
'platform': 'web',
|
'platform': 'web',
|
||||||
'web_location': 1550101,
|
'web_location': 1550101,
|
||||||
|
...wWebid != null ? {'w_webid': wWebid} : {},
|
||||||
});
|
});
|
||||||
var res = await Request().get(
|
var res = await Request().get(
|
||||||
Api.memberInfo,
|
Api.memberInfo,
|
||||||
@ -566,6 +573,10 @@ class MemberHttp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Future getWWebid({required int mid}) async {
|
static Future getWWebid({required int mid}) async {
|
||||||
|
String? wWebid = GlobalDataCache().wWebid;
|
||||||
|
if (wWebid != null) {
|
||||||
|
return {'status': true, 'data': wWebid};
|
||||||
|
}
|
||||||
var res = await Request().get('https://space.bilibili.com/$mid/article');
|
var res = await Request().get('https://space.bilibili.com/$mid/article');
|
||||||
String? headContent = parse(res.data).head?.outerHtml;
|
String? headContent = parse(res.data).head?.outerHtml;
|
||||||
final regex = RegExp(
|
final regex = RegExp(
|
||||||
@ -576,6 +587,7 @@ class MemberHttp {
|
|||||||
final content = match.group(1);
|
final content = match.group(1);
|
||||||
String decodedString = Uri.decodeComponent(content!);
|
String decodedString = Uri.decodeComponent(content!);
|
||||||
Map<String, dynamic> map = jsonDecode(decodedString);
|
Map<String, dynamic> map = jsonDecode(decodedString);
|
||||||
|
GlobalDataCache().wWebid = map['access_id'];
|
||||||
return {'status': true, 'data': map['access_id']};
|
return {'status': true, 'data': map['access_id']};
|
||||||
} else {
|
} else {
|
||||||
return {'status': false, 'data': '请检查登录状态'};
|
return {'status': false, 'data': '请检查登录状态'};
|
||||||
@ -588,25 +600,20 @@ class MemberHttp {
|
|||||||
static Future getMemberArticle({
|
static Future getMemberArticle({
|
||||||
required int mid,
|
required int mid,
|
||||||
required int pn,
|
required int pn,
|
||||||
required String wWebid,
|
|
||||||
String? offset,
|
String? offset,
|
||||||
}) async {
|
}) async {
|
||||||
|
String? wWebid;
|
||||||
|
if ((await getWWebid(mid: mid))['status']) {
|
||||||
|
wWebid = GlobalDataCache().wWebid;
|
||||||
|
}
|
||||||
Map params = await WbiSign().makSign({
|
Map params = await WbiSign().makSign({
|
||||||
'host_mid': mid,
|
'host_mid': mid,
|
||||||
'page': pn,
|
'page': pn,
|
||||||
'offset': offset,
|
'offset': offset,
|
||||||
'web_location': 333.999,
|
'web_location': 333.999,
|
||||||
'w_webid': wWebid,
|
...wWebid != null ? {'w_webid': wWebid} : {},
|
||||||
});
|
|
||||||
var res = await Request().get(Api.opusList, data: {
|
|
||||||
'host_mid': mid,
|
|
||||||
'page': pn,
|
|
||||||
'offset': offset,
|
|
||||||
'web_location': 333.999,
|
|
||||||
'w_webid': wWebid,
|
|
||||||
'w_rid': params['w_rid'],
|
|
||||||
'wts': params['wts'],
|
|
||||||
});
|
});
|
||||||
|
var res = await Request().get(Api.opusList, data: params);
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
return {
|
return {
|
||||||
'status': true,
|
'status': true,
|
||||||
|
|||||||
@ -4,9 +4,12 @@ enum FullScreenGestureMode {
|
|||||||
|
|
||||||
/// 从下滑到上
|
/// 从下滑到上
|
||||||
fromBottomtoTop,
|
fromBottomtoTop,
|
||||||
|
|
||||||
|
/// 关闭手势
|
||||||
|
none,
|
||||||
}
|
}
|
||||||
|
|
||||||
extension FullScreenGestureModeExtension on FullScreenGestureMode {
|
extension FullScreenGestureModeExtension on FullScreenGestureMode {
|
||||||
String get values => ['fromToptoBottom', 'fromBottomtoTop'][index];
|
String get values => ['fromToptoBottom', 'fromBottomtoTop', 'none'][index];
|
||||||
String get labels => ['从上往下滑进入全屏', '从下往上滑进入全屏'][index];
|
String get labels => ['从上往下滑进入全屏', '从下往上滑进入全屏', '关闭手势'][index];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -295,7 +295,7 @@ class AboutController extends GetxController {
|
|||||||
displayTime: const Duration(milliseconds: 500),
|
displayTime: const Duration(milliseconds: 500),
|
||||||
).then(
|
).then(
|
||||||
(value) => launchUrl(
|
(value) => launchUrl(
|
||||||
Uri.parse('https://www.123pan.com/s/9sVqVv-flu0A.html'),
|
Uri.parse('https://www.123684.com/s/9sVqVv-DEZ0A'),
|
||||||
mode: LaunchMode.externalApplication,
|
mode: LaunchMode.externalApplication,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -349,7 +349,7 @@ class AboutController extends GetxController {
|
|||||||
// 官网
|
// 官网
|
||||||
webSiteUrl() {
|
webSiteUrl() {
|
||||||
launchUrl(
|
launchUrl(
|
||||||
Uri.parse('https://pilipalanet.mysxl.cn'),
|
Uri.parse('https://pilipala.life'),
|
||||||
mode: LaunchMode.externalApplication,
|
mode: LaunchMode.externalApplication,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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']) {
|
||||||
|
if (actionType == 'follow') {
|
||||||
|
memberInfo.value.isFollowed = !memberInfo.value.isFollowed!;
|
||||||
|
} else if (actionType == 'block') {
|
||||||
attribute.value = attribute.value != 128 ? 128 : 0;
|
attribute.value = attribute.value != 128 ? 128 : 0;
|
||||||
attributeText.value = attribute.value == 128 ? '已拉黑' : '关注';
|
attributeText.value = attribute.value == 128 ? '已拉黑' : '关注';
|
||||||
memberInfo.value.isFollowed = false;
|
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');
|
||||||
|
|||||||
@ -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,10 +65,7 @@ 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(
|
|
||||||
children: [
|
|
||||||
AppBar(
|
|
||||||
title: StreamBuilder(
|
title: StreamBuilder(
|
||||||
stream: appbarStream.stream.distinct(),
|
stream: appbarStream.stream.distinct(),
|
||||||
initialData: false,
|
initialData: false,
|
||||||
@ -78,8 +75,6 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
curve: Curves.easeOut,
|
curve: Curves.easeOut,
|
||||||
duration: const Duration(milliseconds: 500),
|
duration: const Duration(milliseconds: 500),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
children: [
|
||||||
Obx(
|
Obx(
|
||||||
() => NetworkImgLayer(
|
() => NetworkImgLayer(
|
||||||
@ -94,14 +89,11 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
() => Text(
|
() => Text(
|
||||||
_memberController.memberInfo.value.name ?? '',
|
_memberController.memberInfo.value.name ?? '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color:
|
color: Theme.of(context).colorScheme.onSurface,
|
||||||
Theme.of(context).colorScheme.onSurface,
|
|
||||||
fontSize: 14),
|
fontSize: 14),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -148,14 +140,12 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Expanded(
|
primary: true,
|
||||||
child: SingleChildScrollView(
|
body: ListView(
|
||||||
controller: _extendNestCtr,
|
controller: _extendNestCtr,
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
bottom: MediaQuery.of(context).padding.bottom + 20,
|
bottom: MediaQuery.of(context).padding.bottom + 20,
|
||||||
),
|
),
|
||||||
child: Column(
|
|
||||||
children: [
|
children: [
|
||||||
profileWidget(),
|
profileWidget(),
|
||||||
|
|
||||||
@ -163,10 +153,8 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
Obx(
|
Obx(
|
||||||
() => ListTile(
|
() => ListTile(
|
||||||
onTap: _memberController.pushDynamicsPage,
|
onTap: _memberController.pushDynamicsPage,
|
||||||
title: Text(
|
title: Text('${_memberController.isOwner.value ? '我' : 'Ta'}的动态'),
|
||||||
'${_memberController.isOwner.value ? '我' : 'Ta'}的动态'),
|
trailing: const Icon(Icons.arrow_forward_outlined, size: 19),
|
||||||
trailing:
|
|
||||||
const Icon(Icons.arrow_forward_outlined, size: 19),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -174,10 +162,8 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
Obx(
|
Obx(
|
||||||
() => ListTile(
|
() => ListTile(
|
||||||
onTap: _memberController.pushArchivesPage,
|
onTap: _memberController.pushArchivesPage,
|
||||||
title: Text(
|
title: Text('${_memberController.isOwner.value ? '我' : 'Ta'}的投稿'),
|
||||||
'${_memberController.isOwner.value ? '我' : 'Ta'}的投稿'),
|
trailing: const Icon(Icons.arrow_forward_outlined, size: 19),
|
||||||
trailing:
|
|
||||||
const Icon(Icons.arrow_forward_outlined, size: 19),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -185,10 +171,8 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
Obx(
|
Obx(
|
||||||
() => ListTile(
|
() => ListTile(
|
||||||
onTap: _memberController.pushfavPage,
|
onTap: _memberController.pushfavPage,
|
||||||
title: Text(
|
title: Text('${_memberController.isOwner.value ? '我' : 'Ta'}的收藏'),
|
||||||
'${_memberController.isOwner.value ? '我' : 'Ta'}的收藏'),
|
trailing: const Icon(Icons.arrow_forward_outlined, size: 19),
|
||||||
trailing:
|
|
||||||
const Icon(Icons.arrow_forward_outlined, size: 19),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -196,18 +180,16 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
Obx(
|
Obx(
|
||||||
() => ListTile(
|
() => ListTile(
|
||||||
onTap: _memberController.pushArticlePage,
|
onTap: _memberController.pushArticlePage,
|
||||||
title: Text(
|
title: Text('${_memberController.isOwner.value ? '我' : 'Ta'}的专栏'),
|
||||||
'${_memberController.isOwner.value ? '我' : 'Ta'}的专栏'),
|
trailing: const Icon(Icons.arrow_forward_outlined, size: 19),
|
||||||
trailing:
|
|
||||||
const Icon(Icons.arrow_forward_outlined, size: 19),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
/// 合集
|
/// 合集
|
||||||
Obx(
|
Obx(
|
||||||
() => ListTile(
|
() => ListTile(
|
||||||
title: Text(
|
title: Text('${_memberController.isOwner.value ? '我' : 'Ta'}的合集'),
|
||||||
'${_memberController.isOwner.value ? '我' : 'Ta'}的合集')),
|
),
|
||||||
),
|
),
|
||||||
MediaQuery.removePadding(
|
MediaQuery.removePadding(
|
||||||
removeTop: true,
|
removeTop: true,
|
||||||
@ -216,15 +198,14 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
child: FutureBuilder(
|
child: FutureBuilder(
|
||||||
future: _memberSeasonsFuture,
|
future: _memberSeasonsFuture,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.connectionState ==
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
ConnectionState.done) {
|
|
||||||
if (snapshot.data == null) {
|
if (snapshot.data == null) {
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
}
|
}
|
||||||
if (snapshot.data['status']) {
|
if (snapshot.data['status']) {
|
||||||
Map data = snapshot.data as Map;
|
Map data = snapshot.data as Map;
|
||||||
if (data['data'].seasonsList.isEmpty) {
|
if (data['data'].seasonsList.isEmpty) {
|
||||||
return commenWidget('用户没有设置合集');
|
return const CommenWidget(msg: '用户没有设置合集');
|
||||||
} else {
|
} else {
|
||||||
return MemberSeasonsPanel(data: data['data']);
|
return MemberSeasonsPanel(data: data['data']);
|
||||||
}
|
}
|
||||||
@ -258,8 +239,7 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
child: FutureBuilder(
|
child: FutureBuilder(
|
||||||
future: _memberCoinsFuture,
|
future: _memberCoinsFuture,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.connectionState ==
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
ConnectionState.done) {
|
|
||||||
if (snapshot.data == null) {
|
if (snapshot.data == null) {
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
}
|
}
|
||||||
@ -296,8 +276,7 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
child: FutureBuilder(
|
child: FutureBuilder(
|
||||||
future: _memberLikeFuture,
|
future: _memberLikeFuture,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.connectionState ==
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
ConnectionState.done) {
|
|
||||||
if (snapshot.data == null) {
|
if (snapshot.data == null) {
|
||||||
return const SizedBox();
|
return const SizedBox();
|
||||||
}
|
}
|
||||||
@ -317,11 +296,6 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,11 +308,9 @@ 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,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
ProfilePanel(ctr: _memberController),
|
ProfilePanel(ctr: _memberController),
|
||||||
@ -347,7 +319,7 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
_memberController.memberInfo.value.name!,
|
memberInfo.value.name!,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
@ -355,21 +327,20 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
.titleMedium!
|
.titleMedium!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: _memberController.memberInfo.value
|
color: memberInfo.value.vip!.nicknameColor !=
|
||||||
.vip!.nicknameColor !=
|
|
||||||
null
|
null
|
||||||
? Color(_memberController.memberInfo
|
? Color(_memberController
|
||||||
.value.vip!.nicknameColor!)
|
.memberInfo.value.vip!.nicknameColor!)
|
||||||
: null),
|
: null),
|
||||||
)),
|
)),
|
||||||
const SizedBox(width: 2),
|
const SizedBox(width: 2),
|
||||||
if (_memberController.memberInfo.value.sex == '女')
|
if (memberInfo.value.sex == '女')
|
||||||
const Icon(
|
const Icon(
|
||||||
FontAwesomeIcons.venus,
|
FontAwesomeIcons.venus,
|
||||||
size: 14,
|
size: 14,
|
||||||
color: Colors.pink,
|
color: Colors.pink,
|
||||||
),
|
),
|
||||||
if (_memberController.memberInfo.value.sex == '男')
|
if (memberInfo.value.sex == '男')
|
||||||
const Icon(
|
const Icon(
|
||||||
FontAwesomeIcons.mars,
|
FontAwesomeIcons.mars,
|
||||||
size: 14,
|
size: 14,
|
||||||
@ -377,72 +348,50 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'assets/images/lv/lv${_memberController.memberInfo.value.level}.png',
|
'assets/images/lv/lv${memberInfo.value.level}.png',
|
||||||
height: 11,
|
height: 11,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
if (_memberController
|
if (memberInfo.value.vip!.status == 1 &&
|
||||||
.memberInfo.value.vip!.status ==
|
memberInfo
|
||||||
1 &&
|
.value.vip!.label!['img_label_uri_hans'] !=
|
||||||
_memberController.memberInfo.value.vip!
|
|
||||||
.label!['img_label_uri_hans'] !=
|
|
||||||
'') ...[
|
'') ...[
|
||||||
Image.network(
|
Image.network(
|
||||||
_memberController.memberInfo.value.vip!
|
memberInfo.value.vip!.label!['img_label_uri_hans'],
|
||||||
.label!['img_label_uri_hans'],
|
|
||||||
height: 20,
|
height: 20,
|
||||||
),
|
),
|
||||||
] else if (_memberController
|
] else if (memberInfo.value.vip!.status == 1 &&
|
||||||
.memberInfo.value.vip!.status ==
|
memberInfo.value.vip!
|
||||||
1 &&
|
|
||||||
_memberController.memberInfo.value.vip!
|
|
||||||
.label!['img_label_uri_hans_static'] !=
|
.label!['img_label_uri_hans_static'] !=
|
||||||
'') ...[
|
'') ...[
|
||||||
Image.network(
|
Image.network(
|
||||||
_memberController.memberInfo.value.vip!
|
memberInfo
|
||||||
.label!['img_label_uri_hans_static'],
|
.value.vip!.label!['img_label_uri_hans_static'],
|
||||||
height: 20,
|
height: 20,
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (_memberController
|
if (memberInfo.value.official!['title'] != '') ...[
|
||||||
.memberInfo.value.official!['title'] !=
|
|
||||||
'') ...[
|
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
Text.rich(
|
Text(
|
||||||
|
memberInfo.value.official!['role'] == 1
|
||||||
|
? '个人认证:${memberInfo.value.official!['title']}'
|
||||||
|
: '企业认证:${memberInfo.value.official!['title']}',
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
TextSpan(
|
softWrap: true,
|
||||||
text: _memberController
|
|
||||||
.memberInfo.value.official!['role'] ==
|
|
||||||
1
|
|
||||||
? '个人认证:'
|
|
||||||
: '企业认证:',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
children: [
|
|
||||||
TextSpan(
|
|
||||||
text: _memberController
|
|
||||||
.memberInfo.value.official!['title'],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
softWrap: true,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
const SizedBox(height: 6),
|
const SizedBox(height: 6),
|
||||||
if (_memberController.memberInfo.value.sign != '')
|
SelectableText(memberInfo.value.sign ?? ''),
|
||||||
SelectableText(
|
|
||||||
_memberController.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),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
24
lib/pages/member/widgets/commen_widget.dart
Normal file
24
lib/pages/member/widgets/commen_widget.dart
Normal 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),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,11 +18,53 @@ 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;
|
||||||
|
|
||||||
|
Map<String, dynamic> buildStatItem({
|
||||||
|
required String label,
|
||||||
|
required String value,
|
||||||
|
required VoidCallback onTap,
|
||||||
|
}) {
|
||||||
|
return {
|
||||||
|
'label': label,
|
||||||
|
'value': value,
|
||||||
|
'fn': onTap,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<Map<String, dynamic>> statList = [
|
||||||
|
buildStatItem(
|
||||||
|
label: '关注',
|
||||||
|
value: !loadingStatus ? "${ctr.userStat!['following']}" : '-',
|
||||||
|
onTap: () {
|
||||||
|
Get.toNamed('/follow?mid=$mid&name=$name');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
buildStatItem(
|
||||||
|
label: '粉丝',
|
||||||
|
value: !loadingStatus
|
||||||
|
? ctr.userStat!['follower'] != null
|
||||||
|
? Utils.numFormat(ctr.userStat!['follower'])
|
||||||
|
: '-'
|
||||||
|
: '-',
|
||||||
|
onTap: () {
|
||||||
|
Get.toNamed('/fan?mid=$mid&name=$name');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
buildStatItem(
|
||||||
|
label: '获赞',
|
||||||
|
value: !loadingStatus
|
||||||
|
? ctr.userStat!['likes'] != null
|
||||||
|
? Utils.numFormat(ctr.userStat!['likes'])
|
||||||
|
: '-'
|
||||||
|
: '-',
|
||||||
|
onTap: () {},
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding:
|
padding: const EdgeInsets.only(top: 30, left: 4),
|
||||||
EdgeInsets.only(top: MediaQuery.of(context).padding.top - 20),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Hero(
|
Hero(
|
||||||
@ -43,13 +85,13 @@ class ProfilePanel extends StatelessWidget {
|
|||||||
left: 14,
|
left: 14,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
LiveItemModel liveItem = LiveItemModel.fromJson({
|
LiveItemModel liveItem = LiveItemModel(
|
||||||
'title': memberInfo.liveRoom!.title,
|
title: memberInfo.liveRoom!.title,
|
||||||
'uname': memberInfo.name,
|
uname: memberInfo.name,
|
||||||
'face': memberInfo.face,
|
face: memberInfo.face,
|
||||||
'roomid': memberInfo.liveRoom!.roomId,
|
roomId: memberInfo.liveRoom!.roomId,
|
||||||
'watched_show': memberInfo.liveRoom!.watchedShow,
|
watchedShow: memberInfo.liveRoom!.watchedShow,
|
||||||
});
|
);
|
||||||
Get.toNamed(
|
Get.toNamed(
|
||||||
'/liveRoom?roomid=${memberInfo.liveRoom!.roomId}',
|
'/liveRoom?roomid=${memberInfo.liveRoom!.roomId}',
|
||||||
arguments: {'liveItem': liveItem},
|
arguments: {'liveItem': liveItem},
|
||||||
@ -89,117 +131,80 @@ class ProfilePanel extends StatelessWidget {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding:
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
const EdgeInsets.only(top: 10, left: 10, right: 10),
|
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: [
|
children: statList.map((item) {
|
||||||
InkWell(
|
return buildStatColumn(
|
||||||
onTap: () {
|
context,
|
||||||
Get.toNamed(
|
item['label'],
|
||||||
'/follow?mid=${memberInfo.mid}&name=${memberInfo.name}');
|
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(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
!loadingStatus
|
value,
|
||||||
? ctr.userStat!['following'].toString()
|
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
|
||||||
: '-',
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.bold),
|
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'关注',
|
label,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: Theme.of(context)
|
fontSize: Theme.of(context).textTheme.labelMedium!.fontSize,
|
||||||
.textTheme
|
),
|
||||||
.labelMedium!
|
),
|
||||||
.fontSize),
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
InkWell(
|
}
|
||||||
onTap: () {
|
|
||||||
Get.toNamed(
|
Widget buildActionButtons(
|
||||||
'/fan?mid=${memberInfo.mid}&name=${memberInfo.name}');
|
BuildContext context,
|
||||||
},
|
dynamic ctr,
|
||||||
child: Column(
|
MemberInfoModel memberInfo,
|
||||||
children: [
|
) {
|
||||||
Text(
|
ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||||
!loadingStatus
|
return Row(
|
||||||
? 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: [
|
children: [
|
||||||
|
const SizedBox(width: 20),
|
||||||
Obx(
|
Obx(
|
||||||
() => Expanded(
|
() => Expanded(
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () => loadingStatus
|
onPressed: () => loadingStatus ? null : ctr.actionRelationMod(),
|
||||||
? null
|
|
||||||
: ctr.actionRelationMod(),
|
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
foregroundColor: ctr.attribute.value == -1
|
foregroundColor: ctr.attribute.value == -1
|
||||||
? Colors.transparent
|
? Colors.transparent
|
||||||
: ctr.attribute.value != 0
|
: ctr.attribute.value != 0
|
||||||
? Theme.of(context)
|
? colorScheme.outline
|
||||||
.colorScheme
|
: colorScheme.onPrimary,
|
||||||
.outline
|
|
||||||
: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.onPrimary,
|
|
||||||
backgroundColor: ctr.attribute.value != 0
|
backgroundColor: ctr.attribute.value != 0
|
||||||
? Theme.of(context)
|
? colorScheme.onInverseSurface
|
||||||
.colorScheme
|
: colorScheme.primary,
|
||||||
.onInverseSurface
|
|
||||||
: Theme.of(context)
|
|
||||||
.colorScheme
|
|
||||||
.primary, // 设置按钮背景色
|
|
||||||
),
|
),
|
||||||
child: Obx(() => Text(ctr.attributeText.value)),
|
child: Obx(() => Text(ctr.attributeText.value)),
|
||||||
),
|
),
|
||||||
@ -220,51 +225,38 @@ class ProfilePanel extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
backgroundColor: Theme.of(context)
|
backgroundColor: colorScheme.onInverseSurface,
|
||||||
.colorScheme
|
|
||||||
.onInverseSurface,
|
|
||||||
),
|
),
|
||||||
child: const Text('发消息'),
|
child: const Text('发消息'),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
)
|
);
|
||||||
],
|
}
|
||||||
if (ctr.ownerMid == ctr.mid && ctr.ownerMid != -1) ...[
|
|
||||||
TextButton(
|
Widget buildEditProfileButton(BuildContext context) {
|
||||||
|
return TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
SmartDialog.showToast('功能开发中 💪');
|
SmartDialog.showToast('功能开发中 💪');
|
||||||
},
|
},
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: const EdgeInsets.only(left: 80, right: 80),
|
padding: const EdgeInsets.symmetric(horizontal: 80),
|
||||||
foregroundColor:
|
foregroundColor: Theme.of(context).colorScheme.onPrimary,
|
||||||
Theme.of(context).colorScheme.onPrimary,
|
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||||
backgroundColor:
|
|
||||||
Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
),
|
||||||
child: const Text('编辑资料'),
|
child: const Text('编辑资料'),
|
||||||
)
|
);
|
||||||
],
|
}
|
||||||
if (ctr.ownerMid == -1) ...[
|
|
||||||
TextButton(
|
Widget buildNotLoggedInButton(BuildContext context) {
|
||||||
|
return TextButton(
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: const EdgeInsets.only(left: 80, right: 80),
|
padding: const EdgeInsets.symmetric(horizontal: 80),
|
||||||
foregroundColor:
|
foregroundColor: Theme.of(context).colorScheme.outline,
|
||||||
Theme.of(context).colorScheme.outline,
|
backgroundColor: Theme.of(context).colorScheme.onInverseSurface,
|
||||||
backgroundColor:
|
|
||||||
Theme.of(context).colorScheme.onInverseSurface,
|
|
||||||
),
|
),
|
||||||
child: const Text('未登录'),
|
child: const Text('未登录'),
|
||||||
)
|
|
||||||
]
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,6 @@ class MemberArticleController extends GetxController {
|
|||||||
int pn = 1;
|
int pn = 1;
|
||||||
String? offset;
|
String? offset;
|
||||||
bool hasMore = true;
|
bool hasMore = true;
|
||||||
String? wWebid;
|
|
||||||
RxBool isLoading = false.obs;
|
RxBool isLoading = false.obs;
|
||||||
RxList<MemberArticleItemModel> articleList = <MemberArticleItemModel>[].obs;
|
RxList<MemberArticleItemModel> articleList = <MemberArticleItemModel>[].obs;
|
||||||
|
|
||||||
@ -20,25 +19,11 @@ class MemberArticleController extends GetxController {
|
|||||||
mid = int.parse(Get.parameters['mid']!);
|
mid = int.parse(Get.parameters['mid']!);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取wWebid
|
|
||||||
Future getWWebid() async {
|
|
||||||
var res = await MemberHttp.getWWebid(mid: mid);
|
|
||||||
if (res['status']) {
|
|
||||||
wWebid = res['data'];
|
|
||||||
} else {
|
|
||||||
wWebid = '-1';
|
|
||||||
SmartDialog.showToast(res['msg']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future getMemberArticle(type) async {
|
Future getMemberArticle(type) async {
|
||||||
if (isLoading.value) {
|
if (isLoading.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
isLoading.value = true;
|
isLoading.value = true;
|
||||||
if (wWebid == null) {
|
|
||||||
await getWWebid();
|
|
||||||
}
|
|
||||||
if (type == 'init') {
|
if (type == 'init') {
|
||||||
pn = 1;
|
pn = 1;
|
||||||
articleList.clear();
|
articleList.clear();
|
||||||
@ -47,7 +32,6 @@ class MemberArticleController extends GetxController {
|
|||||||
mid: mid,
|
mid: mid,
|
||||||
pn: pn,
|
pn: pn,
|
||||||
offset: offset,
|
offset: offset,
|
||||||
wWebid: wWebid!,
|
|
||||||
);
|
);
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
offset = res['data'].offset;
|
offset = res['data'].offset;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/utils/global_data_cache.dart';
|
import 'package:pilipala/utils/global_data_cache.dart';
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ class _PlayGesturePageState extends State<PlayGesturePage> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
fullScreenGestureMode = setting.get(SettingBoxKey.fullScreenGestureMode,
|
fullScreenGestureMode = setting.get(SettingBoxKey.fullScreenGestureMode,
|
||||||
defaultValue: FullScreenGestureMode.values.last.index);
|
defaultValue: FullScreenGestureMode.fromBottomtoTop.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -71,6 +72,7 @@ class _PlayGesturePageState extends State<PlayGesturePage> {
|
|||||||
GlobalDataCache().fullScreenGestureMode.index;
|
GlobalDataCache().fullScreenGestureMode.index;
|
||||||
setting.put(
|
setting.put(
|
||||||
SettingBoxKey.fullScreenGestureMode, fullScreenGestureMode);
|
SettingBoxKey.fullScreenGestureMode, fullScreenGestureMode);
|
||||||
|
SmartDialog.showToast('设置成功');
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -204,6 +204,14 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
|||||||
widget.controller.brightness.value = value;
|
widget.controller.brightness.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isUsingFullScreenGestures(double tapPosition, double sectionWidth) {
|
||||||
|
if (fullScreenGestureMode == FullScreenGestureMode.none) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return tapPosition < sectionWidth * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
animationController.dispose();
|
animationController.dispose();
|
||||||
@ -660,12 +668,12 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
|
|||||||
_brightnessValue.value - delta / level;
|
_brightnessValue.value - delta / level;
|
||||||
final double result = brightness.clamp(0.0, 1.0);
|
final double result = brightness.clamp(0.0, 1.0);
|
||||||
setBrightness(result);
|
setBrightness(result);
|
||||||
} else if (tapPosition < sectionWidth * 2) {
|
} else if (isUsingFullScreenGestures(tapPosition, sectionWidth)) {
|
||||||
// 全屏
|
// 全屏
|
||||||
final double dy = details.delta.dy;
|
final double dy = details.delta.dy;
|
||||||
const double threshold = 7.0; // 滑动阈值
|
const double threshold = 7.0; // 滑动阈值
|
||||||
final bool flag =
|
final bool flag = fullScreenGestureMode !=
|
||||||
fullScreenGestureMode != FullScreenGestureMode.values.last;
|
FullScreenGestureMode.fromBottomtoTop;
|
||||||
if (dy > _distance.value &&
|
if (dy > _distance.value &&
|
||||||
dy > threshold &&
|
dy > threshold &&
|
||||||
!_.controlsLock.value) {
|
!_.controlsLock.value) {
|
||||||
|
|||||||
@ -15,6 +15,7 @@ class GlobalDataCache {
|
|||||||
late FullScreenGestureMode fullScreenGestureMode;
|
late FullScreenGestureMode fullScreenGestureMode;
|
||||||
late bool enablePlayerControlAnimation;
|
late bool enablePlayerControlAnimation;
|
||||||
late List<String> actionTypeSort;
|
late List<String> actionTypeSort;
|
||||||
|
String? wWebid;
|
||||||
|
|
||||||
/// 播放器相关
|
/// 播放器相关
|
||||||
// 弹幕开关
|
// 弹幕开关
|
||||||
|
|||||||
@ -306,7 +306,7 @@ class Utils {
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await SmartDialog.dismiss();
|
await SmartDialog.dismiss();
|
||||||
launchUrl(
|
launchUrl(
|
||||||
Uri.parse('https://www.123pan.com/s/9sVqVv-flu0A.html'),
|
Uri.parse('https://www.123684.com/s/9sVqVv-DEZ0A'),
|
||||||
mode: LaunchMode.externalApplication,
|
mode: LaunchMode.externalApplication,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user