mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-08-03 01:00:14 +08:00
feat: cellular video/audio qa
Closes #52 Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
// ignore_for_file: avoid_print
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
import 'package:PiliPalaX/utils/utils.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
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';
|
||||||
@@ -77,29 +77,8 @@ class ApiInterceptor extends Interceptor {
|
|||||||
case DioExceptionType.sendTimeout:
|
case DioExceptionType.sendTimeout:
|
||||||
return '发送请求超时,请检查网络设置';
|
return '发送请求超时,请检查网络设置';
|
||||||
case DioExceptionType.unknown:
|
case DioExceptionType.unknown:
|
||||||
final String res = await checkConnect();
|
final String res = (await Utils.checkConnectivity()).title;
|
||||||
return '$res网络异常 ${error.error}';
|
return '$res网络异常 ${error.error}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<String> checkConnect() async {
|
|
||||||
final List<ConnectivityResult> connectivityResult =
|
|
||||||
await Connectivity().checkConnectivity();
|
|
||||||
switch (connectivityResult.first) {
|
|
||||||
case ConnectivityResult.mobile:
|
|
||||||
return '流量';
|
|
||||||
case ConnectivityResult.wifi:
|
|
||||||
return 'Wi-Fi';
|
|
||||||
case ConnectivityResult.ethernet:
|
|
||||||
return '局域';
|
|
||||||
case ConnectivityResult.vpn:
|
|
||||||
return '代理';
|
|
||||||
case ConnectivityResult.other:
|
|
||||||
return '其他';
|
|
||||||
case ConnectivityResult.none:
|
|
||||||
return '无';
|
|
||||||
default:
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,12 +68,13 @@ class _MainAppState extends State<MainApp>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _checkDefaultSearch([bool shouldCheck = false]) {
|
void _checkDefaultSearch([bool shouldCheck = false]) {
|
||||||
if (shouldCheck &&
|
|
||||||
_mainController.pages[_mainController.pageController.page?.round() ?? 0]
|
|
||||||
is! HomePage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_homeController.enableSearchWord) {
|
if (_homeController.enableSearchWord) {
|
||||||
|
if (shouldCheck &&
|
||||||
|
_mainController
|
||||||
|
.pages[_mainController.pageController.page?.round() ?? 0]
|
||||||
|
is! HomePage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int now = DateTime.now().millisecondsSinceEpoch;
|
int now = DateTime.now().millisecondsSinceEpoch;
|
||||||
if (now - _homeController.lateCheckAt >= 5 * 60 * 1000) {
|
if (now - _homeController.lateCheckAt >= 5 * 60 * 1000) {
|
||||||
_homeController.lateCheckAt = now;
|
_homeController.lateCheckAt = now;
|
||||||
|
|||||||
@@ -148,11 +148,10 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
leading: Stack(
|
leading: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.shield),
|
const Icon(Icons.shield_outlined),
|
||||||
Icon(
|
Icon(
|
||||||
Icons.play_arrow_rounded,
|
Icons.play_arrow_rounded,
|
||||||
size: 18,
|
size: 15,
|
||||||
color: Theme.of(context).colorScheme.surface,
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ class VideoSetting extends StatefulWidget {
|
|||||||
class _VideoSettingState extends State<VideoSetting> {
|
class _VideoSettingState extends State<VideoSetting> {
|
||||||
Box setting = GStorage.setting;
|
Box setting = GStorage.setting;
|
||||||
late dynamic defaultVideoQa;
|
late dynamic defaultVideoQa;
|
||||||
|
late dynamic defaultVideoQaCellular;
|
||||||
late dynamic defaultAudioQa;
|
late dynamic defaultAudioQa;
|
||||||
|
late dynamic defaultAudioQaCellular;
|
||||||
late dynamic defaultDecode;
|
late dynamic defaultDecode;
|
||||||
late dynamic secondDecode;
|
late dynamic secondDecode;
|
||||||
late dynamic hardwareDecoding;
|
late dynamic hardwareDecoding;
|
||||||
@@ -30,20 +32,42 @@ class _VideoSettingState extends State<VideoSetting> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
defaultVideoQa = setting.get(SettingBoxKey.defaultVideoQa,
|
defaultVideoQa = setting.get(
|
||||||
defaultValue: VideoQuality.values.last.code);
|
SettingBoxKey.defaultVideoQa,
|
||||||
defaultAudioQa = setting.get(SettingBoxKey.defaultAudioQa,
|
defaultValue: VideoQuality.values.last.code,
|
||||||
defaultValue: AudioQuality.values.last.code);
|
);
|
||||||
defaultDecode = setting.get(SettingBoxKey.defaultDecode,
|
defaultVideoQaCellular = setting.get(
|
||||||
defaultValue: VideoDecodeFormats.values.last.code);
|
SettingBoxKey.defaultVideoQaCellular,
|
||||||
secondDecode = setting.get(SettingBoxKey.secondDecode,
|
defaultValue: VideoQuality.high1080.code,
|
||||||
defaultValue: VideoDecodeFormats.values[1].code);
|
);
|
||||||
hardwareDecoding = setting.get(SettingBoxKey.hardwareDecoding,
|
defaultAudioQa = setting.get(
|
||||||
defaultValue: Platform.isAndroid ? 'auto-safe' : 'auto');
|
SettingBoxKey.defaultAudioQa,
|
||||||
videoSync =
|
defaultValue: AudioQuality.values.last.code,
|
||||||
setting.get(SettingBoxKey.videoSync, defaultValue: 'display-resample');
|
);
|
||||||
defaultCDNService = setting.get(SettingBoxKey.CDNService,
|
defaultAudioQaCellular = setting.get(
|
||||||
defaultValue: CDNService.backupUrl.code);
|
SettingBoxKey.defaultAudioQaCellular,
|
||||||
|
defaultValue: AudioQuality.k192.code,
|
||||||
|
);
|
||||||
|
defaultDecode = setting.get(
|
||||||
|
SettingBoxKey.defaultDecode,
|
||||||
|
defaultValue: VideoDecodeFormats.values.last.code,
|
||||||
|
);
|
||||||
|
secondDecode = setting.get(
|
||||||
|
SettingBoxKey.secondDecode,
|
||||||
|
defaultValue: VideoDecodeFormats.values[1].code,
|
||||||
|
);
|
||||||
|
hardwareDecoding = setting.get(
|
||||||
|
SettingBoxKey.hardwareDecoding,
|
||||||
|
defaultValue: Platform.isAndroid ? 'auto-safe' : 'auto',
|
||||||
|
);
|
||||||
|
videoSync = setting.get(
|
||||||
|
SettingBoxKey.videoSync,
|
||||||
|
defaultValue: 'display-resample',
|
||||||
|
);
|
||||||
|
defaultCDNService = setting.get(
|
||||||
|
SettingBoxKey.CDNService,
|
||||||
|
defaultValue: CDNService.backupUrl.code,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -79,26 +103,25 @@ class _VideoSettingState extends State<VideoSetting> {
|
|||||||
defaultVal: true,
|
defaultVal: true,
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
enabled: false,
|
title: Text("B站定向流量支持", style: titleStyle),
|
||||||
onTap: null,
|
|
||||||
title: Text("b站定向流量支持", style: titleStyle),
|
|
||||||
subtitle:
|
subtitle:
|
||||||
Text("若套餐含b站定向流量,则会自动使用。可查阅运营商的流量记录确认。", style: subTitleStyle),
|
Text("若套餐含B站定向流量,则会自动使用。可查阅运营商的流量记录确认。", style: subTitleStyle),
|
||||||
leading: const Icon(Icons.perm_data_setting_outlined),
|
leading: const Icon(Icons.perm_data_setting_outlined),
|
||||||
trailing: Transform.scale(
|
trailing: Transform.scale(
|
||||||
alignment: Alignment.centerRight, // 缩放Switch的大小后保持右侧对齐, 避免右侧空隙过大
|
alignment: Alignment.centerRight, // 缩放Switch的大小后保持右侧对齐, 避免右侧空隙过大
|
||||||
scale: 0.8,
|
scale: 0.8,
|
||||||
child: Switch(
|
child: Switch(
|
||||||
thumbIcon: WidgetStateProperty.resolveWith<Icon?>(
|
thumbIcon: WidgetStateProperty.resolveWith<Icon?>(
|
||||||
(Set<WidgetState> states) {
|
(Set<WidgetState> states) {
|
||||||
if (states.isNotEmpty &&
|
if (states.isNotEmpty &&
|
||||||
states.first == WidgetState.selected) {
|
states.first == WidgetState.selected) {
|
||||||
return const Icon(Icons.done);
|
return const Icon(Icons.lock_outline_rounded);
|
||||||
}
|
}
|
||||||
return null; // All other states will use the default thumbIcon.
|
return null; // All other states will use the default thumbIcon.
|
||||||
}),
|
}),
|
||||||
value: true,
|
value: true,
|
||||||
onChanged: null),
|
onChanged: (_) {},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
@@ -147,11 +170,12 @@ class _VideoSettingState extends State<VideoSetting> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return SelectDialog<int>(
|
return SelectDialog<int>(
|
||||||
title: '默认画质',
|
title: '默认画质',
|
||||||
value: defaultVideoQa,
|
value: defaultVideoQa,
|
||||||
values: VideoQuality.values.reversed.map((e) {
|
values: VideoQuality.values.reversed.map((e) {
|
||||||
return {'title': e.description, 'value': e.code};
|
return {'title': e.description, 'value': e.code};
|
||||||
}).toList());
|
}).toList(),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
@@ -161,6 +185,34 @@ class _VideoSettingState extends State<VideoSetting> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
dense: false,
|
||||||
|
title: Text('蜂窝网络画质', style: titleStyle),
|
||||||
|
leading: const Icon(Icons.video_settings_outlined),
|
||||||
|
subtitle: Text(
|
||||||
|
'当前画质:${VideoQualityCode.fromCode(defaultVideoQaCellular)!.description!}',
|
||||||
|
style: subTitleStyle,
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
int? result = await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return SelectDialog<int>(
|
||||||
|
title: '蜂窝网络画质',
|
||||||
|
value: defaultVideoQaCellular,
|
||||||
|
values: VideoQuality.values.reversed.map((e) {
|
||||||
|
return {'title': e.description, 'value': e.code};
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
defaultVideoQaCellular = result;
|
||||||
|
setting.put(SettingBoxKey.defaultVideoQaCellular, result);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
title: Text('默认音质', style: titleStyle),
|
title: Text('默认音质', style: titleStyle),
|
||||||
@@ -174,11 +226,12 @@ class _VideoSettingState extends State<VideoSetting> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return SelectDialog<int>(
|
return SelectDialog<int>(
|
||||||
title: '默认音质',
|
title: '默认音质',
|
||||||
value: defaultAudioQa,
|
value: defaultAudioQa,
|
||||||
values: AudioQuality.values.reversed.map((e) {
|
values: AudioQuality.values.reversed.map((e) {
|
||||||
return {'title': e.description, 'value': e.code};
|
return {'title': e.description, 'value': e.code};
|
||||||
}).toList());
|
}).toList(),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
@@ -188,6 +241,34 @@ class _VideoSettingState extends State<VideoSetting> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
dense: false,
|
||||||
|
title: Text('蜂窝网络音质', style: titleStyle),
|
||||||
|
leading: const Icon(Icons.music_video_outlined),
|
||||||
|
subtitle: Text(
|
||||||
|
'当前音质:${AudioQualityCode.fromCode(defaultAudioQaCellular)!.description!}',
|
||||||
|
style: subTitleStyle,
|
||||||
|
),
|
||||||
|
onTap: () async {
|
||||||
|
int? result = await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return SelectDialog<int>(
|
||||||
|
title: '蜂窝网络音质',
|
||||||
|
value: defaultAudioQaCellular,
|
||||||
|
values: AudioQuality.values.reversed.map((e) {
|
||||||
|
return {'title': e.description, 'value': e.code};
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
defaultAudioQaCellular = result;
|
||||||
|
setting.put(SettingBoxKey.defaultAudioQaCellular, result);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
title: Text('首选解码格式', style: titleStyle),
|
title: Text('首选解码格式', style: titleStyle),
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import 'package:PiliPalaX/pages/video/detail/related/controller.dart';
|
|||||||
import 'package:PiliPalaX/pages/video/detail/reply/controller.dart';
|
import 'package:PiliPalaX/pages/video/detail/reply/controller.dart';
|
||||||
import 'package:PiliPalaX/utils/extension.dart';
|
import 'package:PiliPalaX/utils/extension.dart';
|
||||||
import 'package:canvas_danmaku/models/danmaku_content_item.dart';
|
import 'package:canvas_danmaku/models/danmaku_content_item.dart';
|
||||||
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:floating/floating.dart';
|
import 'package:floating/floating.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -206,7 +207,7 @@ class VideoDetailController extends GetxController
|
|||||||
late PreferredSizeWidget headerControl;
|
late PreferredSizeWidget headerControl;
|
||||||
|
|
||||||
// late bool enableCDN;
|
// late bool enableCDN;
|
||||||
late int? cacheVideoQa;
|
int? cacheVideoQa;
|
||||||
late String cacheDecode;
|
late String cacheDecode;
|
||||||
late String cacheSecondDecode;
|
late String cacheSecondDecode;
|
||||||
late int cacheAudioQa;
|
late int cacheAudioQa;
|
||||||
@@ -303,16 +304,11 @@ class VideoDetailController extends GetxController
|
|||||||
// CDN优化
|
// CDN优化
|
||||||
// enableCDN = setting.get(SettingBoxKey.enableCDN, defaultValue: true);
|
// enableCDN = setting.get(SettingBoxKey.enableCDN, defaultValue: true);
|
||||||
|
|
||||||
// 预设的画质
|
|
||||||
cacheVideoQa = setting.get(SettingBoxKey.defaultVideoQa,
|
|
||||||
defaultValue: VideoQuality.values.last.code);
|
|
||||||
// 预设的解码格式
|
// 预设的解码格式
|
||||||
cacheDecode = setting.get(SettingBoxKey.defaultDecode,
|
cacheDecode = setting.get(SettingBoxKey.defaultDecode,
|
||||||
defaultValue: VideoDecodeFormats.values.last.code);
|
defaultValue: VideoDecodeFormats.values.last.code);
|
||||||
cacheSecondDecode = setting.get(SettingBoxKey.secondDecode,
|
cacheSecondDecode = setting.get(SettingBoxKey.secondDecode,
|
||||||
defaultValue: VideoDecodeFormats.values[1].code);
|
defaultValue: VideoDecodeFormats.values[1].code);
|
||||||
cacheAudioQa = setting.get(SettingBoxKey.defaultAudioQa,
|
|
||||||
defaultValue: AudioQuality.hiRes.code);
|
|
||||||
oid.value = IdUtils.bv2av(Get.parameters['bvid']!);
|
oid.value = IdUtils.bv2av(Get.parameters['bvid']!);
|
||||||
enableSponsorBlock =
|
enableSponsorBlock =
|
||||||
setting.get(SettingBoxKey.enableSponsorBlock, defaultValue: false);
|
setting.get(SettingBoxKey.enableSponsorBlock, defaultValue: false);
|
||||||
@@ -1013,6 +1009,21 @@ class VideoDetailController extends GetxController
|
|||||||
|
|
||||||
// 视频链接
|
// 视频链接
|
||||||
Future queryVideoUrl() async {
|
Future queryVideoUrl() async {
|
||||||
|
if (cacheVideoQa == null) {
|
||||||
|
await Utils.checkConnectivity().then((res) {
|
||||||
|
cacheVideoQa = res == ConnectivityResult.mobile
|
||||||
|
? setting.get(SettingBoxKey.defaultVideoQaCellular,
|
||||||
|
defaultValue: VideoQuality.high1080.code)
|
||||||
|
: setting.get(SettingBoxKey.defaultVideoQa,
|
||||||
|
defaultValue: VideoQuality.values.last.code);
|
||||||
|
|
||||||
|
cacheAudioQa = res == ConnectivityResult.mobile
|
||||||
|
? setting.get(SettingBoxKey.defaultAudioQaCellular,
|
||||||
|
defaultValue: AudioQuality.k192.code)
|
||||||
|
: setting.get(SettingBoxKey.defaultAudioQa,
|
||||||
|
defaultValue: AudioQuality.hiRes.code);
|
||||||
|
});
|
||||||
|
}
|
||||||
var result = await VideoHttp.videoUrl(cid: cid.value, bvid: bvid);
|
var result = await VideoHttp.videoUrl(cid: cid.value, bvid: bvid);
|
||||||
if (result['status']) {
|
if (result['status']) {
|
||||||
data = result['data'];
|
data = result['data'];
|
||||||
|
|||||||
@@ -808,21 +808,21 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
videoFormat[i].quality) {
|
videoFormat[i].quality) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Get.back();
|
||||||
final int quality = videoFormat[i].quality!;
|
final int quality = videoFormat[i].quality!;
|
||||||
widget.videoDetailCtr!.currentVideoQa =
|
widget.videoDetailCtr!.currentVideoQa =
|
||||||
VideoQualityCode.fromCode(quality)!;
|
VideoQualityCode.fromCode(quality)!;
|
||||||
String oldQualityDesc =
|
|
||||||
VideoQualityCode.fromCode(setting.get(
|
|
||||||
SettingBoxKey.defaultVideoQa,
|
|
||||||
defaultValue:
|
|
||||||
VideoQuality.values.last.code))!
|
|
||||||
.description;
|
|
||||||
setting.put(
|
|
||||||
SettingBoxKey.defaultVideoQa, quality);
|
|
||||||
SmartDialog.showToast(
|
|
||||||
"默认画质由:$oldQualityDesc 变为:${VideoQualityCode.fromCode(quality)!.description}");
|
|
||||||
widget.videoDetailCtr!.updatePlayer();
|
widget.videoDetailCtr!.updatePlayer();
|
||||||
Get.back();
|
// String oldQualityDesc =
|
||||||
|
// VideoQualityCode.fromCode(setting.get(
|
||||||
|
// SettingBoxKey.defaultVideoQa,
|
||||||
|
// defaultValue:
|
||||||
|
// VideoQuality.values.last.code))!
|
||||||
|
// .description;
|
||||||
|
// setting.put(
|
||||||
|
// SettingBoxKey.defaultVideoQa, quality);
|
||||||
|
// SmartDialog.showToast(
|
||||||
|
// "默认画质由:$oldQualityDesc 变为:${VideoQualityCode.fromCode(quality)!.description}");
|
||||||
},
|
},
|
||||||
// 可能包含会员解锁画质
|
// 可能包含会员解锁画质
|
||||||
enabled: i >= totalQaSam - userfulQaSam,
|
enabled: i >= totalQaSam - userfulQaSam,
|
||||||
@@ -897,20 +897,20 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
if (currentAudioQa.code == i.id) {
|
if (currentAudioQa.code == i.id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Get.back();
|
||||||
final int quality = i.id!;
|
final int quality = i.id!;
|
||||||
widget.videoDetailCtr!.currentAudioQa =
|
widget.videoDetailCtr!.currentAudioQa =
|
||||||
AudioQualityCode.fromCode(quality)!;
|
AudioQualityCode.fromCode(quality)!;
|
||||||
String oldQualityDesc = AudioQualityCode.fromCode(
|
|
||||||
setting.get(SettingBoxKey.defaultAudioQa,
|
|
||||||
defaultValue:
|
|
||||||
AudioQuality.values.last.code))!
|
|
||||||
.description;
|
|
||||||
setting.put(
|
|
||||||
SettingBoxKey.defaultAudioQa, quality);
|
|
||||||
SmartDialog.showToast(
|
|
||||||
"默认音质由:$oldQualityDesc 变为:${AudioQualityCode.fromCode(quality)!.description}");
|
|
||||||
widget.videoDetailCtr!.updatePlayer();
|
widget.videoDetailCtr!.updatePlayer();
|
||||||
Get.back();
|
// String oldQualityDesc = AudioQualityCode.fromCode(
|
||||||
|
// setting.get(SettingBoxKey.defaultAudioQa,
|
||||||
|
// defaultValue:
|
||||||
|
// AudioQuality.values.last.code))!
|
||||||
|
// .description;
|
||||||
|
// setting.put(
|
||||||
|
// SettingBoxKey.defaultAudioQa, quality);
|
||||||
|
// SmartDialog.showToast(
|
||||||
|
// "默认音质由:$oldQualityDesc 变为:${AudioQualityCode.fromCode(quality)!.description}");
|
||||||
},
|
},
|
||||||
contentPadding:
|
contentPadding:
|
||||||
const EdgeInsets.only(left: 20, right: 20),
|
const EdgeInsets.only(left: 20, right: 20),
|
||||||
@@ -1763,11 +1763,15 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
icon: Stack(
|
icon: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.shield, size: 18),
|
Icon(
|
||||||
|
Icons.shield_outlined,
|
||||||
|
size: 19,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
Icon(
|
Icon(
|
||||||
Icons.play_arrow_rounded,
|
Icons.play_arrow_rounded,
|
||||||
size: 17,
|
size: 13,
|
||||||
color: Colors.black87,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -257,7 +257,9 @@ class SettingBoxKey {
|
|||||||
autoUpgradeEnable = 'autoUpgradeEnable',
|
autoUpgradeEnable = 'autoUpgradeEnable',
|
||||||
feedBackEnable = 'feedBackEnable',
|
feedBackEnable = 'feedBackEnable',
|
||||||
defaultVideoQa = 'defaultVideoQa',
|
defaultVideoQa = 'defaultVideoQa',
|
||||||
|
defaultVideoQaCellular = 'defaultVideoQaCellular',
|
||||||
defaultAudioQa = 'defaultAudioQa',
|
defaultAudioQa = 'defaultAudioQa',
|
||||||
|
defaultAudioQaCellular = 'defaultAudioQaCellular',
|
||||||
autoPlayEnable = 'autoPlayEnable',
|
autoPlayEnable = 'autoPlayEnable',
|
||||||
fullScreenMode = 'fullScreenMode',
|
fullScreenMode = 'fullScreenMode',
|
||||||
defaultDecode = 'defaultDecode',
|
defaultDecode = 'defaultDecode',
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import 'package:PiliPalaX/pages/video/detail/introduction/widgets/group_panel.da
|
|||||||
import 'package:PiliPalaX/utils/feed_back.dart';
|
import 'package:PiliPalaX/utils/feed_back.dart';
|
||||||
import 'package:PiliPalaX/utils/login.dart';
|
import 'package:PiliPalaX/utils/login.dart';
|
||||||
import 'package:PiliPalaX/utils/storage.dart';
|
import 'package:PiliPalaX/utils/storage.dart';
|
||||||
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
import 'package:crypto/crypto.dart';
|
import 'package:crypto/crypto.dart';
|
||||||
import 'package:device_info_plus/device_info_plus.dart';
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -30,9 +31,17 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart' as web;
|
|||||||
import 'package:html/dom.dart' as dom;
|
import 'package:html/dom.dart' as dom;
|
||||||
import 'package:html/parser.dart' as html_parser;
|
import 'package:html/parser.dart' as html_parser;
|
||||||
|
|
||||||
|
extension ConnectivityResultExt on ConnectivityResult {
|
||||||
|
String get title => ['蓝牙', 'Wi-Fi', '局域', '流量', '无', '代理', '其他'][index];
|
||||||
|
}
|
||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
static final Random random = Random();
|
static final Random random = Random();
|
||||||
|
|
||||||
|
static Future<ConnectivityResult> checkConnectivity() async {
|
||||||
|
return (await Connectivity().checkConnectivity()).first;
|
||||||
|
}
|
||||||
|
|
||||||
static Future<dynamic> getWwebid(mid) async {
|
static Future<dynamic> getWwebid(mid) async {
|
||||||
try {
|
try {
|
||||||
dynamic response =
|
dynamic response =
|
||||||
|
|||||||
Reference in New Issue
Block a user