Merge branch 'main' into design
This commit is contained in:
@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:pilipala/common/constants.dart';
|
import 'package:pilipala/common/constants.dart';
|
||||||
@ -98,7 +99,8 @@ class _PagesBottomSheetState extends State<PagesBottomSheet>
|
|||||||
with TickerProviderStateMixin {
|
with TickerProviderStateMixin {
|
||||||
final ScrollController _listScrollController = ScrollController();
|
final ScrollController _listScrollController = ScrollController();
|
||||||
late ListObserverController _listObserverController;
|
late ListObserverController _listObserverController;
|
||||||
final ScrollController _scrollController = ScrollController();
|
late GridObserverController _gridObserverController;
|
||||||
|
final ScrollController _gridScrollController = ScrollController();
|
||||||
late int currentIndex;
|
late int currentIndex;
|
||||||
TabController? tabController;
|
TabController? tabController;
|
||||||
List<ListObserverController>? _listObserverControllerList;
|
List<ListObserverController>? _listObserverControllerList;
|
||||||
@ -163,6 +165,9 @@ class _PagesBottomSheetState extends State<PagesBottomSheet>
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
_gridObserverController =
|
||||||
|
GridObserverController(controller: _gridScrollController);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,18 +190,12 @@ class _PagesBottomSheetState extends State<PagesBottomSheet>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
_gridObserverController.initialIndexModel = ObserverIndexPositionModel(
|
||||||
|
index: currentIndex,
|
||||||
|
isFixedHeight: false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
if (widget.dataType != VideoEpidoesType.videoEpisode) {
|
|
||||||
double itemHeight = (widget.isFullScreen
|
|
||||||
? 400
|
|
||||||
: Get.size.width - 3 * StyleString.safeSpace) /
|
|
||||||
5.2;
|
|
||||||
double offset = ((currentIndex - 1) / 2).ceil() * itemHeight;
|
|
||||||
_scrollController.jumpTo(offset);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取订阅状态
|
// 获取订阅状态
|
||||||
@ -236,7 +235,9 @@ class _PagesBottomSheetState extends State<PagesBottomSheet>
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
try {
|
try {
|
||||||
_listObserverController.controller?.dispose();
|
_listObserverController.controller?.dispose();
|
||||||
|
_gridObserverController.controller?.dispose();
|
||||||
_listScrollController.dispose();
|
_listScrollController.dispose();
|
||||||
|
_gridScrollController.dispose();
|
||||||
for (var element in _listObserverControllerList!) {
|
for (var element in _listObserverControllerList!) {
|
||||||
element.controller?.dispose();
|
element.controller?.dispose();
|
||||||
}
|
}
|
||||||
@ -303,24 +304,27 @@ class _PagesBottomSheetState extends State<PagesBottomSheet>
|
|||||||
: Padding(
|
: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 12.0), // 设置左右间距为12
|
horizontal: 12.0), // 设置左右间距为12
|
||||||
child: GridView.count(
|
child: GridViewObserver(
|
||||||
controller: _scrollController,
|
controller: _gridObserverController,
|
||||||
crossAxisCount: 2,
|
child: GridView.count(
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
controller: _gridScrollController,
|
||||||
childAspectRatio: 2.6,
|
crossAxisCount: 2,
|
||||||
children: List.generate(
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
widget.episodes.length,
|
childAspectRatio: 2.6,
|
||||||
(index) {
|
children: List.generate(
|
||||||
bool isCurrentIndex = currentIndex == index;
|
widget.episodes.length,
|
||||||
return EpisodeGridItem(
|
(index) {
|
||||||
episode: widget.episodes[index],
|
bool isCurrentIndex = currentIndex == index;
|
||||||
index: index,
|
return EpisodeGridItem(
|
||||||
isCurrentIndex: isCurrentIndex,
|
episode: widget.episodes[index],
|
||||||
dataType: widget.dataType,
|
index: index,
|
||||||
changeFucCall: widget.changeFucCall,
|
isCurrentIndex: isCurrentIndex,
|
||||||
isFullScreen: widget.isFullScreen,
|
dataType: widget.dataType,
|
||||||
);
|
changeFucCall: widget.changeFucCall,
|
||||||
},
|
isFullScreen: widget.isFullScreen,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -622,4 +622,8 @@ class Api {
|
|||||||
|
|
||||||
/// 视频标签
|
/// 视频标签
|
||||||
static const String videoTag = '/x/tag/archive/tags';
|
static const String videoTag = '/x/tag/archive/tags';
|
||||||
|
|
||||||
|
/// 修复标题和海报
|
||||||
|
// /api/view?id=${aid} /all/video/av${aid} /video/av${aid}/
|
||||||
|
static const String fixTitleAndPic = '${HttpString.biliplusBaseUrl}/api/view';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:pilipala/models/common/invalid_video.dart';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
@ -50,6 +51,32 @@ class CommonHttp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future fixVideoPicAndTitle({required int aid}) async {
|
||||||
|
var res = await Request().getWithoutCookie(Api.fixTitleAndPic, data: {
|
||||||
|
'id': aid,
|
||||||
|
});
|
||||||
|
if (res != null) {
|
||||||
|
if (res.data['code'] == -404) {
|
||||||
|
return {
|
||||||
|
'status': false,
|
||||||
|
'data': null,
|
||||||
|
'msg': '没有相关信息',
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
'status': true,
|
||||||
|
'data': InvalidVideoModel.fromJson(res.data),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
'status': false,
|
||||||
|
'data': null,
|
||||||
|
'msg': '没有相关信息',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Future buvidActivate() async {
|
static Future buvidActivate() async {
|
||||||
try {
|
try {
|
||||||
// 获取 HTML 数据
|
// 获取 HTML 数据
|
||||||
|
|||||||
@ -8,6 +8,8 @@ class HttpString {
|
|||||||
static const String messageBaseUrl = 'https://message.bilibili.com';
|
static const String messageBaseUrl = 'https://message.bilibili.com';
|
||||||
static const String bangumiBaseUrl = 'https://bili.meark.me';
|
static const String bangumiBaseUrl = 'https://bili.meark.me';
|
||||||
static const String sponsorBlockBaseUrl = 'https://www.bsbsb.top';
|
static const String sponsorBlockBaseUrl = 'https://www.bsbsb.top';
|
||||||
|
static const String biliplusBaseUrl = 'https://www.biliplus.com';
|
||||||
|
|
||||||
static const List<int> validateStatusCodes = [
|
static const List<int> validateStatusCodes = [
|
||||||
302,
|
302,
|
||||||
304,
|
304,
|
||||||
|
|||||||
@ -68,7 +68,7 @@ class Request {
|
|||||||
// 从cookie中获取 csrf token
|
// 从cookie中获取 csrf token
|
||||||
static Future<String> getCsrf() async {
|
static Future<String> getCsrf() async {
|
||||||
List<Cookie> cookies = await cookieManager.cookieJar
|
List<Cookie> cookies = await cookieManager.cookieJar
|
||||||
.loadForRequest(Uri.parse(HttpString.apiBaseUrl));
|
.loadForRequest(Uri.parse(HttpString.baseUrl));
|
||||||
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;
|
||||||
@ -82,9 +82,12 @@ class Request {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final List<Cookie> cookies = await cookieManager.cookieJar
|
final List<Cookie> cookies = await cookieManager.cookieJar
|
||||||
.loadForRequest(Uri.parse(HttpString.baseUrl));
|
.loadForRequest(Uri.parse(HttpString.apiBaseUrl));
|
||||||
buvid = cookies.firstWhere((cookie) => cookie.name == 'buvid3').value;
|
buvid = cookies
|
||||||
if (buvid == null) {
|
.firstWhere((cookie) => cookie.name == 'buvid3',
|
||||||
|
orElse: () => Cookie('buvid3', ''))
|
||||||
|
.value;
|
||||||
|
if (buvid == null || buvid!.isEmpty) {
|
||||||
try {
|
try {
|
||||||
var result = await Request().get(
|
var result = await Request().get(
|
||||||
"${HttpString.apiBaseUrl}/x/frontend/finger/spi",
|
"${HttpString.apiBaseUrl}/x/frontend/finger/spi",
|
||||||
|
|||||||
18
lib/models/common/comment_range_type.dart
Normal file
18
lib/models/common/comment_range_type.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
enum CommentRangeType {
|
||||||
|
video,
|
||||||
|
bangumi,
|
||||||
|
// dynamic,
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ActionTypeExtension on CommentRangeType {
|
||||||
|
String get value => [
|
||||||
|
'video',
|
||||||
|
'bangumi',
|
||||||
|
// 'dynamic',
|
||||||
|
][index];
|
||||||
|
String get label => [
|
||||||
|
'视频',
|
||||||
|
'番剧',
|
||||||
|
// '动态',
|
||||||
|
][index];
|
||||||
|
}
|
||||||
73
lib/models/common/invalid_video.dart
Normal file
73
lib/models/common/invalid_video.dart
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
class InvalidVideoModel {
|
||||||
|
final int? id;
|
||||||
|
final int? ver;
|
||||||
|
final int? aid;
|
||||||
|
final String? lastupdate;
|
||||||
|
final int? lastupdatets;
|
||||||
|
final String? title;
|
||||||
|
final String? description;
|
||||||
|
final String? pic;
|
||||||
|
final int? tid;
|
||||||
|
final String? typename;
|
||||||
|
final int? created;
|
||||||
|
final String? createdAt;
|
||||||
|
final String? author;
|
||||||
|
final int? mid;
|
||||||
|
final String? play;
|
||||||
|
final String? coins;
|
||||||
|
final String? review;
|
||||||
|
final String? videoReview;
|
||||||
|
final String? favorites;
|
||||||
|
final String? tag;
|
||||||
|
final List<String>? tagList;
|
||||||
|
|
||||||
|
InvalidVideoModel({
|
||||||
|
this.id,
|
||||||
|
this.ver,
|
||||||
|
this.aid,
|
||||||
|
this.lastupdate,
|
||||||
|
this.lastupdatets,
|
||||||
|
this.title,
|
||||||
|
this.description,
|
||||||
|
this.pic,
|
||||||
|
this.tid,
|
||||||
|
this.typename,
|
||||||
|
this.created,
|
||||||
|
this.createdAt,
|
||||||
|
this.author,
|
||||||
|
this.mid,
|
||||||
|
this.play,
|
||||||
|
this.coins,
|
||||||
|
this.review,
|
||||||
|
this.videoReview,
|
||||||
|
this.favorites,
|
||||||
|
this.tag,
|
||||||
|
this.tagList,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory InvalidVideoModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return InvalidVideoModel(
|
||||||
|
id: json['id'],
|
||||||
|
ver: json['ver'],
|
||||||
|
aid: json['aid'],
|
||||||
|
lastupdate: json['lastupdate'],
|
||||||
|
lastupdatets: json['lastupdatets'],
|
||||||
|
title: json['title'],
|
||||||
|
description: json['description'],
|
||||||
|
pic: json['pic'],
|
||||||
|
tid: json['tid'],
|
||||||
|
typename: json['typename'],
|
||||||
|
created: json['created'],
|
||||||
|
createdAt: json['created_at'],
|
||||||
|
author: json['author'],
|
||||||
|
mid: json['mid'],
|
||||||
|
play: json['play'],
|
||||||
|
coins: json['coins'],
|
||||||
|
review: json['review'],
|
||||||
|
videoReview: json['video_review'],
|
||||||
|
favorites: json['favorites'],
|
||||||
|
tag: json['tag'],
|
||||||
|
tagList: json['tag'].toString().split(',').toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
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:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/http/common.dart';
|
||||||
import 'package:pilipala/http/user.dart';
|
import 'package:pilipala/http/user.dart';
|
||||||
import 'package:pilipala/http/video.dart';
|
import 'package:pilipala/http/video.dart';
|
||||||
import 'package:pilipala/models/user/fav_detail.dart';
|
import 'package:pilipala/models/user/fav_detail.dart';
|
||||||
@ -8,6 +9,8 @@ import 'package:pilipala/models/user/fav_folder.dart';
|
|||||||
import 'package:pilipala/pages/fav/index.dart';
|
import 'package:pilipala/pages/fav/index.dart';
|
||||||
import 'package:pilipala/utils/utils.dart';
|
import 'package:pilipala/utils/utils.dart';
|
||||||
|
|
||||||
|
import 'widget/invalid_video_card.dart';
|
||||||
|
|
||||||
class FavDetailController extends GetxController {
|
class FavDetailController extends GetxController {
|
||||||
FavFolderItemData? item;
|
FavFolderItemData? item;
|
||||||
RxString title = ''.obs;
|
RxString title = ''.obs;
|
||||||
@ -152,4 +155,22 @@ class FavDetailController extends GetxController {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查看无效视频信息
|
||||||
|
Future toViewInvalidVideo(FavDetailItemData item) async {
|
||||||
|
SmartDialog.showLoading(msg: '加载中...');
|
||||||
|
var res = await CommonHttp.fixVideoPicAndTitle(aid: item.id!);
|
||||||
|
SmartDialog.dismiss();
|
||||||
|
if (res['status']) {
|
||||||
|
showModalBottomSheet(
|
||||||
|
context: Get.context!,
|
||||||
|
isScrollControlled: true,
|
||||||
|
builder: (context) {
|
||||||
|
return InvalidVideoCard(videoInfo: res['data']);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
SmartDialog.showToast(res['msg']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -226,6 +226,8 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
|||||||
isOwner: _favDetailController.isOwner,
|
isOwner: _favDetailController.isOwner,
|
||||||
callFn: () => _favDetailController
|
callFn: () => _favDetailController
|
||||||
.onCancelFav(favList[index].id),
|
.onCancelFav(favList[index].id),
|
||||||
|
viewInvalidVideoCb: () => _favDetailController
|
||||||
|
.toViewInvalidVideo(favList[index]),
|
||||||
);
|
);
|
||||||
}, childCount: favList.length),
|
}, childCount: favList.length),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -19,6 +19,7 @@ class FavVideoCardH extends StatelessWidget {
|
|||||||
final Function? callFn;
|
final Function? callFn;
|
||||||
final int? searchType;
|
final int? searchType;
|
||||||
final String isOwner;
|
final String isOwner;
|
||||||
|
final Function? viewInvalidVideoCb;
|
||||||
|
|
||||||
const FavVideoCardH({
|
const FavVideoCardH({
|
||||||
Key? key,
|
Key? key,
|
||||||
@ -26,6 +27,7 @@ class FavVideoCardH extends StatelessWidget {
|
|||||||
this.callFn,
|
this.callFn,
|
||||||
this.searchType,
|
this.searchType,
|
||||||
required this.isOwner,
|
required this.isOwner,
|
||||||
|
this.viewInvalidVideoCb,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -36,6 +38,10 @@ class FavVideoCardH extends StatelessWidget {
|
|||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
// int? seasonId;
|
// int? seasonId;
|
||||||
|
if (videoItem.title == '已失效视频') {
|
||||||
|
viewInvalidVideoCb?.call();
|
||||||
|
return;
|
||||||
|
}
|
||||||
String? epId;
|
String? epId;
|
||||||
if (videoItem.ogv != null &&
|
if (videoItem.ogv != null &&
|
||||||
(videoItem.ogv['type_name'] == '番剧' ||
|
(videoItem.ogv['type_name'] == '番剧' ||
|
||||||
@ -65,11 +71,17 @@ class FavVideoCardH extends StatelessWidget {
|
|||||||
epId != null ? SearchType.media_bangumi : SearchType.video,
|
epId != null ? SearchType.media_bangumi : SearchType.video,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onLongPress: () => imageSaveDialog(
|
onLongPress: () {
|
||||||
context,
|
if (videoItem.title == '已失效视频') {
|
||||||
videoItem,
|
SmartDialog.showToast('视频已失效');
|
||||||
SmartDialog.dismiss,
|
return;
|
||||||
),
|
}
|
||||||
|
imageSaveDialog(
|
||||||
|
context,
|
||||||
|
videoItem,
|
||||||
|
SmartDialog.dismiss,
|
||||||
|
);
|
||||||
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
|
|||||||
97
lib/pages/fav_detail/widget/invalid_video_card.dart
Normal file
97
lib/pages/fav_detail/widget/invalid_video_card.dart
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:pilipala/common/widgets/network_img_layer.dart';
|
||||||
|
import 'package:pilipala/models/common/invalid_video.dart';
|
||||||
|
|
||||||
|
class InvalidVideoCard extends StatelessWidget {
|
||||||
|
const InvalidVideoCard({required this.videoInfo, Key? key}) : super(key: key);
|
||||||
|
final InvalidVideoModel videoInfo;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
const TextStyle textStyle = TextStyle(fontSize: 14.0);
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(
|
||||||
|
12,
|
||||||
|
14,
|
||||||
|
12,
|
||||||
|
MediaQuery.of(context).padding.bottom + 20,
|
||||||
|
),
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder: (context, constraints) {
|
||||||
|
double maxWidth = constraints.maxWidth;
|
||||||
|
double maxHeight = maxWidth * 9 / 16;
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
NetworkImgLayer(
|
||||||
|
width: maxWidth,
|
||||||
|
height: maxHeight,
|
||||||
|
src: videoInfo.pic,
|
||||||
|
radius: 20,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
SelectableText(
|
||||||
|
videoInfo.title!,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
SelectableText(videoInfo.author!, style: textStyle),
|
||||||
|
const SizedBox(height: 2),
|
||||||
|
SelectableText('创建时间:${videoInfo.createdAt}', style: textStyle),
|
||||||
|
SelectableText('更新时间:${videoInfo.lastupdate}',
|
||||||
|
style: textStyle),
|
||||||
|
SelectableText('分类:${videoInfo.typename}', style: textStyle),
|
||||||
|
SelectableText(
|
||||||
|
'投币:${videoInfo.coins} 收藏:${videoInfo.favorites}',
|
||||||
|
style: textStyle),
|
||||||
|
if (videoInfo.tagList != null &&
|
||||||
|
videoInfo.tagList!.isNotEmpty) ...[
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
_buildTags(context, videoInfo.tagList),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildTags(BuildContext context, List<String>? videoTags) {
|
||||||
|
final ColorScheme colorScheme = Theme.of(context).colorScheme;
|
||||||
|
return Wrap(
|
||||||
|
spacing: 6,
|
||||||
|
runSpacing: 6,
|
||||||
|
direction: Axis.horizontal,
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
children: videoTags!.map((tag) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
Get.toNamed('/searchResult', parameters: {'keyword': tag});
|
||||||
|
},
|
||||||
|
borderRadius: BorderRadius.circular(6),
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colorScheme.surfaceVariant.withOpacity(0.5),
|
||||||
|
borderRadius: BorderRadius.circular(6),
|
||||||
|
),
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 10),
|
||||||
|
child: Text(
|
||||||
|
tag,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -312,25 +312,28 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
// 消息列表
|
// 消息列表
|
||||||
Obx(
|
Visibility(
|
||||||
() => Align(
|
visible: !isLandscape,
|
||||||
alignment: Alignment.bottomCenter,
|
child: Obx(
|
||||||
child: Container(
|
() => Align(
|
||||||
margin: EdgeInsets.only(
|
alignment: Alignment.bottomCenter,
|
||||||
bottom: 90 + padding.bottom,
|
child: Container(
|
||||||
),
|
margin: EdgeInsets.only(
|
||||||
height: Get.size.height -
|
bottom: 90 + padding.bottom,
|
||||||
(padding.top +
|
),
|
||||||
kToolbarHeight +
|
height: Get.size.height -
|
||||||
(_liveRoomController.isPortrait.value
|
(padding.top +
|
||||||
? Get.size.width
|
kToolbarHeight +
|
||||||
: Get.size.width * 9 / 16) +
|
(_liveRoomController.isPortrait.value
|
||||||
100 +
|
? Get.size.width
|
||||||
padding.bottom),
|
: Get.size.width * 9 / 16) +
|
||||||
child: buildMessageListUI(
|
100 +
|
||||||
context,
|
padding.bottom),
|
||||||
_liveRoomController,
|
child: buildMessageListUI(
|
||||||
_scrollController,
|
context,
|
||||||
|
_liveRoomController,
|
||||||
|
_scrollController,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -2,6 +2,7 @@ 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:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:pilipala/models/common/comment_range_type.dart';
|
||||||
import 'package:pilipala/models/common/dynamics_type.dart';
|
import 'package:pilipala/models/common/dynamics_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';
|
||||||
@ -27,6 +28,8 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
late String defaultSystemProxyHost;
|
late String defaultSystemProxyHost;
|
||||||
late String defaultSystemProxyPort;
|
late String defaultSystemProxyPort;
|
||||||
bool userLogin = false;
|
bool userLogin = false;
|
||||||
|
// 记录每个选项是否被选中的状态
|
||||||
|
late List<String> enableComment;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -47,6 +50,8 @@ 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: '');
|
||||||
|
enableComment = setting
|
||||||
|
.get(SettingBoxKey.enableComment, defaultValue: ['video', 'bangumi']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置代理
|
// 设置代理
|
||||||
@ -199,9 +204,94 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
GlobalDataCache.enableDlna = val;
|
GlobalDataCache.enableDlna = val;
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
SetSwitchItem(
|
||||||
|
title: 'Sponsor Block',
|
||||||
|
subTitle: '自动跳过视频中赞助片段',
|
||||||
|
setKey: SettingBoxKey.enableSponsorBlock,
|
||||||
|
defaultVal: false,
|
||||||
|
callFn: (bool val) {
|
||||||
|
GlobalDataCache.enableSponsorBlock = val;
|
||||||
|
},
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
dense: false,
|
dense: false,
|
||||||
title: Text('评论展示', style: titleStyle),
|
title: Text('评论展示', style: titleStyle),
|
||||||
|
onTap: () async {
|
||||||
|
List<String> tempEnableComment = List.from(enableComment);
|
||||||
|
int? result = await showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
// 带多选框的list
|
||||||
|
return StatefulBuilder(
|
||||||
|
builder: (BuildContext context, StateSetter setState) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text('评论展示'),
|
||||||
|
contentPadding: const EdgeInsets.fromLTRB(0, 24, 0, 24),
|
||||||
|
content: SizedBox(
|
||||||
|
width: double.maxFinite,
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: CommentRangeType.values.length,
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return CheckboxListTile(
|
||||||
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 24, vertical: 0),
|
||||||
|
title: Text(
|
||||||
|
'${CommentRangeType.values[index].label}评论'),
|
||||||
|
value: tempEnableComment.contains(
|
||||||
|
CommentRangeType.values[index].value),
|
||||||
|
onChanged: (bool? value) {
|
||||||
|
setState(() {
|
||||||
|
if (value == true) {
|
||||||
|
tempEnableComment.add(
|
||||||
|
CommentRangeType.values[index].value);
|
||||||
|
} else {
|
||||||
|
tempEnableComment.remove(
|
||||||
|
CommentRangeType.values[index].value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: Navigator.of(context).pop,
|
||||||
|
child: Text(
|
||||||
|
'取消',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.outline),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () async {
|
||||||
|
enableComment = tempEnableComment;
|
||||||
|
setting.put(
|
||||||
|
SettingBoxKey.enableComment, enableComment);
|
||||||
|
GlobalDataCache.enableComment = enableComment;
|
||||||
|
SmartDialog.showToast('操作成功');
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: const Text('确认'),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (result != null) {
|
||||||
|
defaultReplySort = result;
|
||||||
|
setting.put(SettingBoxKey.replySortType, result);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
dense: false,
|
||||||
|
title: Text('评论排序', style: titleStyle),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
'当前优先展示「${ReplySortType.values[defaultReplySort].titles}」',
|
'当前优先展示「${ReplySortType.values[defaultReplySort].titles}」',
|
||||||
style: subTitleStyle,
|
style: subTitleStyle,
|
||||||
@ -211,7 +301,7 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return SelectDialog<int>(
|
return SelectDialog<int>(
|
||||||
title: '评论展示',
|
title: '评论排序',
|
||||||
value: defaultReplySort,
|
value: defaultReplySort,
|
||||||
values: ReplySortType.values.map((e) {
|
values: ReplySortType.values.map((e) {
|
||||||
return {'title': e.titles, 'value': e.index};
|
return {'title': e.titles, 'value': e.index};
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import 'package:pilipala/models/video/play/url.dart';
|
|||||||
import 'package:pilipala/models/video/reply/item.dart';
|
import 'package:pilipala/models/video/reply/item.dart';
|
||||||
import 'package:pilipala/pages/video/detail/reply_reply/index.dart';
|
import 'package:pilipala/pages/video/detail/reply_reply/index.dart';
|
||||||
import 'package:pilipala/plugin/pl_player/index.dart';
|
import 'package:pilipala/plugin/pl_player/index.dart';
|
||||||
|
import 'package:pilipala/utils/global_data_cache.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
import 'package:pilipala/utils/utils.dart';
|
import 'package:pilipala/utils/utils.dart';
|
||||||
import 'package:pilipala/utils/video_utils.dart';
|
import 'package:pilipala/utils/video_utils.dart';
|
||||||
@ -140,8 +141,16 @@ class VideoDetailController extends GetxController
|
|||||||
} else if (argMap.containsKey('pic')) {
|
} else if (argMap.containsKey('pic')) {
|
||||||
updateCover(argMap['pic']);
|
updateCover(argMap['pic']);
|
||||||
}
|
}
|
||||||
|
tabs.value = <String>[
|
||||||
tabCtr = TabController(length: 2, vsync: this);
|
'简介',
|
||||||
|
if (videoType == SearchType.video &&
|
||||||
|
GlobalDataCache.enableComment.contains('video'))
|
||||||
|
'评论',
|
||||||
|
if (videoType == SearchType.media_bangumi &&
|
||||||
|
GlobalDataCache.enableComment.contains('bangumi'))
|
||||||
|
'评论'
|
||||||
|
];
|
||||||
|
tabCtr = TabController(length: tabs.length, vsync: this);
|
||||||
autoPlay.value =
|
autoPlay.value =
|
||||||
setting.get(SettingBoxKey.autoPlayEnable, defaultValue: true);
|
setting.get(SettingBoxKey.autoPlayEnable, defaultValue: true);
|
||||||
enableHA.value = setting.get(SettingBoxKey.enableHA, defaultValue: false);
|
enableHA.value = setting.get(SettingBoxKey.enableHA, defaultValue: false);
|
||||||
@ -198,7 +207,7 @@ class VideoDetailController extends GetxController
|
|||||||
});
|
});
|
||||||
|
|
||||||
/// 仅投稿视频skip
|
/// 仅投稿视频skip
|
||||||
if (videoType == SearchType.video) {
|
if (videoType == SearchType.video && GlobalDataCache.enableSponsorBlock) {
|
||||||
querySkipSegments();
|
querySkipSegments();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import 'package:pilipala/pages/video/detail/controller.dart';
|
|||||||
import 'package:pilipala/pages/video/detail/reply/index.dart';
|
import 'package:pilipala/pages/video/detail/reply/index.dart';
|
||||||
import 'package:pilipala/plugin/pl_player/models/play_repeat.dart';
|
import 'package:pilipala/plugin/pl_player/models/play_repeat.dart';
|
||||||
import 'package:pilipala/utils/feed_back.dart';
|
import 'package:pilipala/utils/feed_back.dart';
|
||||||
|
import 'package:pilipala/utils/global_data_cache.dart';
|
||||||
import 'package:pilipala/utils/id_utils.dart';
|
import 'package:pilipala/utils/id_utils.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
@ -87,19 +88,22 @@ class VideoIntroController extends GetxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取视频简介&分p
|
// 获取视频简介&分p
|
||||||
Future queryVideoIntro({cover}) async {
|
Future queryVideoIntro({String? cover, String? type, int? cid}) async {
|
||||||
var result = await VideoHttp.videoIntro(bvid: bvid);
|
var result = await VideoHttp.videoIntro(bvid: bvid);
|
||||||
if (result['status']) {
|
if (result['status']) {
|
||||||
videoDetail.value = result['data']!;
|
videoDetail.value = result['data']!;
|
||||||
ugcSeason = result['data']!.ugcSeason;
|
ugcSeason = result['data']!.ugcSeason;
|
||||||
pages.value = result['data']!.pages!;
|
pages.value = result['data']!.pages!;
|
||||||
lastPlayCid.value = videoDetail.value.cid!;
|
if (type == null) {
|
||||||
if (pages.isNotEmpty) {
|
lastPlayCid.value = cid ?? videoDetail.value.cid!;
|
||||||
lastPlayCid.value = pages.first.cid!;
|
|
||||||
}
|
}
|
||||||
final VideoDetailController videoDetailCtr =
|
final VideoDetailController videoDetailCtr =
|
||||||
Get.find<VideoDetailController>(tag: heroTag);
|
Get.find<VideoDetailController>(tag: heroTag);
|
||||||
videoDetailCtr.tabs.value = ['简介', '评论 ${result['data']?.stat?.reply}'];
|
videoDetailCtr.tabs.value = [
|
||||||
|
'简介',
|
||||||
|
if (GlobalDataCache.enableComment.contains('video'))
|
||||||
|
'评论 ${result['data']?.stat?.reply}'
|
||||||
|
];
|
||||||
videoDetailCtr.cover.value = cover ?? result['data'].pic ?? '';
|
videoDetailCtr.cover.value = cover ?? result['data'].pic ?? '';
|
||||||
// 获取到粉丝数再返回
|
// 获取到粉丝数再返回
|
||||||
await queryUserStat();
|
await queryUserStat();
|
||||||
@ -469,13 +473,16 @@ class VideoIntroController extends GetxController {
|
|||||||
// 重新请求评论
|
// 重新请求评论
|
||||||
try {
|
try {
|
||||||
/// 未渲染回复组件时可能异常
|
/// 未渲染回复组件时可能异常
|
||||||
final VideoReplyController videoReplyCtr =
|
if (GlobalDataCache.enableComment.contains('video')) {
|
||||||
Get.find<VideoReplyController>(tag: heroTag);
|
final VideoReplyController videoReplyCtr =
|
||||||
videoReplyCtr.aid = aid;
|
Get.find<VideoReplyController>(tag: heroTag);
|
||||||
videoReplyCtr.queryReplyList(type: 'init');
|
videoReplyCtr.aid = aid;
|
||||||
|
videoReplyCtr.queryReplyList(type: 'init');
|
||||||
|
}
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
this.bvid = bvid;
|
this.bvid = bvid;
|
||||||
await queryVideoIntro(cover: cover);
|
// 点击切换时,优先取当前cid
|
||||||
|
await queryVideoIntro(cover: cover, cid: cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startTimer() {
|
void startTimer() {
|
||||||
|
|||||||
@ -57,7 +57,7 @@ class _VideoIntroPanelState extends State<VideoIntroPanel>
|
|||||||
heroTag = Get.arguments['heroTag'];
|
heroTag = Get.arguments['heroTag'];
|
||||||
videoIntroController =
|
videoIntroController =
|
||||||
Get.put(VideoIntroController(bvid: widget.bvid), tag: heroTag);
|
Get.put(VideoIntroController(bvid: widget.bvid), tag: heroTag);
|
||||||
_futureBuilderFuture = videoIntroController.queryVideoIntro();
|
_futureBuilderFuture = videoIntroController.queryVideoIntro(type: 'init');
|
||||||
videoIntroController.videoDetail.listen((value) {
|
videoIntroController.videoDetail.listen((value) {
|
||||||
videoDetail = value;
|
videoDetail = value;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -27,7 +27,7 @@ class SeasonPanel extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _SeasonPanelState extends State<SeasonPanel> {
|
class _SeasonPanelState extends State<SeasonPanel> {
|
||||||
late List<EpisodeItem> episodes;
|
List<EpisodeItem>? episodes;
|
||||||
late int cid;
|
late int cid;
|
||||||
late RxInt currentIndex = (-1).obs;
|
late RxInt currentIndex = (-1).obs;
|
||||||
final String heroTag = Get.arguments['heroTag'];
|
final String heroTag = Get.arguments['heroTag'];
|
||||||
@ -75,7 +75,10 @@ class _SeasonPanelState extends State<SeasonPanel> {
|
|||||||
|
|
||||||
// 获取currentIndex
|
// 获取currentIndex
|
||||||
void getCurrentIndex() {
|
void getCurrentIndex() {
|
||||||
currentIndex.value = episodes.indexWhere((EpisodeItem e) => e.cid == cid);
|
if (episodes != null) {
|
||||||
|
currentIndex.value =
|
||||||
|
episodes!.indexWhere((EpisodeItem e) => e.cid == cid);
|
||||||
|
}
|
||||||
final List<SectionItem> sections = widget.ugcSeason.sections!;
|
final List<SectionItem> sections = widget.ugcSeason.sections!;
|
||||||
if (sections.length == 1 && sections.first.type == 1) {
|
if (sections.length == 1 && sections.first.type == 1) {
|
||||||
final List<EpisodeItem> episodesList = sections.first.episodes!;
|
final List<EpisodeItem> episodesList = sections.first.episodes!;
|
||||||
@ -83,6 +86,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
|
|||||||
for (int j = 0; j < episodesList[i].pages!.length; j++) {
|
for (int j = 0; j < episodesList[i].pages!.length; j++) {
|
||||||
if (episodesList[i].pages![j].cid == cid) {
|
if (episodesList[i].pages![j].cid == cid) {
|
||||||
currentIndex.value = i;
|
currentIndex.value = i;
|
||||||
|
episodes = episodesList;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +141,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
|
|||||||
widget.videoIntroCtr.bottomSheetController =
|
widget.videoIntroCtr.bottomSheetController =
|
||||||
_bottomSheetController = EpisodeBottomSheet(
|
_bottomSheetController = EpisodeBottomSheet(
|
||||||
currentCid: cid,
|
currentCid: cid,
|
||||||
episodes: episodes,
|
episodes: episodes!,
|
||||||
changeFucCall: changeFucCall,
|
changeFucCall: changeFucCall,
|
||||||
sheetHeight: widget.sheetHeight,
|
sheetHeight: widget.sheetHeight,
|
||||||
dataType: VideoEpidoesType.videoEpisode,
|
dataType: VideoEpidoesType.videoEpisode,
|
||||||
@ -165,7 +169,7 @@ class _SeasonPanelState extends State<SeasonPanel> {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Obx(() => Text(
|
Obx(() => Text(
|
||||||
'${currentIndex.value + 1}/${episodes.length}',
|
'${currentIndex.value + 1}/${episodes!.length}',
|
||||||
style: Theme.of(context).textTheme.labelMedium,
|
style: Theme.of(context).textTheme.labelMedium,
|
||||||
)),
|
)),
|
||||||
const SizedBox(width: 6),
|
const SizedBox(width: 6),
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import 'package:pilipala/pages/video/detail/related/index.dart';
|
|||||||
import 'package:pilipala/plugin/pl_player/index.dart';
|
import 'package:pilipala/plugin/pl_player/index.dart';
|
||||||
import 'package:pilipala/plugin/pl_player/models/play_repeat.dart';
|
import 'package:pilipala/plugin/pl_player/models/play_repeat.dart';
|
||||||
import 'package:pilipala/services/service_locator.dart';
|
import 'package:pilipala/services/service_locator.dart';
|
||||||
|
import 'package:pilipala/utils/global_data_cache.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
import 'package:status_bar_control/status_bar_control.dart';
|
import 'package:status_bar_control/status_bar_control.dart';
|
||||||
|
|
||||||
@ -779,13 +780,20 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Obx(
|
if ((vdCtr.videoType == SearchType.media_bangumi &&
|
||||||
() => VideoReplyPanel(
|
GlobalDataCache.enableComment
|
||||||
bvid: vdCtr.bvid,
|
.contains('bangumi')) ||
|
||||||
oid: vdCtr.oid.value,
|
(vdCtr.videoType == SearchType.video &&
|
||||||
onControllerCreated: vdCtr.onControllerCreated,
|
GlobalDataCache.enableComment
|
||||||
),
|
.contains('video'))) ...[
|
||||||
)
|
Obx(
|
||||||
|
() => VideoReplyPanel(
|
||||||
|
bvid: vdCtr.bvid,
|
||||||
|
oid: vdCtr.oid.value,
|
||||||
|
onControllerCreated: vdCtr.onControllerCreated,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import 'package:pilipala/plugin/pl_player/models/play_speed.dart';
|
|||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
import '../models/common/index.dart';
|
import '../models/common/index.dart';
|
||||||
|
|
||||||
Box setting = GStorage.setting;
|
Box settingBox = GStorage.setting;
|
||||||
Box localCache = GStorage.localCache;
|
Box localCache = GStorage.localCache;
|
||||||
Box videoStorage = GStorage.video;
|
Box videoStorage = GStorage.video;
|
||||||
Box userInfoCache = GStorage.userInfo;
|
Box userInfoCache = GStorage.userInfo;
|
||||||
@ -58,6 +58,10 @@ class GlobalDataCache {
|
|||||||
static bool enableDlna = false;
|
static bool enableDlna = false;
|
||||||
// 硬件解码格式
|
// 硬件解码格式
|
||||||
static late String hardwareDecodeFormat;
|
static late String hardwareDecodeFormat;
|
||||||
|
// sponsorBlock开关
|
||||||
|
static bool enableSponsorBlock = false;
|
||||||
|
// 视频评论开关
|
||||||
|
static List<String> enableComment = ['video', 'bangumi'];
|
||||||
|
|
||||||
// 私有构造函数
|
// 私有构造函数
|
||||||
GlobalDataCache._();
|
GlobalDataCache._();
|
||||||
@ -70,18 +74,18 @@ class GlobalDataCache {
|
|||||||
|
|
||||||
// 异步初始化方法
|
// 异步初始化方法
|
||||||
static Future<void> initialize() async {
|
static Future<void> initialize() async {
|
||||||
imgQuality = await setting.get(SettingBoxKey.defaultPicQa,
|
imgQuality = await settingBox.get(SettingBoxKey.defaultPicQa,
|
||||||
defaultValue: 10); // 设置全局变量
|
defaultValue: 10); // 设置全局变量
|
||||||
fullScreenGestureMode = FullScreenGestureMode.values[setting.get(
|
fullScreenGestureMode = FullScreenGestureMode.values[settingBox.get(
|
||||||
SettingBoxKey.fullScreenGestureMode,
|
SettingBoxKey.fullScreenGestureMode,
|
||||||
defaultValue: FullScreenGestureMode.fromBottomtoTop.index)];
|
defaultValue: FullScreenGestureMode.fromBottomtoTop.index)];
|
||||||
enablePlayerControlAnimation = setting
|
enablePlayerControlAnimation = settingBox
|
||||||
.get(SettingBoxKey.enablePlayerControlAnimation, defaultValue: true);
|
.get(SettingBoxKey.enablePlayerControlAnimation, defaultValue: true);
|
||||||
actionTypeSort = await setting.get(SettingBoxKey.actionTypeSort,
|
actionTypeSort = await settingBox.get(SettingBoxKey.actionTypeSort,
|
||||||
defaultValue: ['like', 'coin', 'collect', 'watchLater', 'share']);
|
defaultValue: ['like', 'coin', 'collect', 'watchLater', 'share']);
|
||||||
|
|
||||||
isOpenDanmu =
|
isOpenDanmu = await settingBox.get(SettingBoxKey.enableShowDanmaku,
|
||||||
await setting.get(SettingBoxKey.enableShowDanmaku, defaultValue: false);
|
defaultValue: false);
|
||||||
blockTypes =
|
blockTypes =
|
||||||
await localCache.get(LocalCacheKey.danmakuBlockType, defaultValue: []);
|
await localCache.get(LocalCacheKey.danmakuBlockType, defaultValue: []);
|
||||||
showArea =
|
showArea =
|
||||||
@ -102,7 +106,7 @@ class GlobalDataCache {
|
|||||||
.firstWhere((e) => e.value == defaultPlayRepeat);
|
.firstWhere((e) => e.value == defaultPlayRepeat);
|
||||||
playbackSpeed =
|
playbackSpeed =
|
||||||
await videoStorage.get(VideoBoxKey.playSpeedDefault, defaultValue: 1.0);
|
await videoStorage.get(VideoBoxKey.playSpeedDefault, defaultValue: 1.0);
|
||||||
enableAutoLongPressSpeed = await setting
|
enableAutoLongPressSpeed = await settingBox
|
||||||
.get(SettingBoxKey.enableAutoLongPressSpeed, defaultValue: false);
|
.get(SettingBoxKey.enableAutoLongPressSpeed, defaultValue: false);
|
||||||
if (!enableAutoLongPressSpeed) {
|
if (!enableAutoLongPressSpeed) {
|
||||||
longPressSpeed = await videoStorage.get(VideoBoxKey.longPressSpeedDefault,
|
longPressSpeed = await videoStorage.get(VideoBoxKey.longPressSpeedDefault,
|
||||||
@ -120,13 +124,21 @@ class GlobalDataCache {
|
|||||||
sheetHeight = localCache.get('sheetHeight', defaultValue: 0.0);
|
sheetHeight = localCache.get('sheetHeight', defaultValue: 0.0);
|
||||||
historyCacheList = localCache.get('cacheList', defaultValue: []);
|
historyCacheList = localCache.get('cacheList', defaultValue: []);
|
||||||
enableSearchSuggest =
|
enableSearchSuggest =
|
||||||
setting.get(SettingBoxKey.enableSearchSuggest, defaultValue: true);
|
settingBox.get(SettingBoxKey.enableSearchSuggest, defaultValue: true);
|
||||||
enableAutoExpand =
|
enableAutoExpand =
|
||||||
setting.get(SettingBoxKey.enableAutoExpand, defaultValue: false);
|
settingBox.get(SettingBoxKey.enableAutoExpand, defaultValue: false);
|
||||||
enableDynamicSwitch =
|
enableDynamicSwitch =
|
||||||
setting.get(SettingBoxKey.enableDynamicSwitch, defaultValue: true);
|
settingBox.get(SettingBoxKey.enableDynamicSwitch, defaultValue: true);
|
||||||
enableDlna = setting.get(SettingBoxKey.enableDlna, defaultValue: false);
|
enableDlna = settingBox.get(SettingBoxKey.enableDlna, defaultValue: false);
|
||||||
hardwareDecodeFormat = setting.get(SettingBoxKey.hardwareDecodeFormat,
|
hardwareDecodeFormat = settingBox.get(SettingBoxKey.hardwareDecodeFormat,
|
||||||
defaultValue: Platform.isAndroid ? 'auto-safe' : 'auto');
|
defaultValue: Platform.isAndroid ? 'auto-safe' : 'auto');
|
||||||
|
settingBox.get(SettingBoxKey.enableDynamicSwitch, defaultValue: true);
|
||||||
|
enableDlna = settingBox.get(SettingBoxKey.enableDlna, defaultValue: false);
|
||||||
|
enableSponsorBlock =
|
||||||
|
settingBox.get(SettingBoxKey.enableSponsorBlock, defaultValue: false);
|
||||||
|
settingBox.get(SettingBoxKey.enableDynamicSwitch, defaultValue: true);
|
||||||
|
enableDlna = settingBox.get(SettingBoxKey.enableDlna, defaultValue: false);
|
||||||
|
enableComment = settingBox
|
||||||
|
.get(SettingBoxKey.enableComment, defaultValue: ['video', 'bangumi']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -117,7 +117,9 @@ class SettingBoxKey {
|
|||||||
defaultHomePage = 'defaultHomePage',
|
defaultHomePage = 'defaultHomePage',
|
||||||
enableRelatedVideo = 'enableRelatedVideo',
|
enableRelatedVideo = 'enableRelatedVideo',
|
||||||
enableDlna = 'enableDlna',
|
enableDlna = 'enableDlna',
|
||||||
hardwareDecodeFormat = 'hardwareDecodeFormat';
|
hardwareDecodeFormat = 'hardwareDecodeFormat',
|
||||||
|
enableSponsorBlock = 'enableSponsorBlock',
|
||||||
|
enableComment = 'enableComment';
|
||||||
|
|
||||||
/// 外观
|
/// 外观
|
||||||
static const String themeMode = 'themeMode',
|
static const String themeMode = 'themeMode',
|
||||||
|
|||||||
Reference in New Issue
Block a user