mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-12 00:40:23 +01:00
fix: controls gray overlay
This commit is contained in:
@@ -435,7 +435,6 @@ export default function page() {
|
|||||||
position: "relative",
|
position: "relative",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
opacity: showControls ? (Platform.OS === "android" ? 0.7 : 0.5) : 1,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<VlcPlayerView
|
<VlcPlayerView
|
||||||
|
|||||||
@@ -387,7 +387,6 @@ const Player = () => {
|
|||||||
position: "relative",
|
position: "relative",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
opacity: showControls ? 0.5 : 1,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{videoSource ? (
|
{videoSource ? (
|
||||||
|
|||||||
242
app/login.tsx
242
app/login.tsx
@@ -189,133 +189,129 @@ const Login: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (api?.basePath) {
|
|
||||||
return (
|
|
||||||
<SafeAreaView style={{ flex: 1 }}>
|
|
||||||
<KeyboardAvoidingView
|
|
||||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
|
||||||
style={{ flex: 1, height: "100%" }}
|
|
||||||
>
|
|
||||||
<View className="flex flex-col h-full relative items-center justify-center">
|
|
||||||
<View className="px-4 -mt-20 w-full">
|
|
||||||
<View className="flex flex-col space-y-2">
|
|
||||||
<Text className="text-2xl font-bold -mb-2">
|
|
||||||
Log in
|
|
||||||
<>
|
|
||||||
{serverName ? (
|
|
||||||
<>
|
|
||||||
{" to "}
|
|
||||||
<Text className="text-purple-600">{serverName}</Text>
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</>
|
|
||||||
</Text>
|
|
||||||
<Text className="text-xs text-neutral-400">{api.basePath}</Text>
|
|
||||||
<Input
|
|
||||||
placeholder="Username"
|
|
||||||
onChangeText={(text) =>
|
|
||||||
setCredentials({ ...credentials, username: text })
|
|
||||||
}
|
|
||||||
value={credentials.username}
|
|
||||||
autoFocus
|
|
||||||
secureTextEntry={false}
|
|
||||||
keyboardType="default"
|
|
||||||
returnKeyType="done"
|
|
||||||
autoCapitalize="none"
|
|
||||||
textContentType="username"
|
|
||||||
clearButtonMode="while-editing"
|
|
||||||
maxLength={500}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Input
|
|
||||||
className="mb-2"
|
|
||||||
placeholder="Password"
|
|
||||||
onChangeText={(text) =>
|
|
||||||
setCredentials({ ...credentials, password: text })
|
|
||||||
}
|
|
||||||
value={credentials.password}
|
|
||||||
secureTextEntry
|
|
||||||
keyboardType="default"
|
|
||||||
returnKeyType="done"
|
|
||||||
autoCapitalize="none"
|
|
||||||
textContentType="password"
|
|
||||||
clearButtonMode="while-editing"
|
|
||||||
maxLength={500}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<Text className="text-red-600 mb-2">{error}</Text>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View className="absolute bottom-0 left-0 w-full px-4 mb-2">
|
|
||||||
<Button
|
|
||||||
color="black"
|
|
||||||
onPress={handleQuickConnect}
|
|
||||||
className="w-full mb-2"
|
|
||||||
>
|
|
||||||
Use Quick Connect
|
|
||||||
</Button>
|
|
||||||
<Button onPress={handleLogin} loading={loading}>
|
|
||||||
Log in
|
|
||||||
</Button>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</KeyboardAvoidingView>
|
|
||||||
</SafeAreaView>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaView style={{ flex: 1 }}>
|
<SafeAreaView style={{ flex: 1, paddingBottom: 16 }}>
|
||||||
<KeyboardAvoidingView
|
<KeyboardAvoidingView
|
||||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||||
style={{ flex: 1, height: "100%" }}
|
|
||||||
>
|
>
|
||||||
<View className="flex flex-col h-full relative items-center justify-center w-full">
|
{api?.basePath ? (
|
||||||
<View className="flex flex-col gap-y-2 px-4 w-full -mt-36">
|
<>
|
||||||
<Image
|
<View className="flex flex-col h-full relative items-center justify-center">
|
||||||
style={{
|
<View className="px-4 -mt-20 w-full">
|
||||||
width: 100,
|
<View className="flex flex-col space-y-2">
|
||||||
height: 100,
|
<Text className="text-2xl font-bold -mb-2">
|
||||||
marginLeft: -23,
|
Log in
|
||||||
marginBottom: -20,
|
<>
|
||||||
}}
|
{serverName ? (
|
||||||
source={require("@/assets/images/StreamyFinFinal.png")}
|
<>
|
||||||
/>
|
{" to "}
|
||||||
<Text className="text-3xl font-bold">Streamyfin</Text>
|
<Text className="text-purple-600">{serverName}</Text>
|
||||||
<Text className="text-neutral-500">
|
</>
|
||||||
Enter the URL to your Jellyfin server
|
) : null}
|
||||||
</Text>
|
</>
|
||||||
<Input
|
</Text>
|
||||||
placeholder="Server URL"
|
<Text className="text-xs text-neutral-400">
|
||||||
onChangeText={setServerURL}
|
{api.basePath}
|
||||||
value={serverURL}
|
</Text>
|
||||||
keyboardType="url"
|
<Input
|
||||||
returnKeyType="done"
|
placeholder="Username"
|
||||||
autoCapitalize="none"
|
onChangeText={(text) =>
|
||||||
textContentType="URL"
|
setCredentials({ ...credentials, username: text })
|
||||||
maxLength={500}
|
}
|
||||||
/>
|
value={credentials.username}
|
||||||
<Text className="text-xs text-neutral-500 ml-4">
|
autoFocus
|
||||||
Make sure to include http or https
|
secureTextEntry={false}
|
||||||
</Text>
|
keyboardType="default"
|
||||||
<PreviousServersList
|
returnKeyType="done"
|
||||||
onServerSelect={(s) => {
|
autoCapitalize="none"
|
||||||
handleConnect(s.address);
|
textContentType="username"
|
||||||
}}
|
clearButtonMode="while-editing"
|
||||||
/>
|
maxLength={500}
|
||||||
</View>
|
/>
|
||||||
<View className="mb-2 absolute bottom-0 left-0 w-full px-4">
|
|
||||||
<Button
|
<Input
|
||||||
loading={loadingServerCheck}
|
className="mb-2"
|
||||||
disabled={loadingServerCheck}
|
placeholder="Password"
|
||||||
onPress={async () => await handleConnect(serverURL)}
|
onChangeText={(text) =>
|
||||||
className="w-full grow"
|
setCredentials({ ...credentials, password: text })
|
||||||
>
|
}
|
||||||
Connect
|
value={credentials.password}
|
||||||
</Button>
|
secureTextEntry
|
||||||
</View>
|
keyboardType="default"
|
||||||
</View>
|
returnKeyType="done"
|
||||||
|
autoCapitalize="none"
|
||||||
|
textContentType="password"
|
||||||
|
clearButtonMode="while-editing"
|
||||||
|
maxLength={500}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Text className="text-red-600 mb-2">{error}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="absolute bottom-0 left-0 w-full px-4 mb-2">
|
||||||
|
<Button
|
||||||
|
color="black"
|
||||||
|
onPress={handleQuickConnect}
|
||||||
|
className="w-full mb-2"
|
||||||
|
>
|
||||||
|
Use Quick Connect
|
||||||
|
</Button>
|
||||||
|
<Button onPress={handleLogin} loading={loading}>
|
||||||
|
Log in
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<View className="flex flex-col h-full relative items-center justify-center w-full">
|
||||||
|
<View className="flex flex-col gap-y-2 px-4 w-full -mt-36">
|
||||||
|
<Image
|
||||||
|
style={{
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
marginLeft: -23,
|
||||||
|
marginBottom: -20,
|
||||||
|
}}
|
||||||
|
source={require("@/assets/images/StreamyFinFinal.png")}
|
||||||
|
/>
|
||||||
|
<Text className="text-3xl font-bold">Streamyfin</Text>
|
||||||
|
<Text className="text-neutral-500">
|
||||||
|
Enter the URL to your Jellyfin server
|
||||||
|
</Text>
|
||||||
|
<Input
|
||||||
|
placeholder="Server URL"
|
||||||
|
onChangeText={setServerURL}
|
||||||
|
value={serverURL}
|
||||||
|
keyboardType="url"
|
||||||
|
returnKeyType="done"
|
||||||
|
autoCapitalize="none"
|
||||||
|
textContentType="URL"
|
||||||
|
maxLength={500}
|
||||||
|
/>
|
||||||
|
<Text className="text-xs text-neutral-500 ml-4">
|
||||||
|
Make sure to include http or https
|
||||||
|
</Text>
|
||||||
|
<PreviousServersList
|
||||||
|
onServerSelect={(s) => {
|
||||||
|
handleConnect(s.address);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View className="mb-2 absolute bottom-0 left-0 w-full px-4">
|
||||||
|
<Button
|
||||||
|
loading={loadingServerCheck}
|
||||||
|
disabled={loadingServerCheck}
|
||||||
|
onPress={async () => await handleConnect(serverURL)}
|
||||||
|
className="w-full grow"
|
||||||
|
>
|
||||||
|
Connect
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</KeyboardAvoidingView>
|
</KeyboardAvoidingView>
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -497,33 +497,6 @@ export const Controls: React.FC<Props> = ({
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<VideoProvider
|
|
||||||
getAudioTracks={getAudioTracks}
|
|
||||||
getSubtitleTracks={getSubtitleTracks}
|
|
||||||
setAudioTrack={setAudioTrack}
|
|
||||||
setSubtitleTrack={setSubtitleTrack}
|
|
||||||
setSubtitleURL={setSubtitleURL}
|
|
||||||
>
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
{
|
|
||||||
position: "absolute",
|
|
||||||
top: settings?.safeAreaInControlsEnabled ? insets.top : 0,
|
|
||||||
left: settings?.safeAreaInControlsEnabled ? insets.left : 0,
|
|
||||||
opacity: showControls ? 1 : 0,
|
|
||||||
zIndex: 1000,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
className={`flex flex-row items-center space-x-2 z-10 p-4 `}
|
|
||||||
>
|
|
||||||
{!mediaSource?.TranscodingUrl ? (
|
|
||||||
<DropdownViewDirect showControls={showControls} />
|
|
||||||
) : (
|
|
||||||
<DropdownViewTranscoding showControls={showControls} />
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
</VideoProvider>
|
|
||||||
|
|
||||||
<Pressable
|
<Pressable
|
||||||
onPressIn={() => {
|
onPressIn={() => {
|
||||||
toggleControls();
|
toggleControls();
|
||||||
@@ -532,6 +505,8 @@ export const Controls: React.FC<Props> = ({
|
|||||||
position: "absolute",
|
position: "absolute",
|
||||||
width: Dimensions.get("window").width,
|
width: Dimensions.get("window").width,
|
||||||
height: Dimensions.get("window").height,
|
height: Dimensions.get("window").height,
|
||||||
|
backgroundColor: "black",
|
||||||
|
opacity: showControls ? 0.5 : 0,
|
||||||
}}
|
}}
|
||||||
></Pressable>
|
></Pressable>
|
||||||
|
|
||||||
@@ -541,61 +516,82 @@ export const Controls: React.FC<Props> = ({
|
|||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: settings?.safeAreaInControlsEnabled ? insets.top : 0,
|
top: settings?.safeAreaInControlsEnabled ? insets.top : 0,
|
||||||
right: settings?.safeAreaInControlsEnabled ? insets.right : 0,
|
right: settings?.safeAreaInControlsEnabled ? insets.right : 0,
|
||||||
|
width: settings?.safeAreaInControlsEnabled
|
||||||
|
? Dimensions.get("window").width - insets.left - insets.right
|
||||||
|
: Dimensions.get("window").width,
|
||||||
opacity: showControls ? 1 : 0,
|
opacity: showControls ? 1 : 0,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
pointerEvents={showControls ? "auto" : "none"}
|
pointerEvents={showControls ? "auto" : "none"}
|
||||||
className={`flex flex-row items-center space-x-2 z-10 p-4 `}
|
className={`flex flex-row w-full p-4 `}
|
||||||
>
|
>
|
||||||
{item?.Type === "Episode" && !offline && (
|
<View className="mr-auto">
|
||||||
|
<VideoProvider
|
||||||
|
getAudioTracks={getAudioTracks}
|
||||||
|
getSubtitleTracks={getSubtitleTracks}
|
||||||
|
setAudioTrack={setAudioTrack}
|
||||||
|
setSubtitleTrack={setSubtitleTrack}
|
||||||
|
setSubtitleURL={setSubtitleURL}
|
||||||
|
>
|
||||||
|
{!mediaSource?.TranscodingUrl ? (
|
||||||
|
<DropdownViewDirect showControls={showControls} />
|
||||||
|
) : (
|
||||||
|
<DropdownViewTranscoding showControls={showControls} />
|
||||||
|
)}
|
||||||
|
</VideoProvider>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="flex flex-row items-center space-x-2 ">
|
||||||
|
{item?.Type === "Episode" && !offline && (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
switchOnEpisodeMode();
|
||||||
|
}}
|
||||||
|
className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2"
|
||||||
|
>
|
||||||
|
<Ionicons name="list" size={24} color="white" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
{previousItem && !offline && (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={goToPreviousItem}
|
||||||
|
className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2"
|
||||||
|
>
|
||||||
|
<Ionicons name="play-skip-back" size={24} color="white" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{nextItem && !offline && (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={goToNextItem}
|
||||||
|
className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2"
|
||||||
|
>
|
||||||
|
<Ionicons name="play-skip-forward" size={24} color="white" />
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{mediaSource?.TranscodingUrl && (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={toggleIgnoreSafeAreas}
|
||||||
|
className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2"
|
||||||
|
>
|
||||||
|
<Ionicons
|
||||||
|
name={ignoreSafeAreas ? "contract-outline" : "expand"}
|
||||||
|
size={24}
|
||||||
|
color="white"
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
onPress={() => {
|
onPress={async () => {
|
||||||
switchOnEpisodeMode();
|
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
||||||
|
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"
|
||||||
>
|
>
|
||||||
<Ionicons name="list" size={24} color="white" />
|
<Ionicons name="close" size={24} color="white" />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
)}
|
</View>
|
||||||
{previousItem && !offline && (
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={goToPreviousItem}
|
|
||||||
className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2"
|
|
||||||
>
|
|
||||||
<Ionicons name="play-skip-back" size={24} color="white" />
|
|
||||||
</TouchableOpacity>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{nextItem && !offline && (
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={goToNextItem}
|
|
||||||
className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2"
|
|
||||||
>
|
|
||||||
<Ionicons name="play-skip-forward" size={24} color="white" />
|
|
||||||
</TouchableOpacity>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{mediaSource?.TranscodingUrl && (
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={toggleIgnoreSafeAreas}
|
|
||||||
className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2"
|
|
||||||
>
|
|
||||||
<Ionicons
|
|
||||||
name={ignoreSafeAreas ? "contract-outline" : "expand"}
|
|
||||||
size={24}
|
|
||||||
color="white"
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
|
||||||
)}
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={async () => {
|
|
||||||
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
|
|
||||||
router.back();
|
|
||||||
}}
|
|
||||||
className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2"
|
|
||||||
>
|
|
||||||
<Ionicons name="close" size={24} color="white" />
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|||||||
@@ -118,14 +118,7 @@ const DropdownView: React.FC<DropdownViewProps> = ({ showControls }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View>
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
zIndex: 1000,
|
|
||||||
opacity: showControls ? 1 : 0,
|
|
||||||
}}
|
|
||||||
className="p-4"
|
|
||||||
>
|
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger>
|
<DropdownMenu.Trigger>
|
||||||
<TouchableOpacity className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2">
|
<TouchableOpacity className="aspect-square flex flex-col bg-neutral-800/90 rounded-xl items-center justify-center p-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user