Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-09-30 11:35:42 +08:00
parent 06b258cff1
commit 299ee09749
7 changed files with 69 additions and 53 deletions

View File

@@ -267,6 +267,11 @@ class MyApp extends StatelessWidget {
return; return;
} }
if (Get.isDialogOpen ?? Get.isBottomSheetOpen ?? false) {
Get.back();
return;
}
final plCtr = PlPlayerController.instance; final plCtr = PlPlayerController.instance;
if (plCtr != null) { if (plCtr != null) {
if (plCtr.isFullScreen.value == true) { if (plCtr.isFullScreen.value == true) {
@@ -274,10 +279,10 @@ class MyApp extends StatelessWidget {
return; return;
} }
if (plCtr.isDesktopPip) { // if (plCtr.isDesktopPip) {
plCtr.exitDesktopPip(); // plCtr.exitDesktopPip();
return; // return;
} // }
} }
Get.back(); Get.back();

View File

@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/models/common/image_type.dart'; import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models_new/live/live_superchat/item.dart'; import 'package:PiliPlus/models_new/live/live_superchat/item.dart';
import 'package:PiliPlus/pages/video/introduction/ugc/widgets/selectable_text.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@@ -140,7 +141,7 @@ class _SuperChatCardState extends State<SuperChatCard> {
color: bottomColor, color: bottomColor,
), ),
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),
child: SelectableText( child: selectableText(
item.message, item.message,
style: TextStyle(color: Utils.parseColor(item.messageFontColor)), style: TextStyle(color: Utils.parseColor(item.messageFontColor)),
), ),

View File

