mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
@@ -460,12 +460,14 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
|||||||
final isFullScreen = this.isFullScreen;
|
final isFullScreen = this.isFullScreen;
|
||||||
final bottomHeight = 70 + padding.bottom;
|
final bottomHeight = 70 + padding.bottom;
|
||||||
final topPadding = padding.top + kToolbarHeight;
|
final topPadding = padding.top + kToolbarHeight;
|
||||||
final videoHeight = maxHeight - bottomHeight - topPadding;
|
final videoHeight = isFullScreen
|
||||||
|
? maxHeight - padding.top
|
||||||
|
: maxHeight - bottomHeight - topPadding;
|
||||||
return Stack(
|
return Stack(
|
||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
top: isFullScreen ? 0 : topPadding,
|
top: isFullScreen ? padding.top : topPadding,
|
||||||
bottom: isFullScreen ? 0 : bottomHeight,
|
bottom: isFullScreen ? 0 : bottomHeight,
|
||||||
child: videoPlayerPanel(
|
child: videoPlayerPanel(
|
||||||
width: maxWidth,
|
width: maxWidth,
|
||||||
|
|||||||
@@ -551,330 +551,317 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
|
|||||||
return Obx(
|
return Obx(
|
||||||
() {
|
() {
|
||||||
final isFullScreen = this.isFullScreen;
|
final isFullScreen = this.isFullScreen;
|
||||||
return Padding(
|
return Scaffold(
|
||||||
padding: EdgeInsets.only(
|
resizeToAvoidBottomInset: false,
|
||||||
top: isFullScreen && isPortrait ? padding.top : 0,
|
appBar: PreferredSize(
|
||||||
),
|
preferredSize: const Size.fromHeight(0),
|
||||||
child: Scaffold(
|
child: Obx(
|
||||||
resizeToAvoidBottomInset: false,
|
() {
|
||||||
appBar: isFullScreen
|
final scrollRatio = videoDetailController.scrollRatio.value;
|
||||||
? null
|
bool shouldShow =
|
||||||
: PreferredSize(
|
scrollRatio != 0 &&
|
||||||
preferredSize: const Size.fromHeight(0),
|
videoDetailController.scrollCtr.offset != 0 &&
|
||||||
child: Obx(
|
isPortrait;
|
||||||
() {
|
return Stack(
|
||||||
final scrollRatio =
|
clipBehavior: Clip.none,
|
||||||
videoDetailController.scrollRatio.value;
|
children: [
|
||||||
bool shouldShow =
|
AppBar(
|
||||||
scrollRatio != 0 &&
|
backgroundColor: Colors.black,
|
||||||
videoDetailController.scrollCtr.offset != 0 &&
|
toolbarHeight: 0,
|
||||||
isPortrait;
|
systemOverlayStyle: Platform.isAndroid
|
||||||
return Stack(
|
? shouldShow
|
||||||
clipBehavior: Clip.none,
|
? null
|
||||||
children: [
|
: SystemUiOverlayStyle(
|
||||||
AppBar(
|
statusBarIconBrightness: Brightness.light,
|
||||||
backgroundColor: Colors.black,
|
systemNavigationBarIconBrightness:
|
||||||
toolbarHeight: 0,
|
themeData.brightness.reverse,
|
||||||
systemOverlayStyle: Platform.isAndroid
|
)
|
||||||
? shouldShow
|
: null,
|
||||||
? null
|
|
||||||
: SystemUiOverlayStyle(
|
|
||||||
statusBarIconBrightness:
|
|
||||||
Brightness.light,
|
|
||||||
systemNavigationBarIconBrightness:
|
|
||||||
themeData.brightness.reverse,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
if (shouldShow)
|
|
||||||
AppBar(
|
|
||||||
backgroundColor: themeData.colorScheme.surface
|
|
||||||
.withValues(alpha: scrollRatio),
|
|
||||||
toolbarHeight: 0,
|
|
||||||
systemOverlayStyle: Platform.isAndroid
|
|
||||||
? SystemUiOverlayStyle(
|
|
||||||
statusBarIconBrightness:
|
|
||||||
themeData.brightness.reverse,
|
|
||||||
systemNavigationBarIconBrightness:
|
|
||||||
themeData.brightness.reverse,
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
if (shouldShow)
|
||||||
body: ExtendedNestedScrollView(
|
AppBar(
|
||||||
key: videoDetailController.scrollKey,
|
backgroundColor: themeData.colorScheme.surface
|
||||||
controller: videoDetailController.scrollCtr,
|
.withValues(
|
||||||
onlyOneScrollInBody: true,
|
alpha: scrollRatio,
|
||||||
pinnedHeaderSliverHeightBuilder: () {
|
),
|
||||||
double pinnedHeight = this.isFullScreen || !isPortrait
|
toolbarHeight: 0,
|
||||||
? maxHeight - (isPortrait ? padding.top : 0)
|
systemOverlayStyle: Platform.isAndroid
|
||||||
: videoDetailController.isExpanding ||
|
? SystemUiOverlayStyle(
|
||||||
videoDetailController.isCollapsing
|
statusBarIconBrightness:
|
||||||
? animHeight
|
themeData.brightness.reverse,
|
||||||
: videoDetailController.isCollapsing ||
|
systemNavigationBarIconBrightness:
|
||||||
plPlayerController?.playerStatus.status.value ==
|
themeData.brightness.reverse,
|
||||||
PlayerStatus.playing
|
)
|
||||||
? videoDetailController.minVideoHeight
|
: null,
|
||||||
: kToolbarHeight;
|
),
|
||||||
if (videoDetailController.isExpanding &&
|
],
|
||||||
videoDetailController.animationController.value == 1) {
|
);
|
||||||
videoDetailController.isExpanding = false;
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
videoDetailController.scrollRatio.value = 0;
|
|
||||||
refreshPage();
|
|
||||||
});
|
|
||||||
} else if (videoDetailController.isCollapsing &&
|
|
||||||
videoDetailController.animationController.value == 1) {
|
|
||||||
videoDetailController.isCollapsing = false;
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
refreshPage();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return pinnedHeight;
|
|
||||||
},
|
},
|
||||||
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
),
|
||||||
final isFullScreen = this.isFullScreen;
|
),
|
||||||
final height = isFullScreen || !isPortrait
|
body: ExtendedNestedScrollView(
|
||||||
? maxHeight - (isPortrait ? padding.top : 0)
|
key: videoDetailController.scrollKey,
|
||||||
: videoDetailController.isExpanding ||
|
controller: videoDetailController.scrollCtr,
|
||||||
videoDetailController.isCollapsing
|
onlyOneScrollInBody: true,
|
||||||
? animHeight
|
pinnedHeaderSliverHeightBuilder: () {
|
||||||
: videoDetailController.videoHeight;
|
double pinnedHeight = this.isFullScreen || !isPortrait
|
||||||
return [
|
? maxHeight - (isPortrait ? padding.top : 0)
|
||||||
SliverAppBar(
|
: videoDetailController.isExpanding ||
|
||||||
elevation: 0,
|
videoDetailController.isCollapsing
|
||||||
scrolledUnderElevation: 0,
|
? animHeight
|
||||||
primary: false,
|
: videoDetailController.isCollapsing ||
|
||||||
automaticallyImplyLeading: false,
|
plPlayerController?.playerStatus.status.value ==
|
||||||
pinned: true,
|
PlayerStatus.playing
|
||||||
expandedHeight: height,
|
? videoDetailController.minVideoHeight
|
||||||
flexibleSpace: Stack(
|
: kToolbarHeight;
|
||||||
clipBehavior: Clip.none,
|
if (videoDetailController.isExpanding &&
|
||||||
children: [
|
videoDetailController.animationController.value == 1) {
|
||||||
SizedBox(
|
videoDetailController.isExpanding = false;
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
videoDetailController.scrollRatio.value = 0;
|
||||||
|
refreshPage();
|
||||||
|
});
|
||||||
|
} else if (videoDetailController.isCollapsing &&
|
||||||
|
videoDetailController.animationController.value == 1) {
|
||||||
|
videoDetailController.isCollapsing = false;
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
refreshPage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return pinnedHeight;
|
||||||
|
},
|
||||||
|
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||||||
|
final height = isFullScreen || !isPortrait
|
||||||
|
? maxHeight - (isPortrait ? padding.top : 0)
|
||||||
|
: videoDetailController.isExpanding ||
|
||||||
|
videoDetailController.isCollapsing
|
||||||
|
? animHeight
|
||||||
|
: videoDetailController.videoHeight;
|
||||||
|
return [
|
||||||
|
SliverAppBar(
|
||||||
|
elevation: 0,
|
||||||
|
scrolledUnderElevation: 0,
|
||||||
|
primary: false,
|
||||||
|
automaticallyImplyLeading: false,
|
||||||
|
pinned: true,
|
||||||
|
expandedHeight: height,
|
||||||
|
flexibleSpace: Stack(
|
||||||
|
clipBehavior: Clip.none,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: maxWidth,
|
||||||
|
height: height,
|
||||||
|
child: videoPlayer(
|
||||||
width: maxWidth,
|
width: maxWidth,
|
||||||
height: height,
|
height: height,
|
||||||
child: videoPlayer(
|
|
||||||
width: maxWidth,
|
|
||||||
height: height,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Obx(
|
),
|
||||||
() {
|
Obx(
|
||||||
Widget toolbar() => Opacity(
|
() {
|
||||||
opacity: videoDetailController.scrollRatio.value,
|
Widget toolbar() => Opacity(
|
||||||
child: Container(
|
opacity: videoDetailController.scrollRatio.value,
|
||||||
color: themeData.colorScheme.surface,
|
child: Container(
|
||||||
alignment: Alignment.topCenter,
|
color: themeData.colorScheme.surface,
|
||||||
child: SizedBox(
|
alignment: Alignment.topCenter,
|
||||||
height: kToolbarHeight,
|
child: SizedBox(
|
||||||
child: Stack(
|
height: kToolbarHeight,
|
||||||
clipBehavior: Clip.none,
|
child: Stack(
|
||||||
children: [
|
clipBehavior: Clip.none,
|
||||||
Align(
|
children: [
|
||||||
alignment: Alignment.centerLeft,
|
Align(
|
||||||
child: Row(
|
alignment: Alignment.centerLeft,
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: Row(
|
||||||
children: [
|
mainAxisSize: MainAxisSize.min,
|
||||||
SizedBox(
|
children: [
|
||||||
width: 42,
|
SizedBox(
|
||||||
height: 34,
|
width: 42,
|
||||||
child: IconButton(
|
height: 34,
|
||||||
tooltip: '返回',
|
child: IconButton(
|
||||||
icon: Icon(
|
tooltip: '返回',
|
||||||
FontAwesomeIcons.arrowLeft,
|
icon: Icon(
|
||||||
size: 15,
|
FontAwesomeIcons.arrowLeft,
|
||||||
color: themeData
|
size: 15,
|
||||||
.colorScheme
|
color: themeData
|
||||||
.onSurface,
|
.colorScheme
|
||||||
),
|
.onSurface,
|
||||||
onPressed: Get.back,
|
|
||||||
),
|
),
|
||||||
|
onPressed: Get.back,
|
||||||
),
|
),
|
||||||
SizedBox(
|
),
|
||||||
width: 42,
|
SizedBox(
|
||||||
height: 34,
|
width: 42,
|
||||||
child: IconButton(
|
height: 34,
|
||||||
tooltip: '返回主页',
|
child: IconButton(
|
||||||
icon: Icon(
|
tooltip: '返回主页',
|
||||||
FontAwesomeIcons.house,
|
icon: Icon(
|
||||||
size: 15,
|
FontAwesomeIcons.house,
|
||||||
color: themeData
|
size: 15,
|
||||||
.colorScheme
|
color: themeData
|
||||||
.onSurface,
|
.colorScheme
|
||||||
),
|
.onSurface,
|
||||||
onPressed: () {
|
|
||||||
videoDetailController
|
|
||||||
.plPlayerController
|
|
||||||
..isCloseAll = true
|
|
||||||
..dispose();
|
|
||||||
Get.until(
|
|
||||||
(route) => route.isFirst,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
|
onPressed: () {
|
||||||
|
videoDetailController
|
||||||
|
.plPlayerController
|
||||||
|
..isCloseAll = true
|
||||||
|
..dispose();
|
||||||
|
Get.until(
|
||||||
|
(route) => route.isFirst,
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
Center(
|
),
|
||||||
child: Row(
|
Center(
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: Row(
|
||||||
children: [
|
mainAxisSize: MainAxisSize.min,
|
||||||
Icon(
|
children: [
|
||||||
Icons.play_arrow_rounded,
|
Icon(
|
||||||
|
Icons.play_arrow_rounded,
|
||||||
|
color:
|
||||||
|
themeData.colorScheme.primary,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'${videoDetailController.playedTime == null
|
||||||
|
? '立即'
|
||||||
|
: plPlayerController!.playerStatus.status.value == PlayerStatus.completed
|
||||||
|
? '重新'
|
||||||
|
: '继续'}播放',
|
||||||
|
style: TextStyle(
|
||||||
color:
|
color:
|
||||||
themeData.colorScheme.primary,
|
themeData.colorScheme.primary,
|
||||||
),
|
),
|
||||||
Text(
|
),
|
||||||
'${videoDetailController.playedTime == null
|
],
|
||||||
? '立即'
|
|
||||||
: plPlayerController!.playerStatus.status.value == PlayerStatus.completed
|
|
||||||
? '重新'
|
|
||||||
: '继续'}播放',
|
|
||||||
style: TextStyle(
|
|
||||||
color: themeData
|
|
||||||
.colorScheme
|
|
||||||
.primary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
Align(
|
),
|
||||||
alignment: Alignment.centerRight,
|
Align(
|
||||||
child:
|
alignment: Alignment.centerRight,
|
||||||
videoDetailController.playedTime ==
|
child:
|
||||||
null
|
videoDetailController.playedTime ==
|
||||||
? _moreBtn(
|
null
|
||||||
themeData.colorScheme.onSurface,
|
? _moreBtn(
|
||||||
)
|
themeData.colorScheme.onSurface,
|
||||||
: SizedBox(
|
)
|
||||||
width: 42,
|
: SizedBox(
|
||||||
height: 34,
|
width: 42,
|
||||||
child: IconButton(
|
height: 34,
|
||||||
tooltip: "更多设置",
|
child: IconButton(
|
||||||
style: const ButtonStyle(
|
tooltip: "更多设置",
|
||||||
padding:
|
style: const ButtonStyle(
|
||||||
WidgetStatePropertyAll(
|
padding:
|
||||||
EdgeInsets.zero,
|
WidgetStatePropertyAll(
|
||||||
),
|
EdgeInsets.zero,
|
||||||
),
|
),
|
||||||
onPressed: () =>
|
),
|
||||||
videoDetailController
|
onPressed: () =>
|
||||||
.headerCtrKey
|
videoDetailController
|
||||||
.currentState
|
.headerCtrKey
|
||||||
?.showSettingSheet(),
|
.currentState
|
||||||
icon: Icon(
|
?.showSettingSheet(),
|
||||||
Icons.more_vert_outlined,
|
icon: Icon(
|
||||||
size: 19,
|
Icons.more_vert_outlined,
|
||||||
color: themeData
|
size: 19,
|
||||||
.colorScheme
|
color: themeData
|
||||||
.onSurface,
|
.colorScheme
|
||||||
),
|
.onSurface,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
return videoDetailController.scrollRatio.value ==
|
);
|
||||||
0 ||
|
return videoDetailController.scrollRatio.value == 0 ||
|
||||||
videoDetailController.scrollCtr.offset ==
|
videoDetailController.scrollCtr.offset == 0 ||
|
||||||
0 ||
|
!isPortrait
|
||||||
!isPortrait
|
? const SizedBox.shrink()
|
||||||
? const SizedBox.shrink()
|
: Positioned.fill(
|
||||||
: Positioned.fill(
|
bottom: -2,
|
||||||
bottom: -2,
|
child: GestureDetector(
|
||||||
child: GestureDetector(
|
onTap: () async {
|
||||||
onTap: () async {
|
if (videoDetailController.isQuerying) {
|
||||||
if (videoDetailController.isQuerying) {
|
if (kDebugMode) {
|
||||||
if (kDebugMode) {
|
debugPrint(
|
||||||
debugPrint(
|
'handlePlay: querying',
|
||||||
'handlePlay: querying',
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (videoDetailController.videoUrl ==
|
return;
|
||||||
null ||
|
}
|
||||||
videoDetailController.audioUrl ==
|
if (videoDetailController.videoUrl ==
|
||||||
null) {
|
null ||
|
||||||
if (kDebugMode) {
|
videoDetailController.audioUrl ==
|
||||||
debugPrint(
|
null) {
|
||||||
'handlePlay: videoUrl/audioUrl not initialized',
|
if (kDebugMode) {
|
||||||
);
|
debugPrint(
|
||||||
}
|
'handlePlay: videoUrl/audioUrl not initialized',
|
||||||
videoDetailController.queryVideoUrl();
|
);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
videoDetailController
|
videoDetailController.queryVideoUrl();
|
||||||
.scrollRatio
|
return;
|
||||||
.value =
|
}
|
||||||
0;
|
videoDetailController.scrollRatio.value =
|
||||||
if (plPlayerController == null ||
|
0;
|
||||||
videoDetailController.playedTime ==
|
if (plPlayerController == null ||
|
||||||
null) {
|
videoDetailController.playedTime ==
|
||||||
handlePlay();
|
null) {
|
||||||
} else {
|
handlePlay();
|
||||||
if (plPlayerController!
|
} else {
|
||||||
|
if (plPlayerController!
|
||||||
|
.videoPlayerController!
|
||||||
|
.state
|
||||||
|
.completed) {
|
||||||
|
await plPlayerController!
|
||||||
.videoPlayerController!
|
.videoPlayerController!
|
||||||
.state
|
.seek(Duration.zero);
|
||||||
.completed) {
|
plPlayerController!
|
||||||
await plPlayerController!
|
.videoPlayerController!
|
||||||
.videoPlayerController!
|
.play();
|
||||||
.seek(Duration.zero);
|
} else {
|
||||||
plPlayerController!
|
plPlayerController!
|
||||||
.videoPlayerController!
|
.videoPlayerController!
|
||||||
.play();
|
.playOrPause();
|
||||||
} else {
|
|
||||||
plPlayerController!
|
|
||||||
.videoPlayerController!
|
|
||||||
.playOrPause();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
behavior: HitTestBehavior.opaque,
|
},
|
||||||
child: toolbar(),
|
behavior: HitTestBehavior.opaque,
|
||||||
),
|
child: toolbar(),
|
||||||
);
|
),
|
||||||
},
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
body: Scaffold(
|
||||||
|
key: videoDetailController.childKey,
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
buildTabbar(onTap: videoDetailController.animToTop),
|
||||||
|
Expanded(
|
||||||
|
child: videoTabBarView(
|
||||||
|
controller: videoDetailController.tabCtr,
|
||||||
|
children: [
|
||||||
|
videoIntro(
|
||||||
|
isHorizontal: false,
|
||||||
|
needCtr: false,
|
||||||
|
isNested: true,
|
||||||
),
|
),
|
||||||
|
if (videoDetailController.showReply)
|
||||||
|
videoReplyPanel(isNested: true),
|
||||||
|
if (_shouldShowSeasonPanel) seasonPanel,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
];
|
],
|
||||||
},
|
|
||||||
body: Scaffold(
|
|
||||||
key: videoDetailController.childKey,
|
|
||||||
resizeToAvoidBottomInset: false,
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
body: Column(
|
|
||||||
children: [
|
|
||||||
buildTabbar(onTap: videoDetailController.animToTop),
|
|
||||||
Expanded(
|
|
||||||
child: videoTabBarView(
|
|
||||||
controller: videoDetailController.tabCtr,
|
|
||||||
children: [
|
|
||||||
videoIntro(
|
|
||||||
isHorizontal: false,
|
|
||||||
needCtr: false,
|
|
||||||
isNested: true,
|
|
||||||
),
|
|
||||||
if (videoDetailController.showReply)
|
|
||||||
videoReplyPanel(isNested: true),
|
|
||||||
if (_shouldShowSeasonPanel) seasonPanel,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user