mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: 播放页组件嵌套拆分
This commit is contained in:
@@ -357,6 +357,40 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
Widget plPlayer = FutureBuilder(
|
||||||
|
future: _futureBuilderFuture,
|
||||||
|
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||||
|
if (snapshot.hasData && snapshot.data['status']) {
|
||||||
|
return Obx(
|
||||||
|
() => !videoDetailController.autoPlay.value ||
|
||||||
|
plPlayerController == null ||
|
||||||
|
plPlayerController!.videoController == null
|
||||||
|
? nil
|
||||||
|
: PLVideoPlayer(
|
||||||
|
controller: plPlayerController!,
|
||||||
|
videoIntroController:
|
||||||
|
videoDetailController.videoType == SearchType.video
|
||||||
|
? videoIntroController
|
||||||
|
: null,
|
||||||
|
bangumiIntroController: videoDetailController.videoType ==
|
||||||
|
SearchType.media_bangumi
|
||||||
|
? bangumiIntroController
|
||||||
|
: null,
|
||||||
|
headerControl: videoDetailController.headerControl,
|
||||||
|
danmuWidget: Obx(
|
||||||
|
() => PlDanmaku(
|
||||||
|
key: Key(videoDetailController.danmakuCid.value
|
||||||
|
.toString()),
|
||||||
|
cid: videoDetailController.danmakuCid.value,
|
||||||
|
playerController: plPlayerController!,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return const SizedBox();
|
||||||
|
}
|
||||||
|
});
|
||||||
Widget childWhenDisabled = SafeArea(
|
Widget childWhenDisabled = SafeArea(
|
||||||
top: MediaQuery.of(context).orientation == Orientation.portrait &&
|
top: MediaQuery.of(context).orientation == Orientation.portrait &&
|
||||||
isFullScreen.value == true,
|
isFullScreen.value == true,
|
||||||
@@ -433,62 +467,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
},
|
},
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (isShowing)
|
if (isShowing) plPlayer,
|
||||||
FutureBuilder(
|
|
||||||
future: _futureBuilderFuture,
|
|
||||||
builder: (BuildContext context,
|
|
||||||
AsyncSnapshot snapshot) {
|
|
||||||
if (snapshot.hasData &&
|
|
||||||
snapshot.data['status']) {
|
|
||||||
return Obx(
|
|
||||||
() => !videoDetailController
|
|
||||||
.autoPlay.value ||
|
|
||||||
plPlayerController ==
|
|
||||||
null ||
|
|
||||||
plPlayerController!
|
|
||||||
.videoController ==
|
|
||||||
null
|
|
||||||
? nil
|
|
||||||
: PLVideoPlayer(
|
|
||||||
controller:
|
|
||||||
plPlayerController!,
|
|
||||||
videoIntroController:
|
|
||||||
videoDetailController
|
|
||||||
.videoType ==
|
|
||||||
SearchType.video
|
|
||||||
? videoIntroController
|
|
||||||
: null,
|
|
||||||
bangumiIntroController:
|
|
||||||
videoDetailController
|
|
||||||
.videoType ==
|
|
||||||
SearchType
|
|
||||||
.media_bangumi
|
|
||||||
? bangumiIntroController
|
|
||||||
: null,
|
|
||||||
headerControl:
|
|
||||||
videoDetailController
|
|
||||||
.headerControl,
|
|
||||||
danmuWidget: Obx(
|
|
||||||
() => PlDanmaku(
|
|
||||||
key: Key(
|
|
||||||
videoDetailController
|
|
||||||
.danmakuCid
|
|
||||||
.value
|
|
||||||
.toString()),
|
|
||||||
cid:
|
|
||||||
videoDetailController
|
|
||||||
.danmakuCid
|
|
||||||
.value,
|
|
||||||
playerController:
|
|
||||||
plPlayerController!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return const SizedBox();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
/// 关闭自动播放时 手动播放
|
/// 关闭自动播放时 手动播放
|
||||||
if (!videoDetailController
|
if (!videoDetailController
|
||||||
@@ -647,29 +626,12 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
Widget childWhenDisabledLandscapeInner = Obx(() {
|
||||||
Widget childWhenDisabledLandscape = SafeArea(
|
|
||||||
left: isFullScreen.value != true,
|
|
||||||
right: isFullScreen.value != true,
|
|
||||||
child: Stack(children: [
|
|
||||||
Scaffold(
|
|
||||||
resizeToAvoidBottomInset: false,
|
|
||||||
key: videoDetailController.scaffoldKey,
|
|
||||||
backgroundColor: Theme.of(context).colorScheme.background,
|
|
||||||
appBar: PreferredSize(
|
|
||||||
preferredSize: const Size.fromHeight(0),
|
|
||||||
child: AppBar(
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
elevation: 0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: Obx(() {
|
|
||||||
// 系数是以下三个方程(分别代表特定平板、折叠屏内屏、普通手机横屏尺寸)的近似解
|
// 系数是以下三个方程(分别代表特定平板、折叠屏内屏、普通手机横屏尺寸)的近似解
|
||||||
// 820x+1180y+983.67z=450
|
// 820x+1180y+983.67z=450
|
||||||
// 1812x+2176y+1985.68z=680
|
// 1812x+2176y+1985.68z=680
|
||||||
// 1080x+2340y+1589.72z=560
|
// 1080x+2340y+1589.72z=560
|
||||||
final double videoheight =
|
final double videoheight = sqrt(context.height * context.width) * 12.555 -
|
||||||
sqrt(context.height * context.width) * 12.555 -
|
|
||||||
context.height * 7.690 -
|
context.height * 7.690 -
|
||||||
context.width * 4.741;
|
context.width * 4.741;
|
||||||
final double videowidth = videoheight * 16 / 9;
|
final double videowidth = videoheight * 16 / 9;
|
||||||
@@ -678,18 +640,15 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: isFullScreen.value == true
|
width:
|
||||||
? context.width
|
isFullScreen.value == true ? context.width : videowidth,
|
||||||
: videowidth,
|
height:
|
||||||
height: isFullScreen.value == true
|
isFullScreen.value == true ? context.height : videoheight,
|
||||||
? context.height
|
|
||||||
: videoheight,
|
|
||||||
child: PopScope(
|
child: PopScope(
|
||||||
canPop: isFullScreen.value != true,
|
canPop: isFullScreen.value != true,
|
||||||
onPopInvoked: (bool didPop) {
|
onPopInvoked: (bool didPop) {
|
||||||
if (isFullScreen.value == true) {
|
if (isFullScreen.value == true) {
|
||||||
plPlayerController!
|
plPlayerController!.triggerFullScreen(status: false);
|
||||||
.triggerFullScreen(status: false);
|
|
||||||
}
|
}
|
||||||
if (MediaQuery.of(context).orientation ==
|
if (MediaQuery.of(context).orientation ==
|
||||||
Orientation.landscape &&
|
Orientation.landscape &&
|
||||||
@@ -699,71 +658,15 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
},
|
},
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (isShowing)
|
if (isShowing) plPlayer,
|
||||||
FutureBuilder(
|
|
||||||
future: _futureBuilderFuture,
|
|
||||||
builder: (BuildContext context,
|
|
||||||
AsyncSnapshot snapshot) {
|
|
||||||
if (snapshot.hasData &&
|
|
||||||
snapshot.data['status']) {
|
|
||||||
return Obx(
|
|
||||||
() => !videoDetailController
|
|
||||||
.autoPlay.value ||
|
|
||||||
plPlayerController ==
|
|
||||||
null ||
|
|
||||||
plPlayerController!
|
|
||||||
.videoController ==
|
|
||||||
null
|
|
||||||
? nil
|
|
||||||
: PLVideoPlayer(
|
|
||||||
controller:
|
|
||||||
plPlayerController!,
|
|
||||||
videoIntroController:
|
|
||||||
videoDetailController
|
|
||||||
.videoType ==
|
|
||||||
SearchType
|
|
||||||
.video
|
|
||||||
? videoIntroController
|
|
||||||
: null,
|
|
||||||
bangumiIntroController:
|
|
||||||
videoDetailController
|
|
||||||
.videoType ==
|
|
||||||
SearchType
|
|
||||||
.media_bangumi
|
|
||||||
? bangumiIntroController
|
|
||||||
: null,
|
|
||||||
headerControl:
|
|
||||||
videoDetailController
|
|
||||||
.headerControl,
|
|
||||||
danmuWidget: Obx(
|
|
||||||
() => PlDanmaku(
|
|
||||||
key: Key(
|
|
||||||
videoDetailController
|
|
||||||
.danmakuCid
|
|
||||||
.value
|
|
||||||
.toString()),
|
|
||||||
cid:
|
|
||||||
videoDetailController
|
|
||||||
.danmakuCid
|
|
||||||
.value,
|
|
||||||
playerController:
|
|
||||||
plPlayerController!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return const SizedBox();
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
/// 关闭自动播放时 手动播放
|
/// 关闭自动播放时 手动播放
|
||||||
if (!videoDetailController
|
if (!videoDetailController
|
||||||
.autoPlay.value) ...<Widget>[
|
.autoPlay.value) ...<Widget>[
|
||||||
Obx(
|
Obx(
|
||||||
() => Visibility(
|
() => Visibility(
|
||||||
visible: videoDetailController
|
visible:
|
||||||
.isShowCover.value,
|
videoDetailController.isShowCover.value,
|
||||||
child: Positioned(
|
child: Positioned(
|
||||||
top: 0,
|
top: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
@@ -787,8 +690,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
() => Visibility(
|
() => Visibility(
|
||||||
visible: videoDetailController
|
visible: videoDetailController
|
||||||
.isShowCover.value &&
|
.isShowCover.value &&
|
||||||
videoDetailController
|
videoDetailController.isEffective.value,
|
||||||
.isEffective.value,
|
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
@@ -797,26 +699,24 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
right: 0,
|
right: 0,
|
||||||
child: AppBar(
|
child: AppBar(
|
||||||
primary: false,
|
primary: false,
|
||||||
foregroundColor:
|
foregroundColor: Colors.white,
|
||||||
Colors.white,
|
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
scrolledUnderElevation: 0,
|
scrolledUnderElevation: 0,
|
||||||
backgroundColor:
|
backgroundColor: Colors.transparent,
|
||||||
Colors.transparent,
|
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: '稍后再看',
|
tooltip: '稍后再看',
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
var res = await UserHttp
|
var res =
|
||||||
.toViewLater(
|
await UserHttp.toViewLater(
|
||||||
bvid:
|
bvid:
|
||||||
videoDetailController
|
videoDetailController
|
||||||
.bvid);
|
.bvid);
|
||||||
SmartDialog.showToast(
|
SmartDialog.showToast(
|
||||||
res['msg']);
|
res['msg']);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons
|
icon: const Icon(
|
||||||
.history_outlined),
|
Icons.history_outlined),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 14)
|
const SizedBox(width: 14)
|
||||||
],
|
],
|
||||||
@@ -827,8 +727,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
bottom: 10,
|
bottom: 10,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
tooltip: '播放',
|
tooltip: '播放',
|
||||||
onPressed: () =>
|
onPressed: () => handlePlay(),
|
||||||
handlePlay(),
|
|
||||||
icon: Image.asset(
|
icon: Image.asset(
|
||||||
'assets/images/play.png',
|
'assets/images/play.png',
|
||||||
width: 60,
|
width: 60,
|
||||||
@@ -842,9 +741,8 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
],
|
],
|
||||||
))),
|
))),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: isFullScreen.value == true
|
width:
|
||||||
? context.width
|
isFullScreen.value == true ? context.width : videowidth,
|
||||||
: videowidth,
|
|
||||||
height: isFullScreen.value == true
|
height: isFullScreen.value == true
|
||||||
? 0
|
? 0
|
||||||
: context.height -
|
: context.height -
|
||||||
@@ -852,7 +750,8 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
MediaQuery.of(context).padding.top -
|
MediaQuery.of(context).padding.top -
|
||||||
MediaQuery.of(context).padding.bottom,
|
MediaQuery.of(context).padding.bottom,
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
key: const PageStorageKey<String>('简介'),
|
key: PageStorageKey<String>(
|
||||||
|
'简介${videoDetailController.bvid}'),
|
||||||
slivers: <Widget>[
|
slivers: <Widget>[
|
||||||
if (videoDetailController.videoType ==
|
if (videoDetailController.videoType ==
|
||||||
SearchType.video) ...[
|
SearchType.video) ...[
|
||||||
@@ -880,8 +779,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
physics: const BouncingScrollPhysics(),
|
physics: const BouncingScrollPhysics(),
|
||||||
controller: videoDetailController.tabCtr,
|
controller: videoDetailController.tabCtr,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
if (videoDetailController.videoType ==
|
if (videoDetailController.videoType == SearchType.video)
|
||||||
SearchType.video)
|
|
||||||
const CustomScrollView(
|
const CustomScrollView(
|
||||||
slivers: [
|
slivers: [
|
||||||
RelatedVideoPanel(),
|
RelatedVideoPanel(),
|
||||||
@@ -898,8 +796,26 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}))
|
});
|
||||||
]));
|
Widget childWhenDisabledLandscape = Container(
|
||||||
|
color: Theme.of(context).colorScheme.background,
|
||||||
|
child: SafeArea(
|
||||||
|
left: isFullScreen.value != true,
|
||||||
|
right: isFullScreen.value != true,
|
||||||
|
child: Stack(children: [
|
||||||
|
Scaffold(
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
|
key: videoDetailController.scaffoldKey,
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.background,
|
||||||
|
appBar: PreferredSize(
|
||||||
|
preferredSize: const Size.fromHeight(0),
|
||||||
|
child: AppBar(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
elevation: 0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: childWhenDisabledLandscapeInner)
|
||||||
|
])));
|
||||||
Widget childWhenEnabled = Obx(
|
Widget childWhenEnabled = Obx(
|
||||||
() => !videoDetailController.autoPlay.value
|
() => !videoDetailController.autoPlay.value
|
||||||
? const SizedBox()
|
? const SizedBox()
|
||||||
|
|||||||
Reference in New Issue
Block a user