mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-05-30 02:28:26 +01:00
chore(deps): migrate to Expo SDK 56 (Phase 1 - compat)
Compatibility migration from SDK 55 to SDK 56 (react-native-tvos 0.85.3-0, React 19.2.3). Phase 1 = breaking changes needed to build; new-feature adoption and TypeScript 6 are deferred to Phase 2. - Deps aligned to SDK 56 via `expo install --fix` (all expo-* 56.x, screens 4.25.2, reanimated 4.3.1, worklets 0.8.3, gesture-handler 2.31.x, svg 15.15.4) - react-native -> react-native-tvos@0.85.3-0; react/react-dom 19.2.3 - expo-router forked React Navigation: ran the SDK 56 codemod (@react-navigation/* imports -> expo-router/*), removed the 3 now-unused direct @react-navigation/* dependencies, retyped NestedTabPageStack via expo-router Stack.Screen options - StyleSheet.absoluteFillObject -> absoluteFill (removed from RN 0.85 types) - app.json ios.deploymentTarget 15.6 -> 16.4 (SDK 56 minimum) - CI: Xcode 26.2 -> 26.4; made xcode-version Renovate-managed via a customManager + xcodereleases customDatasource - @babel/core 7.29.7; dropped version-locked screens/codegen bun-patches (no longer applicable on SDK 56) Deferred to Phase 2: TypeScript 6 (toolchain: @types/node, jest globals, UdpSocket typing), @expo/vector-icons -> @react-native-vector-icons codemod. typecheck passes. expo-doctor: 2 known failures remain (react-native-track-player New Arch fork; typescript major mismatch pending the deferred TS6 bump).
This commit is contained in:
19
.github/renovate.json
vendored
19
.github/renovate.json
vendored
@@ -25,6 +25,25 @@
|
||||
"osvVulnerabilityAlerts": true,
|
||||
"configMigration": true,
|
||||
"separateMinorPatch": true,
|
||||
"customManagers": [
|
||||
{
|
||||
"customType": "regex",
|
||||
"managerFilePatterns": ["/\\.ya?ml$/"],
|
||||
"matchStrings": [
|
||||
"# renovate: datasource=(?<datasource>\\S+) depName=(?<depName>\\S+)(?: versioning=(?<versioning>\\S+))?\\s+xcode-version:\\s*[\"']?(?<currentValue>[^\"'\\s]+)"
|
||||
],
|
||||
"versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}loose{{/if}}"
|
||||
}
|
||||
],
|
||||
"customDatasources": {
|
||||
"xcode": {
|
||||
"defaultRegistryUrlTemplate": "https://xcodereleases.com/data.json",
|
||||
"format": "json",
|
||||
"transformTemplates": [
|
||||
"{ \"releases\": [$[version.release.release=true].{\"version\": version.number}] }"
|
||||
]
|
||||
}
|
||||
},
|
||||
"lockFileMaintenance": {
|
||||
"vulnerabilityAlerts": {
|
||||
"enabled": true,
|
||||
|
||||
12
.github/workflows/build-apps.yml
vendored
12
.github/workflows/build-apps.yml
vendored
@@ -218,7 +218,8 @@ jobs:
|
||||
- name: 🔧 Setup Xcode
|
||||
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
|
||||
with:
|
||||
xcode-version: "26.2"
|
||||
# renovate: datasource=custom.xcode depName=xcode versioning=loose
|
||||
xcode-version: "26.4"
|
||||
|
||||
- name: 🏗️ Setup EAS
|
||||
uses: expo/expo-github-action@b184ff86a3c926240f1b6db41764c83a01c02eef # main
|
||||
@@ -282,7 +283,8 @@ jobs:
|
||||
- name: 🔧 Setup Xcode
|
||||
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
|
||||
with:
|
||||
xcode-version: "26.2"
|
||||
# renovate: datasource=custom.xcode depName=xcode versioning=loose
|
||||
xcode-version: "26.4"
|
||||
|
||||
- name: 🚀 Build iOS app
|
||||
env:
|
||||
@@ -341,7 +343,8 @@ jobs:
|
||||
- name: 🔧 Setup Xcode
|
||||
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
|
||||
with:
|
||||
xcode-version: "26.2"
|
||||
# renovate: datasource=custom.xcode depName=xcode versioning=loose
|
||||
xcode-version: "26.4"
|
||||
|
||||
- name: 🏗️ Setup EAS
|
||||
uses: expo/expo-github-action@b184ff86a3c926240f1b6db41764c83a01c02eef # main
|
||||
@@ -408,7 +411,8 @@ jobs:
|
||||
- name: 🔧 Setup Xcode
|
||||
uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1
|
||||
with:
|
||||
xcode-version: "26.2"
|
||||
# renovate: datasource=custom.xcode depName=xcode versioning=loose
|
||||
xcode-version: "26.4"
|
||||
|
||||
- name: 🚀 Build iOS app
|
||||
env:
|
||||
|
||||
2
app.json
2
app.json
@@ -78,7 +78,7 @@
|
||||
"expo-build-properties",
|
||||
{
|
||||
"ios": {
|
||||
"deploymentTarget": "15.6",
|
||||
"deploymentTarget": "16.4",
|
||||
"useFrameworks": "static"
|
||||
},
|
||||
"android": {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Slot, Stack, withLayoutContext } from "expo-router";
|
||||
import {
|
||||
createMaterialTopTabNavigator,
|
||||
MaterialTopTabNavigationEventMap,
|
||||
MaterialTopTabNavigationOptions,
|
||||
} from "@react-navigation/material-top-tabs";
|
||||
} from "expo-router/js-top-tabs";
|
||||
import type {
|
||||
ParamListBase,
|
||||
TabNavigationState,
|
||||
} from "@react-navigation/native";
|
||||
import { Slot, Stack, withLayoutContext } from "expo-router";
|
||||
} from "expo-router/react-navigation";
|
||||
import { Platform } from "react-native";
|
||||
|
||||
const { Navigator } = createMaterialTopTabNavigator();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Stack, useLocalSearchParams, withLayoutContext } from "expo-router";
|
||||
import {
|
||||
createMaterialTopTabNavigator,
|
||||
MaterialTopTabNavigationEventMap,
|
||||
MaterialTopTabNavigationOptions,
|
||||
} from "@react-navigation/material-top-tabs";
|
||||
} from "expo-router/js-top-tabs";
|
||||
import type {
|
||||
ParamListBase,
|
||||
TabNavigationState,
|
||||
} from "@react-navigation/native";
|
||||
import { Stack, useLocalSearchParams, withLayoutContext } from "expo-router";
|
||||
} from "expo-router/react-navigation";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const { Navigator } = createMaterialTopTabNavigator();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useRoute } from "@react-navigation/native";
|
||||
import { FlashList } from "@shopify/flash-list";
|
||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useRoute } from "expo-router/react-navigation";
|
||||
import { useAtom } from "jotai";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { getArtistsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useRoute } from "@react-navigation/native";
|
||||
import { FlashList } from "@shopify/flash-list";
|
||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useRoute } from "expo-router/react-navigation";
|
||||
import { useAtom } from "jotai";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useNavigation, useRoute } from "@react-navigation/native";
|
||||
import { FlashList } from "@shopify/flash-list";
|
||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useNavigation, useRoute } from "expo-router/react-navigation";
|
||||
import { useAtom } from "jotai";
|
||||
import { useCallback, useLayoutEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useRoute } from "@react-navigation/native";
|
||||
import { FlashList } from "@shopify/flash-list";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useRoute } from "expo-router/react-navigation";
|
||||
import { useAtom } from "jotai";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@@ -3,11 +3,11 @@ import {
|
||||
type NativeBottomTabNavigationEventMap,
|
||||
type NativeBottomTabNavigationOptions,
|
||||
} from "@bottom-tabs/react-navigation";
|
||||
import { withLayoutContext } from "expo-router";
|
||||
import type {
|
||||
ParamListBase,
|
||||
TabNavigationState,
|
||||
} from "@react-navigation/native";
|
||||
import { withLayoutContext } from "expo-router";
|
||||
} from "expo-router/react-navigation";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Platform, View } from "react-native";
|
||||
import { SystemBars } from "react-native-edge-to-edge";
|
||||
|
||||
@@ -1248,7 +1248,7 @@ const styles = StyleSheet.create({
|
||||
color: "#fff",
|
||||
},
|
||||
downloadingOverlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
...StyleSheet.absoluteFill,
|
||||
backgroundColor: "rgba(0,0,0,0.5)",
|
||||
borderRadius: scaleSize(14),
|
||||
justifyContent: "center",
|
||||
|
||||
@@ -2,12 +2,12 @@ import "@/augmentations";
|
||||
import { ActionSheetProvider } from "@expo/react-native-action-sheet";
|
||||
import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
|
||||
import NetInfo from "@react-native-community/netinfo";
|
||||
import { DarkTheme, ThemeProvider } from "@react-navigation/native";
|
||||
import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister";
|
||||
import { onlineManager, QueryClient } from "@tanstack/react-query";
|
||||
import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client";
|
||||
import * as BackgroundTask from "expo-background-task";
|
||||
import * as Device from "expo-device";
|
||||
import { DarkTheme, ThemeProvider } from "expo-router/react-navigation";
|
||||
import { Platform } from "react-native";
|
||||
import { GlobalModal } from "@/components/GlobalModal";
|
||||
import { enableTVMenuKeyInterception } from "@/hooks/useTVBackHandler";
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
diff --git a/lib/generators/modules/GenerateModuleObjCpp/index.js b/lib/generators/modules/GenerateModuleObjCpp/index.js
|
||||
index 927711514d2deaa3c795fb98e676e0a1f596eddc..0364d66204a76fccd3e06a0dc72bf801aa04a50d 100644
|
||||
--- a/lib/generators/modules/GenerateModuleObjCpp/index.js
|
||||
+++ b/lib/generators/modules/GenerateModuleObjCpp/index.js
|
||||
@@ -67,9 +67,12 @@ const HeaderFileTemplate = ({
|
||||
* must have a single output. More files => more genrule()s => slower builds.
|
||||
*/
|
||||
|
||||
-#ifndef __cplusplus
|
||||
-#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm.
|
||||
-#endif
|
||||
+// Patched: guard the Obj-C++ body with __cplusplus instead of hard-#error-ing.
|
||||
+// With use_frameworks! :static + New Arch, plain Obj-C .m TUs can trigger a
|
||||
+// Clang module build (via Swift-interop -Swift.h umbrellas) that pulls this
|
||||
+// header in Obj-C mode. Skipping the body (instead of erroring) lets the module
|
||||
+// build; .mm consumers still get the full Obj-C++ contents unchanged.
|
||||
+#if defined(__cplusplus)
|
||||
|
||||
// Avoid multiple includes of ${headerFileNameWithNoExt} symbols
|
||||
#ifndef ${headerFileNameWithNoExt}_H
|
||||
@@ -93,7 +96,7 @@ const HeaderFileTemplate = ({
|
||||
structInlineMethods +
|
||||
(assumeNonnull ? '\nNS_ASSUME_NONNULL_END\n' : '\n') +
|
||||
`#endif // ${headerFileNameWithNoExt}_H` +
|
||||
- '\n'
|
||||
+ '\n#endif // defined(__cplusplus)\n'
|
||||
);
|
||||
};
|
||||
const SourceFileTemplate = ({headerFileName, moduleImplementations}) => `/**
|
||||
@@ -1,191 +0,0 @@
|
||||
diff --git a/node_modules/react-native-screens/.bun-tag-10a3b0add1bd4de6 b/.bun-tag-10a3b0add1bd4de6
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
|
||||
diff --git a/node_modules/react-native-screens/.bun-tag-6a8504b742d5cfff b/.bun-tag-6a8504b742d5cfff
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
|
||||
diff --git a/node_modules/react-native-screens/.bun-tag-d28396854bc27a3d b/.bun-tag-d28396854bc27a3d
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
|
||||
diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm
|
||||
index 51f021831aed26a4eed3c85014020423b7b3108b..2f621547932806b94ab1e75ecc73772facd209d0 100644
|
||||
--- a/ios/RNSScreenStack.mm
|
||||
+++ b/ios/RNSScreenStack.mm
|
||||
@@ -34,6 +34,11 @@
|
||||
#import "integrations/RNSDismissibleModalProtocol.h"
|
||||
#import "utils/UINavigationBar+RNSUtility.h"
|
||||
|
||||
+#if TARGET_OS_TV
|
||||
+#import <React/RCTTVNavigationEventNotification.h>
|
||||
+#import <React/RCTTVRemoteHandler.h>
|
||||
+#endif // TARGET_OS_TV
|
||||
+
|
||||
#ifdef RNS_GAMMA_ENABLED
|
||||
#import "RNSFrameCorrectionProvider.h"
|
||||
#import "Swift-Bridging.h"
|
||||
@@ -43,6 +48,12 @@
|
||||
namespace react = facebook::react;
|
||||
#endif // RCT_NEW_ARCH_ENABLED
|
||||
|
||||
+#if TARGET_OS_TV
|
||||
+@interface RNSNavigationController ()
|
||||
+@property (nonatomic, strong) UITapGestureRecognizer *rnscreens_menuGestureRecognizer;
|
||||
+@end
|
||||
+#endif // TARGET_OS_TV
|
||||
+
|
||||
@interface RNSScreenStackView () <
|
||||
UINavigationControllerDelegate,
|
||||
UIAdaptivePresentationControllerDelegate,
|
||||
@@ -62,6 +73,57 @@ namespace react = facebook::react;
|
||||
|
||||
@implementation RNSNavigationController
|
||||
|
||||
+#if TARGET_OS_TV
|
||||
+- (void)viewDidLoad
|
||||
+{
|
||||
+ [super viewDidLoad];
|
||||
+
|
||||
+ self.rnscreens_menuGestureRecognizer =
|
||||
+ [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(rnscreens_menuPressed:)];
|
||||
+ self.rnscreens_menuGestureRecognizer.allowedPressTypes = @[ @(UIPressTypeMenu) ];
|
||||
+
|
||||
+ [[NSNotificationCenter defaultCenter] addObserver:self
|
||||
+ selector:@selector(rnscreens_enableMenuGesture)
|
||||
+ name:RCTTVEnableMenuKeyNotification
|
||||
+ object:nil];
|
||||
+ [[NSNotificationCenter defaultCenter] addObserver:self
|
||||
+ selector:@selector(rnscreens_disableMenuGesture)
|
||||
+ name:RCTTVDisableMenuKeyNotification
|
||||
+ object:nil];
|
||||
+
|
||||
+ if ([RCTTVRemoteHandler useMenuKey]) {
|
||||
+ [self rnscreens_enableMenuGesture];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+- (void)dealloc
|
||||
+{
|
||||
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
+}
|
||||
+
|
||||
+- (void)rnscreens_enableMenuGesture
|
||||
+{
|
||||
+ if (![self.view.gestureRecognizers containsObject:self.rnscreens_menuGestureRecognizer]) {
|
||||
+ [self.view addGestureRecognizer:self.rnscreens_menuGestureRecognizer];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+- (void)rnscreens_disableMenuGesture
|
||||
+{
|
||||
+ if ([self.view.gestureRecognizers containsObject:self.rnscreens_menuGestureRecognizer]) {
|
||||
+ [self.view removeGestureRecognizer:self.rnscreens_menuGestureRecognizer];
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+- (void)rnscreens_menuPressed:(UIGestureRecognizer *)recognizer
|
||||
+{
|
||||
+ [[NSNotificationCenter defaultCenter] postNavigationPressEventWithType:RCTTVRemoteEventMenu
|
||||
+ keyAction:recognizer.eventKeyAction
|
||||
+ tag:nil
|
||||
+ target:nil];
|
||||
+}
|
||||
+#endif // TARGET_OS_TV
|
||||
+
|
||||
#if !TARGET_OS_TV
|
||||
- (UIViewController *)childViewControllerForStatusBarStyle
|
||||
{
|
||||
diff --git a/ios/gamma/split-view/RNSSplitViewAppearanceApplicator.swift b/ios/gamma/split-view/RNSSplitViewAppearanceApplicator.swift
|
||||
index 95c76ccf3528d3a8828e90b272a1d79b0828a139..f29d4df21440d23523ae7a2f6fe71c32154e3928 100644
|
||||
--- a/ios/gamma/split-view/RNSSplitViewAppearanceApplicator.swift
|
||||
+++ b/ios/gamma/split-view/RNSSplitViewAppearanceApplicator.swift
|
||||
@@ -79,11 +79,13 @@ class RNSSplitViewAppearanceApplicator {
|
||||
maxWidth: splitView.maximumSupplementaryColumnWidth)
|
||||
|
||||
#if compiler(>=6.2)
|
||||
+ #if !os(tvOS)
|
||||
if #available(iOS 26.0, *) {
|
||||
validateColumnConstraints(
|
||||
minWidth: splitView.minimumInspectorColumnWidth,
|
||||
maxWidth: splitView.maximumInspectorColumnWidth)
|
||||
}
|
||||
+ #endif
|
||||
#endif
|
||||
|
||||
// Step 2.2 - applying updates to columns
|
||||
@@ -126,6 +128,7 @@ class RNSSplitViewAppearanceApplicator {
|
||||
}
|
||||
|
||||
#if compiler(>=6.2)
|
||||
+ #if !os(tvOS)
|
||||
if #available(iOS 26.0, *) {
|
||||
if splitView.minimumSecondaryColumnWidth >= 0 {
|
||||
splitViewController.minimumSecondaryColumnWidth = splitView.minimumSecondaryColumnWidth
|
||||
@@ -159,6 +162,7 @@ class RNSSplitViewAppearanceApplicator {
|
||||
splitView.preferredInspectorColumnWidthOrFraction
|
||||
}
|
||||
}
|
||||
+ #endif
|
||||
#endif
|
||||
|
||||
// Step 2.3 - manipulating with inspector column
|
||||
diff --git a/ios/gamma/split-view/RNSSplitViewHostController.swift b/ios/gamma/split-view/RNSSplitViewHostController.swift
|
||||
index 0421e3ea92fc7bcdf57417b5ee3a62348fce34f5..cd878ab638d3c78a661e2df4c4c1b21011dfcf48 100644
|
||||
--- a/ios/gamma/split-view/RNSSplitViewHostController.swift
|
||||
+++ b/ios/gamma/split-view/RNSSplitViewHostController.swift
|
||||
@@ -386,7 +386,7 @@ extension RNSSplitViewHostController: RNSSplitViewNavigationControllerViewFrameO
|
||||
/// @param inspectors An array of inspector-type RNSSplitViewScreenComponentView subviews.
|
||||
///
|
||||
func maybeSetupInspector(_ inspectors: [RNSSplitViewScreenComponentView]) {
|
||||
-
|
||||
+ #if !os(tvOS)
|
||||
if #available(iOS 26.0, *) {
|
||||
let inspector = inspectors.first
|
||||
if inspector != nil {
|
||||
@@ -395,6 +395,7 @@ extension RNSSplitViewHostController: RNSSplitViewNavigationControllerViewFrameO
|
||||
setViewController(inspectorViewController, for: .inspector)
|
||||
}
|
||||
}
|
||||
+ #endif
|
||||
}
|
||||
|
||||
///
|
||||
@@ -404,9 +405,11 @@ extension RNSSplitViewHostController: RNSSplitViewNavigationControllerViewFrameO
|
||||
/// Uses the UISplitViewController's new API introduced in iOS 26 to show the inspector column.
|
||||
///
|
||||
func maybeShowInspector() {
|
||||
+ #if !os(tvOS)
|
||||
if #available(iOS 26.0, *) {
|
||||
show(.inspector)
|
||||
}
|
||||
+ #endif
|
||||
}
|
||||
|
||||
///
|
||||
@@ -416,9 +419,11 @@ extension RNSSplitViewHostController: RNSSplitViewNavigationControllerViewFrameO
|
||||
/// Uses the UISplitViewController's new API introduced in iOS 26 to hide the inspector column.
|
||||
///
|
||||
func maybeHideInspector() {
|
||||
+ #if !os(tvOS)
|
||||
if #available(iOS 26.0, *) {
|
||||
hide(.inspector)
|
||||
}
|
||||
+ #endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -444,6 +449,7 @@ extension RNSSplitViewHostController: UISplitViewControllerDelegate {
|
||||
public func splitViewController(
|
||||
_ svc: UISplitViewController, didHide column: UISplitViewController.Column
|
||||
) {
|
||||
+ #if !os(tvOS)
|
||||
if #available(iOS 26.0, *) {
|
||||
// TODO: we may consider removing this logic, because it could be handled by onViewDidDisappear on the column level
|
||||
// On the other hand, maybe dedicated event related to the inspector would be a better approach.
|
||||
@@ -461,6 +467,7 @@ extension RNSSplitViewHostController: UISplitViewControllerDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
+ #endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
import type { ParamListBase, RouteProp } from "@react-navigation/native";
|
||||
import type { NativeStackNavigationOptions } from "@react-navigation/native-stack";
|
||||
import { Stack } from "expo-router";
|
||||
import type { ComponentProps } from "react";
|
||||
import { Platform } from "react-native";
|
||||
import { HeaderBackButton } from "../common/HeaderBackButton";
|
||||
|
||||
type ICommonScreenOptions =
|
||||
| NativeStackNavigationOptions
|
||||
| ((prop: {
|
||||
route: RouteProp<ParamListBase, string>;
|
||||
navigation: any;
|
||||
}) => NativeStackNavigationOptions);
|
||||
type ICommonScreenOptions = ComponentProps<typeof Stack.Screen>["options"];
|
||||
|
||||
export const commonScreenOptions: ICommonScreenOptions = {
|
||||
title: "",
|
||||
|
||||
@@ -263,7 +263,7 @@ const createStyles = (typography: ReturnType<typeof useScaledTVTypography>) =>
|
||||
color: "#fff",
|
||||
},
|
||||
downloadingOverlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
...StyleSheet.absoluteFill,
|
||||
backgroundColor: "rgba(0,0,0,0.5)",
|
||||
borderRadius: scaleSize(14),
|
||||
justifyContent: "center",
|
||||
|
||||
@@ -1408,14 +1408,14 @@ export const Controls: FC<Props> = ({
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
controlsContainer: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
...StyleSheet.absoluteFill,
|
||||
},
|
||||
darkOverlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
...StyleSheet.absoluteFill,
|
||||
backgroundColor: "rgba(0, 0, 0, 0.4)",
|
||||
},
|
||||
focusStealingOverlay: {
|
||||
...StyleSheet.absoluteFillObject,
|
||||
...StyleSheet.absoluteFill,
|
||||
zIndex: 1,
|
||||
},
|
||||
bottomContainer: {
|
||||
|
||||
92
package.json
92
package.json
@@ -28,61 +28,58 @@
|
||||
"dependencies": {
|
||||
"@bottom-tabs/react-navigation": "1.2.0",
|
||||
"@douglowder/expo-av-route-picker-view": "^0.0.5",
|
||||
"@expo/metro-runtime": "~55.0.11",
|
||||
"@expo/metro-runtime": "~56.0.13",
|
||||
"@expo/react-native-action-sheet": "^4.1.1",
|
||||
"@expo/ui": "~55.0.17",
|
||||
"@expo/ui": "~56.0.14",
|
||||
"@expo/vector-icons": "^15.0.3",
|
||||
"@gorhom/bottom-sheet": "5.2.8",
|
||||
"@jellyfin/sdk": "^0.13.0",
|
||||
"@react-native-community/netinfo": "^12.0.0",
|
||||
"@react-navigation/material-top-tabs": "7.4.9",
|
||||
"@react-navigation/native": "^7.2.5",
|
||||
"@react-navigation/native-stack": "~7.14.5",
|
||||
"@shopify/flash-list": "2.0.2",
|
||||
"@tanstack/query-sync-storage-persister": "^5.90.18",
|
||||
"@tanstack/react-pacer": "^0.19.1",
|
||||
"@tanstack/react-query": "5.90.20",
|
||||
"@tanstack/react-query-persist-client": "^5.90.18",
|
||||
"axios": "^1.7.9",
|
||||
"expo": "~55.0.26",
|
||||
"expo-application": "~55.0.15",
|
||||
"expo-asset": "~55.0.17",
|
||||
"expo-audio": "~55.0.0",
|
||||
"expo-background-task": "~55.0.18",
|
||||
"expo-blur": "~55.0.14",
|
||||
"expo-brightness": "~55.0.13",
|
||||
"expo-build-properties": "~55.0.14",
|
||||
"expo-camera": "~55.0.19",
|
||||
"expo-constants": "~55.0.16",
|
||||
"expo-crypto": "~55.0.15",
|
||||
"expo-dev-client": "~55.0.35",
|
||||
"expo-device": "~55.0.17",
|
||||
"expo-font": "~55.0.8",
|
||||
"expo-haptics": "~55.0.14",
|
||||
"expo-image": "~55.0.11",
|
||||
"expo-linear-gradient": "~55.0.14",
|
||||
"expo-linking": "~55.0.15",
|
||||
"expo-localization": "~55.0.15",
|
||||
"expo-location": "~55.1.10",
|
||||
"expo-notifications": "~55.0.23",
|
||||
"expo-router": "~55.0.16",
|
||||
"expo-screen-orientation": "~55.0.16",
|
||||
"expo-secure-store": "~55.0.14",
|
||||
"expo-sharing": "~55.0.20",
|
||||
"expo-splash-screen": "~55.0.21",
|
||||
"expo-status-bar": "~55.0.6",
|
||||
"expo-system-ui": "~55.0.18",
|
||||
"expo-task-manager": "~55.0.16",
|
||||
"expo-web-browser": "~55.0.16",
|
||||
"expo": "~56.0.6",
|
||||
"expo-application": "~56.0.3",
|
||||
"expo-asset": "~56.0.15",
|
||||
"expo-audio": "~56.0.11",
|
||||
"expo-background-task": "~56.0.15",
|
||||
"expo-blur": "~56.0.3",
|
||||
"expo-brightness": "~56.0.5",
|
||||
"expo-build-properties": "~56.0.15",
|
||||
"expo-camera": "~56.0.7",
|
||||
"expo-constants": "~56.0.16",
|
||||
"expo-crypto": "~56.0.4",
|
||||
"expo-dev-client": "~56.0.16",
|
||||
"expo-device": "~56.0.4",
|
||||
"expo-font": "~56.0.5",
|
||||
"expo-haptics": "~56.0.3",
|
||||
"expo-image": "~56.0.9",
|
||||
"expo-linear-gradient": "~56.0.4",
|
||||
"expo-linking": "~56.0.12",
|
||||
"expo-localization": "~56.0.6",
|
||||
"expo-location": "~56.0.14",
|
||||
"expo-notifications": "~56.0.14",
|
||||
"expo-router": "~56.2.7",
|
||||
"expo-screen-orientation": "~56.0.5",
|
||||
"expo-secure-store": "~56.0.4",
|
||||
"expo-sharing": "~56.0.14",
|
||||
"expo-splash-screen": "~56.0.10",
|
||||
"expo-status-bar": "~56.0.4",
|
||||
"expo-system-ui": "~56.0.5",
|
||||
"expo-task-manager": "~56.0.15",
|
||||
"expo-web-browser": "~56.0.5",
|
||||
"i18next": "^25.0.0",
|
||||
"jotai": "2.16.2",
|
||||
"lodash": "4.17.23",
|
||||
"nativewind": "^2.0.11",
|
||||
"patch-package": "^8.0.0",
|
||||
"react": "19.2.0",
|
||||
"react-dom": "19.2.0",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"react-i18next": "16.5.3",
|
||||
"react-native": "npm:react-native-tvos@0.83.6-0",
|
||||
"react-native": "npm:react-native-tvos@0.85.3-0",
|
||||
"react-native-awesome-slider": "^2.9.0",
|
||||
"react-native-bottom-tabs": "1.2.0",
|
||||
"react-native-circular-progress": "^1.4.1",
|
||||
@@ -91,7 +88,7 @@
|
||||
"react-native-device-info": "^15.0.0",
|
||||
"react-native-draggable-flatlist": "^4.0.3",
|
||||
"react-native-edge-to-edge": "^1.7.0",
|
||||
"react-native-gesture-handler": "~2.30.0",
|
||||
"react-native-gesture-handler": "~2.31.1",
|
||||
"react-native-glass-effect-view": "^1.0.0",
|
||||
"react-native-google-cast": "^4.9.1",
|
||||
"react-native-image-colors": "^2.4.0",
|
||||
@@ -99,13 +96,13 @@
|
||||
"react-native-ios-utilities": "5.2.0",
|
||||
"react-native-mmkv": "4.1.1",
|
||||
"react-native-nitro-modules": "0.33.1",
|
||||
"react-native-pager-view": "8.0.0",
|
||||
"react-native-pager-view": "8.0.1",
|
||||
"react-native-qrcode-svg": "^6.3.21",
|
||||
"react-native-reanimated": "4.2.1",
|
||||
"react-native-reanimated": "4.3.1",
|
||||
"react-native-reanimated-carousel": "4.0.3",
|
||||
"react-native-safe-area-context": "~5.6.0",
|
||||
"react-native-screens": "~4.18.0",
|
||||
"react-native-svg": "15.15.3",
|
||||
"react-native-safe-area-context": "~5.7.0",
|
||||
"react-native-screens": "4.25.2",
|
||||
"react-native-svg": "15.15.4",
|
||||
"react-native-text-ticker": "^1.15.0",
|
||||
"react-native-track-player": "github:lovegaoshi/react-native-track-player#APM",
|
||||
"react-native-udp": "^4.1.7",
|
||||
@@ -113,14 +110,14 @@
|
||||
"react-native-uuid": "^2.0.3",
|
||||
"react-native-volume-manager": "^2.0.8",
|
||||
"react-native-web": "^0.21.0",
|
||||
"react-native-worklets": "0.7.4",
|
||||
"react-native-worklets": "0.8.3",
|
||||
"sonner-native": "0.21.2",
|
||||
"tailwindcss": "3.3.2",
|
||||
"use-debounce": "^10.0.4",
|
||||
"zod": "4.1.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.28.6",
|
||||
"@babel/core": "7.29.7",
|
||||
"@biomejs/biome": "2.3.11",
|
||||
"@react-native-community/cli": "20.1.3",
|
||||
"@react-native-tvos/config-tv": "0.1.6",
|
||||
@@ -148,6 +145,7 @@
|
||||
},
|
||||
"install": {
|
||||
"exclude": [
|
||||
"react-native",
|
||||
"react-native-screens"
|
||||
]
|
||||
}
|
||||
@@ -165,9 +163,7 @@
|
||||
"unrs-resolver"
|
||||
],
|
||||
"patchedDependencies": {
|
||||
"react-native-screens@4.18.0": "bun-patches/react-native-screens@4.18.0.patch",
|
||||
"react-native-udp@4.1.7": "bun-patches/react-native-udp@4.1.7.patch",
|
||||
"@react-native/codegen@0.83.6": "bun-patches/@react-native%2Fcodegen@0.83.6.patch",
|
||||
"react-native-bottom-tabs@1.2.0": "bun-patches/react-native-bottom-tabs@1.2.0.patch"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useFocusEffect } from "@react-navigation/core";
|
||||
import {
|
||||
type QueryKey,
|
||||
type UseQueryOptions,
|
||||
type UseQueryResult,
|
||||
useQuery,
|
||||
} from "@tanstack/react-query";
|
||||
import { useFocusEffect } from "expo-router/react-navigation";
|
||||
import { useCallback } from "react";
|
||||
|
||||
export function useReactNavigationQuery<
|
||||
|
||||
Reference in New Issue
Block a user