feat: add button to toggle video orientation in player (#743)

Co-authored-by: Gauvain <68083474+Gauvino@users.noreply.github.com>
Co-authored-by: Fredrik Burmester <fredrik.burmester@gmail.com>
This commit is contained in:
Emre Sanden
2026-01-03 17:52:45 +01:00
committed by GitHub
parent 85d707ef45
commit 090e0cb170
2 changed files with 46 additions and 2 deletions

View File

@@ -4,7 +4,7 @@ import type {
MediaSourceInfo,
} from "@jellyfin/sdk/lib/generated-client";
import { useRouter } from "expo-router";
import type { FC } from "react";
import { type FC, useCallback, useState } from "react";
import {
Platform,
TouchableOpacity,
@@ -13,6 +13,8 @@ import {
} from "react-native";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useHaptic } from "@/hooks/useHaptic";
import { useOrientation } from "@/hooks/useOrientation";
import { OrientationLock } from "@/packages/expo-screen-orientation";
import { useSettings, VideoPlayerIOS } from "@/utils/atoms/settings";
import { ICON_SIZES } from "./constants";
import DropdownView from "./dropdown/DropdownView";
@@ -57,12 +59,38 @@ export const HeaderControls: FC<HeaderControlsProps> = ({
const insets = useSafeAreaInsets();
const { width: _screenWidth } = useWindowDimensions();
const lightHapticFeedback = useHaptic("light");
const { orientation, lockOrientation } = useOrientation();
const [isTogglingOrientation, setIsTogglingOrientation] = useState(false);
const onClose = async () => {
lightHapticFeedback();
router.back();
};
const toggleOrientation = useCallback(async () => {
if (isTogglingOrientation) return;
setIsTogglingOrientation(true);
lightHapticFeedback();
try {
const isPortrait =
orientation === OrientationLock.PORTRAIT_UP ||
orientation === OrientationLock.PORTRAIT_DOWN;
await lockOrientation(
isPortrait ? OrientationLock.LANDSCAPE : OrientationLock.PORTRAIT_UP,
);
} finally {
setIsTogglingOrientation(false);
}
}, [
orientation,
lockOrientation,
isTogglingOrientation,
lightHapticFeedback,
]);
return (
<View
style={[
@@ -85,6 +113,22 @@ export const HeaderControls: FC<HeaderControlsProps> = ({
</View>
<View className='flex flex-row items-center space-x-2'>
{!Platform.isTV && (
<TouchableOpacity
onPress={toggleOrientation}
disabled={isTogglingOrientation}
className='aspect-square flex flex-col rounded-xl items-center justify-center p-2'
accessibilityLabel='Toggle screen orientation'
accessibilityHint='Toggles the screen orientation between portrait and landscape'
>
<MaterialIcons
name='screen-rotation'
size={ICON_SIZES.HEADER}
color='white'
style={{ opacity: isTogglingOrientation ? 0.5 : 1 }}
/>
</TouchableOpacity>
)}
{!Platform.isTV &&
startPictureInPicture &&
settings?.videoPlayerIOS !== VideoPlayerIOS.VLC && (