feat: 用户拉黑功能 issues #107
This commit is contained in:
@ -97,6 +97,9 @@ class Api {
|
|||||||
// 操作用户关系
|
// 操作用户关系
|
||||||
static const String relationMod = '/x/relation/modify';
|
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
|
// 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';
|
static const String replyList = '/x/v2/reply';
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import 'package:pilipala/models/user/fav_folder.dart';
|
|||||||
import 'package:pilipala/models/user/history.dart';
|
import 'package:pilipala/models/user/history.dart';
|
||||||
import 'package:pilipala/models/user/info.dart';
|
import 'package:pilipala/models/user/info.dart';
|
||||||
import 'package:pilipala/models/user/stat.dart';
|
import 'package:pilipala/models/user/stat.dart';
|
||||||
|
import 'package:pilipala/utils/wbi_sign.dart';
|
||||||
|
|
||||||
class UserHttp {
|
class UserHttp {
|
||||||
static Future<dynamic> userStat({required int mid}) async {
|
static Future<dynamic> userStat({required int mid}) async {
|
||||||
@ -248,4 +249,29 @@ class UserHttp {
|
|||||||
return {'status': false, 'msg': res.data['message']};
|
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']};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,10 +3,12 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/http/member.dart';
|
import 'package:pilipala/http/member.dart';
|
||||||
|
import 'package:pilipala/http/user.dart';
|
||||||
import 'package:pilipala/http/video.dart';
|
import 'package:pilipala/http/video.dart';
|
||||||
import 'package:pilipala/models/member/archive.dart';
|
import 'package:pilipala/models/member/archive.dart';
|
||||||
import 'package:pilipala/models/member/info.dart';
|
import 'package:pilipala/models/member/info.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
|
||||||
class MemberController extends GetxController {
|
class MemberController extends GetxController {
|
||||||
late int mid;
|
late int mid;
|
||||||
@ -19,6 +21,8 @@ class MemberController extends GetxController {
|
|||||||
// 投稿列表
|
// 投稿列表
|
||||||
RxList<VListItemModel>? archiveList = [VListItemModel()].obs;
|
RxList<VListItemModel>? archiveList = [VListItemModel()].obs;
|
||||||
var userInfo;
|
var userInfo;
|
||||||
|
RxInt attribute = (-1).obs;
|
||||||
|
RxString attributeText = '关注'.obs;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
@ -28,6 +32,7 @@ class MemberController extends GetxController {
|
|||||||
ownerMid = userInfo != null ? userInfo.mid : -1;
|
ownerMid = userInfo != null ? userInfo.mid : -1;
|
||||||
face = Get.arguments['face'] ?? '';
|
face = Get.arguments['face'] ?? '';
|
||||||
heroTag = Get.arguments['heroTag'] ?? '';
|
heroTag = Get.arguments['heroTag'] ?? '';
|
||||||
|
relationSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
@ -63,7 +68,10 @@ class MemberController extends GetxController {
|
|||||||
SmartDialog.showToast('账号未登录');
|
SmartDialog.showToast('账号未登录');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (attribute.value == 128) {
|
||||||
|
blockUser();
|
||||||
|
return;
|
||||||
|
}
|
||||||
SmartDialog.show(
|
SmartDialog.show(
|
||||||
useSystem: true,
|
useSystem: true,
|
||||||
animationType: SmartAnimationType.centerFade_otherSlide,
|
animationType: SmartAnimationType.centerFade_otherSlide,
|
||||||
@ -74,7 +82,11 @@ class MemberController extends GetxController {
|
|||||||
actions: [
|
actions: [
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => SmartDialog.dismiss(),
|
onPressed: () => SmartDialog.dismiss(),
|
||||||
child: const Text('点错了')),
|
child: Text(
|
||||||
|
'点错了',
|
||||||
|
style: TextStyle(color: Theme.of(context).colorScheme.outline),
|
||||||
|
),
|
||||||
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await VideoHttp.relationMod(
|
await VideoHttp.relationMod(
|
||||||
@ -83,8 +95,7 @@ class MemberController extends GetxController {
|
|||||||
reSrc: 11,
|
reSrc: 11,
|
||||||
);
|
);
|
||||||
memberInfo.value.isFollowed = !memberInfo.value.isFollowed!;
|
memberInfo.value.isFollowed = !memberInfo.value.isFollowed!;
|
||||||
SmartDialog.dismiss();
|
relationSearch();
|
||||||
SmartDialog.showLoading();
|
|
||||||
SmartDialog.dismiss();
|
SmartDialog.dismiss();
|
||||||
memberInfo.update((val) {});
|
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');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -102,7 +102,35 @@ class _MemberPageState extends State<MemberPage>
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(onPressed: () {}, icon: const Icon(Icons.more_vert)),
|
PopupMenuButton(
|
||||||
|
icon: const Icon(Icons.more_vert),
|
||||||
|
itemBuilder: (BuildContext context) => <PopupMenuEntry>[
|
||||||
|
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),
|
const SizedBox(width: 4),
|
||||||
],
|
],
|
||||||
flexibleSpace: FlexibleSpaceBar(
|
flexibleSpace: FlexibleSpaceBar(
|
||||||
|
|||||||
@ -70,7 +70,8 @@ Widget profile(ctr, {loadingStatus = false}) {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
@ -152,34 +153,41 @@ Widget profile(ctr, {loadingStatus = false}) {
|
|||||||
if (ctr.ownerMid != ctr.mid) ...[
|
if (ctr.ownerMid != ctr.mid) ...[
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
TextButton(
|
Obx(
|
||||||
|
() => Expanded(
|
||||||
|
child: TextButton(
|
||||||
onPressed: () => ctr.actionRelationMod(),
|
onPressed: () => ctr.actionRelationMod(),
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: const EdgeInsets.only(left: 42, right: 42),
|
foregroundColor: ctr.attribute.value == -1
|
||||||
foregroundColor:
|
? Colors.transparent
|
||||||
!loadingStatus && memberInfo.isFollowed!
|
: ctr.attribute.value != 0
|
||||||
? Theme.of(context).colorScheme.outline
|
? Theme.of(context).colorScheme.outline
|
||||||
: Theme.of(context).colorScheme.onPrimary,
|
: Theme.of(context)
|
||||||
backgroundColor: !loadingStatus &&
|
.colorScheme
|
||||||
memberInfo.isFollowed!
|
.onPrimary,
|
||||||
? Theme.of(context).colorScheme.onInverseSurface
|
backgroundColor: ctr.attribute.value != 0
|
||||||
|
? Theme.of(context)
|
||||||
|
.colorScheme
|
||||||
|
.onInverseSurface
|
||||||
: Theme.of(context)
|
: Theme.of(context)
|
||||||
.colorScheme
|
.colorScheme
|
||||||
.primary, // 设置按钮背景色
|
.primary, // 设置按钮背景色
|
||||||
),
|
),
|
||||||
child: Text(!loadingStatus && memberInfo.isFollowed!
|
child: Obx(() => Text(ctr.attributeText.value)),
|
||||||
? '取关'
|
),
|
||||||
: '关注'),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
TextButton(
|
Expanded(
|
||||||
|
child: TextButton(
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: const EdgeInsets.only(left: 42, right: 42),
|
backgroundColor: Theme.of(context)
|
||||||
backgroundColor:
|
.colorScheme
|
||||||
Theme.of(context).colorScheme.onInverseSurface,
|
.onInverseSurface,
|
||||||
),
|
),
|
||||||
child: const Text('发消息'),
|
child: const Text('发消息'),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user