@@ -118,17 +118,11 @@ class LiveHeaderControl extends StatelessWidget {
plPlayerController.toggleDesktopPip(); plPlayerController.toggleDesktopPip();
return; return;
} }
try { if (await Floating().isPipAvailable) {
var floating = Floating(); plPlayerController
if ((await floating.isPipAvailable) == true) { ..hiddenControls(false)
plPlayerController.hiddenControls(false); ..enterPip();
floating.enable( }
plPlayerController.isVertical
? const EnableManual(aspectRatio: Rational.vertical())
: const EnableManual(),
);
}
} catch (_) {}
}, },
icon: const Icon( icon: const Icon(
size: 18, size: 18,

View File

@@ -1,3 +1,4 @@
import 'package:PiliPlus/common/skeleton/video_card_h.dart';
import 'package:PiliPlus/common/widgets/button/icon_button.dart'; import 'package:PiliPlus/common/widgets/button/icon_button.dart';
import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart'; import 'package:PiliPlus/common/widgets/custom_sliver_persistent_header_delegate.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
@@ -16,7 +17,6 @@ import 'package:PiliPlus/pages/video/introduction/ugc/controller.dart';
import 'package:PiliPlus/pages/video/member/controller.dart'; import 'package:PiliPlus/pages/video/member/controller.dart';
import 'package:PiliPlus/services/account_service.dart'; import 'package:PiliPlus/services/account_service.dart';
import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/grid.dart';
import 'package:PiliPlus/utils/num_utils.dart'; import 'package:PiliPlus/utils/num_utils.dart';
import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/request_utils.dart'; import 'package:PiliPlus/utils/request_utils.dart';
@@ -41,11 +41,10 @@ class HorizontalMemberPage extends StatefulWidget {
State<HorizontalMemberPage> createState() => _HorizontalMemberPageState(); State<HorizontalMemberPage> createState() => _HorizontalMemberPageState();
} }
class _HorizontalMemberPageState extends State<HorizontalMemberPage> class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
with GridMixin {
late final HorizontalMemberPageController _controller; late final HorizontalMemberPageController _controller;
AccountService accountService = Get.find<AccountService>(); AccountService accountService = Get.find<AccountService>();
dynamic _bvid; late final String _bvid;
@override @override
void initState() { void initState() {
@@ -58,6 +57,15 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage>
tag: widget.videoDetailController.heroTag, tag: widget.videoDetailController.heroTag,
); );
_bvid = widget.videoDetailController.bvid; _bvid = widget.videoDetailController.bvid;
if (_controller.loadingState.value
case Success<List<SpaceArchiveItem>?> res) {
final index = res.response?.indexWhere((e) => e.bvid == _bvid) ?? -1;
if (index != -1) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_controller.scrollController.jumpTo(100.0 * index + 40);
});
}
}
} }
@override @override
@@ -180,32 +188,39 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage>
LoadingState<List<SpaceArchiveItem>?> loadingState, LoadingState<List<SpaceArchiveItem>?> loadingState,
) { ) {
return switch (loadingState) { return switch (loadingState) {
Loading() => gridSkeleton, Loading() => SliverPrototypeExtentList.builder(
itemCount: 10,
itemBuilder: (_, _) => const VideoCardHSkeleton(),
prototypeItem: const VideoCardHSkeleton(),
),
Success(:var response) => Success(:var response) =>
response?.isNotEmpty == true response?.isNotEmpty == true
? SliverGrid.builder( ? SliverFixedExtentList.builder(
gridDelegate: gridDelegate,
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (index == response.length - 1 && _controller.hasNext) { if (index == response.length - 1 && _controller.hasNext) {
_controller.onLoadMore(); _controller.onLoadMore();
} }
final SpaceArchiveItem videoItem = response[index]; final SpaceArchiveItem videoItem = response[index];
return VideoCardHMemberVideo( return Padding(
videoItem: videoItem, padding: const EdgeInsets.only(bottom: 2),
bvid: _bvid, child: VideoCardHMemberVideo(
onTap: () { videoItem: videoItem,
Get.back(); bvid: _bvid,
widget.ugcIntroController.onChangeEpisode( onTap: () {
BaseEpisodeItem( Get.back();
bvid: videoItem.bvid, widget.ugcIntroController.onChangeEpisode(
cid: videoItem.cid, BaseEpisodeItem(
cover: videoItem.cover, bvid: videoItem.bvid,
), cid: videoItem.cid,
); cover: videoItem.cover,
}, ),
);
},
),
); );
}, },
itemCount: response!.length, itemCount: response!.length,
itemExtent: 100,
) )
: HttpError(onReload: _controller.onReload), : HttpError(onReload: _controller.onReload),
Error(:var errMsg) => HttpError( Error(:var errMsg) => HttpError(

View File

@@ -2158,9 +2158,8 @@ class HeaderControlState extends State<HeaderControl> {
plPlayerController.toggleDesktopPip(); plPlayerController.toggleDesktopPip();
return; return;
} }
bool canUsePiP = await Floating().isPipAvailable; if (await Floating().isPipAvailable) {
plPlayerController.hiddenControls(false); plPlayerController.hiddenControls(false);
if (canUsePiP) {
if (context.mounted && if (context.mounted &&
!videoPlayerServiceHandler!.enableBackgroundPlay) { !videoPlayerServiceHandler!.enableBackgroundPlay) {
final theme = Theme.of(context); final theme = Theme.of(context);
@@ -2236,10 +2235,7 @@ class HeaderControlState extends State<HeaderControl> {
await Future.delayed(const Duration(seconds: 3)); await Future.delayed(const Duration(seconds: 3));
} }
if (!context.mounted) return; if (!context.mounted) return;
PageUtils.enterPip( plPlayerController.enterPip();
width: widget.videoDetailCtr.firstVideo.width,
height: widget.videoDetailCtr.firstVideo.height,
);
} }
}, },
icon: const Icon( icon: const Icon(

View File

@@ -29,12 +29,12 @@ class PlayerFocus extends StatelessWidget {
final VoidCallback onSendDanmaku; final VoidCallback onSendDanmaku;
final bool Function()? canPlay; final bool Function()? canPlay;
static bool _shouldHandled(KeyEvent event) { static bool _shouldHandle(LogicalKeyboardKey logicalKey) {
return event.logicalKey == LogicalKeyboardKey.tab || return logicalKey == LogicalKeyboardKey.tab ||
event.logicalKey == LogicalKeyboardKey.arrowLeft || logicalKey == LogicalKeyboardKey.arrowLeft ||
event.logicalKey == LogicalKeyboardKey.arrowRight || logicalKey == LogicalKeyboardKey.arrowRight ||
event.logicalKey == LogicalKeyboardKey.arrowUp || logicalKey == LogicalKeyboardKey.arrowUp ||
event.logicalKey == LogicalKeyboardKey.arrowDown; logicalKey == LogicalKeyboardKey.arrowDown;
} }
@override @override
@@ -43,7 +43,7 @@ class PlayerFocus extends StatelessWidget {
autofocus: true, autofocus: true,
onKeyEvent: (node, event) { onKeyEvent: (node, event) {
final handled = _handleKey(event); final handled = _handleKey(event);
if (handled || _shouldHandled(event)) { if (handled || _shouldHandle(event.logicalKey)) {
return KeyEventResult.handled; return KeyEventResult.handled;
} }
return KeyEventResult.ignored; return KeyEventResult.ignored;

View File

@@ -304,8 +304,12 @@ class PlPlayerController {
} }
void enterPip() { void enterPip() {
if (Get.currentRoute.startsWith('/video')) { if (videoController != null) {
PageUtils.enterPip(width: width, height: height); final state = videoController!.player.state;
PageUtils.enterPip(
width: state.width ?? width,
height: state.height ?? height,
);
} }
} }
@@ -547,7 +551,8 @@ class PlPlayerController {
if (Platform.isAndroid && autoPiP) { if (Platform.isAndroid && autoPiP) {
Utils.channel.setMethodCallHandler((call) async { Utils.channel.setMethodCallHandler((call) async {
if (call.method == 'onUserLeaveHint') { if (call.method == 'onUserLeaveHint') {
if (playerStatus.status.value == PlayerStatus.playing) { if (playerStatus.status.value == PlayerStatus.playing &&
Get.currentRoute.startsWith('/video')) {
enterPip(); enterPip();
} }
} }