feat: 黑名单查看、屏蔽黑名单用户推荐/最热 #22

This commit is contained in:
guozhigq
2023-08-15 14:43:20 +08:00
parent 1fe234d702
commit eb38dfc313
9 changed files with 306 additions and 3 deletions

View File

@ -278,4 +278,7 @@ class Api {
// 我的订阅
static const String bangumiFollow =
'/x/space/bangumi/follow/list?type=1&follow_status=0&pn=1&ps=15&ts=1691544359969';
// 黑名单
static const String blackLst = '/x/relation/blacks';
}

26
lib/http/black.dart Normal file
View File

@ -0,0 +1,26 @@
import 'package:pilipala/http/index.dart';
import 'package:pilipala/models/user/black.dart';
class BlackHttp {
static Future blackList({required int pn, int? ps}) async {
var res = await Request().get(Api.blackLst, data: {
'pn': pn,
'ps': ps ?? 50,
're_version': 0,
'jsonp': 'jsonp',
'csrf': await Request.getCsrf(),
});
if (res.data['code'] == 0) {
return {
'status': true,
'data': BlackListDataModel.fromJson(res.data['data'])
};
} else {
return {
'status': false,
'data': [],
'msg': res.data['message'],
};
}
}
}

View File

@ -66,8 +66,13 @@ class VideoHttp {
);
if (res.data['code'] == 0) {
List<RecVideoItemAppModel> list = [];
List<int> blackMidsList =
setting.get(SettingBoxKey.blackMidsList, defaultValue: [-1]);
for (var i in res.data['data']['items']) {
if (i['card_goto'] != 'ad_av') {
// 屏蔽推广和拉黑用户
if (i['card_goto'] != 'ad_av' &&
(i['args'] != null &&
!blackMidsList.contains(i['args']['up_mid']))) {
list.add(RecVideoItemAppModel.fromJson(i));
}
}
@ -89,8 +94,12 @@ class VideoHttp {
);
if (res.data['code'] == 0) {
List<HotVideoItemModel> list = [];
List<int> blackMidsList =
setting.get(SettingBoxKey.blackMidsList, defaultValue: [-1]);
for (var i in res.data['data']['list']) {
list.add(HotVideoItemModel.fromJson(i));
if (!blackMidsList.contains(i['owner']['mid'])) {
list.add(HotVideoItemModel.fromJson(i));
}
}
return {'status': true, 'data': list};
} else {

View File

@ -0,0 +1,37 @@
class BlackListDataModel {
BlackListDataModel({
this.list,
this.total,
});
List<BlackListItem>? list;
int? total;
BlackListDataModel.fromJson(Map<String, dynamic> json) {
list = json['list']
.map<BlackListItem>((e) => BlackListItem.fromJson(e))
.toList();
total = json['total'];
}
}
class BlackListItem {
BlackListItem({
this.face,
this.mid,
this.mtime,
this.uname,
});
String? face;
int? mid;
int? mtime;
String? uname;
BlackListItem.fromJson(Map<String, dynamic> json) {
face = json['face'];
mid = json['mid'];
mtime = json['mtime'];
uname = json['uname'];
}
}

View File

@ -0,0 +1,156 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/common/widgets/http_error.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/http/black.dart';
import 'package:pilipala/models/user/black.dart';
import 'package:pilipala/utils/storage.dart';
import 'package:pilipala/utils/utils.dart';
class BlackListPage extends StatefulWidget {
const BlackListPage({super.key});
@override
State<BlackListPage> createState() => _BlackListPageState();
}
class _BlackListPageState extends State<BlackListPage> {
final BlackListController _blackListController =
Get.put(BlackListController());
final ScrollController scrollController = ScrollController();
Future? _futureBuilderFuture;
bool _isLoadingMore = false;
Box setting = GStrorage.setting;
@override
void initState() {
super.initState();
_futureBuilderFuture = _blackListController.queryBlacklist();
scrollController.addListener(
() async {
if (scrollController.position.pixels >=
scrollController.position.maxScrollExtent - 200) {
if (!_isLoadingMore) {
_isLoadingMore = true;
await _blackListController.queryBlacklist(type: 'onLoad');
_isLoadingMore = false;
}
}
},
);
}
@override
void dispose() {
List<int> blackMidsList =
_blackListController.blackList.map<int>((e) => e.mid!).toList();
setting.put(SettingBoxKey.blackMidsList, blackMidsList);
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
scrolledUnderElevation: 0,
titleSpacing: 0,
centerTitle: false,
title: Obx(
() => Text(
'黑名单管理 ${_blackListController.blackList.length} / 5000',
style: Theme.of(context).textTheme.titleMedium,
),
),
),
body: RefreshIndicator(
onRefresh: () async => await _blackListController.queryBlacklist(),
child: FutureBuilder(
future: _futureBuilderFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
var data = snapshot.data;
if (data['status']) {
List<BlackListItem> list = _blackListController.blackList;
return Obx(
() => list.length == 1
? const SizedBox()
: ListView.builder(
controller: scrollController,
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
onTap: () {},
leading: NetworkImgLayer(
width: 45,
height: 45,
type: 'avatar',
src: list[index].face,
),
title: Text(
list[index].uname!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 14),
),
subtitle: Text(
Utils.dateFormat(list[index].mtime),
maxLines: 1,
style: TextStyle(
color:
Theme.of(context).colorScheme.outline),
overflow: TextOverflow.ellipsis,
),
dense: true,
// trailing: TextButton(
// onPressed: () {},
// child: const Text('移除'),
// ),
);
},
),
);
} else {
return CustomScrollView(
slivers: [
HttpError(
errMsg: data['msg'],
fn: () => _blackListController.queryBlacklist(),
)
],
);
}
} else {
// 骨架屏
return const SizedBox();
}
},
),
),
);
}
}
class BlackListController extends GetxController {
int currentPage = 1;
int pageSize = 50;
RxList<BlackListItem> blackList = [BlackListItem()].obs;
Future queryBlacklist({type = 'init'}) async {
if (type == 'init') {
currentPage = 1;
}
var result = await BlackHttp.blackList(pn: currentPage, ps: pageSize);
if (result['status']) {
if (type == 'init') {
blackList.value = result['data'].list;
} else {
blackList.addAll(result['data'].list);
}
currentPage += 1;
}
return result;
}
}

