diff --git a/app/(auth)/(tabs)/_layout.tsx b/app/(auth)/(tabs)/_layout.tsx
index e1f6c115..15d8b239 100644
--- a/app/(auth)/(tabs)/_layout.tsx
+++ b/app/(auth)/(tabs)/_layout.tsx
@@ -3,8 +3,9 @@ import React, { useEffect } from "react";
import * as NavigationBar from "expo-navigation-bar";
import { TabBarIcon } from "@/components/navigation/TabBarIcon";
import { Colors } from "@/constants/Colors";
-import { Platform, TouchableOpacity } from "react-native";
+import { Platform, TouchableOpacity, View } from "react-native";
import { Feather } from "@expo/vector-icons";
+import { Chromecast } from "@/components/Chromecast";
export default function TabLayout() {
useEffect(() => {
@@ -41,18 +42,23 @@ export default function TabLayout() {
router.push("/(auth)/downloads");
}}
>
-
+
),
headerRight: () => (
- {
- router.push("/(auth)/settings");
- }}
- >
-
-
+
+
+ {
+ router.push("/(auth)/settings");
+ }}
+ >
+
+
+
+
+
),
}}
/>
diff --git a/app/(auth)/items/[id]/page.tsx b/app/(auth)/items/[id]/page.tsx
index 85d2a01c..32a74f3d 100644
--- a/app/(auth)/items/[id]/page.tsx
+++ b/app/(auth)/items/[id]/page.tsx
@@ -137,35 +137,38 @@ const page: React.FC = () => {
const [cp, setCp] = useAtom(currentlyPlayingItemAtom);
const client = useRemoteMediaClient();
- const onPressPlay = useCallback(async () => {
- if (!playbackUrl || !item) return;
+ const onPressPlay = useCallback(
+ async (type: "device" | "cast" = "device") => {
+ if (!playbackUrl || !item) return;
- if (chromecastReady && client) {
- await CastContext.getPlayServicesState().then((state) => {
- if (state && state !== PlayServicesState.SUCCESS)
- CastContext.showPlayServicesErrorDialog(state);
- else {
- client.loadMedia({
- mediaInfo: {
- contentUrl: playbackUrl,
- contentType: "video/mp4",
- metadata: {
- type: item.Type === "Episode" ? "tvShow" : "movie",
- title: item.Name || "",
- subtitle: item.Overview || "",
+ if (type === "cast" && client) {
+ await CastContext.getPlayServicesState().then((state) => {
+ if (state && state !== PlayServicesState.SUCCESS)
+ CastContext.showPlayServicesErrorDialog(state);
+ else {
+ client.loadMedia({
+ mediaInfo: {
+ contentUrl: playbackUrl,
+ contentType: "video/mp4",
+ metadata: {
+ type: item.Type === "Episode" ? "tvShow" : "movie",
+ title: item.Name || "",
+ subtitle: item.Overview || "",
+ },
},
- },
- startTime: 0,
- });
- }
- });
- } else {
- setCp({
- item,
- playbackUrl,
- });
- }
- }, [playbackUrl, item]);
+ startTime: 0,
+ });
+ }
+ });
+ } else {
+ setCp({
+ item,
+ playbackUrl,
+ });
+ }
+ },
+ [playbackUrl, item],
+ );
if (l1)
return (
@@ -262,7 +265,6 @@ const page: React.FC = () => {
)}
-
{item.Overview}
@@ -287,7 +289,7 @@ const page: React.FC = () => {
diff --git a/app/_layout.tsx b/app/_layout.tsx
index 0bcddda6..dde840d1 100644
--- a/app/_layout.tsx
+++ b/app/_layout.tsx
@@ -9,8 +9,8 @@ import { useEffect, useRef, useState } from "react";
import "react-native-reanimated";
import * as ScreenOrientation from "expo-screen-orientation";
import { StatusBar } from "expo-status-bar";
-import { useSafeAreaInsets } from "react-native-safe-area-context";
import { CurrentlyPlayingBar } from "@/components/CurrentlyPlayingBar";
+import { ActionSheetProvider } from "@expo/react-native-action-sheet";
// Prevent the splash screen from auto-hiding before asset loading is complete.
SplashScreen.preventAutoHideAsync();
@@ -75,67 +75,69 @@ export default function RootLayout() {
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
diff --git a/components/ParallaxPage.tsx b/components/ParallaxPage.tsx
index 90f8bff6..d4aa87ec 100644
--- a/components/ParallaxPage.tsx
+++ b/components/ParallaxPage.tsx
@@ -9,6 +9,7 @@ import Animated, {
useScrollViewOffset,
} from "react-native-reanimated";
import { useSafeAreaInsets } from "react-native-safe-area-context";
+import { Chromecast } from "./Chromecast";
const HEADER_HEIGHT = 400;
@@ -72,6 +73,15 @@ export const ParallaxScrollView: React.FC = ({
/>
+
+
+
+
{logo && (
{logo}
diff --git a/components/PlayButton.tsx b/components/PlayButton.tsx
index 2ebfe94e..4429cd31 100644
--- a/components/PlayButton.tsx
+++ b/components/PlayButton.tsx
@@ -2,10 +2,12 @@ import { Button } from "./Button";
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import { Feather, Ionicons } from "@expo/vector-icons";
import { runtimeTicksToMinutes } from "@/utils/time";
+import { useActionSheet } from "@expo/react-native-action-sheet";
+import { View } from "react-native";
interface Props extends React.ComponentProps {
item: BaseItemDto;
- onPress: () => void;
+ onPress: (type?: "cast" | "device") => void;
chromecastReady: boolean;
}
@@ -15,15 +17,45 @@ export const PlayButton: React.FC = ({
chromecastReady,
...props
}) => {
+ const { showActionSheetWithOptions } = useActionSheet();
+
+ const _onPress = () => {
+ if (!chromecastReady) {
+ onPress("device");
+ return;
+ }
+
+ const options = ["Chromecast", "Device", "Cancel"];
+ const cancelButtonIndex = 2;
+
+ showActionSheetWithOptions(
+ {
+ options,
+ cancelButtonIndex,
+ },
+ (selectedIndex: number | undefined) => {
+ switch (selectedIndex) {
+ case 0:
+ onPress("cast");
+ break;
+ case 1:
+ onPress("device");
+ break;
+ case cancelButtonIndex:
+ console.log("calcel");
+ }
+ },
+ );
+ };
+
return (
- ) : (
+
- )
+ {chromecastReady && }
+
}
{...props}
>