Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-07-31 17:33:36 +08:00
parent edc9a1ca7b
commit f7d4db6aad
21 changed files with 220 additions and 458 deletions

View File

@@ -55,7 +55,7 @@ class InteractiveviewerGallery<T> extends StatefulWidget {
final int quality;
final ValueChanged? onClose;
final ValueChanged<bool>? onClose;
final bool? setStatusBar;

View File

@@ -141,7 +141,7 @@ class MyApp extends StatelessWidget {
// 强制设置高帧率
if (Platform.isAndroid) {
late List modes;
late List<DisplayMode> modes;
FlutterDisplayMode.supported.then((value) {
modes = value;
var storageDisplay = GStorage.setting.get(SettingBoxKey.displayMode);

View File

@@ -239,14 +239,14 @@ class FormatItem {
String? format;
String? newDesc;
String? displayDesc;
List? codecs;
List<String>? codecs;
FormatItem.fromJson(Map<String, dynamic> json) {
quality = json['quality'];
format = json['format'];
newDesc = json['new_description'];
displayDesc = json['display_desc'];
codecs = json['codecs'];
codecs = (json['codecs'] as List?)?.cast<String>();
}
}

View File

@@ -1,11 +0,0 @@
class Freya {
int? bubbleShowCnt;
int? iconShow;
Freya({this.bubbleShowCnt, this.iconShow});
factory Freya.fromJson(Map<String, dynamic> json) => Freya(
bubbleShowCnt: json['bubble_show_cnt'] as int?,
iconShow: json['icon_show'] as int?,
);
}

View File

@@ -1,26 +0,0 @@
class PayType {
int? allowDiscount;
int? allowPack;
int? allowTicket;
int? allowTimeLimit;
int? allowVipDiscount;
int? forbidBb;
PayType({
this.allowDiscount,
this.allowPack,
this.allowTicket,
this.allowTimeLimit,
this.allowVipDiscount,
this.forbidBb,
});
factory PayType.fromJson(Map<String, dynamic> json) => PayType(
allowDiscount: json['allow_discount'] as int?,
allowPack: json['allow_pack'] as int?,
allowTicket: json['allow_ticket'] as int?,
allowTimeLimit: json['allow_time_limit'] as int?,
allowVipDiscount: json['allow_vip_discount'] as int?,
forbidBb: json['forbid_bb'] as int?,
);
}

View File

@@ -1,42 +0,0 @@
import 'package:PiliPlus/models_new/pgc/pgc_info_model/pay_type.dart';
class Payment {
int? discount;
PayType? payType;
String? price;
String? promotion;
String? tip;
int? viewStartTime;
int? vipDiscount;
String? vipFirstPromotion;
String? vipPrice;
String? vipPromotion;
Payment({
this.discount,
this.payType,
this.price,
this.promotion,
this.tip,
this.viewStartTime,
this.vipDiscount,
this.vipFirstPromotion,
this.vipPrice,
this.vipPromotion,
});
factory Payment.fromJson(Map<String, dynamic> json) => Payment(
discount: json['discount'] as int?,
payType: json['pay_type'] == null
? null
: PayType.fromJson(json['pay_type'] as Map<String, dynamic>),
price: json['price'] as String?,
promotion: json['promotion'] as String?,
tip: json['tip'] as String?,
viewStartTime: json['view_start_time'] as int?,
vipDiscount: json['vip_discount'] as int?,
vipFirstPromotion: json['vip_first_promotion'] as String?,
vipPrice: json['vip_price'] as String?,
vipPromotion: json['vip_promotion'] as String?,
);
}

View File

@@ -1,9 +0,0 @@
class PlayStrategy {
List? strategies;
PlayStrategy({this.strategies});
factory PlayStrategy.fromJson(Map<String, dynamic> json) => PlayStrategy(
strategies: json['strategies'],
);
}

View File

@@ -1,11 +0,0 @@
class Positive {
int? id;
String? title;
Positive({this.id, this.title});
factory Positive.fromJson(Map<String, dynamic> json) => Positive(
id: json['id'] as int?,
title: json['title'] as String?,
);
}

View File

@@ -1,19 +1,14 @@
import 'package:PiliPlus/models_new/pgc/pgc_info_model/activity.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/area.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/episode.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/freya.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/icon_font.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/new_ep.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/payment.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/play_strategy.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/positive.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/publish.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/rating.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/rights.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/season.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/section.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/series.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/show.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/stat.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/up_info.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/user_status.dart';
@@ -25,11 +20,9 @@ class PgcInfoModel {
List<Area>? areas;
String? bkgCover;
String? cover;
bool? deliveryFragmentVideo;
bool? enableVt;
List<EpisodeItem>? episodes;
String? evaluate;
Freya? freya;
int? hideEpVvVtDm;
IconFont? iconFont;
String? jpTitle;
@@ -37,9 +30,6 @@ class PgcInfoModel {
int? mediaId;
int? mode;
NewEp? newEp;
Payment? payment;
PlayStrategy? playStrategy;
Positive? positive;
Publish? publish;
Rating? rating;
String? record;
@@ -52,13 +42,11 @@ class PgcInfoModel {
String? shareCopy;
String? shareSubTitle;
String? shareUrl;
Show? show;
int? showSeasonType;
String? squareCover;
String? staff;
PgcStat? stat;
int? status;
List? styles;
String? subtitle;
String? title;
int? total;
@@ -73,11 +61,9 @@ class PgcInfoModel {
this.areas,
this.bkgCover,
this.cover,
this.deliveryFragmentVideo,
this.enableVt,
this.episodes,
this.evaluate,
this.freya,
this.hideEpVvVtDm,
this.iconFont,
this.jpTitle,
@@ -85,9 +71,6 @@ class PgcInfoModel {
this.mediaId,
this.mode,
this.newEp,
this.payment,
this.playStrategy,
this.positive,
this.publish,
this.rating,
this.record,
@@ -100,13 +83,11 @@ class PgcInfoModel {
this.shareCopy,
this.shareSubTitle,
this.shareUrl,
this.show,
this.showSeasonType,
this.squareCover,
this.staff,
this.stat,
this.status,
this.styles,
this.subtitle,
this.title,
this.total,
@@ -126,15 +107,11 @@ class PgcInfoModel {
.toList(),
bkgCover: json['bkg_cover'] as String?,
cover: json['cover'] as String?,
deliveryFragmentVideo: json['delivery_fragment_video'] as bool?,
enableVt: json['enable_vt'] as bool?,
episodes: (json['episodes'] as List<dynamic>?)
?.map((e) => EpisodeItem.fromJson(e as Map<String, dynamic>))
.toList(),
evaluate: json['evaluate'] as String?,
freya: json['freya'] == null
? null
: Freya.fromJson(json['freya'] as Map<String, dynamic>),
hideEpVvVtDm: json['hide_ep_vv_vt_dm'] as int?,
iconFont: json['icon_font'] == null
? null
@@ -146,15 +123,6 @@ class PgcInfoModel {
newEp: json['new_ep'] == null
? null
: NewEp.fromJson(json['new_ep'] as Map<String, dynamic>),
payment: json['payment'] == null
? null
: Payment.fromJson(json['payment'] as Map<String, dynamic>),
playStrategy: json['play_strategy'] == null
? null
: PlayStrategy.fromJson(json['play_strategy'] as Map<String, dynamic>),
positive: json['positive'] == null
? null
: Positive.fromJson(json['positive'] as Map<String, dynamic>),
publish: json['publish'] == null
? null
: Publish.fromJson(json['publish'] as Map<String, dynamic>),
@@ -179,9 +147,6 @@ class PgcInfoModel {
shareCopy: json['share_copy'] as String?,
shareSubTitle: json['share_sub_title'] as String?,
shareUrl: json['share_url'] as String?,
show: json['show'] == null
? null
: Show.fromJson(json['show'] as Map<String, dynamic>),
showSeasonType: json['show_season_type'] as int?,
squareCover: json['square_cover'] as String?,
staff: json['staff'] as String?,
@@ -189,7 +154,6 @@ class PgcInfoModel {
? null
: PgcStat.fromJson(json['stat'] as Map<String, dynamic>),
status: json['status'] as int?,
styles: json['styles'],
subtitle: json['subtitle'] as String?,
title: json['title'] as String?,
total: json['total'] as int?,

View File

@@ -1,9 +0,0 @@
class Show {
int? wideScreen;
Show({this.wideScreen});
factory Show.fromJson(Map<String, dynamic> json) => Show(
wideScreen: json['wide_screen'] as int?,
);
}

View File

@@ -56,58 +56,18 @@ class _ArticlePageState extends State<ArticlePage>
tag: Utils.generateRandomString(8),
);
bool _isFabVisible = true;
bool? _imageStatus;
late final AnimationController fabAnimationCtr;
late final Animation<Offset> _anim;
late final List<double> _ratio = Pref.dynamicDetailRatio;
bool get _horizontalPreview =>
context.orientation == Orientation.landscape &&
_articleCtr.horizontalPreview;
_articleCtr.horizontalPreview &&
context.orientation == Orientation.landscape;
late final _key = GlobalKey<ScaffoldState>();
Function(dynamic imgList, dynamic index)? get _getImageCallback =>
_horizontalPreview
? (imgList, index) {
_imageStatus = true;
bool isFabVisible = _isFabVisible;
if (isFabVisible) {
_hideFab();
}
final ctr = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 200),
)..forward();
PageUtils.onHorizontalPreview(
_key,
AnimationController(
vsync: this,
duration: Duration.zero,
),
ctr,
imgList,
index,
(value) async {
_imageStatus = null;
if (isFabVisible) {
isFabVisible = false;
_showFab();
}
if (value == false) {
await ctr.reverse();
}
try {
ctr.dispose();
} catch (_) {}
if (value == false) {
Get.back();
}
},
);
}
: null;
late Function(dynamic imgList, dynamic index)? _imageCallback;
@override
void initState() {
@@ -182,14 +142,21 @@ class _ArticlePageState extends State<ArticlePage>
EasyThrottle.throttle('replyReply', const Duration(milliseconds: 500), () {
int oid = replyItem.oid.toInt();
int rpid = replyItem.id.toInt();
Widget replyReplyPage({
bool automaticallyImplyLeading = true,
VoidCallback? onDispose,
}) => Scaffold(
Widget replyReplyPage({bool showBackBtn = true}) => Scaffold(
appBar: AppBar(
toolbarHeight: showBackBtn ? null : 45,
title: const Text('评论详情'),
titleSpacing: automaticallyImplyLeading ? null : 12,
automaticallyImplyLeading: automaticallyImplyLeading,
titleSpacing: showBackBtn ? null : 12,
automaticallyImplyLeading: showBackBtn,
actions: showBackBtn
? null
: [
IconButton(
tooltip: '关闭',
icon: const Icon(Icons.close, size: 20),
onPressed: Get.back,
),
],
),
body: SafeArea(
top: false,
@@ -202,7 +169,6 @@ class _ArticlePageState extends State<ArticlePage>
isVideoDetail: false,
replyType: _articleCtr.commentType,
firstFloor: replyItem,
onDispose: onDispose,
),
),
);
@@ -226,14 +192,7 @@ class _ArticlePageState extends State<ArticlePage>
(context) => MediaQuery.removePadding(
context: context,
removeLeft: true,
child: replyReplyPage(
automaticallyImplyLeading: false,
onDispose: () {
if (isFabVisible && _imageStatus != true) {
_showFab();
}
},
),
child: replyReplyPage(showBackBtn: false),
),
);
} else {
@@ -252,6 +211,17 @@ class _ArticlePageState extends State<ArticlePage>
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
_imageCallback = _horizontalPreview
? (imgList, index) {
_hideFab();
PageUtils.onHorizontalPreview(
_key,
this,
imgList,
index,
);
}
: null;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar,
@@ -386,7 +356,7 @@ class _ArticlePageState extends State<ArticlePage>
if (kDebugMode) debugPrint('json page');
content = OpusContent(
opus: _articleCtr.opus!,
callback: _getImageCallback,
callback: _imageCallback,
maxWidth: maxWidth,
);
} else if (_articleCtr.opusData?.modules.moduleBlocked != null) {
@@ -408,7 +378,7 @@ class _ArticlePageState extends State<ArticlePage>
context: context,
html: _articleCtr.articleData!.content!,
maxWidth: maxWidth,
callback: _getImageCallback,
callback: _imageCallback,
),
);
} else {
@@ -419,7 +389,7 @@ class _ArticlePageState extends State<ArticlePage>
context: context,
element: res.body!.children[index],
maxWidth: maxWidth,
callback: _getImageCallback,
callback: _imageCallback,
);
},
separatorBuilder: (context, index) =>
@@ -655,7 +625,7 @@ class _ArticlePageState extends State<ArticlePage>
onDelete: (item, subIndex) =>
_articleCtr.onRemove(index, item, subIndex),
upMid: _articleCtr.upMid,
callback: _getImageCallback,
callback: _imageCallback,
onCheckReply: (item) =>
_articleCtr.onCheckReply(item, isManual: true),
onToggleTop: (item) => _articleCtr.onToggleTop(

View File

@@ -35,7 +35,7 @@ class DynamicsController extends GetxController
late int _upPage = 1;
late bool _upEnd = false;
List<UpItem>? _cacheUpList;
late final showAllUp = Pref.dynamicsShowAllFollowedUp;
late final _showAllUp = Pref.dynamicsShowAllFollowedUp;
late bool showLiveUp = Pref.expandDynLivePanel;
final upPanelPosition = Pref.upPanelPosition;
@@ -55,7 +55,7 @@ class DynamicsController extends GetxController
@override
void onInit() {
super.onInit();
if (showAllUp) {
if (_showAllUp) {
scrollController.addListener(listener);
}
queryFollowUp();
@@ -64,15 +64,11 @@ class DynamicsController extends GetxController
void listener() {
if (scrollController.position.pixels >=
scrollController.position.maxScrollExtent - 300) {
EasyThrottle.throttle(
'following',
const Duration(seconds: 1),
queryFollowing2,
);
queryAllUp();
}
}
Future<void> queryFollowing2() async {
Future<void> queryAllUp() async {
if (isQuerying) return;
isQuerying = true;
if (_upEnd) {
@@ -116,7 +112,7 @@ class DynamicsController extends GetxController
final res = await Future.wait([
DynamicsHttp.followUp(),
if (showAllUp)
if (_showAllUp)
FollowHttp.followings(
vmid: accountService.mid,
pn: _upPage,
@@ -126,11 +122,10 @@ class DynamicsController extends GetxController
]);
final first = res.first;
final second = res.getOrNull(1);
if (first.isSuccess) {
FollowUpModel data = first.data as FollowUpModel;
final second = res.getOrNull(1);
if (second != null && second.isSuccess) {
_cacheUpList = List<UpItem>.from(data.upList);
FollowData data1 = second.data as FollowData;
final list1 = data1.list;
@@ -140,6 +135,7 @@ class DynamicsController extends GetxController
}
final list = data.upList;
_cacheUpList = List<UpItem>.from(list);
list.addAll(list1..removeWhere((e) => list.contains(e)));
}
upState.value = Success(data);
@@ -166,7 +162,7 @@ class DynamicsController extends GetxController
@override
Future<void> onRefresh() async {
if (showAllUp) {
if (_showAllUp) {
_upPage = 1;
_cacheUpList = null;
}

View File

@@ -110,7 +110,7 @@ class _UpPanelState extends State<UpPanel> {
),
),
),
if (upList.isNotEmpty == true)
if (upList.isNotEmpty)
SliverList.builder(
itemCount: upList.length,
itemBuilder: (context, index) {

View File

@@ -49,7 +49,6 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
final RxBool _visibleTitle = false.obs;
bool _isFabVisible = true;
bool? _imageStatus;
late final List<double> _ratio = Pref.dynamicDetailRatio;
@@ -59,46 +58,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
late final _key = GlobalKey<ScaffoldState>();
Function(dynamic imgList, dynamic index)? get _getImageCallback =>
_horizontalPreview
? (imgList, index) {
_imageStatus = true;
bool isFabVisible = _isFabVisible;
if (isFabVisible) {
_hideFab();
}
final ctr = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 200),
)..forward();
PageUtils.onHorizontalPreview(
_key,
AnimationController(
vsync: this,
duration: Duration.zero,
),
ctr,
imgList,
index,
(value) async {
_imageStatus = null;
if (isFabVisible) {
isFabVisible = false;
_showFab();
}
if (value == false) {
await ctr.reverse();
}
try {
ctr.dispose();
} catch (_) {}
if (value == false) {
Get.back();
}
},
);
}
: null;
late Function(List<String> imgList, int index)? _imageCallback;
@override
void initState() {
@@ -126,14 +86,21 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
EasyThrottle.throttle('replyReply', const Duration(milliseconds: 500), () {
int oid = replyItem.oid.toInt();
int rpid = replyItem.id.toInt();
Widget replyReplyPage({
bool automaticallyImplyLeading = true,
VoidCallback? onDispose,
}) => Scaffold(
Widget replyReplyPage({bool showBackBtn = true}) => Scaffold(
appBar: AppBar(
toolbarHeight: showBackBtn ? null : 45,
title: const Text('评论详情'),
titleSpacing: automaticallyImplyLeading ? null : 12,
automaticallyImplyLeading: automaticallyImplyLeading,
titleSpacing: showBackBtn ? null : 12,
automaticallyImplyLeading: showBackBtn,
actions: showBackBtn
? null
: [
IconButton(
tooltip: '关闭',
icon: const Icon(Icons.close, size: 20),
onPressed: Get.back,
),
],
),
body: SafeArea(
top: false,
@@ -146,7 +113,6 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
isVideoDetail: false,
replyType: _controller.replyType,
firstFloor: replyItem,
onDispose: onDispose,
),
),
);
@@ -170,14 +136,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
(context) => MediaQuery.removePadding(
context: context,
removeLeft: true,
child: replyReplyPage(
automaticallyImplyLeading: false,
onDispose: () {
if (isFabVisible && _imageStatus != true) {
_showFab();
}
},
),
child: replyReplyPage(showBackBtn: false),
),
);
} else {
@@ -247,6 +206,17 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
_imageCallback = _horizontalPreview
? (imgList, index) {
_hideFab();
PageUtils.onHorizontalPreview(
_key,
this,
imgList,
index,
);
}
: null;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
@@ -343,7 +313,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
child: DynamicPanel(
item: _controller.dynItem,
isDetail: true,
callback: _getImageCallback,
callback: _imageCallback,
),
),
replyPersistentHeader(theme),
@@ -378,7 +348,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
child: DynamicPanel(
item: _controller.dynItem,
isDetail: true,
callback: _getImageCallback,
callback: _imageCallback,
),
),
),
@@ -788,7 +758,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
onDelete: (item, subIndex) =>
_controller.onRemove(index, item, subIndex),
upMid: _controller.upMid,
callback: _getImageCallback,
callback: _imageCallback,
onCheckReply: (item) =>
_controller.onCheckReply(item, isManual: true),
onToggleTop: (item) => _controller.onToggleTop(

View File

@@ -96,7 +96,11 @@ class _PgcIndexPageState extends State<PgcIndexPage>
};
}
Widget _buildSortWidget(ThemeData theme, count, data) => Column(
Widget _buildSortWidget(
ThemeData theme,
int count,
PgcIndexConditionData data,
) => Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -122,10 +126,12 @@ class _PgcIndexPageState extends State<PgcIndexPage>
padding: const EdgeInsets.symmetric(
horizontal: 12,
),
childBuilder: (childIndex) => Obx(
childBuilder: (childIndex) {
final e = item[childIndex];
return Obx(
() => SearchText(
bgColor:
(item[childIndex] is PgcConditionOrder
(e is PgcConditionOrder
? _ctr.indexParams['order']
: _ctr.indexParams[data
.filter![data.order?.isNotEmpty ==
@@ -133,13 +139,11 @@ class _PgcIndexPageState extends State<PgcIndexPage>
? index - 1
: index]
.field]) ==
(item[childIndex] is PgcConditionOrder
? item[childIndex].field
: item[childIndex].keyword)
(e is PgcConditionOrder ? e.field : e.keyword)
? theme.colorScheme.secondaryContainer
: Colors.transparent,
textColor:
(item[childIndex] is PgcConditionOrder
(e is PgcConditionOrder
? _ctr.indexParams['order']
: _ctr.indexParams[data
.filter![data.order?.isNotEmpty ==
@@ -147,32 +151,30 @@ class _PgcIndexPageState extends State<PgcIndexPage>
? index - 1
: index]
.field]) ==
(item[childIndex] is PgcConditionOrder
? item[childIndex].field
: item[childIndex].keyword)
(e is PgcConditionOrder ? e.field : e.keyword)
? theme.colorScheme.onSecondaryContainer
: theme.colorScheme.onSurfaceVariant,
text: item[childIndex].name,
text: e.name,
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 3,
),
onTap: (_) {
String name = item[childIndex] is PgcConditionOrder
String name = e is PgcConditionOrder
? 'order'
: data
.filter![data.order?.isNotEmpty == true
? index - 1
: index]
.field!;
_ctr.indexParams[name] =
(item[childIndex] is PgcConditionOrder
? item[childIndex].field
: item[childIndex].keyword);
_ctr.indexParams[name] = (e is PgcConditionOrder
? e.field
: e.keyword);
_ctr.onReload();
},
),
),
);
},
itemCount: item!.length,
),
)

View File

@@ -1027,7 +1027,9 @@ class VideoDetailController extends GetxController
.where((i) => i.id == currentVideoQa.code)
.toList();
final List supportDecodeFormats = videoList.map((e) => e.codecs!).toList();
final List<String> supportDecodeFormats = videoList
.map((e) => e.codecs!)
.toList();
VideoDecodeFormatType defaultDecodeFormats =
VideoDecodeFormatTypeExt.fromString(cacheDecode)!;
VideoDecodeFormatType secondDecodeFormats =
@@ -1264,7 +1266,7 @@ class VideoDetailController extends GetxController
/// 优先顺序 设置中指定解码格式 -> 当前可选的首个解码格式
final List<FormatItem> supportFormats = data.supportFormats!;
// 根据画质选编码格式
final List supportDecodeFormats = supportFormats
final List<String> supportDecodeFormats = supportFormats
.firstWhere(
(e) => e.quality == resVideoQa,
orElse: () => supportFormats.first,

View File

@@ -329,7 +329,7 @@ class PgcIntroController extends CommonIntroController {
}
bool prevPlay() {
List episodes = pgcItem.episodes!;
final episodes = pgcItem.episodes!;
VideoDetailController videoDetailCtr = Get.find<VideoDetailController>(
tag: Get.arguments['heroTag'],
);
@@ -345,19 +345,21 @@ class PgcIntroController extends CommonIntroController {
return false;
}
}
int epid = episodes[prevIndex].epId;
int cid = episodes[prevIndex].cid;
String bvid = episodes[prevIndex].bvid;
int aid = episodes[prevIndex].aid;
dynamic cover = episodes[prevIndex].cover;
changeSeasonOrbangu(epid, bvid, cid, aid, cover);
final episode = episodes[prevIndex];
changeSeasonOrbangu(
episode.epId,
episode.bvid,
episode.cid,
episode.aid,
episode.cover,
);
return true;
}
/// 列表循环或者顺序播放时,自动播放下一个;自动连播时,播放相关视频
bool nextPlay() {
try {
List episodes = pgcItem.episodes!;
final episodes = pgcItem.episodes!;
VideoDetailController videoDetailCtr = Get.find<VideoDetailController>(
tag: Get.arguments['heroTag'],
);
@@ -377,12 +379,14 @@ class PgcIntroController extends CommonIntroController {
return false;
}
}
int epid = episodes[nextIndex].epId;
int cid = episodes[nextIndex].cid;
String bvid = episodes[nextIndex].bvid;
int aid = episodes[nextIndex].aid;
dynamic cover = episodes[nextIndex].cover;
changeSeasonOrbangu(epid, bvid, cid, aid, cover);
final episode = episodes[nextIndex];
changeSeasonOrbangu(
episode.epId,
episode.bvid,
episode.cid,
episode.aid,
episode.cover,
);
return true;
} catch (_) {
return false;

View File

@@ -28,7 +28,6 @@ class VideoReplyReplyPanel extends CommonSlidePage {
this.isDialogue = false,
this.onViewImage,
this.onDismissed,
this.onDispose,
});
final int? id;
final int oid;
@@ -40,7 +39,6 @@ class VideoReplyReplyPanel extends CommonSlidePage {
final bool isDialogue;
final VoidCallback? onViewImage;
final ValueChanged<int>? onDismissed;
final VoidCallback? onDispose;
@override
State<VideoReplyReplyPanel> createState() => _VideoReplyReplyPanelState();
@@ -59,8 +57,9 @@ class _VideoReplyReplyPanelState
ReplyInfo? get firstFloor => widget.firstFloor ?? _controller.firstFloor;
bool get _horizontalPreview =>
context.orientation == Orientation.landscape &&
_controller.horizontalPreview;
_controller.horizontalPreview &&
context.orientation == Orientation.landscape;
late Function(List<String> imgList, int index)? _imageCallback;
Animation<Color?>? colorAnimation;
@@ -83,36 +82,20 @@ class _VideoReplyReplyPanelState
@override
void dispose() {
widget.onDispose?.call();
Get.delete<VideoReplyReplyController>(tag: _tag);
super.dispose();
}
Widget _header(ThemeData theme) => firstFloor == null
? _sortWidget(theme)
: ValueListenableBuilder<Iterable<ItemPosition>>(
valueListenable: itemPositionsListener.itemPositions,
builder: (context, positions, child) {
int min = -1;
if (positions.isNotEmpty) {
min = positions
.where(
(ItemPosition position) => position.itemTrailingEdge > 0,
)
.reduce(
(ItemPosition min, ItemPosition position) =>
position.itemTrailingEdge < min.itemTrailingEdge
? position
: min,
)
.index;
}
return min >= 2 ? _sortWidget(theme) : const SizedBox.shrink();
},
);
@override
Widget buildPage(ThemeData theme) {
_imageCallback = _horizontalPreview
? (imgList, index) => PageUtils.onHorizontalPreview(
_key,
this,
imgList,
index,
)
: null;
return Scaffold(
key: _key,
resizeToAvoidBottomInset: false,
@@ -146,9 +129,7 @@ class _VideoReplyReplyPanelState
height: 1,
color: theme.dividerColor.withValues(alpha: 0.1),
),
Expanded(
child: enableSlide ? slideList(theme) : buildList(theme),
),
Expanded(child: enableSlide ? slideList(theme) : buildList(theme)),
],
),
);
@@ -190,7 +171,7 @@ class _VideoReplyReplyPanelState
upMid: _controller.upMid,
onViewImage: widget.onViewImage,
onDismissed: widget.onDismissed,
callback: _getImageCallback,
callback: _imageCallback,
onCheckReply: (item) =>
_controller.onCheckReply(item, isManual: true),
);
@@ -232,6 +213,29 @@ class _VideoReplyReplyPanelState
);
}
Widget _header(ThemeData theme) => firstFloor == null
? _sortWidget(theme)
: ValueListenableBuilder<Iterable<ItemPosition>>(
valueListenable: itemPositionsListener.itemPositions,
builder: (context, positions, child) {
int min = -1;
if (positions.isNotEmpty) {
min = positions
.where(
(ItemPosition position) => position.itemTrailingEdge > 0,
)
.reduce(
(ItemPosition min, ItemPosition position) =>
position.itemTrailingEdge < min.itemTrailingEdge
? position
: min,
)
.index;
}
return min >= 2 ? _sortWidget(theme) : const SizedBox.shrink();
},
);
Widget _sortWidget(ThemeData theme) => Container(
height: 40,
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
@@ -261,7 +265,7 @@ class _VideoReplyReplyPanelState
SizedBox(
height: 35,
child: TextButton.icon(
onPressed: () => _controller.queryBySort(),
onPressed: _controller.queryBySort,
icon: Icon(
Icons.sort,
size: 16,
@@ -282,36 +286,6 @@ class _VideoReplyReplyPanelState
),
);
Function(List<String>, int)? get _getImageCallback => _horizontalPreview
? (imgList, index) {
final ctr = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 200),
)..forward();
PageUtils.onHorizontalPreview(
_key,
AnimationController(
vsync: this,
duration: Duration.zero,
),
ctr,
imgList,
index,
(value) async {
if (value == false) {
await ctr.reverse();
}
try {
ctr.dispose();
} catch (_) {}
if (value == false) {
Get.back();
}
},
);
}
: null;
Widget _buildBody(
ThemeData theme,
LoadingState<List<ReplyInfo>?> loadingState,
@@ -381,9 +355,7 @@ class _VideoReplyReplyPanelState
replyLevel: widget.isDialogue ? 3 : 2,
onReply: (replyItem) =>
_controller.onReply(context, replyItem: replyItem, index: index),
onDelete: (item, subIndex) {
_controller.onRemove(index, item, null);
},
onDelete: (item, subIndex) => _controller.onRemove(index, item, null),
upMid: _controller.upMid,
showDialogue: () => _key.currentState?.showBottomSheet(
backgroundColor: Colors.transparent,
@@ -398,7 +370,7 @@ class _VideoReplyReplyPanelState
),
onViewImage: widget.onViewImage,
onDismissed: widget.onDismissed,
callback: _getImageCallback,
callback: _imageCallback,
onCheckReply: (item) => _controller.onCheckReply(item, isManual: true),
);
}

View File

@@ -100,16 +100,16 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
bool get isFullScreen => plPlayerController?.isFullScreen.value ?? false;
bool get _shouldShowSeasonPanel {
final videoDetail = videoIntroController.videoDetail.value;
return (videoDetail.ugcSeason != null ||
late final videoDetail = videoIntroController.videoDetail.value;
return videoDetailController.plPlayerController.horizontalSeasonPanel &&
(videoDetail.ugcSeason != null ||
((videoDetail.pages?.length ?? 0) > 1)) &&
context.orientation == Orientation.landscape &&
videoDetailController.plPlayerController.horizontalSeasonPanel;
context.orientation == Orientation.landscape;
}
bool get _horizontalPreview =>
context.orientation == Orientation.landscape &&
videoDetailController.plPlayerController.horizontalPreview;
videoDetailController.plPlayerController.horizontalPreview &&
context.orientation == Orientation.landscape;
StreamSubscription? _listenerFS;
@@ -2014,33 +2014,12 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
onViewImage: videoDetailController.onViewImage,
onDismissed: videoDetailController.onDismissed,
callback: _horizontalPreview
? (imgList, index) {
final ctr = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 200),
)..forward();
PageUtils.onHorizontalPreview(
? (imgList, index) => PageUtils.onHorizontalPreview(
videoDetailController.childKey,
AnimationController(
vsync: this,
duration: Duration.zero,
),
ctr,
this,
imgList,
index,
(value) async {
if (value == false) {
await ctr.reverse();
}
try {
ctr.dispose();
} catch (_) {}
if (value == false) {
Get.back();
}
},
);
}
)
: null,
),
);

View File

@@ -779,7 +779,7 @@ class HeaderControlState extends State<HeaderControl> {
final VideoItem firstVideo = videoDetailCtr.firstVideo;
// 当前视频可用的解码格式
final List<FormatItem> videoFormat = videoInfo.supportFormats!;
final List? list = videoFormat
final List<String>? list = videoFormat
.firstWhere((FormatItem e) => e.quality == firstVideo.quality.code)
.codecs;
if (list == null) {
@@ -829,7 +829,7 @@ class HeaderControlState extends State<HeaderControl> {
VideoDecodeFormatTypeExt.fromString(i)!.description,
),
subtitle: Text(
i!,
i,
style: subTitleStyle,
),
trailing: i.startsWith(currentDecodeFormats.code)
@@ -2054,7 +2054,7 @@ class HeaderControlState extends State<HeaderControl> {
),
),
Obx(
() => videoDetailCtr.segmentList.isNotEmpty == true
() => videoDetailCtr.segmentList.isNotEmpty
? SizedBox(
width: 42,
height: 34,

View File

@@ -515,12 +515,14 @@ class PageUtils {
static void onHorizontalPreview(
GlobalKey<ScaffoldState> key,
transitionAnimationController,
ctr,
TickerProvider vsync,
List<String> imgList,
index,
onClose,
int index,
) {
final ctr = AnimationController(
vsync: vsync,
duration: const Duration(milliseconds: 200),
)..forward();
key.currentState?.showBottomSheet(
(context) {
return FadeTransition(
@@ -529,7 +531,17 @@ class PageUtils {
sources: imgList.map((url) => SourceModel(url: url)).toList(),
initIndex: index,
setStatusBar: false,
onClose: onClose,
onClose: (value) async {
if (value == false) {
await ctr.reverse();
}
try {
ctr.dispose();
} catch (_) {}
if (value == false) {
Get.back();
}
},
quality: GlobalData().imgQuality,
),
);
@@ -537,7 +549,6 @@ class PageUtils {
enableDrag: false,
elevation: 0,
backgroundColor: Colors.transparent,
transitionAnimationController: transitionAnimationController,
sheetAnimationStyle: const AnimationStyle(duration: Duration.zero),
);
}