mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-15 10:20:27 +01:00
fix: add safe areas back to controls
This commit is contained in:
@@ -43,6 +43,7 @@ import {
|
|||||||
View,
|
View,
|
||||||
AppState,
|
AppState,
|
||||||
AppStateStatus,
|
AppStateStatus,
|
||||||
|
Platform,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import { useSharedValue } from "react-native-reanimated";
|
import { useSharedValue } from "react-native-reanimated";
|
||||||
import settings from "../(tabs)/(home)/settings";
|
import settings from "../(tabs)/(home)/settings";
|
||||||
@@ -448,7 +449,7 @@ export default function page() {
|
|||||||
position: "relative",
|
position: "relative",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
opacity: showControls ? 0.5 : 1,
|
opacity: showControls ? (Platform.OS === "android" ? 0.7 : 0.5) : 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<VlcPlayerView
|
<VlcPlayerView
|
||||||
|
|||||||
@@ -42,7 +42,10 @@ import {
|
|||||||
useAnimatedReaction,
|
useAnimatedReaction,
|
||||||
useSharedValue,
|
useSharedValue,
|
||||||
} from "react-native-reanimated";
|
} from "react-native-reanimated";
|
||||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
import {
|
||||||
|
SafeAreaView,
|
||||||
|
useSafeAreaInsets,
|
||||||
|
} from "react-native-safe-area-context";
|
||||||
import { VideoRef } from "react-native-video";
|
import { VideoRef } from "react-native-video";
|
||||||
import AudioSlider from "./AudioSlider";
|
import AudioSlider from "./AudioSlider";
|
||||||
import BrightnessSlider from "./BrightnessSlider";
|
import BrightnessSlider from "./BrightnessSlider";
|
||||||
@@ -506,11 +509,23 @@ export const Controls: React.FC<Props> = ({
|
|||||||
setSubtitleTrack={setSubtitleTrack}
|
setSubtitleTrack={setSubtitleTrack}
|
||||||
setSubtitleURL={setSubtitleURL}
|
setSubtitleURL={setSubtitleURL}
|
||||||
>
|
>
|
||||||
{!mediaSource?.TranscodingUrl ? (
|
<View
|
||||||
<DropdownViewDirect showControls={showControls} />
|
style={[
|
||||||
) : (
|
{
|
||||||
<DropdownViewTranscoding showControls={showControls} />
|
position: "absolute",
|
||||||
)}
|
top: insets.top,
|
||||||
|
left: insets.left,
|
||||||
|
opacity: showControls ? 1 : 0,
|
||||||
|
zIndex: 1000,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
{!mediaSource?.TranscodingUrl ? (
|
||||||
|
<DropdownViewDirect showControls={showControls} />
|
||||||
|
) : (
|
||||||
|
<DropdownViewTranscoding showControls={showControls} />
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
</VideoProvider>
|
</VideoProvider>
|
||||||
|
|
||||||
<Pressable
|
<Pressable
|
||||||
@@ -528,8 +543,8 @@ export const Controls: React.FC<Props> = ({
|
|||||||
style={[
|
style={[
|
||||||
{
|
{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: 0,
|
top: insets.top,
|
||||||
right: 0,
|
right: insets.right,
|
||||||
opacity: showControls ? 1 : 0,
|
opacity: showControls ? 1 : 0,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
@@ -579,7 +594,7 @@ export const Controls: React.FC<Props> = ({
|
|||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
||||||
stop();
|
router.back();
|
||||||
}}
|
}}
|
||||||
className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2"
|
className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2"
|
||||||
>
|
>
|
||||||
@@ -591,8 +606,8 @@ export const Controls: React.FC<Props> = ({
|
|||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: "50%", // Center vertically
|
top: "50%", // Center vertically
|
||||||
left: 0,
|
left: insets.left,
|
||||||
right: 0,
|
right: insets.right,
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
@@ -705,9 +720,9 @@ export const Controls: React.FC<Props> = ({
|
|||||||
style={[
|
style={[
|
||||||
{
|
{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
right: 0,
|
right: insets.right,
|
||||||
left: 0,
|
left: insets.left,
|
||||||
bottom: 0,
|
bottom: insets.bottom,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
className={`flex flex-col p-4`}
|
className={`flex flex-col p-4`}
|
||||||
|
|||||||
@@ -72,105 +72,93 @@ const DropdownViewDirect: React.FC<DropdownViewDirectProps> = ({
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<DropdownMenu.Root>
|
||||||
style={{
|
<DropdownMenu.Trigger>
|
||||||
position: "absolute",
|
<TouchableOpacity className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2">
|
||||||
zIndex: 1000,
|
<Ionicons name="ellipsis-horizontal" size={24} color={"white"} />
|
||||||
opacity: showControls ? 1 : 0,
|
</TouchableOpacity>
|
||||||
}}
|
</DropdownMenu.Trigger>
|
||||||
className="p-4"
|
<DropdownMenu.Content
|
||||||
>
|
loop={true}
|
||||||
<DropdownMenu.Root>
|
side="bottom"
|
||||||
<DropdownMenu.Trigger>
|
align="start"
|
||||||
<TouchableOpacity className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2">
|
alignOffset={0}
|
||||||
<Ionicons name="ellipsis-horizontal" size={24} color={"white"} />
|
avoidCollisions={true}
|
||||||
</TouchableOpacity>
|
collisionPadding={8}
|
||||||
</DropdownMenu.Trigger>
|
sideOffset={8}
|
||||||
<DropdownMenu.Content
|
>
|
||||||
loop={true}
|
<DropdownMenu.Sub>
|
||||||
side="bottom"
|
<DropdownMenu.SubTrigger key="subtitle-trigger">
|
||||||
align="start"
|
Subtitle
|
||||||
alignOffset={0}
|
</DropdownMenu.SubTrigger>
|
||||||
avoidCollisions={true}
|
<DropdownMenu.SubContent
|
||||||
collisionPadding={8}
|
alignOffset={-10}
|
||||||
sideOffset={8}
|
avoidCollisions={true}
|
||||||
>
|
collisionPadding={0}
|
||||||
<DropdownMenu.Sub>
|
loop={true}
|
||||||
<DropdownMenu.SubTrigger key="subtitle-trigger">
|
sideOffset={10}
|
||||||
Subtitle
|
>
|
||||||
</DropdownMenu.SubTrigger>
|
{allSubtitleTracksForDirectPlay?.map((sub, idx: number) => (
|
||||||
<DropdownMenu.SubContent
|
<DropdownMenu.CheckboxItem
|
||||||
alignOffset={-10}
|
key={`subtitle-item-${idx}`}
|
||||||
avoidCollisions={true}
|
value={subtitleIndex === sub.index.toString()}
|
||||||
collisionPadding={0}
|
onValueChange={() => {
|
||||||
loop={true}
|
if ("deliveryUrl" in sub && sub.deliveryUrl) {
|
||||||
sideOffset={10}
|
setSubtitleURL &&
|
||||||
>
|
setSubtitleURL(api?.basePath + sub.deliveryUrl, sub.name);
|
||||||
{allSubtitleTracksForDirectPlay?.map((sub, idx: number) => (
|
|
||||||
<DropdownMenu.CheckboxItem
|
|
||||||
key={`subtitle-item-${idx}`}
|
|
||||||
value={subtitleIndex === sub.index.toString()}
|
|
||||||
onValueChange={() => {
|
|
||||||
if ("deliveryUrl" in sub && sub.deliveryUrl) {
|
|
||||||
setSubtitleURL &&
|
|
||||||
setSubtitleURL(
|
|
||||||
api?.basePath + sub.deliveryUrl,
|
|
||||||
sub.name
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
"Set external subtitle: ",
|
"Set external subtitle: ",
|
||||||
api?.basePath + sub.deliveryUrl
|
api?.basePath + sub.deliveryUrl
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log("Set sub index: ", sub.index);
|
console.log("Set sub index: ", sub.index);
|
||||||
setSubtitleTrack && setSubtitleTrack(sub.index);
|
setSubtitleTrack && setSubtitleTrack(sub.index);
|
||||||
}
|
}
|
||||||
router.setParams({
|
router.setParams({
|
||||||
subtitleIndex: sub.index.toString(),
|
subtitleIndex: sub.index.toString(),
|
||||||
});
|
});
|
||||||
console.log("Subtitle: ", sub);
|
console.log("Subtitle: ", sub);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DropdownMenu.ItemTitle key={`subtitle-item-title-${idx}`}>
|
<DropdownMenu.ItemTitle key={`subtitle-item-title-${idx}`}>
|
||||||
{sub.name}
|
{sub.name}
|
||||||
</DropdownMenu.ItemTitle>
|
</DropdownMenu.ItemTitle>
|
||||||
</DropdownMenu.CheckboxItem>
|
</DropdownMenu.CheckboxItem>
|
||||||
))}
|
))}
|
||||||
</DropdownMenu.SubContent>
|
</DropdownMenu.SubContent>
|
||||||
</DropdownMenu.Sub>
|
</DropdownMenu.Sub>
|
||||||
<DropdownMenu.Sub>
|
<DropdownMenu.Sub>
|
||||||
<DropdownMenu.SubTrigger key="audio-trigger">
|
<DropdownMenu.SubTrigger key="audio-trigger">
|
||||||
Audio
|
Audio
|
||||||
</DropdownMenu.SubTrigger>
|
</DropdownMenu.SubTrigger>
|
||||||
<DropdownMenu.SubContent
|
<DropdownMenu.SubContent
|
||||||
alignOffset={-10}
|
alignOffset={-10}
|
||||||
avoidCollisions={true}
|
avoidCollisions={true}
|
||||||
collisionPadding={0}
|
collisionPadding={0}
|
||||||
loop={true}
|
loop={true}
|
||||||
sideOffset={10}
|
sideOffset={10}
|
||||||
>
|
>
|
||||||
{audioTracks?.map((track, idx: number) => (
|
{audioTracks?.map((track, idx: number) => (
|
||||||
<DropdownMenu.CheckboxItem
|
<DropdownMenu.CheckboxItem
|
||||||
key={`audio-item-${idx}`}
|
key={`audio-item-${idx}`}
|
||||||
value={audioIndex === track.index.toString()}
|
value={audioIndex === track.index.toString()}
|
||||||
onValueChange={() => {
|
onValueChange={() => {
|
||||||
setAudioTrack && setAudioTrack(track.index);
|
setAudioTrack && setAudioTrack(track.index);
|
||||||
router.setParams({
|
router.setParams({
|
||||||
audioIndex: track.index.toString(),
|
audioIndex: track.index.toString(),
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DropdownMenu.ItemTitle key={`audio-item-title-${idx}`}>
|
<DropdownMenu.ItemTitle key={`audio-item-title-${idx}`}>
|
||||||
{track.name}
|
{track.name}
|
||||||
</DropdownMenu.ItemTitle>
|
</DropdownMenu.ItemTitle>
|
||||||
</DropdownMenu.CheckboxItem>
|
</DropdownMenu.CheckboxItem>
|
||||||
))}
|
))}
|
||||||
</DropdownMenu.SubContent>
|
</DropdownMenu.SubContent>
|
||||||
</DropdownMenu.Sub>
|
</DropdownMenu.Sub>
|
||||||
</DropdownMenu.Content>
|
</DropdownMenu.Content>
|
||||||
</DropdownMenu.Root>
|
</DropdownMenu.Root>
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user