From fff54a55a139d2be11e19e02d71bc1b8e07a605a Mon Sep 17 00:00:00 2001 From: guozhigq Date: Tue, 12 Sep 2023 22:49:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=94=A8=E6=88=B7=E6=8B=89=E9=BB=91?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20issues=20#107?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/api.dart | 3 + lib/http/user.dart | 26 ++++ lib/pages/member/controller.dart | 86 +++++++++++++- lib/pages/member/view.dart | 30 ++++- lib/pages/member/widgets/profile.dart | 164 ++++++++++++++------------ 5 files changed, 225 insertions(+), 84 deletions(-) diff --git a/lib/http/api.dart b/lib/http/api.dart index 0a2e6616..ef9fe94a 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -97,6 +97,9 @@ class Api { // 操作用户关系 static const String relationMod = '/x/relation/modify'; + // 相互关系查询 + static const String relationSearch = '/x/space/wbi/acc/relation'; + // 评论列表 // https://api.bilibili.com/x/v2/reply/main?csrf=6e22efc1a47225ea25f901f922b5cfdd&mode=3&oid=254175381&pagination_str=%7B%22offset%22:%22%22%7D&plat=1&seek_rpid=0&type=11 static const String replyList = '/x/v2/reply'; diff --git a/lib/http/user.dart b/lib/http/user.dart index 44002805..b27cfde1 100644 --- a/lib/http/user.dart +++ b/lib/http/user.dart @@ -8,6 +8,7 @@ import 'package:pilipala/models/user/fav_folder.dart'; import 'package:pilipala/models/user/history.dart'; import 'package:pilipala/models/user/info.dart'; import 'package:pilipala/models/user/stat.dart'; +import 'package:pilipala/utils/wbi_sign.dart'; class UserHttp { static Future userStat({required int mid}) async { @@ -248,4 +249,29 @@ class UserHttp { return {'status': false, 'msg': res.data['message']}; } } + + // 相互关系查询 + static Future relationSearch(int mid) async { + Map params = await WbiSign().makSign({ + 'mid': mid, + 'token': '', + 'platform': 'web', + 'web_location': 1550101, + }); + var res = await Request().get( + Api.relationSearch, + data: { + 'mid': mid, + 'w_rid': params['w_rid'], + 'wts': params['wts'], + }, + ); + if (res.data['code'] == 0) { + // relation 主动状态 + // 被动状态 + return {'status': true, 'data': res.data['data']}; + } else { + return {'status': false, 'msg': res.data['message']}; + } + } } diff --git a/lib/pages/member/controller.dart b/lib/pages/member/controller.dart index db4deaae..df1ecf43 100644 --- a/lib/pages/member/controller.dart +++ b/lib/pages/member/controller.dart @@ -3,10 +3,12 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:pilipala/http/member.dart'; +import 'package:pilipala/http/user.dart'; import 'package:pilipala/http/video.dart'; import 'package:pilipala/models/member/archive.dart'; import 'package:pilipala/models/member/info.dart'; import 'package:pilipala/utils/storage.dart'; +import 'package:share_plus/share_plus.dart'; class MemberController extends GetxController { late int mid; @@ -19,6 +21,8 @@ class MemberController extends GetxController { // 投稿列表 RxList? archiveList = [VListItemModel()].obs; var userInfo; + RxInt attribute = (-1).obs; + RxString attributeText = '关注'.obs; @override void onInit() { @@ -28,6 +32,7 @@ class MemberController extends GetxController { ownerMid = userInfo != null ? userInfo.mid : -1; face = Get.arguments['face'] ?? ''; heroTag = Get.arguments['heroTag'] ?? ''; + relationSearch(); } // 获取用户信息 @@ -63,7 +68,10 @@ class MemberController extends GetxController { SmartDialog.showToast('账号未登录'); return; } - + if (attribute.value == 128) { + blockUser(); + return; + } SmartDialog.show( useSystem: true, animationType: SmartAnimationType.centerFade_otherSlide, @@ -73,8 +81,12 @@ class MemberController extends GetxController { content: Text(memberInfo.value.isFollowed! ? '取消关注UP主?' : '关注UP主?'), actions: [ TextButton( - onPressed: () => SmartDialog.dismiss(), - child: const Text('点错了')), + onPressed: () => SmartDialog.dismiss(), + child: Text( + '点错了', + style: TextStyle(color: Theme.of(context).colorScheme.outline), + ), + ), TextButton( onPressed: () async { await VideoHttp.relationMod( @@ -83,8 +95,7 @@ class MemberController extends GetxController { reSrc: 11, ); memberInfo.value.isFollowed = !memberInfo.value.isFollowed!; - SmartDialog.dismiss(); - SmartDialog.showLoading(); + relationSearch(); SmartDialog.dismiss(); memberInfo.update((val) {}); }, @@ -95,4 +106,69 @@ class MemberController extends GetxController { }, ); } + + // 关系查询 + Future relationSearch() async { + if (userInfo == null) return; + var res = await UserHttp.relationSearch(mid); + if (res['status']) { + attribute.value = res['data']['relation']['attribute']; + attributeText.value = attribute.value == 0 + ? '关注' + : attribute.value == 2 + ? '已关注' + : attribute.value == 2 + ? '已互粉' + : '已拉黑'; + } + } + + // 拉黑用户 + Future blockUser() async { + if (userInfo == null) { + SmartDialog.showToast('账号未登录'); + return; + } + SmartDialog.show( + useSystem: true, + animationType: SmartAnimationType.centerFade_otherSlide, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('提示'), + content: Text(attribute.value != 128 ? '确定拉黑UP主?' : '从黑名单移除UP主'), + actions: [ + TextButton( + onPressed: () => SmartDialog.dismiss(), + child: Text( + '点错了', + style: TextStyle(color: Theme.of(context).colorScheme.outline), + ), + ), + TextButton( + onPressed: () async { + var res = await VideoHttp.relationMod( + mid: mid, + act: attribute.value != 128 ? 5 : 6, + reSrc: 11, + ); + SmartDialog.dismiss(); + if (res['status']) { + attribute.value = attribute.value != 128 ? 128 : 0; + attributeText.value = attribute.value == 128 ? '已拉黑' : '关注'; + memberInfo.value.isFollowed = false; + relationSearch(); + memberInfo.update((val) {}); + } + }, + child: const Text('确认'), + ) + ], + ); + }, + ); + } + + void shareUser() { + Share.share('${memberInfo.value.name} - https://space.bilibili.com/$mid'); + } } diff --git a/lib/pages/member/view.dart b/lib/pages/member/view.dart index 55dad4f0..c5130206 100644 --- a/lib/pages/member/view.dart +++ b/lib/pages/member/view.dart @@ -102,7 +102,35 @@ class _MemberPageState extends State }, ), actions: [ - IconButton(onPressed: () {}, icon: const Icon(Icons.more_vert)), + PopupMenuButton( + icon: const Icon(Icons.more_vert), + itemBuilder: (BuildContext context) => [ + 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: const Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.share_outlined, size: 19), + SizedBox(width: 10), + Text('分享UP主'), + ], + ), + ), + ], + ), const SizedBox(width: 4), ], flexibleSpace: FlexibleSpaceBar( diff --git a/lib/pages/member/widgets/profile.dart b/lib/pages/member/widgets/profile.dart index d8dc651a..2574c9ae 100644 --- a/lib/pages/member/widgets/profile.dart +++ b/lib/pages/member/widgets/profile.dart @@ -15,62 +15,63 @@ Widget profile(ctr, {loadingStatus = false}) { child: Row( children: [ Hero( - tag: ctr.heroTag!, - child: Stack( - children: [ - NetworkImgLayer( - width: 90, - height: 90, - type: 'avatar', - src: !loadingStatus ? memberInfo.face : ctr.face, - ), - if (!loadingStatus && - memberInfo.liveRoom != null && - memberInfo.liveRoom!.liveStatus == 1) - Positioned( - bottom: 0, - left: 14, - child: GestureDetector( - onTap: () { - LiveItemModel liveItem = LiveItemModel.fromJson({ - 'title': memberInfo.liveRoom!.title, - 'uname': memberInfo.name, - 'face': memberInfo.face, - 'roomid': memberInfo.liveRoom!.roomId, - 'watched_show': memberInfo.liveRoom!.watchedShow, - }); - Get.toNamed( - '/liveRoom?roomid=${memberInfo.liveRoom!.roomId}', - arguments: {'liveItem': liveItem}, - ); - }, - child: Container( - padding: const EdgeInsets.fromLTRB(6, 2, 6, 2), - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.primary, - borderRadius: - const BorderRadius.all(Radius.circular(10)), - ), - child: Row(children: [ - Image.asset( - 'assets/images/live.gif', - height: 10, - ), - Text( - ' 直播中', - style: TextStyle( - color: Colors.white, - fontSize: Theme.of(context) - .textTheme - .labelSmall! - .fontSize), - ) - ]), + tag: ctr.heroTag!, + child: Stack( + children: [ + NetworkImgLayer( + width: 90, + height: 90, + type: 'avatar', + src: !loadingStatus ? memberInfo.face : ctr.face, + ), + if (!loadingStatus && + memberInfo.liveRoom != null && + memberInfo.liveRoom!.liveStatus == 1) + Positioned( + bottom: 0, + left: 14, + child: GestureDetector( + onTap: () { + LiveItemModel liveItem = LiveItemModel.fromJson({ + 'title': memberInfo.liveRoom!.title, + 'uname': memberInfo.name, + 'face': memberInfo.face, + 'roomid': memberInfo.liveRoom!.roomId, + 'watched_show': memberInfo.liveRoom!.watchedShow, + }); + Get.toNamed( + '/liveRoom?roomid=${memberInfo.liveRoom!.roomId}', + arguments: {'liveItem': liveItem}, + ); + }, + child: Container( + padding: const EdgeInsets.fromLTRB(6, 2, 6, 2), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.primary, + borderRadius: + const BorderRadius.all(Radius.circular(10)), ), + child: Row(children: [ + Image.asset( + 'assets/images/live.gif', + height: 10, + ), + Text( + ' 直播中', + style: TextStyle( + color: Colors.white, + fontSize: Theme.of(context) + .textTheme + .labelSmall! + .fontSize), + ) + ]), ), - ) - ], - )), + ), + ) + ], + ), + ), const SizedBox(width: 12), Expanded( child: Column( @@ -152,34 +153,41 @@ Widget profile(ctr, {loadingStatus = false}) { if (ctr.ownerMid != ctr.mid) ...[ Row( children: [ - TextButton( - onPressed: () => ctr.actionRelationMod(), - style: TextButton.styleFrom( - padding: const EdgeInsets.only(left: 42, right: 42), - foregroundColor: - !loadingStatus && memberInfo.isFollowed! - ? Theme.of(context).colorScheme.outline - : Theme.of(context).colorScheme.onPrimary, - backgroundColor: !loadingStatus && - memberInfo.isFollowed! - ? Theme.of(context).colorScheme.onInverseSurface - : Theme.of(context) - .colorScheme - .primary, // 设置按钮背景色 + Obx( + () => Expanded( + child: TextButton( + onPressed: () => 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)), + ), ), - child: Text(!loadingStatus && memberInfo.isFollowed! - ? '取关' - : '关注'), ), const SizedBox(width: 8), - TextButton( - onPressed: () {}, - style: TextButton.styleFrom( - padding: const EdgeInsets.only(left: 42, right: 42), - backgroundColor: - Theme.of(context).colorScheme.onInverseSurface, + Expanded( + child: TextButton( + onPressed: () {}, + style: TextButton.styleFrom( + backgroundColor: Theme.of(context) + .colorScheme + .onInverseSurface, + ), + child: const Text('发消息'), ), - child: const Text('发消息'), ) ], )