mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-17 23:56:13 +08:00
@@ -55,7 +55,7 @@ class InteractiveviewerGallery<T> extends StatefulWidget {
|
|||||||
|
|
||||||
final int quality;
|
final int quality;
|
||||||
|
|
||||||
final ValueChanged? onClose;
|
final ValueChanged<bool>? onClose;
|
||||||
|
|
||||||
final bool? setStatusBar;
|
final bool? setStatusBar;
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ class MyApp extends StatelessWidget {
|
|||||||
|
|
||||||
// 强制设置高帧率
|
// 强制设置高帧率
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
late List modes;
|
late List<DisplayMode> modes;
|
||||||
FlutterDisplayMode.supported.then((value) {
|
FlutterDisplayMode.supported.then((value) {
|
||||||
modes = value;
|
modes = value;
|
||||||
var storageDisplay = GStorage.setting.get(SettingBoxKey.displayMode);
|
var storageDisplay = GStorage.setting.get(SettingBoxKey.displayMode);
|
||||||
|
|||||||
@@ -239,14 +239,14 @@ class FormatItem {
|
|||||||
String? format;
|
String? format;
|
||||||
String? newDesc;
|
String? newDesc;
|
||||||
String? displayDesc;
|
String? displayDesc;
|
||||||
List? codecs;
|
List<String>? codecs;
|
||||||
|
|
||||||
FormatItem.fromJson(Map<String, dynamic> json) {
|
FormatItem.fromJson(Map<String, dynamic> json) {
|
||||||
quality = json['quality'];
|
quality = json['quality'];
|
||||||
format = json['format'];
|
format = json['format'];
|
||||||
newDesc = json['new_description'];
|
newDesc = json['new_description'];
|
||||||
displayDesc = json['display_desc'];
|
displayDesc = json['display_desc'];
|
||||||
codecs = json['codecs'];
|
codecs = (json['codecs'] as List?)?.cast<String>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -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?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -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?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
class PlayStrategy {
|
|
||||||
List? strategies;
|
|
||||||
|
|
||||||
PlayStrategy({this.strategies});
|
|
||||||
|
|
||||||
factory PlayStrategy.fromJson(Map<String, dynamic> json) => PlayStrategy(
|
|
||||||
strategies: json['strategies'],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -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?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,19 +1,14 @@
|
|||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/activity.dart';
|
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/area.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/episode.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/icon_font.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/new_ep.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/publish.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/rating.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/rights.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/season.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/section.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/series.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/stat.dart';
|
||||||
import 'package:PiliPlus/models_new/pgc/pgc_info_model/up_info.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';
|
import 'package:PiliPlus/models_new/pgc/pgc_info_model/user_status.dart';
|
||||||
@@ -25,11 +20,9 @@ class PgcInfoModel {
|
|||||||
List<Area>? areas;
|
List<Area>? areas;
|
||||||
String? bkgCover;
|
String? bkgCover;
|
||||||
String? cover;
|
String? cover;
|
||||||
bool? deliveryFragmentVideo;
|
|
||||||
bool? enableVt;
|
bool? enableVt;
|
||||||
List<EpisodeItem>? episodes;
|
List<EpisodeItem>? episodes;
|
||||||
String? evaluate;
|
String? evaluate;
|
||||||
Freya? freya;
|
|
||||||
int? hideEpVvVtDm;
|
int? hideEpVvVtDm;
|
||||||
IconFont? iconFont;
|
IconFont? iconFont;
|
||||||
String? jpTitle;
|
String? jpTitle;
|
||||||
@@ -37,9 +30,6 @@ class PgcInfoModel {
|
|||||||
int? mediaId;
|
int? mediaId;
|
||||||
int? mode;
|
int? mode;
|
||||||
NewEp? newEp;
|
NewEp? newEp;
|
||||||
Payment? payment;
|
|
||||||
PlayStrategy? playStrategy;
|
|
||||||
Positive? positive;
|
|
||||||
Publish? publish;
|
Publish? publish;
|
||||||
Rating? rating;
|
Rating? rating;
|
||||||
String? record;
|
String? record;
|
||||||
@@ -52,13 +42,11 @@ class PgcInfoModel {
|
|||||||
String? shareCopy;
|
String? shareCopy;
|
||||||
String? shareSubTitle;
|
String? shareSubTitle;
|
||||||
String? shareUrl;
|
String? shareUrl;
|
||||||
Show? show;
|
|
||||||
int? showSeasonType;
|
int? showSeasonType;
|
||||||
String? squareCover;
|
String? squareCover;
|
||||||
String? staff;
|
String? staff;
|
||||||
PgcStat? stat;
|
PgcStat? stat;
|
||||||
int? status;
|
int? status;
|
||||||
List? styles;
|
|
||||||
String? subtitle;
|
String? subtitle;
|
||||||
String? title;
|
String? title;
|
||||||
int? total;
|
int? total;
|
||||||
@@ -73,11 +61,9 @@ class PgcInfoModel {
|
|||||||
this.areas,
|
this.areas,
|
||||||
this.bkgCover,
|
this.bkgCover,
|
||||||
this.cover,
|
this.cover,
|
||||||
this.deliveryFragmentVideo,
|
|
||||||
this.enableVt,
|
this.enableVt,
|
||||||
this.episodes,
|
this.episodes,
|
||||||
this.evaluate,
|
this.evaluate,
|
||||||
this.freya,
|
|
||||||
this.hideEpVvVtDm,
|
this.hideEpVvVtDm,
|
||||||
this.iconFont,
|
this.iconFont,
|
||||||
this.jpTitle,
|
this.jpTitle,
|
||||||
@@ -85,9 +71,6 @@ class PgcInfoModel {
|
|||||||
this.mediaId,
|
this.mediaId,
|
||||||
this.mode,
|
this.mode,
|
||||||
this.newEp,
|
this.newEp,
|
||||||
this.payment,
|
|
||||||
this.playStrategy,
|
|
||||||
this.positive,
|
|
||||||
this.publish,
|
this.publish,
|
||||||
this.rating,
|
this.rating,
|
||||||
this.record,
|
this.record,
|
||||||
@@ -100,13 +83,11 @@ class PgcInfoModel {
|
|||||||
this.shareCopy,
|
this.shareCopy,
|
||||||
this.shareSubTitle,
|
this.shareSubTitle,
|
||||||
this.shareUrl,
|
this.shareUrl,
|
||||||
this.show,
|
|
||||||
this.showSeasonType,
|
this.showSeasonType,
|
||||||
this.squareCover,
|
this.squareCover,
|
||||||
this.staff,
|
this.staff,
|
||||||
this.stat,
|
this.stat,
|
||||||
this.status,
|
this.status,
|
||||||
this.styles,
|
|
||||||
this.subtitle,
|
this.subtitle,
|
||||||
this.title,
|
this.title,
|
||||||
this.total,
|
this.total,
|
||||||
@@ -126,15 +107,11 @@ class PgcInfoModel {
|
|||||||
.toList(),
|
.toList(),
|
||||||
bkgCover: json['bkg_cover'] as String?,
|
bkgCover: json['bkg_cover'] as String?,
|
||||||
cover: json['cover'] as String?,
|
cover: json['cover'] as String?,
|
||||||
deliveryFragmentVideo: json['delivery_fragment_video'] as bool?,
|
|
||||||
enableVt: json['enable_vt'] as bool?,
|
enableVt: json['enable_vt'] as bool?,
|
||||||
episodes: (json['episodes'] as List<dynamic>?)
|
episodes: (json['episodes'] as List<dynamic>?)
|
||||||
?.map((e) => EpisodeItem.fromJson(e as Map<String, dynamic>))
|
?.map((e) => EpisodeItem.fromJson(e as Map<String, dynamic>))
|
||||||
.toList(),
|
.toList(),
|
||||||
evaluate: json['evaluate'] as String?,
|
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?,
|
hideEpVvVtDm: json['hide_ep_vv_vt_dm'] as int?,
|
||||||
iconFont: json['icon_font'] == null
|
iconFont: json['icon_font'] == null
|
||||||
? null
|
? null
|
||||||
@@ -146,15 +123,6 @@ class PgcInfoModel {
|
|||||||
newEp: json['new_ep'] == null
|
newEp: json['new_ep'] == null
|
||||||
? null
|
? null
|
||||||
: NewEp.fromJson(json['new_ep'] as Map<String, dynamic>),
|
: 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
|
publish: json['publish'] == null
|
||||||
? null
|
? null
|
||||||
: Publish.fromJson(json['publish'] as Map<String, dynamic>),
|
: Publish.fromJson(json['publish'] as Map<String, dynamic>),
|
||||||
@@ -179,9 +147,6 @@ class PgcInfoModel {
|
|||||||
shareCopy: json['share_copy'] as String?,
|
shareCopy: json['share_copy'] as String?,
|
||||||
shareSubTitle: json['share_sub_title'] as String?,
|
shareSubTitle: json['share_sub_title'] as String?,
|
||||||
shareUrl: json['share_url'] 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?,
|
showSeasonType: json['show_season_type'] as int?,
|
||||||
squareCover: json['square_cover'] as String?,
|
squareCover: json['square_cover'] as String?,
|
||||||
staff: json['staff'] as String?,
|
staff: json['staff'] as String?,
|
||||||
@@ -189,7 +154,6 @@ class PgcInfoModel {
|
|||||||
? null
|
? null
|
||||||
: PgcStat.fromJson(json['stat'] as Map<String, dynamic>),
|
: PgcStat.fromJson(json['stat'] as Map<String, dynamic>),
|
||||||
status: json['status'] as int?,
|
status: json['status'] as int?,
|
||||||
styles: json['styles'],
|
|
||||||
subtitle: json['subtitle'] as String?,
|
subtitle: json['subtitle'] as String?,
|
||||||
title: json['title'] as String?,
|
title: json['title'] as String?,
|
||||||
total: json['total'] as int?,
|
total: json['total'] as int?,
|
||||||
|
|||||||
@@ -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?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -56,58 +56,18 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
tag: Utils.generateRandomString(8),
|
tag: Utils.generateRandomString(8),
|
||||||
);
|
);
|
||||||
bool _isFabVisible = true;
|
bool _isFabVisible = true;
|
||||||
bool? _imageStatus;
|
|
||||||
late final AnimationController fabAnimationCtr;
|
late final AnimationController fabAnimationCtr;
|
||||||
late final Animation<Offset> _anim;
|
late final Animation<Offset> _anim;
|
||||||
|
|
||||||
late final List<double> _ratio = Pref.dynamicDetailRatio;
|
late final List<double> _ratio = Pref.dynamicDetailRatio;
|
||||||
|
|
||||||
bool get _horizontalPreview =>
|
bool get _horizontalPreview =>
|
||||||
context.orientation == Orientation.landscape &&
|
_articleCtr.horizontalPreview &&
|
||||||
_articleCtr.horizontalPreview;
|
context.orientation == Orientation.landscape;
|
||||||
|
|
||||||
late final _key = GlobalKey<ScaffoldState>();
|
late final _key = GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
Function(dynamic imgList, dynamic index)? get _getImageCallback =>
|
late Function(dynamic imgList, dynamic index)? _imageCallback;
|
||||||
_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;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -182,14 +142,21 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
EasyThrottle.throttle('replyReply', const Duration(milliseconds: 500), () {
|
EasyThrottle.throttle('replyReply', const Duration(milliseconds: 500), () {
|
||||||
int oid = replyItem.oid.toInt();
|
int oid = replyItem.oid.toInt();
|
||||||
int rpid = replyItem.id.toInt();
|
int rpid = replyItem.id.toInt();
|
||||||
Widget replyReplyPage({
|
Widget replyReplyPage({bool showBackBtn = true}) => Scaffold(
|
||||||
bool automaticallyImplyLeading = true,
|
|
||||||
VoidCallback? onDispose,
|
|
||||||
}) => Scaffold(
|
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
toolbarHeight: showBackBtn ? null : 45,
|
||||||
title: const Text('评论详情'),
|
title: const Text('评论详情'),
|
||||||
titleSpacing: automaticallyImplyLeading ? null : 12,
|
titleSpacing: showBackBtn ? null : 12,
|
||||||
automaticallyImplyLeading: automaticallyImplyLeading,
|
automaticallyImplyLeading: showBackBtn,
|
||||||
|
actions: showBackBtn
|
||||||
|
? null
|
||||||
|
: [
|
||||||
|
IconButton(
|
||||||
|
tooltip: '关闭',
|
||||||
|
icon: const Icon(Icons.close, size: 20),
|
||||||
|
onPressed: Get.back,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
top: false,
|
top: false,
|
||||||
@@ -202,7 +169,6 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
isVideoDetail: false,
|
isVideoDetail: false,
|
||||||
replyType: _articleCtr.commentType,
|
replyType: _articleCtr.commentType,
|
||||||
firstFloor: replyItem,
|
firstFloor: replyItem,
|
||||||
onDispose: onDispose,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -226,14 +192,7 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
(context) => MediaQuery.removePadding(
|
(context) => MediaQuery.removePadding(
|
||||||
context: context,
|
context: context,
|
||||||
removeLeft: true,
|
removeLeft: true,
|
||||||
child: replyReplyPage(
|
child: replyReplyPage(showBackBtn: false),
|
||||||
automaticallyImplyLeading: false,
|
|
||||||
onDispose: () {
|
|
||||||
if (isFabVisible && _imageStatus != true) {
|
|
||||||
_showFab();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -252,6 +211,17 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
|
_imageCallback = _horizontalPreview
|
||||||
|
? (imgList, index) {
|
||||||
|
_hideFab();
|
||||||
|
PageUtils.onHorizontalPreview(
|
||||||
|
_key,
|
||||||
|
this,
|
||||||
|
imgList,
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
: null;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: _buildAppBar,
|
appBar: _buildAppBar,
|
||||||
@@ -386,7 +356,7 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
if (kDebugMode) debugPrint('json page');
|
if (kDebugMode) debugPrint('json page');
|
||||||
content = OpusContent(
|
content = OpusContent(
|
||||||
opus: _articleCtr.opus!,
|
opus: _articleCtr.opus!,
|
||||||
callback: _getImageCallback,
|
callback: _imageCallback,
|
||||||
maxWidth: maxWidth,
|
maxWidth: maxWidth,
|
||||||
);
|
);
|
||||||
} else if (_articleCtr.opusData?.modules.moduleBlocked != null) {
|
} else if (_articleCtr.opusData?.modules.moduleBlocked != null) {
|
||||||
@@ -408,7 +378,7 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
context: context,
|
context: context,
|
||||||
html: _articleCtr.articleData!.content!,
|
html: _articleCtr.articleData!.content!,
|
||||||
maxWidth: maxWidth,
|
maxWidth: maxWidth,
|
||||||
callback: _getImageCallback,
|
callback: _imageCallback,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -419,7 +389,7 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
context: context,
|
context: context,
|
||||||
element: res.body!.children[index],
|
element: res.body!.children[index],
|
||||||
maxWidth: maxWidth,
|
maxWidth: maxWidth,
|
||||||
callback: _getImageCallback,
|
callback: _imageCallback,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
separatorBuilder: (context, index) =>
|
separatorBuilder: (context, index) =>
|
||||||
@@ -655,7 +625,7 @@ class _ArticlePageState extends State<ArticlePage>
|
|||||||
onDelete: (item, subIndex) =>
|
onDelete: (item, subIndex) =>
|
||||||
_articleCtr.onRemove(index, item, subIndex),
|
_articleCtr.onRemove(index, item, subIndex),
|
||||||
upMid: _articleCtr.upMid,
|
upMid: _articleCtr.upMid,
|
||||||
callback: _getImageCallback,
|
callback: _imageCallback,
|
||||||
onCheckReply: (item) =>
|
onCheckReply: (item) =>
|
||||||
_articleCtr.onCheckReply(item, isManual: true),
|
_articleCtr.onCheckReply(item, isManual: true),
|
||||||
onToggleTop: (item) => _articleCtr.onToggleTop(
|
onToggleTop: (item) => _articleCtr.onToggleTop(
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class DynamicsController extends GetxController
|
|||||||
late int _upPage = 1;
|
late int _upPage = 1;
|
||||||
late bool _upEnd = false;
|
late bool _upEnd = false;
|
||||||
List<UpItem>? _cacheUpList;
|
List<UpItem>? _cacheUpList;
|
||||||
late final showAllUp = Pref.dynamicsShowAllFollowedUp;
|
late final _showAllUp = Pref.dynamicsShowAllFollowedUp;
|
||||||
late bool showLiveUp = Pref.expandDynLivePanel;
|
late bool showLiveUp = Pref.expandDynLivePanel;
|
||||||
|
|
||||||
final upPanelPosition = Pref.upPanelPosition;
|
final upPanelPosition = Pref.upPanelPosition;
|
||||||
@@ -55,7 +55,7 @@ class DynamicsController extends GetxController
|
|||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
if (showAllUp) {
|
if (_showAllUp) {
|
||||||
scrollController.addListener(listener);
|
scrollController.addListener(listener);
|
||||||
}
|
}
|
||||||
queryFollowUp();
|
queryFollowUp();
|
||||||
@@ -64,15 +64,11 @@ class DynamicsController extends GetxController
|
|||||||
void listener() {
|
void listener() {
|
||||||
if (scrollController.position.pixels >=
|
if (scrollController.position.pixels >=
|
||||||
scrollController.position.maxScrollExtent - 300) {
|
scrollController.position.maxScrollExtent - 300) {
|
||||||
EasyThrottle.throttle(
|
queryAllUp();
|
||||||
'following',
|
|
||||||
const Duration(seconds: 1),
|
|
||||||
queryFollowing2,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> queryFollowing2() async {
|
Future<void> queryAllUp() async {
|
||||||
if (isQuerying) return;
|
if (isQuerying) return;
|
||||||
isQuerying = true;
|
isQuerying = true;
|
||||||
if (_upEnd) {
|
if (_upEnd) {
|
||||||
@@ -116,7 +112,7 @@ class DynamicsController extends GetxController
|
|||||||
|
|
||||||
final res = await Future.wait([
|
final res = await Future.wait([
|
||||||
DynamicsHttp.followUp(),
|
DynamicsHttp.followUp(),
|
||||||
if (showAllUp)
|
if (_showAllUp)
|
||||||
FollowHttp.followings(
|
FollowHttp.followings(
|
||||||
vmid: accountService.mid,
|
vmid: accountService.mid,
|
||||||
pn: _upPage,
|
pn: _upPage,
|
||||||
@@ -126,11 +122,10 @@ class DynamicsController extends GetxController
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
final first = res.first;
|
final first = res.first;
|
||||||
final second = res.getOrNull(1);
|
|
||||||
if (first.isSuccess) {
|
if (first.isSuccess) {
|
||||||
FollowUpModel data = first.data as FollowUpModel;
|
FollowUpModel data = first.data as FollowUpModel;
|
||||||
|
final second = res.getOrNull(1);
|
||||||
if (second != null && second.isSuccess) {
|
if (second != null && second.isSuccess) {
|
||||||
_cacheUpList = List<UpItem>.from(data.upList);
|
|
||||||
FollowData data1 = second.data as FollowData;
|
FollowData data1 = second.data as FollowData;
|
||||||
final list1 = data1.list;
|
final list1 = data1.list;
|
||||||
|
|
||||||
@@ -140,6 +135,7 @@ class DynamicsController extends GetxController
|
|||||||
}
|
}
|
||||||
|
|
||||||
final list = data.upList;
|
final list = data.upList;
|
||||||
|
_cacheUpList = List<UpItem>.from(list);
|
||||||
list.addAll(list1..removeWhere((e) => list.contains(e)));
|
list.addAll(list1..removeWhere((e) => list.contains(e)));
|
||||||
}
|
}
|
||||||
upState.value = Success(data);
|
upState.value = Success(data);
|
||||||
@@ -166,7 +162,7 @@ class DynamicsController extends GetxController
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> onRefresh() async {
|
Future<void> onRefresh() async {
|
||||||
if (showAllUp) {
|
if (_showAllUp) {
|
||||||
_upPage = 1;
|
_upPage = 1;
|
||||||
_cacheUpList = null;
|
_cacheUpList = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class _UpPanelState extends State<UpPanel> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (upList.isNotEmpty == true)
|
if (upList.isNotEmpty)
|
||||||
SliverList.builder(
|
SliverList.builder(
|
||||||
itemCount: upList.length,
|
itemCount: upList.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
|
|
||||||
final RxBool _visibleTitle = false.obs;
|
final RxBool _visibleTitle = false.obs;
|
||||||
bool _isFabVisible = true;
|
bool _isFabVisible = true;
|
||||||
bool? _imageStatus;
|
|
||||||
|
|
||||||
late final List<double> _ratio = Pref.dynamicDetailRatio;
|
late final List<double> _ratio = Pref.dynamicDetailRatio;
|
||||||
|
|
||||||
@@ -59,46 +58,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
|
|
||||||
late final _key = GlobalKey<ScaffoldState>();
|
late final _key = GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
Function(dynamic imgList, dynamic index)? get _getImageCallback =>
|
late Function(List<String> imgList, int index)? _imageCallback;
|
||||||
_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;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -126,14 +86,21 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
EasyThrottle.throttle('replyReply', const Duration(milliseconds: 500), () {
|
EasyThrottle.throttle('replyReply', const Duration(milliseconds: 500), () {
|
||||||
int oid = replyItem.oid.toInt();
|
int oid = replyItem.oid.toInt();
|
||||||
int rpid = replyItem.id.toInt();
|
int rpid = replyItem.id.toInt();
|
||||||
Widget replyReplyPage({
|
Widget replyReplyPage({bool showBackBtn = true}) => Scaffold(
|
||||||
bool automaticallyImplyLeading = true,
|
|
||||||
VoidCallback? onDispose,
|
|
||||||
}) => Scaffold(
|
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
toolbarHeight: showBackBtn ? null : 45,
|
||||||
title: const Text('评论详情'),
|
title: const Text('评论详情'),
|
||||||
titleSpacing: automaticallyImplyLeading ? null : 12,
|
titleSpacing: showBackBtn ? null : 12,
|
||||||
automaticallyImplyLeading: automaticallyImplyLeading,
|
automaticallyImplyLeading: showBackBtn,
|
||||||
|
actions: showBackBtn
|
||||||
|
? null
|
||||||
|
: [
|
||||||
|
IconButton(
|
||||||
|
tooltip: '关闭',
|
||||||
|
icon: const Icon(Icons.close, size: 20),
|
||||||
|
onPressed: Get.back,
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
top: false,
|
top: false,
|
||||||
@@ -146,7 +113,6 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
isVideoDetail: false,
|
isVideoDetail: false,
|
||||||
replyType: _controller.replyType,
|
replyType: _controller.replyType,
|
||||||
firstFloor: replyItem,
|
firstFloor: replyItem,
|
||||||
onDispose: onDispose,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -170,14 +136,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
(context) => MediaQuery.removePadding(
|
(context) => MediaQuery.removePadding(
|
||||||
context: context,
|
context: context,
|
||||||
removeLeft: true,
|
removeLeft: true,
|
||||||
child: replyReplyPage(
|
child: replyReplyPage(showBackBtn: false),
|
||||||
automaticallyImplyLeading: false,
|
|
||||||
onDispose: () {
|
|
||||||
if (isFabVisible && _imageStatus != true) {
|
|
||||||
_showFab();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -247,6 +206,17 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
|
_imageCallback = _horizontalPreview
|
||||||
|
? (imgList, index) {
|
||||||
|
_hideFab();
|
||||||
|
PageUtils.onHorizontalPreview(
|
||||||
|
_key,
|
||||||
|
this,
|
||||||
|
imgList,
|
||||||
|
index,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
: null;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
@@ -343,7 +313,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
child: DynamicPanel(
|
child: DynamicPanel(
|
||||||
item: _controller.dynItem,
|
item: _controller.dynItem,
|
||||||
isDetail: true,
|
isDetail: true,
|
||||||
callback: _getImageCallback,
|
callback: _imageCallback,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
replyPersistentHeader(theme),
|
replyPersistentHeader(theme),
|
||||||
@@ -378,7 +348,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
child: DynamicPanel(
|
child: DynamicPanel(
|
||||||
item: _controller.dynItem,
|
item: _controller.dynItem,
|
||||||
isDetail: true,
|
isDetail: true,
|
||||||
callback: _getImageCallback,
|
callback: _imageCallback,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -788,7 +758,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
onDelete: (item, subIndex) =>
|
onDelete: (item, subIndex) =>
|
||||||
_controller.onRemove(index, item, subIndex),
|
_controller.onRemove(index, item, subIndex),
|
||||||
upMid: _controller.upMid,
|
upMid: _controller.upMid,
|
||||||
callback: _getImageCallback,
|
callback: _imageCallback,
|
||||||
onCheckReply: (item) =>
|
onCheckReply: (item) =>
|
||||||
_controller.onCheckReply(item, isManual: true),
|
_controller.onCheckReply(item, isManual: true),
|
||||||
onToggleTop: (item) => _controller.onToggleTop(
|
onToggleTop: (item) => _controller.onToggleTop(
|
||||||
|
|||||||
@@ -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,
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@@ -122,57 +126,55 @@ class _PgcIndexPageState extends State<PgcIndexPage>
|
|||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 12,
|
horizontal: 12,
|
||||||
),
|
),
|
||||||
childBuilder: (childIndex) => Obx(
|
childBuilder: (childIndex) {
|
||||||
() => SearchText(
|
final e = item[childIndex];
|
||||||
bgColor:
|
return Obx(
|
||||||
(item[childIndex] is PgcConditionOrder
|
() => SearchText(
|
||||||
? _ctr.indexParams['order']
|
bgColor:
|
||||||
: _ctr.indexParams[data
|
(e is PgcConditionOrder
|
||||||
.filter![data.order?.isNotEmpty ==
|
? _ctr.indexParams['order']
|
||||||
true
|
: _ctr.indexParams[data
|
||||||
? index - 1
|
.filter![data.order?.isNotEmpty ==
|
||||||
: index]
|
true
|
||||||
.field]) ==
|
? index - 1
|
||||||
(item[childIndex] is PgcConditionOrder
|
: index]
|
||||||
? item[childIndex].field
|
.field]) ==
|
||||||
: item[childIndex].keyword)
|
(e is PgcConditionOrder ? e.field : e.keyword)
|
||||||
? theme.colorScheme.secondaryContainer
|
? theme.colorScheme.secondaryContainer
|
||||||
: Colors.transparent,
|
: Colors.transparent,
|
||||||
textColor:
|
textColor:
|
||||||
(item[childIndex] is PgcConditionOrder
|
(e is PgcConditionOrder
|
||||||
? _ctr.indexParams['order']
|
? _ctr.indexParams['order']
|
||||||
: _ctr.indexParams[data
|
: _ctr.indexParams[data
|
||||||
.filter![data.order?.isNotEmpty ==
|
.filter![data.order?.isNotEmpty ==
|
||||||
true
|
true
|
||||||
? index - 1
|
? index - 1
|
||||||
: index]
|
: index]
|
||||||
.field]) ==
|
.field]) ==
|
||||||
(item[childIndex] is PgcConditionOrder
|
(e is PgcConditionOrder ? e.field : e.keyword)
|
||||||
? item[childIndex].field
|
? theme.colorScheme.onSecondaryContainer
|
||||||
: item[childIndex].keyword)
|
: theme.colorScheme.onSurfaceVariant,
|
||||||
? theme.colorScheme.onSecondaryContainer
|
text: e.name,
|
||||||
: theme.colorScheme.onSurfaceVariant,
|
padding: const EdgeInsets.symmetric(
|
||||||
text: item[childIndex].name,
|
horizontal: 6,
|
||||||
padding: const EdgeInsets.symmetric(
|
vertical: 3,
|
||||||
horizontal: 6,
|
),
|
||||||
vertical: 3,
|
onTap: (_) {
|
||||||
|
String name = e is PgcConditionOrder
|
||||||
|
? 'order'
|
||||||
|
: data
|
||||||
|
.filter![data.order?.isNotEmpty == true
|
||||||
|
? index - 1
|
||||||
|
: index]
|
||||||
|
.field!;
|
||||||
|
_ctr.indexParams[name] = (e is PgcConditionOrder
|
||||||
|
? e.field
|
||||||
|
: e.keyword);
|
||||||
|
_ctr.onReload();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
onTap: (_) {
|
);
|
||||||
String name = item[childIndex] 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.onReload();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
itemCount: item!.length,
|
itemCount: item!.length,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1027,7 +1027,9 @@ class VideoDetailController extends GetxController
|
|||||||
.where((i) => i.id == currentVideoQa.code)
|
.where((i) => i.id == currentVideoQa.code)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
final List supportDecodeFormats = videoList.map((e) => e.codecs!).toList();
|
final List<String> supportDecodeFormats = videoList
|
||||||
|
.map((e) => e.codecs!)
|
||||||
|
.toList();
|
||||||
VideoDecodeFormatType defaultDecodeFormats =
|
VideoDecodeFormatType defaultDecodeFormats =
|
||||||
VideoDecodeFormatTypeExt.fromString(cacheDecode)!;
|
VideoDecodeFormatTypeExt.fromString(cacheDecode)!;
|
||||||
VideoDecodeFormatType secondDecodeFormats =
|
VideoDecodeFormatType secondDecodeFormats =
|
||||||
@@ -1264,7 +1266,7 @@ class VideoDetailController extends GetxController
|
|||||||
/// 优先顺序 设置中指定解码格式 -> 当前可选的首个解码格式
|
/// 优先顺序 设置中指定解码格式 -> 当前可选的首个解码格式
|
||||||
final List<FormatItem> supportFormats = data.supportFormats!;
|
final List<FormatItem> supportFormats = data.supportFormats!;
|
||||||
// 根据画质选编码格式
|
// 根据画质选编码格式
|
||||||
final List supportDecodeFormats = supportFormats
|
final List<String> supportDecodeFormats = supportFormats
|
||||||
.firstWhere(
|
.firstWhere(
|
||||||
(e) => e.quality == resVideoQa,
|
(e) => e.quality == resVideoQa,
|
||||||
orElse: () => supportFormats.first,
|
orElse: () => supportFormats.first,
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ class PgcIntroController extends CommonIntroController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool prevPlay() {
|
bool prevPlay() {
|
||||||
List episodes = pgcItem.episodes!;
|
final episodes = pgcItem.episodes!;
|
||||||
VideoDetailController videoDetailCtr = Get.find<VideoDetailController>(
|
VideoDetailController videoDetailCtr = Get.find<VideoDetailController>(
|
||||||
tag: Get.arguments['heroTag'],
|
tag: Get.arguments['heroTag'],
|
||||||
);
|
);
|
||||||
@@ -345,19 +345,21 @@ class PgcIntroController extends CommonIntroController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int epid = episodes[prevIndex].epId;
|
final episode = episodes[prevIndex];
|
||||||
int cid = episodes[prevIndex].cid;
|
changeSeasonOrbangu(
|
||||||
String bvid = episodes[prevIndex].bvid;
|
episode.epId,
|
||||||
int aid = episodes[prevIndex].aid;
|
episode.bvid,
|
||||||
dynamic cover = episodes[prevIndex].cover;
|
episode.cid,
|
||||||
changeSeasonOrbangu(epid, bvid, cid, aid, cover);
|
episode.aid,
|
||||||
|
episode.cover,
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 列表循环或者顺序播放时,自动播放下一个;自动连播时,播放相关视频
|
/// 列表循环或者顺序播放时,自动播放下一个;自动连播时,播放相关视频
|
||||||
bool nextPlay() {
|
bool nextPlay() {
|
||||||
try {
|
try {
|
||||||
List episodes = pgcItem.episodes!;
|
final episodes = pgcItem.episodes!;
|
||||||
VideoDetailController videoDetailCtr = Get.find<VideoDetailController>(
|
VideoDetailController videoDetailCtr = Get.find<VideoDetailController>(
|
||||||
tag: Get.arguments['heroTag'],
|
tag: Get.arguments['heroTag'],
|
||||||
);
|
);
|
||||||
@@ -377,12 +379,14 @@ class PgcIntroController extends CommonIntroController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int epid = episodes[nextIndex].epId;
|
final episode = episodes[nextIndex];
|
||||||
int cid = episodes[nextIndex].cid;
|
changeSeasonOrbangu(
|
||||||
String bvid = episodes[nextIndex].bvid;
|
episode.epId,
|
||||||
int aid = episodes[nextIndex].aid;
|
episode.bvid,
|
||||||
dynamic cover = episodes[nextIndex].cover;
|
episode.cid,
|
||||||
changeSeasonOrbangu(epid, bvid, cid, aid, cover);
|
episode.aid,
|
||||||
|
episode.cover,
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ class VideoReplyReplyPanel extends CommonSlidePage {
|
|||||||
this.isDialogue = false,
|
this.isDialogue = false,
|
||||||
this.onViewImage,
|
this.onViewImage,
|
||||||
this.onDismissed,
|
this.onDismissed,
|
||||||
this.onDispose,
|
|
||||||
});
|
});
|
||||||
final int? id;
|
final int? id;
|
||||||
final int oid;
|
final int oid;
|
||||||
@@ -40,7 +39,6 @@ class VideoReplyReplyPanel extends CommonSlidePage {
|
|||||||
final bool isDialogue;
|
final bool isDialogue;
|
||||||
final VoidCallback? onViewImage;
|
final VoidCallback? onViewImage;
|
||||||
final ValueChanged<int>? onDismissed;
|
final ValueChanged<int>? onDismissed;
|
||||||
final VoidCallback? onDispose;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<VideoReplyReplyPanel> createState() => _VideoReplyReplyPanelState();
|
State<VideoReplyReplyPanel> createState() => _VideoReplyReplyPanelState();
|
||||||
@@ -59,8 +57,9 @@ class _VideoReplyReplyPanelState
|
|||||||
ReplyInfo? get firstFloor => widget.firstFloor ?? _controller.firstFloor;
|
ReplyInfo? get firstFloor => widget.firstFloor ?? _controller.firstFloor;
|
||||||
|
|
||||||
bool get _horizontalPreview =>
|
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;
|
Animation<Color?>? colorAnimation;
|
||||||
|
|
||||||
@@ -83,36 +82,20 @@ class _VideoReplyReplyPanelState
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
widget.onDispose?.call();
|
|
||||||
Get.delete<VideoReplyReplyController>(tag: _tag);
|
Get.delete<VideoReplyReplyController>(tag: _tag);
|
||||||
super.dispose();
|
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
|
@override
|
||||||
Widget buildPage(ThemeData theme) {
|
Widget buildPage(ThemeData theme) {
|
||||||
|
_imageCallback = _horizontalPreview
|
||||||
|
? (imgList, index) => PageUtils.onHorizontalPreview(
|
||||||
|
_key,
|
||||||
|
this,
|
||||||
|
imgList,
|
||||||
|
index,
|
||||||
|
)
|
||||||
|
: null;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
key: _key,
|
key: _key,
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
@@ -146,9 +129,7 @@ class _VideoReplyReplyPanelState
|
|||||||
height: 1,
|
height: 1,
|
||||||
color: theme.dividerColor.withValues(alpha: 0.1),
|
color: theme.dividerColor.withValues(alpha: 0.1),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(child: enableSlide ? slideList(theme) : buildList(theme)),
|
||||||
child: enableSlide ? slideList(theme) : buildList(theme),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -190,7 +171,7 @@ class _VideoReplyReplyPanelState
|
|||||||
upMid: _controller.upMid,
|
upMid: _controller.upMid,
|
||||||
onViewImage: widget.onViewImage,
|
onViewImage: widget.onViewImage,
|
||||||
onDismissed: widget.onDismissed,
|
onDismissed: widget.onDismissed,
|
||||||
callback: _getImageCallback,
|
callback: _imageCallback,
|
||||||
onCheckReply: (item) =>
|
onCheckReply: (item) =>
|
||||||
_controller.onCheckReply(item, isManual: true),
|
_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(
|
Widget _sortWidget(ThemeData theme) => Container(
|
||||||
height: 40,
|
height: 40,
|
||||||
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
|
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
|
||||||
@@ -261,7 +265,7 @@ class _VideoReplyReplyPanelState
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
height: 35,
|
height: 35,
|
||||||
child: TextButton.icon(
|
child: TextButton.icon(
|
||||||
onPressed: () => _controller.queryBySort(),
|
onPressed: _controller.queryBySort,
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.sort,
|
Icons.sort,
|
||||||
size: 16,
|
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(
|
Widget _buildBody(
|
||||||
ThemeData theme,
|
ThemeData theme,
|
||||||
LoadingState<List<ReplyInfo>?> loadingState,
|
LoadingState<List<ReplyInfo>?> loadingState,
|
||||||
@@ -381,9 +355,7 @@ class _VideoReplyReplyPanelState
|
|||||||
replyLevel: widget.isDialogue ? 3 : 2,
|
replyLevel: widget.isDialogue ? 3 : 2,
|
||||||
onReply: (replyItem) =>
|
onReply: (replyItem) =>
|
||||||
_controller.onReply(context, replyItem: replyItem, index: index),
|
_controller.onReply(context, replyItem: replyItem, index: index),
|
||||||
onDelete: (item, subIndex) {
|
onDelete: (item, subIndex) => _controller.onRemove(index, item, null),
|
||||||
_controller.onRemove(index, item, null);
|
|
||||||
},
|
|
||||||
upMid: _controller.upMid,
|
upMid: _controller.upMid,
|
||||||
showDialogue: () => _key.currentState?.showBottomSheet(
|
showDialogue: () => _key.currentState?.showBottomSheet(
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
@@ -398,7 +370,7 @@ class _VideoReplyReplyPanelState
|
|||||||
),
|
),
|
||||||
onViewImage: widget.onViewImage,
|
onViewImage: widget.onViewImage,
|
||||||
onDismissed: widget.onDismissed,
|
onDismissed: widget.onDismissed,
|
||||||
callback: _getImageCallback,
|
callback: _imageCallback,
|
||||||
onCheckReply: (item) => _controller.onCheckReply(item, isManual: true),
|
onCheckReply: (item) => _controller.onCheckReply(item, isManual: true),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,16 +100,16 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
|||||||
bool get isFullScreen => plPlayerController?.isFullScreen.value ?? false;
|
bool get isFullScreen => plPlayerController?.isFullScreen.value ?? false;
|
||||||
|
|
||||||
bool get _shouldShowSeasonPanel {
|
bool get _shouldShowSeasonPanel {
|
||||||
final videoDetail = videoIntroController.videoDetail.value;
|
late final videoDetail = videoIntroController.videoDetail.value;
|
||||||
return (videoDetail.ugcSeason != null ||
|
return videoDetailController.plPlayerController.horizontalSeasonPanel &&
|
||||||
|
(videoDetail.ugcSeason != null ||
|
||||||
((videoDetail.pages?.length ?? 0) > 1)) &&
|
((videoDetail.pages?.length ?? 0) > 1)) &&
|
||||||
context.orientation == Orientation.landscape &&
|
context.orientation == Orientation.landscape;
|
||||||
videoDetailController.plPlayerController.horizontalSeasonPanel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get _horizontalPreview =>
|
bool get _horizontalPreview =>
|
||||||
context.orientation == Orientation.landscape &&
|
videoDetailController.plPlayerController.horizontalPreview &&
|
||||||
videoDetailController.plPlayerController.horizontalPreview;
|
context.orientation == Orientation.landscape;
|
||||||
|
|
||||||
StreamSubscription? _listenerFS;
|
StreamSubscription? _listenerFS;
|
||||||
|
|
||||||
@@ -2014,33 +2014,12 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
|||||||
onViewImage: videoDetailController.onViewImage,
|
onViewImage: videoDetailController.onViewImage,
|
||||||
onDismissed: videoDetailController.onDismissed,
|
onDismissed: videoDetailController.onDismissed,
|
||||||
callback: _horizontalPreview
|
callback: _horizontalPreview
|
||||||
? (imgList, index) {
|
? (imgList, index) => PageUtils.onHorizontalPreview(
|
||||||
final ctr = AnimationController(
|
videoDetailController.childKey,
|
||||||
vsync: this,
|
this,
|
||||||
duration: const Duration(milliseconds: 200),
|
imgList,
|
||||||
)..forward();
|
index,
|
||||||
PageUtils.onHorizontalPreview(
|
)
|
||||||
videoDetailController.childKey,
|
|
||||||
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,
|
: null,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -779,7 +779,7 @@ class HeaderControlState extends State<HeaderControl> {
|
|||||||
final VideoItem firstVideo = videoDetailCtr.firstVideo;
|
final VideoItem firstVideo = videoDetailCtr.firstVideo;
|
||||||
// 当前视频可用的解码格式
|
// 当前视频可用的解码格式
|
||||||
final List<FormatItem> videoFormat = videoInfo.supportFormats!;
|
final List<FormatItem> videoFormat = videoInfo.supportFormats!;
|
||||||
final List? list = videoFormat
|
final List<String>? list = videoFormat
|
||||||
.firstWhere((FormatItem e) => e.quality == firstVideo.quality.code)
|
.firstWhere((FormatItem e) => e.quality == firstVideo.quality.code)
|
||||||
.codecs;
|
.codecs;
|
||||||
if (list == null) {
|
if (list == null) {
|
||||||
@@ -829,7 +829,7 @@ class HeaderControlState extends State<HeaderControl> {
|
|||||||
VideoDecodeFormatTypeExt.fromString(i)!.description,
|
VideoDecodeFormatTypeExt.fromString(i)!.description,
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
i!,
|
i,
|
||||||
style: subTitleStyle,
|
style: subTitleStyle,
|
||||||
),
|
),
|
||||||
trailing: i.startsWith(currentDecodeFormats.code)
|
trailing: i.startsWith(currentDecodeFormats.code)
|
||||||
@@ -2054,7 +2054,7 @@ class HeaderControlState extends State<HeaderControl> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Obx(
|
Obx(
|
||||||
() => videoDetailCtr.segmentList.isNotEmpty == true
|
() => videoDetailCtr.segmentList.isNotEmpty
|
||||||
? SizedBox(
|
? SizedBox(
|
||||||
width: 42,
|
width: 42,
|
||||||
height: 34,
|
height: 34,
|
||||||
|
|||||||
@@ -515,12 +515,14 @@ class PageUtils {
|
|||||||
|
|
||||||
static void onHorizontalPreview(
|
static void onHorizontalPreview(
|
||||||
GlobalKey<ScaffoldState> key,
|
GlobalKey<ScaffoldState> key,
|
||||||
transitionAnimationController,
|
TickerProvider vsync,
|
||||||
ctr,
|
|
||||||
List<String> imgList,
|
List<String> imgList,
|
||||||
index,
|
int index,
|
||||||
onClose,
|
|
||||||
) {
|
) {
|
||||||
|
final ctr = AnimationController(
|
||||||
|
vsync: vsync,
|
||||||
|
duration: const Duration(milliseconds: 200),
|
||||||
|
)..forward();
|
||||||
key.currentState?.showBottomSheet(
|
key.currentState?.showBottomSheet(
|
||||||
(context) {
|
(context) {
|
||||||
return FadeTransition(
|
return FadeTransition(
|
||||||
@@ -529,7 +531,17 @@ class PageUtils {
|
|||||||
sources: imgList.map((url) => SourceModel(url: url)).toList(),
|
sources: imgList.map((url) => SourceModel(url: url)).toList(),
|
||||||
initIndex: index,
|
initIndex: index,
|
||||||
setStatusBar: false,
|
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,
|
quality: GlobalData().imgQuality,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -537,7 +549,6 @@ class PageUtils {
|
|||||||
enableDrag: false,
|
enableDrag: false,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
transitionAnimationController: transitionAnimationController,
|
|
||||||
sheetAnimationStyle: const AnimationStyle(duration: Duration.zero),
|
sheetAnimationStyle: const AnimationStyle(duration: Duration.zero),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user