diff --git a/app.json b/app.json index 8a0f4f54..2395acc2 100644 --- a/app.json +++ b/app.json @@ -13,13 +13,18 @@ "backgroundColor": "#2E2E2E" }, "jsEngine": "hermes", - "assetBundlePatterns": ["**/*"], + "assetBundlePatterns": [ + "**/*" + ], "ios": { "requireFullScreen": true, "infoPlist": { "NSCameraUsageDescription": "The app needs access to your camera to scan barcodes.", "NSMicrophoneUsageDescription": "The app needs access to your microphone.", - "UIBackgroundModes": ["audio", "fetch"], + "UIBackgroundModes": [ + "audio", + "fetch" + ], "NSLocalNetworkUsageDescription": "The app needs access to your local network to connect to your Jellyfin server.", "NSAppTransportSecurity": { "NSAllowsArbitraryLoads": true @@ -48,6 +53,7 @@ ] }, "plugins": [ + "@react-native-tvos/config-tv", "expo-router", "expo-font", "@config-plugins/ffmpeg-kit-react-native", @@ -108,10 +114,18 @@ "expo-asset", [ "react-native-edge-to-edge", - { "android": { "parentTheme": "Material3" } } + { + "android": { + "parentTheme": "Material3" + } + } ], - ["react-native-bottom-tabs"], - ["./plugins/withChangeNativeAndroidTextToWhite.js"] + [ + "react-native-bottom-tabs" + ], + [ + "./plugins/withChangeNativeAndroidTextToWhite.js" + ] ], "experiments": { "typedRoutes": true @@ -132,4 +146,4 @@ "url": "https://u.expo.dev/e79219d1-797f-4fbe-9fa1-cfd360690a68" } } -} +} \ No newline at end of file diff --git a/app/(auth)/(tabs)/(custom-links)/index.tsx b/app/(auth)/(tabs)/(custom-links)/index.tsx index bf6dc46b..29091e19 100644 --- a/app/(auth)/(tabs)/(custom-links)/index.tsx +++ b/app/(auth)/(tabs)/(custom-links)/index.tsx @@ -1,13 +1,15 @@ +import { Platform } from "react-native"; import { FlatList, TouchableOpacity, View } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import React, { useCallback, useEffect, useState } from "react"; import { useAtom } from "jotai/index"; import { apiAtom } from "@/providers/JellyfinProvider"; import { ListItem } from "@/components/list/ListItem"; -import * as WebBrowser from "expo-web-browser"; import Ionicons from "@expo/vector-icons/Ionicons"; import { Text } from "@/components/common/Text"; +const WebBrowser = !Platform.isTV ? require("expo-web-browser") : null; + export interface MenuLink { name: string; url: string; @@ -50,7 +52,13 @@ export default function menuLinks() { }} data={menuLinks} renderItem={({ item }) => ( - WebBrowser.openBrowserAsync(item.url)}> + { + if (!Platform.isTV) { + WebBrowser.openBrowserAsync(item.url); + } + }} + > } diff --git a/bun.lockb b/bun.lockb index 3a1947ce..902c36ca 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/modules/vlc-player/ios/VlcPlayer.podspec b/modules/vlc-player/ios/VlcPlayer.podspec index 642026ae..eaa622ac 100644 --- a/modules/vlc-player/ios/VlcPlayer.podspec +++ b/modules/vlc-player/ios/VlcPlayer.podspec @@ -10,7 +10,8 @@ Pod::Spec.new do |s| s.static_framework = true s.dependency 'ExpoModulesCore' - s.dependency 'MobileVLCKit', '~> 3.6.1b1' + s.ios.dependency 'MobileVLCKit', '~> 3.6.1b1' + s.tvos.dependency 'TVVLCKit', '~> 3.6.1b1' # Swift/Objective-C compatibility s.pod_target_xcconfig = { diff --git a/modules/vlc-player/ios/VlcPlayerView.swift b/modules/vlc-player/ios/VlcPlayerView.swift index f63aff44..cb75721f 100644 --- a/modules/vlc-player/ios/VlcPlayerView.swift +++ b/modules/vlc-player/ios/VlcPlayerView.swift @@ -1,5 +1,9 @@ import ExpoModulesCore +#if os(tvOS) +import TVVLCKit +#else import MobileVLCKit +#endif import UIKit class VlcPlayerView: ExpoView { diff --git a/package.json b/package.json index e5ebb82a..e8e25416 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,13 @@ "submodule-reload": "git submodule update --init --remote --recursive", "start": "bun run submodule-reload && expo start", "reset-project": "node ./scripts/reset-project.js", - "android": "bun run submodule-reload && expo run:android", "ios": "bun run submodule-reload && expo run:ios", + "tvos": "EXPO_TV=1 expo run:ios", + "android": "bun run submodule-reload && expo run:android", + "androidtv": "EXPO_TV=1 expo run:android", "web": "bun run submodule-reload && expo start --web", + "prebuild": "expo prebuild --clean", + "prebuild-tv": "EXPO_TV=1 expo prebuild --clean", "test": "jest --watchAll", "lint": "expo lint", "postinstall": "patch-package" @@ -70,7 +74,7 @@ "nativewind": "^2.0.11", "react": "18.2.0", "react-dom": "18.2.0", - "react-native": "0.74.5", + "react-native": "npm:react-native-tvos@0.74.5-0", "react-native-awesome-slider": "^2.5.6", "react-native-bottom-tabs": "0.7.1", "react-native-circular-progress": "^1.4.1", @@ -108,6 +112,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@react-native-tvos/config-tv": "^0.1.1", "@babel/core": "^7.26.0", "@types/jest": "^29.5.14", "@types/react": "~18.2.79", @@ -119,5 +124,12 @@ "react-test-renderer": "18.2.0", "typescript": "~5.3.3" }, - "private": true -} + "private": true, + "expo": { + "install": { + "exclude": [ + "react-native" + ] + } + } +} \ No newline at end of file