Merge branch 'main' into fix
This commit is contained in:
@ -548,4 +548,8 @@ class Api {
|
|||||||
|
|
||||||
/// 收到的赞
|
/// 收到的赞
|
||||||
static const String messageLikeAPi = '/x/msgfeed/like';
|
static const String messageLikeAPi = '/x/msgfeed/like';
|
||||||
|
|
||||||
|
/// 系统通知
|
||||||
|
static const String messageSystemAPi =
|
||||||
|
'${HttpString.messageBaseUrl}/x/sys-msg/query_unified_notify';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,8 @@ class HttpString {
|
|||||||
static const String appBaseUrl = 'https://app.bilibili.com';
|
static const String appBaseUrl = 'https://app.bilibili.com';
|
||||||
static const String liveBaseUrl = 'https://api.live.bilibili.com';
|
static const String liveBaseUrl = 'https://api.live.bilibili.com';
|
||||||
static const String passBaseUrl = 'https://passport.bilibili.com';
|
static const String passBaseUrl = 'https://passport.bilibili.com';
|
||||||
|
static const String messageBaseUrl = 'https://message.bilibili.com';
|
||||||
|
static const String bangumiBaseUrl = 'https://bili.meark.me';
|
||||||
static const List<int> validateStatusCodes = [
|
static const List<int> validateStatusCodes = [
|
||||||
302,
|
302,
|
||||||
304,
|
304,
|
||||||
|
|||||||
@ -27,11 +27,13 @@ class Request {
|
|||||||
late bool enableSystemProxy;
|
late bool enableSystemProxy;
|
||||||
late String systemProxyHost;
|
late String systemProxyHost;
|
||||||
late String systemProxyPort;
|
late String systemProxyPort;
|
||||||
static final RegExp spmPrefixExp = RegExp(r'<meta name="spm_prefix" content="([^"]+?)">');
|
static final RegExp spmPrefixExp =
|
||||||
|
RegExp(r'<meta name="spm_prefix" content="([^"]+?)">');
|
||||||
|
|
||||||
/// 设置cookie
|
/// 设置cookie
|
||||||
static setCookie() async {
|
static setCookie() async {
|
||||||
Box userInfoCache = GStrorage.userInfo;
|
Box userInfoCache = GStrorage.userInfo;
|
||||||
|
Box setting = GStrorage.setting;
|
||||||
final String cookiePath = await Utils.getCookiePath();
|
final String cookiePath = await Utils.getCookiePath();
|
||||||
final PersistCookieJar cookieJar = PersistCookieJar(
|
final PersistCookieJar cookieJar = PersistCookieJar(
|
||||||
ignoreExpires: true,
|
ignoreExpires: true,
|
||||||
@ -54,7 +56,11 @@ class Request {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
setOptionsHeaders(userInfo, userInfo != null && userInfo.mid != null);
|
setOptionsHeaders(userInfo, userInfo != null && userInfo.mid != null);
|
||||||
|
String baseUrlType = 'default';
|
||||||
|
if (setting.get(SettingBoxKey.enableGATMode, defaultValue: false)) {
|
||||||
|
baseUrlType = 'bangumi';
|
||||||
|
}
|
||||||
|
setBaseUrl(type: baseUrlType);
|
||||||
try {
|
try {
|
||||||
await buvidActivate();
|
await buvidActivate();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -98,8 +104,7 @@ class Request {
|
|||||||
List<int>.generate(32, (_) => rand.nextInt(256)) +
|
List<int>.generate(32, (_) => rand.nextInt(256)) +
|
||||||
List<int>.filled(4, 0) +
|
List<int>.filled(4, 0) +
|
||||||
[73, 69, 78, 68] +
|
[73, 69, 78, 68] +
|
||||||
List<int>.generate(4, (_) => rand.nextInt(256))
|
List<int>.generate(4, (_) => rand.nextInt(256)));
|
||||||
);
|
|
||||||
|
|
||||||
String jsonData = json.encode({
|
String jsonData = json.encode({
|
||||||
'3064': 1,
|
'3064': 1,
|
||||||
@ -110,11 +115,9 @@ class Request {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
await Request().post(
|
await Request().post(Api.activateBuvidApi,
|
||||||
Api.activateBuvidApi,
|
|
||||||
data: {'payload': jsonData},
|
data: {'payload': jsonData},
|
||||||
options: Options(contentType: 'application/json')
|
options: Options(contentType: 'application/json'));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -294,4 +297,17 @@ class Request {
|
|||||||
}
|
}
|
||||||
return headerUa;
|
return headerUa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static setBaseUrl({String type = 'default'}) {
|
||||||
|
switch (type) {
|
||||||
|
case 'default':
|
||||||
|
dio.options.baseUrl = HttpString.apiBaseUrl;
|
||||||
|
break;
|
||||||
|
case 'bangumi':
|
||||||
|
dio.options.baseUrl = HttpString.bangumiBaseUrl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dio.options.baseUrl = HttpString.apiBaseUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import 'dart:math';
|
|||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:pilipala/models/msg/like.dart';
|
import 'package:pilipala/models/msg/like.dart';
|
||||||
import 'package:pilipala/models/msg/reply.dart';
|
import 'package:pilipala/models/msg/reply.dart';
|
||||||
|
import 'package:pilipala/models/msg/system.dart';
|
||||||
import '../models/msg/account.dart';
|
import '../models/msg/account.dart';
|
||||||
import '../models/msg/session.dart';
|
import '../models/msg/session.dart';
|
||||||
import '../utils/wbi_sign.dart';
|
import '../utils/wbi_sign.dart';
|
||||||
@ -149,7 +150,7 @@ class MsgHttp {
|
|||||||
'msg[msg_status]': 0,
|
'msg[msg_status]': 0,
|
||||||
'msg[content]': jsonEncode(content),
|
'msg[content]': jsonEncode(content),
|
||||||
'msg[timestamp]': DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
'msg[timestamp]': DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||||
'msg[new_face_version]': 0,
|
'msg[new_face_version]': 1,
|
||||||
'msg[dev_id]': getDevId(),
|
'msg[dev_id]': getDevId(),
|
||||||
'from_firework': 0,
|
'from_firework': 0,
|
||||||
'build': 0,
|
'build': 0,
|
||||||
@ -287,4 +288,28 @@ class MsgHttp {
|
|||||||
return {'status': false, 'date': [], 'msg': res.data['message']};
|
return {'status': false, 'date': [], 'msg': res.data['message']};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future messageSystem() async {
|
||||||
|
var res = await Request().get(Api.messageSystemAPi, data: {
|
||||||
|
'csrf': await Request.getCsrf(),
|
||||||
|
'page_size': 20,
|
||||||
|
'build': 0,
|
||||||
|
'mobi_app': 'web',
|
||||||
|
});
|
||||||
|
if (res.data['code'] == 0) {
|
||||||
|
try {
|
||||||
|
print(res.data['data']['system_notify_list']);
|
||||||
|
return {
|
||||||
|
'status': true,
|
||||||
|
'data': res.data['data']['system_notify_list']
|
||||||
|
.map<MessageSystemModel>((e) => MessageSystemModel.fromJson(e))
|
||||||
|
.toList(),
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
return {'status': false, 'date': [], 'msg': err.toString()};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {'status': false, 'date': [], 'msg': res.data['message']};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,95 +0,0 @@
|
|||||||
enum SubtitleType {
|
|
||||||
// 中文(中国)
|
|
||||||
zhCN,
|
|
||||||
// 中文(自动翻译)
|
|
||||||
aizh,
|
|
||||||
// 英语(自动生成)
|
|
||||||
aien,
|
|
||||||
// 中文(简体)
|
|
||||||
zhHans,
|
|
||||||
// 英文(美国)
|
|
||||||
enUS,
|
|
||||||
// 中文繁体
|
|
||||||
zhTW,
|
|
||||||
//
|
|
||||||
en,
|
|
||||||
//
|
|
||||||
pt,
|
|
||||||
//
|
|
||||||
es,
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SubtitleTypeExtension on SubtitleType {
|
|
||||||
String get description {
|
|
||||||
switch (this) {
|
|
||||||
case SubtitleType.zhCN:
|
|
||||||
return '中文(中国)';
|
|
||||||
case SubtitleType.aizh:
|
|
||||||
return '中文(自动翻译)';
|
|
||||||
case SubtitleType.aien:
|
|
||||||
return '英语(自动生成)';
|
|
||||||
case SubtitleType.zhHans:
|
|
||||||
return '中文(简体)';
|
|
||||||
case SubtitleType.enUS:
|
|
||||||
return '英文(美国)';
|
|
||||||
case SubtitleType.zhTW:
|
|
||||||
return '中文(繁体)';
|
|
||||||
case SubtitleType.en:
|
|
||||||
return '英文';
|
|
||||||
case SubtitleType.pt:
|
|
||||||
return '葡萄牙语';
|
|
||||||
case SubtitleType.es:
|
|
||||||
return '西班牙语';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SubtitleIdExtension on SubtitleType {
|
|
||||||
String get id {
|
|
||||||
switch (this) {
|
|
||||||
case SubtitleType.zhCN:
|
|
||||||
return 'zh-CN';
|
|
||||||
case SubtitleType.aizh:
|
|
||||||
return 'ai-zh';
|
|
||||||
case SubtitleType.aien:
|
|
||||||
return 'ai-en';
|
|
||||||
case SubtitleType.zhHans:
|
|
||||||
return 'zh-Hans';
|
|
||||||
case SubtitleType.enUS:
|
|
||||||
return 'en-US';
|
|
||||||
case SubtitleType.zhTW:
|
|
||||||
return 'zh-TW';
|
|
||||||
case SubtitleType.en:
|
|
||||||
return 'en';
|
|
||||||
case SubtitleType.pt:
|
|
||||||
return 'pt';
|
|
||||||
case SubtitleType.es:
|
|
||||||
return 'es';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SubtitleCodeExtension on SubtitleType {
|
|
||||||
int get code {
|
|
||||||
switch (this) {
|
|
||||||
case SubtitleType.zhCN:
|
|
||||||
return 1;
|
|
||||||
case SubtitleType.aizh:
|
|
||||||
return 2;
|
|
||||||
case SubtitleType.aien:
|
|
||||||
return 3;
|
|
||||||
case SubtitleType.zhHans:
|
|
||||||
return 4;
|
|
||||||
case SubtitleType.enUS:
|
|
||||||
return 5;
|
|
||||||
case SubtitleType.zhTW:
|
|
||||||
return 6;
|
|
||||||
case SubtitleType.en:
|
|
||||||
return 7;
|
|
||||||
case SubtitleType.pt:
|
|
||||||
return 8;
|
|
||||||
case SubtitleType.es:
|
|
||||||
return 9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
77
lib/models/msg/system.dart
Normal file
77
lib/models/msg/system.dart
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
class MessageSystemModel {
|
||||||
|
int? id;
|
||||||
|
int? cursor;
|
||||||
|
int? type;
|
||||||
|
String? title;
|
||||||
|
Map? content;
|
||||||
|
Source? source;
|
||||||
|
String? timeAt;
|
||||||
|
int? cardType;
|
||||||
|
String? cardBrief;
|
||||||
|
String? cardMsgBrief;
|
||||||
|
String? cardCover;
|
||||||
|
String? cardStoryTitle;
|
||||||
|
String? cardLink;
|
||||||
|
String? mc;
|
||||||
|
int? isStation;
|
||||||
|
int? isSend;
|
||||||
|
int? notifyCursor;
|
||||||
|
|
||||||
|
MessageSystemModel({
|
||||||
|
this.id,
|
||||||
|
this.cursor,
|
||||||
|
this.type,
|
||||||
|
this.title,
|
||||||
|
this.content,
|
||||||
|
this.source,
|
||||||
|
this.timeAt,
|
||||||
|
this.cardType,
|
||||||
|
this.cardBrief,
|
||||||
|
this.cardMsgBrief,
|
||||||
|
this.cardCover,
|
||||||
|
this.cardStoryTitle,
|
||||||
|
this.cardLink,
|
||||||
|
this.mc,
|
||||||
|
this.isStation,
|
||||||
|
this.isSend,
|
||||||
|
this.notifyCursor,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory MessageSystemModel.fromJson(Map<String, dynamic> jsons) =>
|
||||||
|
MessageSystemModel(
|
||||||
|
id: jsons["id"],
|
||||||
|
cursor: jsons["cursor"],
|
||||||
|
type: jsons["type"],
|
||||||
|
title: jsons["title"],
|
||||||
|
content: json.decode(jsons["content"]),
|
||||||
|
source: Source.fromJson(jsons["source"]),
|
||||||
|
timeAt: jsons["time_at"],
|
||||||
|
cardType: jsons["card_type"],
|
||||||
|
cardBrief: jsons["card_brief"],
|
||||||
|
cardMsgBrief: jsons["card_msg_brief"],
|
||||||
|
cardCover: jsons["card_cover"],
|
||||||
|
cardStoryTitle: jsons["card_story_title"],
|
||||||
|
cardLink: jsons["card_link"],
|
||||||
|
mc: jsons["mc"],
|
||||||
|
isStation: jsons["is_station"],
|
||||||
|
isSend: jsons["is_send"],
|
||||||
|
notifyCursor: jsons["notify_cursor"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Source {
|
||||||
|
String? name;
|
||||||
|
String? logo;
|
||||||
|
|
||||||
|
Source({
|
||||||
|
this.name,
|
||||||
|
this.logo,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory Source.fromJson(Map<String, dynamic> json) => Source(
|
||||||
|
name: json["name"],
|
||||||
|
logo: json["logo"],
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,6 +1,3 @@
|
|||||||
import 'package:get/get.dart';
|
|
||||||
import '../../common/subtitle_type.dart';
|
|
||||||
|
|
||||||
class SubTitlteModel {
|
class SubTitlteModel {
|
||||||
SubTitlteModel({
|
SubTitlteModel({
|
||||||
this.aid,
|
this.aid,
|
||||||
@ -78,11 +75,6 @@ class SubTitlteItemModel {
|
|||||||
aiType: json["ai_type"],
|
aiType: json["ai_type"],
|
||||||
aiStatus: json["ai_status"],
|
aiStatus: json["ai_status"],
|
||||||
title: json["lan_doc"],
|
title: json["lan_doc"],
|
||||||
code: SubtitleType.values
|
|
||||||
.firstWhereOrNull(
|
|
||||||
(element) => element.id.toString() == json["lan"])
|
|
||||||
?.index ??
|
|
||||||
-1,
|
|
||||||
content: '',
|
content: '',
|
||||||
body: [],
|
body: [],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,3 +1,15 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/http/msg.dart';
|
||||||
|
import 'package:pilipala/models/msg/system.dart';
|
||||||
|
|
||||||
class MessageSystemController extends GetxController {}
|
class MessageSystemController extends GetxController {
|
||||||
|
RxList<MessageSystemModel> systemItems = <MessageSystemModel>[].obs;
|
||||||
|
|
||||||
|
Future queryMessageSystem({String type = 'init'}) async {
|
||||||
|
var res = await MsgHttp.messageSystem();
|
||||||
|
if (res['status']) {
|
||||||
|
systemItems.addAll(res['data']);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/common/widgets/http_error.dart';
|
||||||
|
import 'package:pilipala/models/msg/system.dart';
|
||||||
|
import 'controller.dart';
|
||||||
|
|
||||||
class MessageSystemPage extends StatefulWidget {
|
class MessageSystemPage extends StatefulWidget {
|
||||||
const MessageSystemPage({super.key});
|
const MessageSystemPage({super.key});
|
||||||
@ -8,12 +12,112 @@ class MessageSystemPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MessageSystemPageState extends State<MessageSystemPage> {
|
class _MessageSystemPageState extends State<MessageSystemPage> {
|
||||||
|
final MessageSystemController _messageSystemCtr =
|
||||||
|
Get.put(MessageSystemController());
|
||||||
|
late Future _futureBuilderFuture;
|
||||||
|
final ScrollController scrollController = ScrollController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_futureBuilderFuture = _messageSystemCtr.queryMessageSystem();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('系统通知'),
|
title: const Text('系统通知'),
|
||||||
),
|
),
|
||||||
|
body: RefreshIndicator(
|
||||||
|
onRefresh: () async {
|
||||||
|
await _messageSystemCtr.queryMessageSystem();
|
||||||
|
},
|
||||||
|
child: FutureBuilder(
|
||||||
|
future: _futureBuilderFuture,
|
||||||
|
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
if (snapshot.data == null) {
|
||||||
|
return const SizedBox();
|
||||||
|
}
|
||||||
|
if (snapshot.data['status']) {
|
||||||
|
final systemItems = _messageSystemCtr.systemItems;
|
||||||
|
print(systemItems.length);
|
||||||
|
return Obx(
|
||||||
|
() => ListView.separated(
|
||||||
|
controller: scrollController,
|
||||||
|
itemBuilder: (context, index) => SystemItem(
|
||||||
|
item: systemItems[index],
|
||||||
|
index: index,
|
||||||
|
messageSystemCtr: _messageSystemCtr,
|
||||||
|
),
|
||||||
|
itemCount: systemItems.length,
|
||||||
|
separatorBuilder: (BuildContext context, int index) {
|
||||||
|
return Divider(
|
||||||
|
indent: 14,
|
||||||
|
endIndent: 14,
|
||||||
|
height: 1,
|
||||||
|
color: Colors.grey.withOpacity(0.1),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// 请求错误
|
||||||
|
return CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
HttpError(
|
||||||
|
errMsg: snapshot.data['msg'],
|
||||||
|
fn: () {
|
||||||
|
setState(() {
|
||||||
|
_futureBuilderFuture =
|
||||||
|
_messageSystemCtr.queryMessageSystem();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return const SizedBox();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SystemItem extends StatelessWidget {
|
||||||
|
final MessageSystemModel item;
|
||||||
|
final int index;
|
||||||
|
final MessageSystemController messageSystemCtr;
|
||||||
|
|
||||||
|
const SystemItem(
|
||||||
|
{super.key,
|
||||||
|
required this.item,
|
||||||
|
required this.index,
|
||||||
|
required this.messageSystemCtr});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(14, 14, 14, 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(item.title!,
|
||||||
|
style:
|
||||||
|
const TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
item.timeAt!,
|
||||||
|
style: TextStyle(color: Theme.of(context).colorScheme.outline),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
Text(item.content!['web']),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import 'dart:io';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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/init.dart';
|
||||||
import 'package:pilipala/models/video/play/ao_output.dart';
|
import 'package:pilipala/models/video/play/ao_output.dart';
|
||||||
import 'package:pilipala/models/video/play/quality.dart';
|
import 'package:pilipala/models/video/play/quality.dart';
|
||||||
import 'package:pilipala/pages/setting/widgets/select_dialog.dart';
|
import 'package:pilipala/pages/setting/widgets/select_dialog.dart';
|
||||||
@ -163,6 +164,14 @@ class _PlaySettingState extends State<PlaySetting> {
|
|||||||
callFn: (bool val) {
|
callFn: (bool val) {
|
||||||
GlobalData().enablePlayerControlAnimation = val;
|
GlobalData().enablePlayerControlAnimation = val;
|
||||||
}),
|
}),
|
||||||
|
SetSwitchItem(
|
||||||
|
title: '港澳台模式',
|
||||||
|
setKey: SettingBoxKey.enableGATMode,
|
||||||
|
defaultVal: false,
|
||||||
|
callFn: (bool val) {
|
||||||
|
Request.setBaseUrl(type: val ? 'bangumi' : 'default');
|
||||||
|
},
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
title: Text('默认视频画质', style: titleStyle),
|
title: Text('默认视频画质', style: titleStyle),
|
||||||
|
|||||||
@ -141,13 +141,7 @@ class VideoDetailController extends GetxController
|
|||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
floating = Floating();
|
floating = Floating();
|
||||||
}
|
}
|
||||||
headerControl = HeaderControl(
|
|
||||||
controller: plPlayerController,
|
|
||||||
videoDetailCtr: this,
|
|
||||||
floating: floating,
|
|
||||||
bvid: bvid,
|
|
||||||
videoType: videoType,
|
|
||||||
);
|
|
||||||
// CDN优化
|
// CDN优化
|
||||||
enableCDN = setting.get(SettingBoxKey.enableCDN, defaultValue: true);
|
enableCDN = setting.get(SettingBoxKey.enableCDN, defaultValue: true);
|
||||||
// 预设的画质
|
// 预设的画质
|
||||||
@ -158,7 +152,18 @@ class VideoDetailController extends GetxController
|
|||||||
defaultAudioQa = setting.get(SettingBoxKey.defaultAudioQa,
|
defaultAudioQa = setting.get(SettingBoxKey.defaultAudioQa,
|
||||||
defaultValue: AudioQuality.hiRes.code);
|
defaultValue: AudioQuality.hiRes.code);
|
||||||
oid.value = IdUtils.bv2av(Get.parameters['bvid']!);
|
oid.value = IdUtils.bv2av(Get.parameters['bvid']!);
|
||||||
getSubtitle();
|
getSubtitle().then(
|
||||||
|
(subtitles) {
|
||||||
|
headerControl = HeaderControl(
|
||||||
|
controller: plPlayerController,
|
||||||
|
videoDetailCtr: this,
|
||||||
|
floating: floating,
|
||||||
|
bvid: bvid,
|
||||||
|
videoType: videoType,
|
||||||
|
showSubtitleBtn: subtitles.isNotEmpty,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
showReplyReplyPanel(oid, fRpid, firstFloor) {
|
showReplyReplyPanel(oid, fRpid, firstFloor) {
|
||||||
@ -432,6 +437,14 @@ class VideoDetailController extends GetxController
|
|||||||
if (result['status']) {
|
if (result['status']) {
|
||||||
if (result['data'].subtitles.isNotEmpty) {
|
if (result['data'].subtitles.isNotEmpty) {
|
||||||
subtitles = result['data'].subtitles;
|
subtitles = result['data'].subtitles;
|
||||||
|
getDanmaku(subtitles);
|
||||||
|
}
|
||||||
|
return subtitles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取弹幕
|
||||||
|
Future getDanmaku(List subtitles) async {
|
||||||
if (subtitles.isNotEmpty) {
|
if (subtitles.isNotEmpty) {
|
||||||
for (var i in subtitles) {
|
for (var i in subtitles) {
|
||||||
final Map<String, dynamic> res = await VideoHttp.getSubtitleContent(
|
final Map<String, dynamic> res = await VideoHttp.getSubtitleContent(
|
||||||
@ -442,18 +455,6 @@ class VideoDetailController extends GetxController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result['data'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取字幕内容
|
|
||||||
// Future getSubtitleContent(String url) async {
|
|
||||||
// var res = await Request().get('https:$url');
|
|
||||||
// subtitleContents.value = res.data['body'].map<SubTitileContentModel>((e) {
|
|
||||||
// return SubTitileContentModel.fromJson(e);
|
|
||||||
// }).toList();
|
|
||||||
// setSubtitleContent();
|
|
||||||
// }
|
|
||||||
|
|
||||||
setSubtitleContent() {
|
setSubtitleContent() {
|
||||||
plPlayerController.subtitleContent.value = '';
|
plPlayerController.subtitleContent.value = '';
|
||||||
|
|||||||
@ -435,7 +435,8 @@ class VideoIntroController extends GetxController {
|
|||||||
videoDetailCtr.danmakuCid.value = cid;
|
videoDetailCtr.danmakuCid.value = cid;
|
||||||
videoDetailCtr.cover.value = cover;
|
videoDetailCtr.cover.value = cover;
|
||||||
videoDetailCtr.queryVideoUrl();
|
videoDetailCtr.queryVideoUrl();
|
||||||
videoDetailCtr.getSubtitle();
|
videoDetailCtr.clearSubtitleContent();
|
||||||
|
await videoDetailCtr.getSubtitle();
|
||||||
videoDetailCtr.setSubtitleContent();
|
videoDetailCtr.setSubtitleContent();
|
||||||
// 重新请求评论
|
// 重新请求评论
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -188,7 +188,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
|||||||
if (snapshot.connectionState == ConnectionState.done) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
var data = snapshot.data;
|
var data = snapshot.data;
|
||||||
if (_videoReplyController.replyList.isNotEmpty ||
|
if (_videoReplyController.replyList.isNotEmpty ||
|
||||||
(data && data['status'])) {
|
(data != null && data['status'])) {
|
||||||
// 请求成功
|
// 请求成功
|
||||||
return Obx(
|
return Obx(
|
||||||
() => _videoReplyController.isLoadingMore &&
|
() => _videoReplyController.isLoadingMore &&
|
||||||
|
|||||||
@ -30,6 +30,7 @@ class HeaderControl extends StatefulWidget implements PreferredSizeWidget {
|
|||||||
this.floating,
|
this.floating,
|
||||||
this.bvid,
|
this.bvid,
|
||||||
this.videoType,
|
this.videoType,
|
||||||
|
this.showSubtitleBtn,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
final PlPlayerController? controller;
|
final PlPlayerController? controller;
|
||||||
@ -37,6 +38,7 @@ class HeaderControl extends StatefulWidget implements PreferredSizeWidget {
|
|||||||
final Floating? floating;
|
final Floating? floating;
|
||||||
final String? bvid;
|
final String? bvid;
|
||||||
final SearchType? videoType;
|
final SearchType? videoType;
|
||||||
|
final bool? showSubtitleBtn;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<HeaderControl> createState() => _HeaderControlState();
|
State<HeaderControl> createState() => _HeaderControlState();
|
||||||
@ -426,7 +428,12 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
/// 选择字幕
|
/// 选择字幕
|
||||||
void showSubtitleDialog() async {
|
void showSubtitleDialog() async {
|
||||||
int tempThemeValue = widget.controller!.subTitleCode.value;
|
int tempThemeValue = widget.controller!.subTitleCode.value;
|
||||||
int len = widget.videoDetailCtr!.subtitles.length;
|
final List subtitles = widget.videoDetailCtr!.subtitles;
|
||||||
|
int len = subtitles.length;
|
||||||
|
if (subtitles.firstWhereOrNull((element) => element.id == tempThemeValue) ==
|
||||||
|
null) {
|
||||||
|
tempThemeValue = -1;
|
||||||
|
}
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
@ -458,7 +465,7 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
),
|
),
|
||||||
...widget.videoDetailCtr!.subtitles
|
...widget.videoDetailCtr!.subtitles
|
||||||
.map((e) => RadioListTile(
|
.map((e) => RadioListTile(
|
||||||
value: e.code,
|
value: e.id,
|
||||||
title: Text(e.title),
|
title: Text(e.title),
|
||||||
groupValue: tempThemeValue,
|
groupValue: tempThemeValue,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
@ -1322,6 +1329,7 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
],
|
],
|
||||||
|
|
||||||
/// 字幕
|
/// 字幕
|
||||||
|
if (widget.showSubtitleBtn!)
|
||||||
ComBtn(
|
ComBtn(
|
||||||
icon: const Icon(
|
icon: const Icon(
|
||||||
Icons.closed_caption_off,
|
Icons.closed_caption_off,
|
||||||
|
|||||||
@ -71,7 +71,7 @@ class _WhisperPageState extends State<WhisperPage> {
|
|||||||
..._whisperController.noticesList.map((element) {
|
..._whisperController.noticesList.map((element) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (['/messageAt', '/messageSystem']
|
if (['/messageAt']
|
||||||
.contains(element['path'])) {
|
.contains(element['path'])) {
|
||||||
SmartDialog.showToast('功能开发中');
|
SmartDialog.showToast('功能开发中');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -123,7 +123,7 @@ class PlPlayerController {
|
|||||||
PreferredSizeWidget? headerControl;
|
PreferredSizeWidget? headerControl;
|
||||||
PreferredSizeWidget? bottomControl;
|
PreferredSizeWidget? bottomControl;
|
||||||
Widget? danmuWidget;
|
Widget? danmuWidget;
|
||||||
late RxList subtitles;
|
RxList subtitles = [].obs;
|
||||||
String videoType = 'archive';
|
String videoType = 'archive';
|
||||||
|
|
||||||
/// 数据加载监听
|
/// 数据加载监听
|
||||||
@ -642,10 +642,6 @@ class PlPlayerController {
|
|||||||
const Duration(seconds: 1),
|
const Duration(seconds: 1),
|
||||||
() => videoPlayerServiceHandler.onPositionChange(event));
|
() => videoPlayerServiceHandler.onPositionChange(event));
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// onSubTitleOpenChanged.listen((bool event) {
|
|
||||||
// toggleSubtitle(event ? subTitleCode.value : -1);
|
|
||||||
// })
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1049,25 +1045,6 @@ class PlPlayerController {
|
|||||||
void toggleSubtitle(int code) {
|
void toggleSubtitle(int code) {
|
||||||
_subTitleOpen.value = code != -1;
|
_subTitleOpen.value = code != -1;
|
||||||
_subTitleCode.value = code;
|
_subTitleCode.value = code;
|
||||||
// if (code == -1) {
|
|
||||||
// // 关闭字幕
|
|
||||||
// _subTitleOpen.value = false;
|
|
||||||
// _subTitleCode.value = code;
|
|
||||||
// _videoPlayerController?.setSubtitleTrack(SubtitleTrack.no());
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// final SubTitlteItemModel? subtitle = subtitles?.firstWhereOrNull(
|
|
||||||
// (element) => element.code == code,
|
|
||||||
// );
|
|
||||||
// _subTitleOpen.value = true;
|
|
||||||
// _subTitleCode.value = code;
|
|
||||||
// _videoPlayerController?.setSubtitleTrack(
|
|
||||||
// SubtitleTrack.data(
|
|
||||||
// subtitle!.content!,
|
|
||||||
// title: subtitle.title,
|
|
||||||
// language: subtitle.lan,
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void querySubtitleContent(double progress) {
|
void querySubtitleContent(double progress) {
|
||||||
@ -1079,7 +1056,7 @@ class PlPlayerController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final SubTitlteItemModel? subtitle = subtitles.firstWhereOrNull(
|
final SubTitlteItemModel? subtitle = subtitles.firstWhereOrNull(
|
||||||
(element) => element.code == subTitleCode.value,
|
(element) => element.id == subTitleCode.value,
|
||||||
);
|
);
|
||||||
if (subtitle != null && subtitle.body!.isNotEmpty) {
|
if (subtitle != null && subtitle.body!.isNotEmpty) {
|
||||||
for (var content in subtitle.body!) {
|
for (var content in subtitle.body!) {
|
||||||
|
|||||||
@ -104,6 +104,8 @@ class SettingBoxKey {
|
|||||||
enablePlayerControlAnimation = 'enablePlayerControlAnimation',
|
enablePlayerControlAnimation = 'enablePlayerControlAnimation',
|
||||||
// 默认音频输出方式
|
// 默认音频输出方式
|
||||||
defaultAoOutput = 'defaultAoOutput',
|
defaultAoOutput = 'defaultAoOutput',
|
||||||
|
// 港澳台模式
|
||||||
|
enableGATMode = 'enableGATMode',
|
||||||
|
|
||||||
// youtube 双击快进快退
|
// youtube 双击快进快退
|
||||||
enableQuickDouble = 'enableQuickDouble',
|
enableQuickDouble = 'enableQuickDouble',
|
||||||
|
|||||||
Reference in New Issue
Block a user