mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
refa: vertical video page (#328)
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -2,7 +2,6 @@ import 'package:PiliPlus/common/widgets/image_save.dart';
|
||||
import 'package:PiliPlus/models/model_hot_video_item.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../http/search.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../constants.dart';
|
||||
@@ -88,8 +87,8 @@ class VideoCardH extends StatelessWidget {
|
||||
try {
|
||||
final int cid = videoItem.cid ??
|
||||
await SearchHttp.ab2c(aid: aid, bvid: bvid);
|
||||
Get.toNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'videoItem': videoItem,
|
||||
'heroTag': Utils.makeHeroTag(aid)
|
||||
|
||||
@@ -6,7 +6,6 @@ import 'package:PiliPlus/common/widgets/video_progress_indicator.dart';
|
||||
import 'package:PiliPlus/models/space_archive/item.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../constants.dart';
|
||||
import 'badge.dart';
|
||||
@@ -48,8 +47,8 @@ class VideoCardHMemberVideo extends StatelessWidget {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Get.toNamed(
|
||||
'/video?bvid=${videoItem.bvid}&cid=${videoItem.firstCid}',
|
||||
Utils.toViewPage(
|
||||
'bvid=${videoItem.bvid}&cid=${videoItem.firstCid}',
|
||||
arguments: {
|
||||
'heroTag': Utils.makeHeroTag(videoItem.bvid),
|
||||
},
|
||||
|
||||
@@ -43,8 +43,8 @@ class VideoCardV extends StatelessWidget {
|
||||
if (cid == -1) {
|
||||
cid = await SearchHttp.ab2c(aid: videoItem.aid, bvid: bvid);
|
||||
}
|
||||
Get.toNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
// 'videoItem': videoItem,
|
||||
'pic': videoItem.pic,
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'package:PiliPlus/common/widgets/image_save.dart';
|
||||
import 'package:PiliPlus/models/space/item.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import '../../utils/utils.dart';
|
||||
import '../constants.dart';
|
||||
import 'badge.dart';
|
||||
@@ -30,8 +29,8 @@ class VideoCardVMemberHome extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
String bvid = videoItem.bvid ?? '';
|
||||
Get.toNamed(
|
||||
'/video?bvid=$bvid&cid=${videoItem.firstCid}',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=${videoItem.firstCid}',
|
||||
arguments: {
|
||||
// 'videoItem': videoItem,
|
||||
'pic': videoItem.cover,
|
||||
|
||||
@@ -29,45 +29,6 @@ class BangumiCardV extends StatelessWidget {
|
||||
onTap: () async {
|
||||
final int seasonId = bangumiItem.seasonId;
|
||||
Utils.viewBangumi(seasonId: seasonId);
|
||||
// SmartDialog.showLoading(msg: '获取中...');
|
||||
// final res = await SearchHttp.bangumiInfo(seasonId: seasonId);
|
||||
// SmartDialog.dismiss().then((value) {
|
||||
// if (res['status']) {
|
||||
// if (res['data'].episodes.isEmpty) {
|
||||
// SmartDialog.showToast('资源加载失败');
|
||||
// return;
|
||||
// }
|
||||
// EpisodeItem episode = res['data'].episodes.first;
|
||||
// int? epId = res['data'].userStatus?.progress?.lastEpId;
|
||||
// if (epId == null) {
|
||||
// epId = episode.epId;
|
||||
// } else {
|
||||
// for (var item in res['data'].episodes) {
|
||||
// if (item.epId == epId) {
|
||||
// episode = item;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// String bvid = episode.bvid!;
|
||||
// int cid = episode.cid!;
|
||||
// String pic = episode.cover!;
|
||||
// // debugPrint('epId');
|
||||
// // debugPrint(epId);
|
||||
// String heroTag = Utils.makeHeroTag(cid);
|
||||
// Get.toNamed(
|
||||
// '/video?bvid=$bvid&cid=$cid&seasonId=$seasonId&epId=$epId',
|
||||
// arguments: {
|
||||
// 'pic': pic,
|
||||
// 'heroTag': heroTag,
|
||||
// 'videoType': SearchType.media_bangumi,
|
||||
// 'bangumiItem': res['data'],
|
||||
// },
|
||||
// );
|
||||
// } else {
|
||||
// SmartDialog.showToast(res['msg']);
|
||||
// }
|
||||
// });
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
|
||||
@@ -24,45 +24,6 @@ class BangumiCardVMemberHome extends StatelessWidget {
|
||||
onTap: () async {
|
||||
final int seasonId = int.tryParse(bangumiItem.param ?? '') ?? -1;
|
||||
Utils.viewBangumi(seasonId: seasonId);
|
||||
// SmartDialog.showLoading(msg: '获取中...');
|
||||
// final res = await SearchHttp.bangumiInfo(seasonId: seasonId);
|
||||
// SmartDialog.dismiss().then((value) {
|
||||
// if (res['status']) {
|
||||
// if (res['data'].episodes.isEmpty) {
|
||||
// SmartDialog.showToast('资源加载失败');
|
||||
// return;
|
||||
// }
|
||||
// EpisodeItem episode = res['data'].episodes.first;
|
||||
// int? epId = res['data'].userStatus?.progress?.lastEpId;
|
||||
// if (epId == null) {
|
||||
// epId = episode.epId;
|
||||
// } else {
|
||||
// for (var item in res['data'].episodes) {
|
||||
// if (item.epId == epId) {
|
||||
// episode = item;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// String bvid = episode.bvid!;
|
||||
// int cid = episode.cid!;
|
||||
// String pic = episode.cover!;
|
||||
// // debugPrint('epId');
|
||||
// // debugPrint(epId);
|
||||
// String heroTag = Utils.makeHeroTag(cid);
|
||||
// Get.toNamed(
|
||||
// '/video?bvid=$bvid&cid=$cid&seasonId=$seasonId&epId=$epId',
|
||||
// arguments: {
|
||||
// 'pic': pic,
|
||||
// 'heroTag': heroTag,
|
||||
// 'videoType': SearchType.media_bangumi,
|
||||
// 'bangumiItem': res['data'],
|
||||
// },
|
||||
// );
|
||||
// } else {
|
||||
// SmartDialog.showToast(res['msg']);
|
||||
// }
|
||||
// });
|
||||
},
|
||||
onLongPress: () => imageSaveDialog(
|
||||
context: context,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||
import 'package:PiliPlus/http/search.dart';
|
||||
|
||||
@@ -35,8 +34,8 @@ Widget addWidget(item, context, type, {floor = 1}) {
|
||||
String cover = dynamicProperty[type].cover;
|
||||
try {
|
||||
int cid = await SearchHttp.ab2c(bvid: bvid);
|
||||
Get.toNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'pic': cover,
|
||||
'heroTag': Utils.makeHeroTag(bvid),
|
||||
|
||||
@@ -238,8 +238,8 @@ InlineSpan? richNode(item, context) {
|
||||
onTap: () async {
|
||||
try {
|
||||
int cid = await SearchHttp.ab2c(bvid: i.rid);
|
||||
Get.toNamed(
|
||||
'/video?bvid=${i.rid}&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=${i.rid}&cid=$cid',
|
||||
arguments: {
|
||||
'pic': null,
|
||||
'heroTag': Utils.makeHeroTag(i.rid),
|
||||
|
||||
@@ -145,8 +145,8 @@ class FavDetailController extends MultiSelectController {
|
||||
if (element.bvid != list.first.bvid) {
|
||||
SmartDialog.showToast('已跳过不支持播放的视频');
|
||||
}
|
||||
Get.toNamed(
|
||||
'/video?bvid=${element.bvid}&cid=${element.cid}',
|
||||
Utils.toViewPage(
|
||||
'bvid=${element.bvid}&cid=${element.cid}',
|
||||
arguments: {
|
||||
'videoItem': element,
|
||||
'heroTag': Utils.makeHeroTag(element.bvid),
|
||||
|
||||
@@ -67,8 +67,8 @@ class FavVideoCardH extends StatelessWidget {
|
||||
// if (seasonId != null) {
|
||||
// parameters['seasonId'] = seasonId.toString();
|
||||
// }
|
||||
Get.toNamed(
|
||||
'/video',
|
||||
Utils.toViewPage(
|
||||
'',
|
||||
parameters: parameters,
|
||||
arguments: {
|
||||
'videoItem': videoItem,
|
||||
|
||||
@@ -89,8 +89,8 @@ class HistoryItem extends StatelessWidget {
|
||||
} else {
|
||||
int cid = videoItem.history.cid ??
|
||||
await SearchHttp.ab2c(aid: aid, bvid: bvid);
|
||||
Get.toNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'heroTag': Utils.makeHeroTag(cid),
|
||||
'pic': videoItem.cover,
|
||||
@@ -103,49 +103,14 @@ class HistoryItem extends StatelessWidget {
|
||||
} else {
|
||||
if (videoItem.history.epid != '') {
|
||||
Utils.viewBangumi(epId: videoItem.history.epid);
|
||||
// SmartDialog.showLoading(msg: '获取中...');
|
||||
// var res =
|
||||
// await SearchHttp.bangumiInfo(epId: videoItem.history.epid);
|
||||
// SmartDialog.dismiss();
|
||||
// if (res['status']) {
|
||||
// var bangumiDetail = res['data'];
|
||||
// EpisodeItem episode = res['data'].episodes.first;
|
||||
// int? epId = res['data'].userStatus?.progress?.lastEpId;
|
||||
// if (epId == null) {
|
||||
// epId = episode.epId;
|
||||
// } else {
|
||||
// for (var item in res['data'].episodes) {
|
||||
// if (item.epId == epId) {
|
||||
// episode = item;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// String bvid = episode.bvid!;
|
||||
// int cid = episode.cid!;
|
||||
// String pic = episode.cover!;
|
||||
// String seasonId = bangumiDetail.seasonId;
|
||||
// dynamic heroTag = Utils.makeHeroTag(cid);
|
||||
// Get.toNamed(
|
||||
// '/video?bvid=$bvid&cid=$cid&seasonId=$seasonId&epId=$epId',
|
||||
// arguments: {
|
||||
// 'pic': pic,
|
||||
// 'heroTag': heroTag,
|
||||
// 'videoType': SearchType.media_bangumi,
|
||||
// 'bangumiItem': res['data'],
|
||||
// },
|
||||
// );
|
||||
// } else {
|
||||
// SmartDialog.showToast(res['msg']);
|
||||
// }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int cid = videoItem.history.cid ??
|
||||
// videoItem.history.oid ??
|
||||
await SearchHttp.ab2c(aid: aid, bvid: bvid);
|
||||
Get.toNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'heroTag': Utils.makeHeroTag(aid),
|
||||
'pic': videoItem.cover,
|
||||
|
||||
@@ -164,8 +164,8 @@ class LaterController extends MultiSelectController {
|
||||
if (item.bvid != list.first.bvid) {
|
||||
SmartDialog.showToast('已跳过不支持播放的视频');
|
||||
}
|
||||
Get.toNamed(
|
||||
'/video?bvid=${item.bvid}&cid=${item.cid}',
|
||||
Utils.toViewPage(
|
||||
'bvid=${item.bvid}&cid=${item.cid}',
|
||||
arguments: {
|
||||
'videoItem': item,
|
||||
'heroTag': Utils.makeHeroTag(item.bvid),
|
||||
|
||||
@@ -104,8 +104,8 @@ class MemberVideoCtr extends CommonController {
|
||||
?.group(1);
|
||||
dynamic bvid = IdUtils.av2bv(int.tryParse(oid) ?? 0);
|
||||
dynamic cid = await SearchHttp.ab2c(aid: oid, bvid: bvid);
|
||||
Get.toNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'heroTag': Utils.makeHeroTag(oid),
|
||||
'sourceType': 'archive',
|
||||
@@ -145,8 +145,8 @@ class MemberVideoCtr extends CommonController {
|
||||
: sort.value == 'asc')
|
||||
? desc.not
|
||||
: desc;
|
||||
Get.toNamed(
|
||||
'/video?bvid=${element.bvid}&cid=${element.firstCid}',
|
||||
Utils.toViewPage(
|
||||
'bvid=${element.bvid}&cid=${element.firstCid}',
|
||||
arguments: {
|
||||
'videoItem': element,
|
||||
'heroTag': Utils.makeHeroTag(element.bvid),
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:PiliPlus/common/widgets/image_save.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||
@@ -26,8 +25,8 @@ class MemberCoinsItem extends StatelessWidget {
|
||||
onTap: () async {
|
||||
int cid =
|
||||
await SearchHttp.ab2c(aid: coinItem.aid, bvid: coinItem.bvid);
|
||||
Get.toNamed(
|
||||
'/video?bvid=${coinItem.bvid}&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=${coinItem.bvid}&cid=$cid',
|
||||
arguments: {
|
||||
'videoItem': coinItem,
|
||||
'heroTag': Utils.makeHeroTag(coinItem.aid)
|
||||
|
||||
@@ -256,8 +256,8 @@ class SearchDynamic extends StatelessWidget {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
Get.toNamed(
|
||||
'/video?bvid=${IdUtils.av2bv(json['aid'])}&cid=${json['cid']}',
|
||||
Utils.toViewPage(
|
||||
'bvid=${IdUtils.av2bv(json['aid'])}&cid=${json['cid']}',
|
||||
arguments: {
|
||||
'heroTag': Utils.makeHeroTag(json['aid']),
|
||||
},
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/badge.dart';
|
||||
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||
@@ -25,8 +24,8 @@ class MemberSeasonsItem extends StatelessWidget {
|
||||
onTap: () async {
|
||||
int cid =
|
||||
await SearchHttp.ab2c(aid: seasonItem.aid, bvid: seasonItem.bvid);
|
||||
Get.toNamed(
|
||||
'/video?bvid=${seasonItem.bvid}&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=${seasonItem.bvid}&cid=$cid',
|
||||
arguments: {
|
||||
'videoItem': seasonItem,
|
||||
'heroTag': Utils.makeHeroTag(seasonItem.aid)
|
||||
|
||||
@@ -2101,6 +2101,16 @@ List<SettingsModel> get extraSettings => [
|
||||
setKey: SettingBoxKey.antiGoodsReply,
|
||||
defaultVal: false,
|
||||
),
|
||||
SettingsModel(
|
||||
settingsType: SettingsType.sw1tch,
|
||||
title: '使用可折叠的播放页面',
|
||||
leading: Icon(Icons.video_settings),
|
||||
setKey: SettingBoxKey.collapsibleVideoPage,
|
||||
defaultVal: false,
|
||||
onChanged: (value) {
|
||||
GStorage.collapsibleVideoPage = value;
|
||||
},
|
||||
),
|
||||
SettingsModel(
|
||||
settingsType: SettingsType.sw1tch,
|
||||
enableFeedback: true,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:PiliPlus/common/widgets/image_save.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/stat/danmu.dart';
|
||||
@@ -34,8 +33,8 @@ class SubVideoCardH extends StatelessWidget {
|
||||
'cid': cid.toString(),
|
||||
};
|
||||
|
||||
Get.toNamed(
|
||||
'/video',
|
||||
Utils.toViewPage(
|
||||
'',
|
||||
parameters: parameters,
|
||||
arguments: {
|
||||
'videoItem': videoItem,
|
||||
|
||||
@@ -27,6 +27,7 @@ import 'package:PiliPlus/utils/extension.dart';
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
|
||||
import 'package:floating/floating.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@@ -126,6 +127,9 @@ class VideoDetailController extends GetxController
|
||||
PlayerStatus? playerStatus;
|
||||
StreamSubscription<Duration>? positionSubscription;
|
||||
|
||||
late final scrollKey = GlobalKey<ExtendedNestedScrollViewState>();
|
||||
late final RxString direction = 'horizontal'.obs;
|
||||
|
||||
bool imageStatus = false;
|
||||
|
||||
void onViewImage() {
|
||||
@@ -1082,6 +1086,11 @@ class VideoDetailController extends GetxController
|
||||
baseUrl: videoUrl,
|
||||
codecs: 'avc1',
|
||||
quality: VideoQualityCode.fromCode(data.quality!)!);
|
||||
direction.value = firstVideo.width != null && firstVideo.height != null
|
||||
? firstVideo.width! > firstVideo.height!
|
||||
? 'horizontal'
|
||||
: 'vertical'
|
||||
: 'horizontal';
|
||||
currentDecodeFormats = VideoDecodeFormatsCode.fromString('avc1')!;
|
||||
currentVideoQa = VideoQualityCode.fromCode(data.quality!)!;
|
||||
if (autoPlay.value) {
|
||||
@@ -1152,6 +1161,11 @@ class VideoDetailController extends GetxController
|
||||
firstVideo = videosList.firstWhere(
|
||||
(e) => e.codecs!.startsWith(currentDecodeFormats.code),
|
||||
orElse: () => videosList.first);
|
||||
direction.value = firstVideo.width != null && firstVideo.height != null
|
||||
? firstVideo.width! > firstVideo.height!
|
||||
? 'horizontal'
|
||||
: 'vertical'
|
||||
: 'horizontal';
|
||||
|
||||
// videoUrl = enableCDN
|
||||
// ? VideoUtils.getCdnUrl(firstVideo)
|
||||
|
||||
@@ -821,13 +821,6 @@ class VideoIntroController extends GetxController
|
||||
(relatedCtr.loadingState.value as Success).response[0];
|
||||
try {
|
||||
if (videoItem.cid != null) {
|
||||
// Get.offNamed(
|
||||
// '/video?bvid=${videoItem.bvid}&cid=${videoItem.cid}',
|
||||
// arguments: {
|
||||
// 'videoItem': videoItem,
|
||||
// 'heroTag': heroTag,
|
||||
// },
|
||||
// );
|
||||
changeSeasonOrbangu(
|
||||
null,
|
||||
videoItem.bvid,
|
||||
@@ -837,12 +830,14 @@ class VideoIntroController extends GetxController
|
||||
);
|
||||
} else {
|
||||
SearchHttp.ab2c(aid: videoItem.aid, bvid: videoItem.bvid).then(
|
||||
(cid) => Get.offNamed(
|
||||
'/video?bvid=${videoItem.bvid}&cid=${videoItem.cid}',
|
||||
arguments: {
|
||||
'videoItem': videoItem,
|
||||
'heroTag': heroTag,
|
||||
}),
|
||||
(cid) => Utils.toViewPage(
|
||||
'bvid=${videoItem.bvid}&cid=${videoItem.cid}',
|
||||
arguments: {
|
||||
'videoItem': videoItem,
|
||||
'heroTag': heroTag,
|
||||
},
|
||||
off: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -305,8 +305,9 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
final ThemeData t = Theme.of(context);
|
||||
return SliverLayoutBuilder(
|
||||
builder: (BuildContext context, SliverConstraints constraints) {
|
||||
bool isHorizontal = constraints.crossAxisExtent >
|
||||
constraints.viewportMainAxisExtent * 1.25;
|
||||
// bool isHorizontal = constraints.crossAxisExtent >
|
||||
// constraints.viewportMainAxisExtent * 1.25;
|
||||
bool isHorizontal = context.orientation == Orientation.landscape;
|
||||
return SliverPadding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: StyleString.safeSpace,
|
||||
|
||||
@@ -6,8 +6,11 @@ import 'package:PiliPlus/http/reply.dart';
|
||||
import 'package:PiliPlus/utils/global_data.dart';
|
||||
import 'package:PiliPlus/utils/id_utils.dart';
|
||||
import 'package:fixnum/fixnum.dart' as $fixnum;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get_state_manager/src/rx_flutter/rx_ticket_provider_mixin.dart';
|
||||
|
||||
class VideoReplyController extends ReplyController {
|
||||
class VideoReplyController extends ReplyController
|
||||
with GetTickerProviderStateMixin {
|
||||
VideoReplyController({required this.aid});
|
||||
// 视频aid 请求时使用的oid
|
||||
int aid;
|
||||
@@ -15,6 +18,25 @@ class VideoReplyController extends ReplyController {
|
||||
@override
|
||||
dynamic get sourceId => IdUtils.av2bv(aid);
|
||||
|
||||
bool _isFabVisible = true;
|
||||
late final AnimationController fabAnimationCtr = AnimationController(
|
||||
vsync: this, duration: const Duration(milliseconds: 100))
|
||||
..forward();
|
||||
|
||||
void showFab() {
|
||||
if (!_isFabVisible) {
|
||||
_isFabVisible = true;
|
||||
fabAnimationCtr.forward();
|
||||
}
|
||||
}
|
||||
|
||||
void hideFab() {
|
||||
if (_isFabVisible) {
|
||||
_isFabVisible = false;
|
||||
fabAnimationCtr.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<LoadingState> customGetData() => GlobalData().grpcReply
|
||||
? ReplyHttp.replyListGrpc(
|
||||
@@ -34,4 +56,10 @@ class VideoReplyController extends ReplyController {
|
||||
page: currentPage,
|
||||
antiGoodsReply: antiGoodsReply,
|
||||
);
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
fabAnimationCtr.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ class VideoReplyPanel extends StatefulWidget {
|
||||
final VoidCallback? onViewImage;
|
||||
final ValueChanged<int>? onDismissed;
|
||||
final Function(List<String>, int)? callback;
|
||||
final bool? needController;
|
||||
|
||||
const VideoReplyPanel({
|
||||
super.key,
|
||||
@@ -38,6 +39,7 @@ class VideoReplyPanel extends StatefulWidget {
|
||||
this.onViewImage,
|
||||
this.onDismissed,
|
||||
this.callback,
|
||||
this.needController,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -47,9 +49,7 @@ class VideoReplyPanel extends StatefulWidget {
|
||||
class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
with AutomaticKeepAliveClientMixin, TickerProviderStateMixin {
|
||||
late VideoReplyController _videoReplyController;
|
||||
late AnimationController fabAnimationCtr;
|
||||
|
||||
bool _isFabVisible = true;
|
||||
String replyLevel = '1';
|
||||
late String heroTag;
|
||||
|
||||
@@ -66,52 +66,33 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
replyLevel = widget.replyLevel ?? '1';
|
||||
_videoReplyController = Get.find<VideoReplyController>(tag: heroTag);
|
||||
|
||||
fabAnimationCtr = AnimationController(
|
||||
vsync: this, duration: const Duration(milliseconds: 100));
|
||||
|
||||
fabAnimationCtr.forward();
|
||||
scrollListener();
|
||||
if (widget.needController != false) {
|
||||
_videoReplyController.scrollController.addListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_videoReplyController.scrollController.removeListener(listener);
|
||||
fabAnimationCtr.dispose();
|
||||
if (widget.needController != false) {
|
||||
_videoReplyController.scrollController.removeListener(listener);
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void scrollListener() {
|
||||
_videoReplyController.scrollController.addListener(listener);
|
||||
}
|
||||
|
||||
void listener() {
|
||||
final ScrollDirection direction =
|
||||
_videoReplyController.scrollController.position.userScrollDirection;
|
||||
if (direction == ScrollDirection.forward) {
|
||||
if (mounted) {
|
||||
_showFab();
|
||||
_videoReplyController.showFab();
|
||||
}
|
||||
} else if (direction == ScrollDirection.reverse) {
|
||||
if (mounted) {
|
||||
_hideFab();
|
||||
_videoReplyController.hideFab();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _showFab() {
|
||||
if (!_isFabVisible) {
|
||||
_isFabVisible = true;
|
||||
fabAnimationCtr.forward();
|
||||
}
|
||||
}
|
||||
|
||||
void _hideFab() {
|
||||
if (_isFabVisible) {
|
||||
_isFabVisible = false;
|
||||
fabAnimationCtr.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
@@ -122,8 +103,14 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
child: Stack(
|
||||
children: [
|
||||
CustomScrollView(
|
||||
controller: _videoReplyController.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: widget.needController == false
|
||||
? null
|
||||
: _videoReplyController.scrollController,
|
||||
physics: widget.needController == false
|
||||
? const NeverScrollableScrollPhysics(
|
||||
parent: ClampingScrollPhysics(),
|
||||
)
|
||||
: const AlwaysScrollableScrollPhysics(),
|
||||
// key: const PageStorageKey<String>('评论'),
|
||||
slivers: <Widget>[
|
||||
SliverPersistentHeader(
|
||||
@@ -182,7 +169,7 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
||||
begin: const Offset(0, 2),
|
||||
end: const Offset(0, 0),
|
||||
).animate(CurvedAnimation(
|
||||
parent: fabAnimationCtr,
|
||||
parent: _videoReplyController.fabAnimationCtr,
|
||||
curve: Curves.easeInOut,
|
||||
)),
|
||||
child: FloatingActionButton(
|
||||
|
||||
2359
lib/pages/video/detail/view_v.dart
Normal file
2359
lib/pages/video/detail/view_v.dart
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,6 @@ import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactivevie
|
||||
import 'package:PiliPlus/utils/extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:PiliPlus/common/widgets/network_img_layer.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
|
||||
@@ -182,8 +181,8 @@ class ChatItem extends StatelessWidget {
|
||||
var bvid = content["bvid"];
|
||||
final int cid = await SearchHttp.ab2c(bvid: bvid);
|
||||
SmartDialog.dismiss<dynamic>().then(
|
||||
(e) => Get.toNamed<dynamic>(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
(e) => Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: <String, String?>{
|
||||
'pic': content['thumb'],
|
||||
'heroTag': Utils.makeHeroTag(bvid),
|
||||
@@ -230,8 +229,8 @@ class ChatItem extends StatelessWidget {
|
||||
var bvid = content["bvid"];
|
||||
final int cid = await SearchHttp.ab2c(bvid: bvid);
|
||||
SmartDialog.dismiss().then(
|
||||
(_) => Get.toNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
(_) => Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'pic': content['thumb'],
|
||||
'heroTag': Utils.makeHeroTag(bvid),
|
||||
@@ -317,8 +316,7 @@ class ChatItem extends StatelessWidget {
|
||||
SmartDialog.showLoading();
|
||||
final int cid = await SearchHttp.ab2c(bvid: bvid);
|
||||
SmartDialog.dismiss<dynamic>().then(
|
||||
(e) => Get.toNamed<dynamic>(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
(e) => Utils.toViewPage('bvid=$bvid&cid=$cid',
|
||||
arguments: <String, String?>{
|
||||
'pic': i['cover_url'],
|
||||
'heroTag': Utils.makeHeroTag(bvid),
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:PiliPlus/pages/setting/search_page.dart';
|
||||
import 'package:PiliPlus/pages/setting/sponsor_block_page.dart';
|
||||
import 'package:PiliPlus/pages/setting/view.dart';
|
||||
import 'package:PiliPlus/pages/video/detail/introduction/widgets/create_fav_page.dart';
|
||||
import 'package:PiliPlus/pages/video/detail/view_v.dart';
|
||||
import 'package:PiliPlus/pages/webview/webview_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -63,6 +64,7 @@ class Routes {
|
||||
CustomGetPage(name: '/hot', page: () => const HotPage()),
|
||||
// 视频详情
|
||||
CustomGetPage(name: '/video', page: () => const VideoDetailPage()),
|
||||
CustomGetPage(name: '/videoV', page: () => const VideoDetailPageV()),
|
||||
//
|
||||
CustomGetPage(name: '/webview', page: () => const WebviewPageNew()),
|
||||
// 设置
|
||||
|
||||
@@ -134,8 +134,8 @@ class PiliScheme {
|
||||
if (aid != null || bvid != null) {
|
||||
if (queryParameters['cid'] != null) {
|
||||
bvid ??= IdUtils.av2bv(int.parse(aid!));
|
||||
Utils.toDupNamed(
|
||||
'/video?bvid=$bvid&cid=${queryParameters['cid']}',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=${queryParameters['cid']}',
|
||||
arguments: {
|
||||
'pic': null,
|
||||
'heroTag': Utils.makeHeroTag(aid),
|
||||
@@ -143,6 +143,7 @@ class PiliScheme {
|
||||
'progress': int.tryParse(queryParameters['dm_progress']!),
|
||||
},
|
||||
off: off,
|
||||
preventDuplicates: false,
|
||||
);
|
||||
} else {
|
||||
videoPush(
|
||||
@@ -566,14 +567,15 @@ class PiliScheme {
|
||||
if (showDialog) {
|
||||
SmartDialog.dismiss();
|
||||
}
|
||||
Utils.toDupNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'pic': null,
|
||||
'heroTag': Utils.makeHeroTag(aid),
|
||||
if (progress != null) 'progress': int.tryParse(progress),
|
||||
},
|
||||
off: off,
|
||||
preventDuplicates: false,
|
||||
);
|
||||
} catch (e) {
|
||||
SmartDialog.dismiss();
|
||||
|
||||
@@ -388,6 +388,9 @@ class GStorage {
|
||||
static bool get expandDynLivePanel => GStorage.setting
|
||||
.get(SettingBoxKey.expandDynLivePanel, defaultValue: false);
|
||||
|
||||
static bool collapsibleVideoPage = GStorage.setting
|
||||
.get(SettingBoxKey.collapsibleVideoPage, defaultValue: true);
|
||||
|
||||
static List<double> get dynamicDetailRatio => List<double>.from(setting
|
||||
.get(SettingBoxKey.dynamicDetailRatio, defaultValue: [60.0, 40.0]));
|
||||
|
||||
@@ -640,6 +643,7 @@ class SettingBoxKey {
|
||||
antiGoodsReply = 'antiGoodsReply',
|
||||
expandDynLivePanel = 'expandDynLivePanel',
|
||||
springDescription = 'springDescription',
|
||||
collapsibleVideoPage = 'collapsibleVideoPage',
|
||||
|
||||
// Sponsor Block
|
||||
enableSponsorBlock = 'enableSponsorBlock',
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../http/init.dart';
|
||||
import '../http/search.dart';
|
||||
@@ -66,8 +65,8 @@ class UrlUtils {
|
||||
String? bvid = matchRes['BV'];
|
||||
bvid ??= IdUtils.av2bv(aid!);
|
||||
final int cid = await SearchHttp.ab2c(aid: aid, bvid: bvid);
|
||||
await Get.toNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: <String, String?>{
|
||||
'pic': '',
|
||||
'heroTag': Utils.makeHeroTag(bvid),
|
||||
|
||||
@@ -48,6 +48,33 @@ class Utils {
|
||||
|
||||
static const channel = MethodChannel("PiliPlus");
|
||||
|
||||
static void toViewPage(
|
||||
String page, {
|
||||
dynamic arguments,
|
||||
int? id,
|
||||
bool preventDuplicates = true,
|
||||
Map<String, String>? parameters,
|
||||
bool off = false,
|
||||
}) {
|
||||
if (off) {
|
||||
Get.offNamed(
|
||||
'${GStorage.collapsibleVideoPage ? '/videoV' : '/video'}?$page',
|
||||
arguments: arguments,
|
||||
id: id,
|
||||
preventDuplicates: preventDuplicates,
|
||||
parameters: parameters,
|
||||
);
|
||||
} else {
|
||||
Get.toNamed(
|
||||
'${GStorage.collapsibleVideoPage ? '/videoV' : '/video'}?$page',
|
||||
arguments: arguments,
|
||||
id: id,
|
||||
preventDuplicates: preventDuplicates,
|
||||
parameters: parameters,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static Future insertCreatedDyn(result) async {
|
||||
try {
|
||||
dynamic id = result['data']['dyn_id'];
|
||||
@@ -384,12 +411,13 @@ class Utils {
|
||||
String bvid = item.modules.moduleDynamic.major.archive.bvid;
|
||||
String cover = item.modules.moduleDynamic.major.archive.cover;
|
||||
int cid = await SearchHttp.ab2c(bvid: bvid);
|
||||
Utils.toDupNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'pic': cover,
|
||||
'heroTag': Utils.makeHeroTag(bvid),
|
||||
},
|
||||
preventDuplicates: false,
|
||||
);
|
||||
} catch (err) {
|
||||
SmartDialog.showToast(err.toString());
|
||||
@@ -454,12 +482,13 @@ class Utils {
|
||||
String bvid = IdUtils.av2bv(aid);
|
||||
String cover = ugcSeason.cover!;
|
||||
int cid = await SearchHttp.ab2c(bvid: bvid);
|
||||
Utils.toDupNamed(
|
||||
'/video?bvid=$bvid&cid=$cid',
|
||||
Utils.toViewPage(
|
||||
'bvid=$bvid&cid=$cid',
|
||||
arguments: {
|
||||
'pic': cover,
|
||||
'heroTag': Utils.makeHeroTag(bvid),
|
||||
},
|
||||
preventDuplicates: false,
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -845,14 +874,15 @@ class Utils {
|
||||
for (EpisodeItem item in item.episodes!) {
|
||||
if (item.epId.toString() == epId.toString()) {
|
||||
// view as normal video
|
||||
Utils.toDupNamed(
|
||||
'/video?bvid=${item.bvid}&cid=${item.cid}&seasonId=${data.seasonId}&epId=${item.epId}',
|
||||
Utils.toViewPage(
|
||||
'bvid=${item.bvid}&cid=${item.cid}&seasonId=${data.seasonId}&epId=${item.epId}',
|
||||
arguments: {
|
||||
'pgcApi': true,
|
||||
'pic': item.cover,
|
||||
'heroTag': Utils.makeHeroTag(item.cid),
|
||||
'videoType': SearchType.video,
|
||||
},
|
||||
preventDuplicates: false,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -873,14 +903,15 @@ class Utils {
|
||||
) ??
|
||||
data.episodes!.first
|
||||
: data.episodes!.first;
|
||||
Utils.toDupNamed(
|
||||
'/video?bvid=${episode.bvid}&cid=${episode.cid}&seasonId=${data.seasonId}&epId=${episode.epId}&type=${data.type}',
|
||||
Utils.toViewPage(
|
||||
'bvid=${episode.bvid}&cid=${episode.cid}&seasonId=${data.seasonId}&epId=${episode.epId}&type=${data.type}',
|
||||
arguments: {
|
||||
'pic': episode.cover,
|
||||
'heroTag': Utils.makeHeroTag(episode.cid),
|
||||
'videoType': SearchType.media_bangumi,
|
||||
'bangumiItem': data,
|
||||
},
|
||||
preventDuplicates: false,
|
||||
);
|
||||
} else {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
|
||||
Reference in New Issue
Block a user