mod: 默认使用web端推荐
This commit is contained in:
@ -1,8 +1,10 @@
|
|||||||
|
import 'constants.dart';
|
||||||
|
|
||||||
class Api {
|
class Api {
|
||||||
// 推荐视频
|
// 推荐视频
|
||||||
static const String recommendListApp =
|
static const String recommendListApp =
|
||||||
'https://app.bilibili.com/x/v2/feed/index';
|
'${HttpString.appBaseUrl}/x/v2/feed/index';
|
||||||
static const String recommendList = '/x/web-interface/index/top/feed/rcmd';
|
static const String recommendListWeb = '/x/web-interface/index/top/feed/rcmd';
|
||||||
|
|
||||||
// 热门视频
|
// 热门视频
|
||||||
static const String hotList = '/x/web-interface/popular';
|
static const String hotList = '/x/web-interface/popular';
|
||||||
@ -152,7 +154,7 @@ class Api {
|
|||||||
|
|
||||||
// 动态点赞
|
// 动态点赞
|
||||||
static const String likeDynamic =
|
static const String likeDynamic =
|
||||||
'https://api.vc.bilibili.com/dynamic_like/v1/dynamic_like/thumb';
|
'${HttpString.tUrl}/dynamic_like/v1/dynamic_like/thumb';
|
||||||
|
|
||||||
// 获取稍后再看
|
// 获取稍后再看
|
||||||
static const String seeYouLater = '/x/v2/history/toview';
|
static const String seeYouLater = '/x/v2/history/toview';
|
||||||
@ -220,13 +222,13 @@ class Api {
|
|||||||
// 直播
|
// 直播
|
||||||
// ?page=1&page_size=30&platform=web
|
// ?page=1&page_size=30&platform=web
|
||||||
static const String liveList =
|
static const String liveList =
|
||||||
'https://api.live.bilibili.com/xlive/web-interface/v1/second/getUserRecommend';
|
'${HttpString.liveBaseUrl}/xlive/web-interface/v1/second/getUserRecommend';
|
||||||
|
|
||||||
// 直播间详情
|
// 直播间详情
|
||||||
// cid roomId
|
// cid roomId
|
||||||
// qn 80:流畅,150:高清,400:蓝光,10000:原画,20000:4K, 30000:杜比
|
// qn 80:流畅,150:高清,400:蓝光,10000:原画,20000:4K, 30000:杜比
|
||||||
static const String liveRoomInfo =
|
static const String liveRoomInfo =
|
||||||
'https://api.live.bilibili.com/xlive/web-room/v2/index/getRoomPlayInfo';
|
'${HttpString.liveBaseUrl}/xlive/web-room/v2/index/getRoomPlayInfo';
|
||||||
|
|
||||||
// 用户信息 需要Wbi签名
|
// 用户信息 需要Wbi签名
|
||||||
// https://api.bilibili.com/x/space/wbi/acc/info?mid=503427686&token=&platform=web&web_location=1550101&w_rid=d709892496ce93e3d94d6d37c95bde91&wts=1689301482
|
// https://api.bilibili.com/x/space/wbi/acc/info?mid=503427686&token=&platform=web&web_location=1550101&w_rid=d709892496ce93e3d94d6d37c95bde91&wts=1689301482
|
||||||
@ -338,13 +340,13 @@ class Api {
|
|||||||
/// wts=1697305010
|
/// wts=1697305010
|
||||||
|
|
||||||
static const String sessionList =
|
static const String sessionList =
|
||||||
'https://api.vc.bilibili.com/session_svr/v1/session_svr/get_sessions';
|
'${HttpString.tUrl}/session_svr/v1/session_svr/get_sessions';
|
||||||
|
|
||||||
/// 私聊用户信息
|
/// 私聊用户信息
|
||||||
/// uids
|
/// uids
|
||||||
/// build=0&mobi_app=web
|
/// build=0&mobi_app=web
|
||||||
static const String sessionAccountList =
|
static const String sessionAccountList =
|
||||||
'https://api.vc.bilibili.com/account/v1/user/cards';
|
'${HttpString.tUrl}/account/v1/user/cards';
|
||||||
|
|
||||||
/// https://api.vc.bilibili.com/svr_sync/v1/svr_sync/fetch_session_msgs?
|
/// https://api.vc.bilibili.com/svr_sync/v1/svr_sync/fetch_session_msgs?
|
||||||
/// talker_id=400787461&
|
/// talker_id=400787461&
|
||||||
@ -358,7 +360,7 @@ class Api {
|
|||||||
/// wts=1697350697
|
/// wts=1697350697
|
||||||
|
|
||||||
static const String sessionMsg =
|
static const String sessionMsg =
|
||||||
'https://api.vc.bilibili.com/svr_sync/v1/svr_sync/fetch_session_msgs';
|
'${HttpString.tUrl}/svr_sync/v1/svr_sync/fetch_session_msgs';
|
||||||
|
|
||||||
/// 标记已读 POST
|
/// 标记已读 POST
|
||||||
/// talker_id:
|
/// talker_id:
|
||||||
@ -369,7 +371,7 @@ class Api {
|
|||||||
/// csrf_token:
|
/// csrf_token:
|
||||||
/// csrf:
|
/// csrf:
|
||||||
static const String updateAck =
|
static const String updateAck =
|
||||||
'https://api.vc.bilibili.com/session_svr/v1/session_svr/update_ack';
|
'${HttpString.tUrl}/session_svr/v1/session_svr/update_ack';
|
||||||
|
|
||||||
// 获取某个动态详情
|
// 获取某个动态详情
|
||||||
// timezone_offset=-480
|
// timezone_offset=-480
|
||||||
@ -388,11 +390,11 @@ class Api {
|
|||||||
|
|
||||||
// captcha验证码
|
// captcha验证码
|
||||||
static const String getCaptcha =
|
static const String getCaptcha =
|
||||||
'https://passport.bilibili.com/x/passport-login/captcha?source=main_web';
|
'${HttpString.passBaseUrl}/x/passport-login/captcha?source=main_web';
|
||||||
|
|
||||||
// web端短信验证码
|
// web端短信验证码
|
||||||
static const String smsCode =
|
static const String smsCode =
|
||||||
'https://passport.bilibili.com/x/passport-login/web/sms/send';
|
'${HttpString.passBaseUrl}/x/passport-login/web/sms/send';
|
||||||
|
|
||||||
// web端验证码登录
|
// web端验证码登录
|
||||||
|
|
||||||
@ -400,7 +402,7 @@ class Api {
|
|||||||
|
|
||||||
// app端短信验证码
|
// app端短信验证码
|
||||||
static const String appSmsCode =
|
static const String appSmsCode =
|
||||||
'https://passport.bilibili.com/x/passport-login/sms/send';
|
'${HttpString.passBaseUrl}/x/passport-login/sms/send';
|
||||||
|
|
||||||
// app端验证码登录
|
// app端验证码登录
|
||||||
|
|
||||||
@ -414,17 +416,16 @@ class Api {
|
|||||||
/// key
|
/// key
|
||||||
/// rhash
|
/// rhash
|
||||||
static const String loginInByPwdApi =
|
static const String loginInByPwdApi =
|
||||||
'https://passport.bilibili.com/x/passport-login/oauth2/login';
|
'${HttpString.passBaseUrl}/x/passport-login/oauth2/login';
|
||||||
|
|
||||||
/// 密码加密密钥
|
/// 密码加密密钥
|
||||||
/// disable_rcmd
|
/// disable_rcmd
|
||||||
/// local_id
|
/// local_id
|
||||||
static const getWebKey =
|
static const getWebKey = '${HttpString.passBaseUrl}/x/passport-login/web/key';
|
||||||
'https://passport.bilibili.com/x/passport-login/web/key';
|
|
||||||
|
|
||||||
/// cookie转access_key
|
/// cookie转access_key
|
||||||
static const cookieToKey =
|
static const cookieToKey =
|
||||||
'https://passport.bilibili.com/x/passport-tv-login/h5/qrcode/confirm';
|
'${HttpString.passBaseUrl}/x/passport-tv-login/h5/qrcode/confirm';
|
||||||
|
|
||||||
/// 申请二维码(TV端)
|
/// 申请二维码(TV端)
|
||||||
static const getTVCode =
|
static const getTVCode =
|
||||||
@ -432,7 +433,7 @@ class Api {
|
|||||||
|
|
||||||
///扫码登录(TV端)
|
///扫码登录(TV端)
|
||||||
static const qrcodePoll =
|
static const qrcodePoll =
|
||||||
'https://passport.bilibili.com/x/passport-tv-login/qrcode/poll';
|
'${HttpString.passBaseUrl}/x/passport-tv-login/qrcode/poll';
|
||||||
|
|
||||||
/// 置顶视频
|
/// 置顶视频
|
||||||
static const getTopVideoApi = '/x/space/top/arc';
|
static const getTopVideoApi = '/x/space/top/arc';
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
class HttpString {
|
class HttpString {
|
||||||
static const String baseUrl = 'https://www.bilibili.com';
|
static const String baseUrl = 'https://www.bilibili.com';
|
||||||
static const String baseApiUrl = 'https://api.bilibili.com';
|
static const String apiBaseUrl = 'https://api.bilibili.com';
|
||||||
static const String tUrl = 'https://api.vc.bilibili.com';
|
static const String tUrl = 'https://api.vc.bilibili.com';
|
||||||
|
static const String appBaseUrl = 'https://app.bilibili.com';
|
||||||
|
static const String liveBaseUrl = 'https://api.live.bilibili.com';
|
||||||
|
static const String passBaseUrl = 'https://passport.bilibili.com';
|
||||||
static const List<int> validateStatusCodes = [
|
static const List<int> validateStatusCodes = [
|
||||||
302,
|
302,
|
||||||
304,
|
304,
|
||||||
|
|||||||
@ -65,7 +65,7 @@ class Request {
|
|||||||
// 从cookie中获取 csrf token
|
// 从cookie中获取 csrf token
|
||||||
static Future<String> getCsrf() async {
|
static Future<String> getCsrf() async {
|
||||||
var cookies = await cookieManager.cookieJar
|
var cookies = await cookieManager.cookieJar
|
||||||
.loadForRequest(Uri.parse(HttpString.baseApiUrl));
|
.loadForRequest(Uri.parse(HttpString.apiBaseUrl));
|
||||||
String token = '';
|
String token = '';
|
||||||
if (cookies.where((e) => e.name == 'bili_jct').isNotEmpty) {
|
if (cookies.where((e) => e.name == 'bili_jct').isNotEmpty) {
|
||||||
token = cookies.firstWhere((e) => e.name == 'bili_jct').value;
|
token = cookies.firstWhere((e) => e.name == 'bili_jct').value;
|
||||||
@ -91,7 +91,7 @@ class Request {
|
|||||||
//BaseOptions、Options、RequestOptions 都可以配置参数,优先级别依次递增,且可以根据优先级别覆盖参数
|
//BaseOptions、Options、RequestOptions 都可以配置参数,优先级别依次递增,且可以根据优先级别覆盖参数
|
||||||
BaseOptions options = BaseOptions(
|
BaseOptions options = BaseOptions(
|
||||||
//请求基地址,可以包含子路径
|
//请求基地址,可以包含子路径
|
||||||
baseUrl: HttpString.baseApiUrl,
|
baseUrl: HttpString.apiBaseUrl,
|
||||||
//连接服务器超时时间,单位是毫秒.
|
//连接服务器超时时间,单位是毫秒.
|
||||||
connectTimeout: const Duration(milliseconds: 12000),
|
connectTimeout: const Duration(milliseconds: 12000),
|
||||||
//响应流上前后两次接受到数据的间隔,单位为毫秒。
|
//响应流上前后两次接受到数据的间隔,单位为毫秒。
|
||||||
|
|||||||
@ -30,7 +30,7 @@ class VideoHttp {
|
|||||||
static Future rcmdVideoList({required int ps, required int freshIdx}) async {
|
static Future rcmdVideoList({required int ps, required int freshIdx}) async {
|
||||||
try {
|
try {
|
||||||
var res = await Request().get(
|
var res = await Request().get(
|
||||||
Api.recommendList,
|
Api.recommendListWeb,
|
||||||
data: {
|
data: {
|
||||||
'version': 1,
|
'version': 1,
|
||||||
'feed_version': 'V3',
|
'feed_version': 'V3',
|
||||||
|
|||||||
7
lib/models/common/rcmd_type.dart
Normal file
7
lib/models/common/rcmd_type.dart
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// 首页推荐类型
|
||||||
|
enum RcmdType { web, app }
|
||||||
|
|
||||||
|
extension RcmdTypeExtension on RcmdType {
|
||||||
|
String get values => ['web', 'app'][index];
|
||||||
|
String get labels => ['web端', 'app端'][index];
|
||||||
|
}
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:pilipala/utils/utils.dart';
|
||||||
|
|
||||||
import './model_owner.dart';
|
import './model_owner.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
|
||||||
@ -56,7 +58,7 @@ class RecVideoItemModel {
|
|||||||
uri = json["uri"];
|
uri = json["uri"];
|
||||||
pic = json["pic"];
|
pic = json["pic"];
|
||||||
title = json["title"];
|
title = json["title"];
|
||||||
duration = json["duration"].toString();
|
duration = Utils.tampToSeektime(json["duration"]);
|
||||||
pubdate = json["pubdate"];
|
pubdate = json["pubdate"];
|
||||||
owner = Owner.fromJson(json["owner"]);
|
owner = Owner.fromJson(json["owner"]);
|
||||||
stat = Stat.fromJson(json["stat"]);
|
stat = Stat.fromJson(json["stat"]);
|
||||||
|
|||||||
@ -3,20 +3,21 @@ import 'package:get/get.dart';
|
|||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/http/video.dart';
|
import 'package:pilipala/http/video.dart';
|
||||||
import 'package:pilipala/models/home/rcmd/result.dart';
|
import 'package:pilipala/models/home/rcmd/result.dart';
|
||||||
// import 'package:pilipala/models/model_rec_video_item.dart';
|
import 'package:pilipala/models/model_rec_video_item.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
|
|
||||||
class RcmdController extends GetxController {
|
class RcmdController extends GetxController {
|
||||||
final ScrollController scrollController = ScrollController();
|
final ScrollController scrollController = ScrollController();
|
||||||
int _currentPage = 0;
|
int _currentPage = 0;
|
||||||
RxList<RecVideoItemAppModel> videoList = <RecVideoItemAppModel>[].obs;
|
RxList<RecVideoItemAppModel> appVideoList = <RecVideoItemAppModel>[].obs;
|
||||||
// RxList<RecVideoItemModel> videoList = <RecVideoItemModel>[].obs;
|
RxList<RecVideoItemModel> webVideoList = <RecVideoItemModel>[].obs;
|
||||||
bool isLoadingMore = true;
|
bool isLoadingMore = true;
|
||||||
OverlayEntry? popupDialog;
|
OverlayEntry? popupDialog;
|
||||||
Box recVideo = GStrorage.recVideo;
|
Box recVideo = GStrorage.recVideo;
|
||||||
Box setting = GStrorage.setting;
|
Box setting = GStrorage.setting;
|
||||||
RxInt crossAxisCount = 2.obs;
|
RxInt crossAxisCount = 2.obs;
|
||||||
late bool enableSaveLastData;
|
late bool enableSaveLastData;
|
||||||
|
late String defaultRcmdType = 'web';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
@ -24,22 +25,30 @@ class RcmdController extends GetxController {
|
|||||||
crossAxisCount.value =
|
crossAxisCount.value =
|
||||||
setting.get(SettingBoxKey.customRows, defaultValue: 2);
|
setting.get(SettingBoxKey.customRows, defaultValue: 2);
|
||||||
// 读取app端缓存内容
|
// 读取app端缓存内容
|
||||||
if (recVideo.get('cacheList') != null &&
|
// if (recVideo.get('cacheList') != null &&
|
||||||
recVideo.get('cacheList').isNotEmpty) {
|
// recVideo.get('cacheList').isNotEmpty) {
|
||||||
List<RecVideoItemAppModel> list = [];
|
// List<RecVideoItemAppModel> list = [];
|
||||||
for (var i in recVideo.get('cacheList')) {
|
// for (var i in recVideo.get('cacheList')) {
|
||||||
list.add(i);
|
// list.add(i);
|
||||||
}
|
// }
|
||||||
videoList.value = list;
|
// videoList.value = list;
|
||||||
}
|
// }
|
||||||
enableSaveLastData =
|
enableSaveLastData =
|
||||||
setting.get(SettingBoxKey.enableSaveLastData, defaultValue: false);
|
setting.get(SettingBoxKey.enableSaveLastData, defaultValue: false);
|
||||||
|
defaultRcmdType =
|
||||||
|
setting.get(SettingBoxKey.defaultRcmdType, defaultValue: 'web');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取推荐
|
// 获取推荐
|
||||||
Future queryRcmdFeed(type) async {
|
Future queryRcmdFeed(type) async {
|
||||||
|
print(defaultRcmdType);
|
||||||
|
if (defaultRcmdType == 'app') {
|
||||||
return await queryRcmdFeedApp(type);
|
return await queryRcmdFeedApp(type);
|
||||||
}
|
}
|
||||||
|
if (defaultRcmdType == 'web') {
|
||||||
|
return await queryRcmdFeedWeb(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 获取app端推荐
|
// 获取app端推荐
|
||||||
Future queryRcmdFeedApp(type) async {
|
Future queryRcmdFeedApp(type) async {
|
||||||
@ -54,19 +63,19 @@ class RcmdController extends GetxController {
|
|||||||
);
|
);
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
if (type == 'init') {
|
if (type == 'init') {
|
||||||
if (videoList.isNotEmpty) {
|
if (appVideoList.isNotEmpty) {
|
||||||
videoList.addAll(res['data']);
|
appVideoList.addAll(res['data']);
|
||||||
} else {
|
} else {
|
||||||
videoList.value = res['data'];
|
appVideoList.value = res['data'];
|
||||||
}
|
}
|
||||||
} else if (type == 'onRefresh') {
|
} else if (type == 'onRefresh') {
|
||||||
if (enableSaveLastData) {
|
if (enableSaveLastData) {
|
||||||
videoList.insertAll(0, res['data']);
|
appVideoList.insertAll(0, res['data']);
|
||||||
} else {
|
} else {
|
||||||
videoList.value = res['data'];
|
appVideoList.value = res['data'];
|
||||||
}
|
}
|
||||||
} else if (type == 'onLoad') {
|
} else if (type == 'onLoad') {
|
||||||
videoList.addAll(res['data']);
|
appVideoList.addAll(res['data']);
|
||||||
}
|
}
|
||||||
recVideo.put('cacheList', res['data']);
|
recVideo.put('cacheList', res['data']);
|
||||||
_currentPage += 1;
|
_currentPage += 1;
|
||||||
@ -89,19 +98,19 @@ class RcmdController extends GetxController {
|
|||||||
);
|
);
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
if (type == 'init') {
|
if (type == 'init') {
|
||||||
if (videoList.isNotEmpty) {
|
if (webVideoList.isNotEmpty) {
|
||||||
videoList.addAll(res['data']);
|
webVideoList.addAll(res['data']);
|
||||||
} else {
|
} else {
|
||||||
videoList.value = res['data'];
|
webVideoList.value = res['data'];
|
||||||
}
|
}
|
||||||
} else if (type == 'onRefresh') {
|
} else if (type == 'onRefresh') {
|
||||||
if (enableSaveLastData) {
|
if (enableSaveLastData) {
|
||||||
videoList.insertAll(0, res['data']);
|
webVideoList.insertAll(0, res['data']);
|
||||||
} else {
|
} else {
|
||||||
videoList.value = res['data'];
|
webVideoList.value = res['data'];
|
||||||
}
|
}
|
||||||
} else if (type == 'onLoad') {
|
} else if (type == 'onLoad') {
|
||||||
videoList.addAll(res['data']);
|
webVideoList.addAll(res['data']);
|
||||||
}
|
}
|
||||||
_currentPage += 1;
|
_currentPage += 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -98,12 +98,22 @@ class _RcmdPageState extends State<RcmdPage>
|
|||||||
Map data = snapshot.data as Map;
|
Map data = snapshot.data as Map;
|
||||||
if (data['status']) {
|
if (data['status']) {
|
||||||
return Platform.isAndroid || Platform.isIOS
|
return Platform.isAndroid || Platform.isIOS
|
||||||
? Obx(() => contentGrid(
|
? Obx(
|
||||||
_rcmdController, _rcmdController.videoList))
|
() => contentGrid(
|
||||||
|
_rcmdController,
|
||||||
|
_rcmdController.defaultRcmdType == 'web'
|
||||||
|
? _rcmdController.webVideoList
|
||||||
|
: _rcmdController.appVideoList),
|
||||||
|
)
|
||||||
: SliverLayoutBuilder(
|
: SliverLayoutBuilder(
|
||||||
builder: (context, boxConstraints) {
|
builder: (context, boxConstraints) {
|
||||||
return Obx(() => contentGrid(
|
return Obx(
|
||||||
_rcmdController, _rcmdController.videoList));
|
() => contentGrid(
|
||||||
|
_rcmdController,
|
||||||
|
_rcmdController.defaultRcmdType == 'web'
|
||||||
|
? _rcmdController.webVideoList
|
||||||
|
: _rcmdController.appVideoList),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return HttpError(
|
return HttpError(
|
||||||
@ -118,14 +128,14 @@ class _RcmdPageState extends State<RcmdPage>
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 缓存数据
|
// 缓存数据
|
||||||
if (_rcmdController.videoList.isNotEmpty) {
|
// if (_rcmdController.videoList.isNotEmpty) {
|
||||||
return contentGrid(
|
// return contentGrid(
|
||||||
_rcmdController, _rcmdController.videoList);
|
// _rcmdController, _rcmdController.videoList);
|
||||||
}
|
// }
|
||||||
// 骨架屏
|
// // 骨架屏
|
||||||
else {
|
// else {
|
||||||
return contentGrid(_rcmdController, []);
|
return contentGrid(_rcmdController, []);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:pilipala/http/member.dart';
|
||||||
import 'package:pilipala/models/common/dynamics_type.dart';
|
import 'package:pilipala/models/common/dynamics_type.dart';
|
||||||
|
import 'package:pilipala/models/common/rcmd_type.dart';
|
||||||
import 'package:pilipala/models/common/reply_sort_type.dart';
|
import 'package:pilipala/models/common/reply_sort_type.dart';
|
||||||
import 'package:pilipala/pages/setting/widgets/select_dialog.dart';
|
import 'package:pilipala/pages/setting/widgets/select_dialog.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
@ -18,15 +20,23 @@ class ExtraSetting extends StatefulWidget {
|
|||||||
class _ExtraSettingState extends State<ExtraSetting> {
|
class _ExtraSettingState extends State<ExtraSetting> {
|
||||||
Box setting = GStrorage.setting;
|
Box setting = GStrorage.setting;
|
||||||
static Box localCache = GStrorage.localCache;
|
static Box localCache = GStrorage.localCache;
|
||||||
|
late dynamic defaultRcmdType;
|
||||||
late dynamic defaultReplySort;
|
late dynamic defaultReplySort;
|
||||||
late dynamic defaultDynamicType;
|
late dynamic defaultDynamicType;
|
||||||
late dynamic enableSystemProxy;
|
late dynamic enableSystemProxy;
|
||||||
late String defaultSystemProxyHost;
|
late String defaultSystemProxyHost;
|
||||||
late String defaultSystemProxyPort;
|
late String defaultSystemProxyPort;
|
||||||
|
Box userInfoCache = GStrorage.userInfo;
|
||||||
|
var userInfo;
|
||||||
|
bool userLogin = false;
|
||||||
|
var accessKeyInfo;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
// 首页默认推荐类型
|
||||||
|
defaultRcmdType =
|
||||||
|
setting.get(SettingBoxKey.defaultRcmdType, defaultValue: 'web');
|
||||||
// 默认优先显示最新评论
|
// 默认优先显示最新评论
|
||||||
defaultReplySort =
|
defaultReplySort =
|
||||||
setting.get(SettingBoxKey.replySortType, defaultValue: 0);
|
setting.get(SettingBoxKey.replySortType, defaultValue: 0);
|
||||||
@ -39,6 +49,9 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
localCache.get(LocalCacheKey.systemProxyHost, defaultValue: '');
|
localCache.get(LocalCacheKey.systemProxyHost, defaultValue: '');
|
||||||
defaultSystemProxyPort =
|
defaultSystemProxyPort =
|
||||||
localCache.get(LocalCacheKey.systemProxyPort, defaultValue: '');
|
localCache.get(LocalCacheKey.systemProxyPort, defaultValue: '');
|
||||||
|
userInfo = userInfoCache.get('userInfoCache');
|
||||||
|
userLogin = userInfo != null;
|
||||||
|
accessKeyInfo = localCache.get(LocalCacheKey.accessKey, defaultValue: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置代理
|
// 设置代理
|
||||||
@ -170,6 +183,44 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
setKey: SettingBoxKey.enableSaveLastData,
|
setKey: SettingBoxKey.enableSaveLastData,
|
||||||
defaultVal: false,
|
defaultVal: false,
|
||||||
),
|
),
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
await MemberHttp.cookieToKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defaultRcmdType = result;
|
||||||
|
setting.put(SettingBoxKey.defaultRcmdType, result);
|
||||||
|
SmartDialog.showToast('下次启动时生效');
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
const SetSwitchItem(
|
const SetSwitchItem(
|
||||||
title: '启用ai总结',
|
title: '启用ai总结',
|
||||||
subTitle: '视频详情页开启ai总结',
|
subTitle: '视频详情页开启ai总结',
|
||||||
@ -187,7 +238,10 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
int? result = await showDialog(
|
int? result = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return SelectDialog<int>(title: '评论展示', value: defaultReplySort, values: ReplySortType.values.map((e) {
|
return SelectDialog<int>(
|
||||||
|
title: '评论展示',
|
||||||
|
value: defaultReplySort,
|
||||||
|
values: ReplySortType.values.map((e) {
|
||||||
return {'title': e.titles, 'value': e.index};
|
return {'title': e.titles, 'value': e.index};
|
||||||
}).toList());
|
}).toList());
|
||||||
},
|
},
|
||||||
@ -210,7 +264,10 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
int? result = await showDialog(
|
int? result = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return SelectDialog<int>(title: '动态展示', value: defaultDynamicType, values: DynamicsType.values.map((e) {
|
return SelectDialog<int>(
|
||||||
|
title: '动态展示',
|
||||||
|
value: defaultDynamicType,
|
||||||
|
values: DynamicsType.values.map((e) {
|
||||||
return {'title': e.labels, 'value': e.index};
|
return {'title': e.labels, 'value': e.index};
|
||||||
}).toList());
|
}).toList());
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,18 +1,20 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:pilipala/models/common/theme_type.dart';
|
|
||||||
|
|
||||||
class SelectDialog<T> extends StatefulWidget {
|
class SelectDialog<T> extends StatefulWidget {
|
||||||
final T value;
|
final T value;
|
||||||
final String title;
|
final String title;
|
||||||
final List<dynamic> values;
|
final List<dynamic> values;
|
||||||
const SelectDialog({super.key, required this.value, required this.values, required this.title});
|
const SelectDialog(
|
||||||
|
{super.key,
|
||||||
|
required this.value,
|
||||||
|
required this.values,
|
||||||
|
required this.title});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_SelectDialogState<T> createState() => _SelectDialogState<T>();
|
_SelectDialogState<T> createState() => _SelectDialogState<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SelectDialogState<T> extends State<SelectDialog<T>> {
|
class _SelectDialogState<T> extends State<SelectDialog<T>> {
|
||||||
|
|
||||||
late T _tempValue;
|
late T _tempValue;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -28,8 +30,7 @@ class _SelectDialogState<T> extends State<SelectDialog<T>> {
|
|||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: Text(widget.title),
|
title: Text(widget.title),
|
||||||
contentPadding: const EdgeInsets.fromLTRB(0, 12, 0, 12),
|
contentPadding: const EdgeInsets.fromLTRB(0, 12, 0, 12),
|
||||||
content: StatefulBuilder(
|
content: StatefulBuilder(builder: (context, StateSetter setState) {
|
||||||
builder: (context, StateSetter setState) {
|
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@ -40,7 +41,6 @@ class _SelectDialogState<T> extends State<SelectDialog<T>> {
|
|||||||
title: Text(i['title'], style: titleStyle),
|
title: Text(i['title'], style: titleStyle),
|
||||||
groupValue: _tempValue,
|
groupValue: _tempValue,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
print(value);
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_tempValue = value as T;
|
_tempValue = value as T;
|
||||||
});
|
});
|
||||||
@ -56,12 +56,13 @@ class _SelectDialogState<T> extends State<SelectDialog<T>> {
|
|||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
child: Text(
|
child: Text(
|
||||||
'取消',
|
'取消',
|
||||||
style: TextStyle(
|
style: TextStyle(color: Theme.of(context).colorScheme.outline),
|
||||||
color: Theme.of(context).colorScheme.outline),
|
),
|
||||||
)),
|
),
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () => Navigator.pop(context, _tempValue),
|
onPressed: () => Navigator.pop(context, _tempValue),
|
||||||
child: const Text('确定'))
|
child: const Text('确定'),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,7 +115,6 @@ class WebviewController extends GetxController {
|
|||||||
MediaController mediaCtr = Get.find<MediaController>();
|
MediaController mediaCtr = Get.find<MediaController>();
|
||||||
mediaCtr.mid = result['data'].mid;
|
mediaCtr.mid = result['data'].mid;
|
||||||
await LoginUtils.refreshLoginStatus(true);
|
await LoginUtils.refreshLoginStatus(true);
|
||||||
MemberHttp.cookieToKey();
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
SmartDialog.show(builder: (context) {
|
SmartDialog.show(builder: (context) {
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
|
|||||||
@ -11,9 +11,9 @@ class SetCookie {
|
|||||||
cookies.map((cookie) => '${cookie.name}=${cookie.value}').join('; ');
|
cookies.map((cookie) => '${cookie.name}=${cookie.value}').join('; ');
|
||||||
Request.dio.options.headers['cookie'] = cookieString;
|
Request.dio.options.headers['cookie'] = cookieString;
|
||||||
|
|
||||||
cookies = await WebviewCookieManager().getCookies(HttpString.baseApiUrl);
|
cookies = await WebviewCookieManager().getCookies(HttpString.apiBaseUrl);
|
||||||
await Request.cookieManager.cookieJar
|
await Request.cookieManager.cookieJar
|
||||||
.saveFromResponse(Uri.parse(HttpString.baseApiUrl), cookies);
|
.saveFromResponse(Uri.parse(HttpString.apiBaseUrl), cookies);
|
||||||
|
|
||||||
cookies = await WebviewCookieManager().getCookies(HttpString.tUrl);
|
cookies = await WebviewCookieManager().getCookies(HttpString.tUrl);
|
||||||
await Request.cookieManager.cookieJar
|
await Request.cookieManager.cookieJar
|
||||||
|
|||||||
@ -88,98 +88,99 @@ class GStrorage {
|
|||||||
|
|
||||||
class SettingBoxKey {
|
class SettingBoxKey {
|
||||||
/// 播放器
|
/// 播放器
|
||||||
static const String btmProgressBehavior = 'btmProgressBehavior';
|
static const btmProgressBehavior = 'btmProgressBehavior',
|
||||||
static const String defaultVideoSpeed = 'defaultVideoSpeed';
|
defaultVideoSpeed = 'defaultVideoSpeed',
|
||||||
static const String autoUpgradeEnable = 'autoUpgradeEnable';
|
autoUpgradeEnable = 'autoUpgradeEnable',
|
||||||
static const String feedBackEnable = 'feedBackEnable';
|
feedBackEnable = 'feedBackEnable',
|
||||||
static const String defaultVideoQa = 'defaultVideoQa';
|
defaultVideoQa = 'defaultVideoQa',
|
||||||
static const String defaultAudioQa = 'defaultAudioQa';
|
defaultAudioQa = 'defaultAudioQa',
|
||||||
static const String autoPlayEnable = 'autoPlayEnable';
|
autoPlayEnable = 'autoPlayEnable',
|
||||||
static const String fullScreenMode = 'fullScreenMode';
|
fullScreenMode = 'fullScreenMode',
|
||||||
static const String defaultDecode = 'defaultDecode';
|
defaultDecode = 'defaultDecode',
|
||||||
static const String danmakuEnable = 'danmakuEnable';
|
danmakuEnable = 'danmakuEnable',
|
||||||
static const String defaultPicQa = 'defaultPicQa';
|
defaultPicQa = 'defaultPicQa',
|
||||||
static const String enableHA = 'enableHA';
|
enableHA = 'enableHA',
|
||||||
static const String enableOnlineTotal = 'enableOnlineTotal';
|
enableOnlineTotal = 'enableOnlineTotal',
|
||||||
static const String enableAutoBrightness = 'enableAutoBrightness';
|
enableAutoBrightness = 'enableAutoBrightness',
|
||||||
static const String enableAutoEnter = 'enableAutoEnter';
|
enableAutoEnter = 'enableAutoEnter',
|
||||||
static const String enableAutoExit = 'enableAutoExit';
|
enableAutoExit = 'enableAutoExit',
|
||||||
static const String p1080 = 'p1080';
|
p1080 = 'p1080',
|
||||||
static const String enableCDN = 'enableCDN';
|
enableCDN = 'enableCDN',
|
||||||
static const String autoPiP = 'autoPiP';
|
autoPiP = 'autoPiP',
|
||||||
static const String enableAutoLongPressSpeed = 'enableAutoLongPressSpeed';
|
enableAutoLongPressSpeed = 'enableAutoLongPressSpeed',
|
||||||
|
|
||||||
// youtube 双击快进快退
|
// youtube 双击快进快退
|
||||||
static const String enableQuickDouble = 'enableQuickDouble';
|
enableQuickDouble = 'enableQuickDouble',
|
||||||
static const String enableShowDanmaku = 'enableShowDanmaku';
|
enableShowDanmaku = 'enableShowDanmaku',
|
||||||
static const String enableBackgroundPlay = 'enableBackgroundPlay';
|
enableBackgroundPlay = 'enableBackgroundPlay',
|
||||||
|
|
||||||
/// 隐私
|
/// 隐私
|
||||||
static const String blackMidsList = 'blackMidsList';
|
blackMidsList = 'blackMidsList',
|
||||||
|
|
||||||
/// 其他
|
/// 其他
|
||||||
static const String autoUpdate = 'autoUpdate';
|
autoUpdate = 'autoUpdate',
|
||||||
static const String replySortType = 'replySortType';
|
defaultRcmdType = 'defaultRcmdType',
|
||||||
static const String defaultDynamicType = 'defaultDynamicType';
|
replySortType = 'replySortType',
|
||||||
static const String enableHotKey = 'enableHotKey';
|
defaultDynamicType = 'defaultDynamicType',
|
||||||
static const String enableQuickFav = 'enableQuickFav';
|
enableHotKey = 'enableHotKey',
|
||||||
static const String enableWordRe = 'enableWordRe';
|
enableQuickFav = 'enableQuickFav',
|
||||||
static const String enableSearchWord = 'enableSearchWord';
|
enableWordRe = 'enableWordRe',
|
||||||
static const String enableRcmdDynamic = 'enableRcmdDynamic';
|
enableSearchWord = 'enableSearchWord',
|
||||||
static const String enableSaveLastData = 'enableSaveLastData';
|
enableRcmdDynamic = 'enableRcmdDynamic',
|
||||||
static const String enableSystemProxy = 'enableSystemProxy';
|
enableSaveLastData = 'enableSaveLastData',
|
||||||
static const String enableAi = 'enableAi';
|
enableSystemProxy = 'enableSystemProxy',
|
||||||
|
enableAi = 'enableAi';
|
||||||
|
|
||||||
/// 外观
|
/// 外观
|
||||||
static const String themeMode = 'themeMode';
|
static const String themeMode = 'themeMode',
|
||||||
static const String defaultTextScale = 'textScale';
|
defaultTextScale = 'textScale',
|
||||||
static const String dynamicColor = 'dynamicColor'; // bool
|
dynamicColor = 'dynamicColor', // bool
|
||||||
static const String customColor = 'customColor'; // 自定义主题色
|
customColor = 'customColor', // 自定义主题色
|
||||||
static const String enableSingleRow = 'enableSingleRow'; // 首页单列
|
enableSingleRow = 'enableSingleRow', // 首页单列
|
||||||
static const String displayMode = 'displayMode';
|
displayMode = 'displayMode',
|
||||||
static const String customRows = 'customRows'; // 自定义列
|
customRows = 'customRows', // 自定义列
|
||||||
static const String enableMYBar = 'enableMYBar';
|
enableMYBar = 'enableMYBar',
|
||||||
static const String hideSearchBar = 'hideSearchBar'; // 收起顶栏
|
hideSearchBar = 'hideSearchBar', // 收起顶栏
|
||||||
static const String hideTabBar = 'hideTabBar'; // 收起底栏
|
hideTabBar = 'hideTabBar'; // 收起底栏
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocalCacheKey {
|
class LocalCacheKey {
|
||||||
// 历史记录暂停状态 默认false 记录
|
// 历史记录暂停状态 默认false 记录
|
||||||
static const String historyPause = 'historyPause';
|
static const String historyPause = 'historyPause',
|
||||||
// access_key
|
// access_key
|
||||||
static const String accessKey = 'accessKey';
|
accessKey = 'accessKey',
|
||||||
|
|
||||||
//
|
//
|
||||||
static const String wbiKeys = 'wbiKeys';
|
wbiKeys = 'wbiKeys',
|
||||||
static const String timeStamp = 'timeStamp';
|
timeStamp = 'timeStamp',
|
||||||
|
|
||||||
// 弹幕相关设置 屏蔽类型 显示区域 透明度 字体大小 弹幕时间
|
// 弹幕相关设置 屏蔽类型 显示区域 透明度 字体大小 弹幕时间
|
||||||
static const String danmakuBlockType = 'danmakuBlockType';
|
danmakuBlockType = 'danmakuBlockType',
|
||||||
static const String danmakuShowArea = 'danmakuShowArea';
|
danmakuShowArea = 'danmakuShowArea',
|
||||||
static const String danmakuOpacity = 'danmakuOpacity';
|
danmakuOpacity = 'danmakuOpacity',
|
||||||
static const String danmakuFontScale = 'danmakuFontScale';
|
danmakuFontScale = 'danmakuFontScale',
|
||||||
static const String danmakuDuration = 'danmakuDuration';
|
danmakuDuration = 'danmakuDuration',
|
||||||
|
|
||||||
// 代理host port
|
// 代理host port
|
||||||
static const String systemProxyHost = 'systemProxyHost';
|
systemProxyHost = 'systemProxyHost',
|
||||||
static const String systemProxyPort = 'systemProxyPort';
|
systemProxyPort = 'systemProxyPort';
|
||||||
}
|
}
|
||||||
|
|
||||||
class VideoBoxKey {
|
class VideoBoxKey {
|
||||||
// 视频比例
|
// 视频比例
|
||||||
static const String videoFit = 'videoFit';
|
static const String videoFit = 'videoFit',
|
||||||
// 亮度
|
// 亮度
|
||||||
static const String videoBrightness = 'videoBrightness';
|
videoBrightness = 'videoBrightness',
|
||||||
// 倍速
|
// 倍速
|
||||||
static const String videoSpeed = 'videoSpeed';
|
videoSpeed = 'videoSpeed',
|
||||||
// 播放顺序
|
// 播放顺序
|
||||||
static const String playRepeat = 'playRepeat';
|
playRepeat = 'playRepeat',
|
||||||
// 默认倍速
|
// 默认倍速
|
||||||
static const String playSpeedDefault = 'playSpeedDefault';
|
playSpeedDefault = 'playSpeedDefault',
|
||||||
// 默认长按倍速
|
// 默认长按倍速
|
||||||
static const String longPressSpeedDefault = 'longPressSpeedDefault';
|
longPressSpeedDefault = 'longPressSpeedDefault',
|
||||||
// 自定义倍速集合
|
// 自定义倍速集合
|
||||||
static const String customSpeedsList = 'customSpeedsList';
|
customSpeedsList = 'customSpeedsList',
|
||||||
// 画面填充比例
|
// 画面填充比例
|
||||||
static const String cacheVideoFit = 'cacheVideoFit';
|
cacheVideoFit = 'cacheVideoFit';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user