Files
pilipala/lib/pages/setting/recommend_setting.dart

261 lines
10 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:hive/hive.dart';
import 'package:pilipala/http/member.dart';
import 'package:pilipala/models/common/rcmd_type.dart';
import 'package:pilipala/pages/setting/widgets/select_dialog.dart';
import 'package:pilipala/utils/recommend_filter.dart';
import 'package:pilipala/utils/storage.dart';
import 'widgets/switch_item.dart';
class RecommendSetting extends StatefulWidget {
const RecommendSetting({super.key});
@override
State<RecommendSetting> createState() => _RecommendSettingState();
}
class _RecommendSettingState extends State<RecommendSetting> {
Box setting = GStrorage.setting;
static Box localCache = GStrorage.localCache;
late dynamic defaultRcmdType;
Box userInfoCache = GStrorage.userInfo;
late dynamic userInfo;
bool userLogin = false;
late dynamic accessKeyInfo;
// late int filterUnfollowedRatio;
late int minDurationForRcmd;
late int minLikeRatioForRecommend;
@override
void initState() {
super.initState();
// 首页默认推荐类型
defaultRcmdType =
setting.get(SettingBoxKey.defaultRcmdType, defaultValue: 'web');
userInfo = userInfoCache.get('userInfoCache');
userLogin = userInfo != null;
accessKeyInfo = localCache.get(LocalCacheKey.accessKey, defaultValue: null);
// filterUnfollowedRatio = setting
// .get(SettingBoxKey.filterUnfollowedRatio, defaultValue: 0);
minDurationForRcmd =
setting.get(SettingBoxKey.minDurationForRcmd, defaultValue: 0);
minLikeRatioForRecommend =
setting.get(SettingBoxKey.minLikeRatioForRecommend, defaultValue: 0);
}
@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: ListView(
children: [
ListTile(
dense: false,
title: Text('首页推荐类型', style: titleStyle),
subtitle: Text(
'当前使用「$defaultRcmdType端」推荐¹',
style: subTitleStyle,
),
onTap: () async {
String? result = await showDialog(
context: context,
builder: (context) {
return SelectDialog<String>(
title: '推荐类型',
value: defaultRcmdType,
values: RcmdType.values.map((e) {
return {'title': e.labels, 'value': e.values};
}).toList(),
);
},
);
if (result != null) {
if (result == 'app') {
// app端推荐需要access_key
if (accessKeyInfo == null) {
if (!userLogin) {
SmartDialog.showToast('请先登录');
return;
}
// 显示一个确认框,告知用户可能会导致账号被风控
SmartDialog.show(
animationType: SmartAnimationType.centerFade_otherSlide,
builder: (context) {
return AlertDialog(
title: const Text('提示'),
content: const Text(
'使用app端推荐需获取access_key有小概率触发风控导致账号退出在官方版本app重新登录即可解除是否继续'),
actions: [
TextButton(
onPressed: () {
result = null;
SmartDialog.dismiss();
},
child: const Text('取消'),
),
TextButton(
onPressed: () async {
SmartDialog.dismiss();
await MemberHttp.cookieToKey();
},
child: const Text('确定'),
),
],
);
});
}
}
if (result != null) {
defaultRcmdType = result;
setting.put(SettingBoxKey.defaultRcmdType, result);
SmartDialog.showToast('下次启动时生效');
setState(() {});
}
}
},
),
const SetSwitchItem(
title: '推荐动态',
subTitle: '是否在推荐内容中展示动态(仅app端)',
setKey: SettingBoxKey.enableRcmdDynamic,
defaultVal: true,
),
const SetSwitchItem(
title: '首页推荐刷新',
subTitle: '下拉刷新时保留上次内容',
setKey: SettingBoxKey.enableSaveLastData,
defaultVal: false,
),
// 分割线
const Divider(height: 1),
ListTile(
dense: false,
title: Text('点赞率过滤', style: titleStyle),
subtitle: Text(
'过滤掉点赞数/播放量「小于$minLikeRatioForRecommend%」的推荐视频(仅web端)',
style: subTitleStyle,
),
onTap: () async {
int? result = await showDialog(
context: context,
builder: (context) {
return SelectDialog<int>(
title: '选择点赞率0即不过滤',
value: minLikeRatioForRecommend,
values: [0, 1, 2, 3, 4].map((e) {
return {'title': '$e %', 'value': e};
}).toList());
},
);
if (result != null) {
minLikeRatioForRecommend = result;
setting.put(SettingBoxKey.minLikeRatioForRecommend, result);
RecommendFilter.update();
setState(() {});
}
},
),
ListTile(
dense: false,
title: Text('视频时长过滤', style: titleStyle),
subtitle: Text(
'过滤掉时长「小于$minDurationForRcmd秒」的推荐视频',
style: subTitleStyle,
),
onTap: () async {
int? result = await showDialog(
context: context,
builder: (context) {
return SelectDialog<int>(
title: '选择时长0即不过滤',
value: minDurationForRcmd,
values: [0, 30, 60, 90, 120].map((e) {
return {'title': '$e', 'value': e};
}).toList());
},
);
if (result != null) {
minDurationForRcmd = result;
setting.put(SettingBoxKey.minDurationForRcmd, result);
RecommendFilter.update();
setState(() {});
}
},
),
SetSwitchItem(
title: '已关注Up豁免推荐过滤',
subTitle: '推荐中已关注用户发布的内容不会被过滤',
setKey: SettingBoxKey.exemptFilterForFollowed,
defaultVal: true,
callFn: (_) => {RecommendFilter.update},
),
// ListTile(
// dense: false,
// title: Text('按比例过滤未关注Up', style: titleStyle),
// subtitle: Text(
// '滤除推荐中占比「$filterUnfollowedRatio%」的未关注用户发布的内容',
// style: subTitleStyle,
// ),
// onTap: () async {
// int? result = await showDialog(
// context: context,
// builder: (context) {
// return SelectDialog<int>(
// title: '选择滤除比例0即不过滤',
// value: filterUnfollowedRatio,
// values: [0, 16, 32, 48, 64].map((e) {
// return {'title': '$e %', 'value': e};
// }).toList());
// },
// );
// if (result != null) {
// filterUnfollowedRatio = result;
// setting.put(
// SettingBoxKey.filterUnfollowedRatio, result);
// RecommendFilter.update();
// setState(() {});
// }
// },
// ),
SetSwitchItem(
title: '过滤器也应用于相关视频',
subTitle: '视频详情页的相关视频也进行过滤²',
setKey: SettingBoxKey.applyFilterToRelatedVideos,
defaultVal: true,
callFn: (_) => {RecommendFilter.update},
),
ListTile(
dense: true,
subtitle: Text(
'¹ 若默认web端推荐不太符合预期可尝试切换至app端。\n'
'¹ 选择“模拟未登录(notLogin)”将以空的key请求推荐接口但播放页仍会携带用户信息保证账号能正常记录进度、点赞投币等。\n\n'
'² 由于接口未提供关注信息无法豁免相关视频中的已关注Up。\n\n'
'* 其它(如热门视频、手动搜索、链接跳转等)均不受过滤器影响。\n'
'* 设定较严苛的条件可导致推荐项数锐减或多次请求,请酌情选择。\n'
'* 后续可能会增加更多过滤条件,敬请期待。',
style: Theme.of(context)
.textTheme
.labelSmall!
.copyWith(color: Theme.of(context).colorScheme.outline.withOpacity(0.7)),
),
)
],
),
);
}
}