View File

@ -0,0 +1,58 @@
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/utils/storage.dart';
class PrivacySetting extends StatefulWidget {
const PrivacySetting({super.key});
@override
State<PrivacySetting> createState() => _PrivacySettingState();
}
class _PrivacySettingState extends State<PrivacySetting> {
bool userLogin = false;
Box user = GStrorage.user;
@override
void initState() {
super.initState();
userLogin = user.get(UserBoxKey.userLogin) ?? false;
}
@override
Widget build(BuildContext context) {
TextStyle titleStyle = Theme.of(context).textTheme.titleMedium!;
TextStyle subTitleStyle = Theme.of(context)
.textTheme
.labelMedium!
.copyWith(color: Theme.of(context).colorScheme.outline);
return Scaffold(
appBar: AppBar(
centerTitle: false,
titleSpacing: 0,
title: Text(
'隐私设置',
style: Theme.of(context).textTheme.titleMedium,
),
),
body: Column(
children: [
ListTile(
onTap: () {
if (!userLogin) {
SmartDialog.showToast('登录后查看');
return;
}
Get.toNamed('/blackListPage');
},
dense: false,
title: Text('黑名单管理', style: titleStyle),
subtitle: Text('已拉黑用户', style: subTitleStyle),
),
],
),
);
}
}

View File

@ -19,6 +19,11 @@ class SettingPage extends StatelessWidget {
),
body: Column(
children: [
ListTile(
onTap: () => Get.toNamed('/privacySetting'),
dense: false,
title: const Text('隐私设置'),
),
ListTile(
onTap: () => Get.toNamed('/playSetting'),
dense: false,

View File

@ -1,4 +1,5 @@
import 'package:get/get.dart';
import 'package:pilipala/pages/blacklist/index.dart';
import 'package:pilipala/pages/dynamics/deatil/index.dart';
import 'package:pilipala/pages/dynamics/index.dart';
import 'package:pilipala/pages/fan/index.dart';
@ -15,6 +16,7 @@ import 'package:pilipala/pages/preview/index.dart';
import 'package:pilipala/pages/search/index.dart';
import 'package:pilipala/pages/searchResult/index.dart';
import 'package:pilipala/pages/setting/play_setting.dart';
import 'package:pilipala/pages/setting/privacy_setting.dart';
import 'package:pilipala/pages/setting/style_setting.dart';
import 'package:pilipala/pages/video/detail/index.dart';
import 'package:pilipala/pages/video/detail/replyReply/index.dart';
@ -73,7 +75,12 @@ class Routes {
// 播放设置
GetPage(name: '/playSetting', page: () => const PlaySetting()),
// 外观设置
GetPage(name: '/styleSetting', page: () => const StyleSetting()),
// 隐私设置
GetPage(name: '/privacySetting', page: () => const PrivacySetting()),
//
GetPage(name: '/blackListPage', page: () => const BlackListPage()),
];
}

View File

@ -117,6 +117,8 @@ class SettingBoxKey {
static const String danmakuEnable = 'danmakuEnable';
static const String fullScreenMode = 'fullScreenMode';
static const String blackMidsList = 'blackMidsList';
}
class LocalCacheKey {