fix: update versions and use native-edge-to-edge

This commit is contained in:
Fredrik Burmester
2024-11-04 21:35:26 +00:00
parent 120fd4a32b
commit 8943708ff5
12 changed files with 64 additions and 241 deletions

View File

@@ -100,7 +100,8 @@
"motionPermission": "Allow Streamyfin to access your device motion for landscape video watching."
}
],
"./plugins/withNativeStyles.js"
["react-native-edge-to-edge"],
["react-native-bottom-tabs", { "theme": "material2" }]
],
"experiments": {
"typedRoutes": true

View File

@@ -1,4 +1,3 @@
import * as NavigationBar from "expo-navigation-bar";
import React, { useEffect } from "react";
import { Platform, View } from "react-native";
@@ -19,6 +18,7 @@ import type {
} from "@react-navigation/native";
import {} from "@expo/vector-icons/Ionicons";
import { Colors } from "@/constants/Colors";
import { SystemBars } from "react-native-edge-to-edge";
export const NativeTabs = withLayoutContext<
BottomTabNavigationOptions,
@@ -28,58 +28,54 @@ export const NativeTabs = withLayoutContext<
>(Navigator);
export default function TabLayout() {
useEffect(() => {
if (Platform.OS === "android") {
NavigationBar.setBackgroundColorAsync("#121212");
NavigationBar.setBorderColorAsync("#121212");
}
}, []);
return (
<NativeTabs
sidebarAdaptable
ignoresTopSafeArea
barTintColor={"#121212"}
tabBarActiveTintColor={Colors.primary}
scrollEdgeAppearance="default"
screenOptions={{
lazy: false,
}}
>
<NativeTabs.Screen redirect name="index" />
<NativeTabs.Screen
name="(home)"
options={{
title: "Home",
tabBarIcon:
Platform.OS == "android"
? ({ color, focused, size }) =>
require("@/assets/icons/house.fill.png")
: () => ({ sfSymbol: "house" }),
<>
<SystemBars hidden={false} style="light" />
<NativeTabs
sidebarAdaptable
ignoresTopSafeArea
barTintColor={"#121212"}
tabBarActiveTintColor={Colors.primary}
scrollEdgeAppearance="default"
screenOptions={{
lazy: false,
}}
/>
<NativeTabs.Screen
name="(search)"
options={{
title: "Search",
tabBarIcon:
Platform.OS == "android"
? ({ color, focused, size }) =>
require("@/assets/icons/magnifyingglass.png")
: () => ({ sfSymbol: "magnifyingglass" }),
}}
/>
<NativeTabs.Screen
name="(libraries)"
options={{
title: "Library",
tabBarIcon:
Platform.OS == "android"
? ({ color, focused, size }) =>
require("@/assets/icons/server.rack.png")
: () => ({ sfSymbol: "rectangle.stack" }),
}}
/>
</NativeTabs>
>
<NativeTabs.Screen redirect name="index" />
<NativeTabs.Screen
name="(home)"
options={{
title: "Home",
tabBarIcon:
Platform.OS == "android"
? ({ color, focused, size }) =>
require("@/assets/icons/house.fill.png")
: () => ({ sfSymbol: "house" }),
}}
/>
<NativeTabs.Screen
name="(search)"
options={{
title: "Search",
tabBarIcon:
Platform.OS == "android"
? ({ color, focused, size }) =>
require("@/assets/icons/magnifyingglass.png")
: () => ({ sfSymbol: "magnifyingglass" }),
}}
/>
<NativeTabs.Screen
name="(libraries)"
options={{
title: "Library",
tabBarIcon:
Platform.OS == "android"
? ({ color, focused, size }) =>
require("@/assets/icons/server.rack.png")
: () => ({ sfSymbol: "rectangle.stack" }),
}}
/>
</NativeTabs>
</>
);
}

View File

@@ -1,7 +1,4 @@
import { Text } from "@/components/common/Text";
import AlbumCover from "@/components/posters/AlbumCover";
import { Controls } from "@/components/video-player/Controls";
import { useAndroidNavigationBar } from "@/hooks/useAndroidNavigationBar";
import { useOrientation } from "@/hooks/useOrientation";
import { useOrientationSettings } from "@/hooks/useOrientationSettings";
import { useWebSocket } from "@/hooks/useWebsockets";
@@ -20,9 +17,9 @@ import * as Haptics from "expo-haptics";
import { Image } from "expo-image";
import { useFocusEffect } from "expo-router";
import { useAtomValue } from "jotai";
import { debounce } from "lodash";
import React, { useCallback, useMemo, useRef, useState } from "react";
import { Dimensions, Pressable, StatusBar, View } from "react-native";
import { Dimensions, Pressable, View } from "react-native";
import { SystemBars } from "react-native-edge-to-edge";
import { useSharedValue } from "react-native-reanimated";
import Video, { OnProgressData, VideoRef } from "react-native-video";
@@ -176,7 +173,6 @@ export default function page() {
const { orientation } = useOrientation();
useOrientationSettings();
useAndroidNavigationBar();
useWebSocket({
isPlaying: isPlaying,
@@ -194,7 +190,7 @@ export default function page() {
}}
className="flex flex-col items-center justify-center"
>
<StatusBar hidden />
<SystemBars hidden />
<View className="h-screen w-screen top-0 left-0 flex flex-col items-center justify-center p-4 absolute z-0">
<Image

View File

@@ -1,5 +1,4 @@
import { Controls } from "@/components/video-player/Controls";
import { useAndroidNavigationBar } from "@/hooks/useAndroidNavigationBar";
import { useOrientation } from "@/hooks/useOrientation";
import { useOrientationSettings } from "@/hooks/useOrientationSettings";
import { apiAtom } from "@/providers/JellyfinProvider";
@@ -13,7 +12,8 @@ import * as Haptics from "expo-haptics";
import { useFocusEffect } from "expo-router";
import { useAtomValue } from "jotai";
import React, { useCallback, useMemo, useRef, useState } from "react";
import { Pressable, StatusBar, useWindowDimensions, View } from "react-native";
import { Pressable, useWindowDimensions, View } from "react-native";
import { SystemBars } from "react-native-edge-to-edge";
import { useSharedValue } from "react-native-reanimated";
import Video, { OnProgressData, VideoRef } from "react-native-video";
@@ -28,7 +28,6 @@ export default function page() {
const dimensions = useWindowDimensions();
useOrientation();
useOrientationSettings();
useAndroidNavigationBar();
const [showControls, setShowControls] = useState(true);
const [ignoreSafeAreas, setIgnoreSafeAreas] = useState(false);
@@ -87,7 +86,7 @@ export default function page() {
}}
className="flex flex-col items-center justify-center"
>
<StatusBar hidden />
<SystemBars hidden />
<Pressable
onPress={() => {
setShowControls(!showControls);
@@ -119,7 +118,6 @@ export default function page() {
}}
/>
</Pressable>
<Controls
item={playSettings.item}
videoRef={videoRef}

View File

@@ -1,5 +1,4 @@
import { Controls } from "@/components/video-player/Controls";
import { useAndroidNavigationBar } from "@/hooks/useAndroidNavigationBar";
import { useOrientation } from "@/hooks/useOrientation";
import { useOrientationSettings } from "@/hooks/useOrientationSettings";
import { useWebSocket } from "@/hooks/useWebsockets";
@@ -18,7 +17,8 @@ import * as Haptics from "expo-haptics";
import { useFocusEffect } from "expo-router";
import { useAtomValue } from "jotai";
import React, { useCallback, useMemo, useRef, useState } from "react";
import { Pressable, StatusBar, useWindowDimensions, View } from "react-native";
import { Pressable, useWindowDimensions, View } from "react-native";
import { SystemBars } from "react-native-edge-to-edge";
import { useSharedValue } from "react-native-reanimated";
import Video, {
OnProgressData,
@@ -171,7 +171,6 @@ export default function page() {
useOrientation();
useOrientationSettings();
useAndroidNavigationBar();
useWebSocket({
isPlaying: isPlaying,
@@ -222,7 +221,7 @@ export default function page() {
position: "relative",
}}
>
<StatusBar hidden />
<SystemBars hidden />
<Pressable
onPress={() => {
setShowControls(!showControls);

View File

@@ -31,7 +31,6 @@ import * as Notifications from "expo-notifications";
import { router, Stack } from "expo-router";
import * as ScreenOrientation from "expo-screen-orientation";
import * as SplashScreen from "expo-splash-screen";
import { StatusBar } from "expo-status-bar";
import * as TaskManager from "expo-task-manager";
import { Provider as JotaiProvider, useAtom } from "jotai";
import { useEffect, useRef } from "react";
@@ -39,6 +38,7 @@ import { AppState } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import "react-native-reanimated";
import { Toaster } from "sonner-native";
import { SystemBars } from "react-native-edge-to-edge";
SplashScreen.preventAutoHideAsync();
@@ -326,7 +326,7 @@ function Layout() {
<PlaySettingsProvider>
<DownloadProvider>
<BottomSheetModalProvider>
<StatusBar style="light" backgroundColor="#000" />
<SystemBars style="light" hidden={false} />
<ThemeProvider value={DarkTheme}>
<Stack initialRouteName="/home">
<Stack.Screen
@@ -335,7 +335,6 @@ function Layout() {
headerShown: false,
title: "",
header: () => null,
}}
/>
<Stack.Screen

BIN
bun.lockb

Binary file not shown.

View File

@@ -63,7 +63,7 @@ export const DownloadItem: React.FC<DownloadProps> = ({ item, ...props }) => {
getDefaultPlaySettings(item, settings);
// 4. Set states
setSelectedMediaSource(mediaSource);
setSelectedMediaSource(mediaSource ?? undefined);
setSelectedAudioStream(audioIndex ?? 0);
setSelectedSubtitleStream(subtitleIndex ?? -1);
setMaxBitrate(bitrate);

View File

@@ -1,17 +0,0 @@
import * as NavigationBar from "expo-navigation-bar";
import { useEffect } from "react";
import { Platform } from "react-native";
export const useAndroidNavigationBar = () => {
useEffect(() => {
if (Platform.OS === "android") {
NavigationBar.setVisibilityAsync("hidden");
NavigationBar.setBehaviorAsync("overlay-swipe");
return () => {
NavigationBar.setVisibilityAsync("visible");
NavigationBar.setBehaviorAsync("inset-swipe");
};
}
}, []);
};

View File

@@ -1,27 +0,0 @@
// hooks/useNavigationBarVisibility.ts
import { useEffect } from "react";
import { Platform } from "react-native";
import * as NavigationBar from "expo-navigation-bar";
export const useNavigationBarVisibility = (isPlaying: boolean | null) => {
useEffect(() => {
const handleVisibility = async () => {
if (Platform.OS === "android") {
if (isPlaying) {
await NavigationBar.setVisibilityAsync("hidden");
} else {
await NavigationBar.setVisibilityAsync("visible");
}
}
};
handleVisibility();
return () => {
if (Platform.OS === "android") {
NavigationBar.setVisibilityAsync("visible");
}
};
}, [isPlaying]);
};

View File

@@ -47,7 +47,6 @@
"expo-keep-awake": "~13.0.2",
"expo-linear-gradient": "~13.0.2",
"expo-linking": "~6.3.1",
"expo-navigation-bar": "~3.0.7",
"expo-network": "~6.0.1",
"expo-notifications": "~0.28.19",
"expo-router": "~3.5.23",
@@ -68,9 +67,10 @@
"react-dom": "18.2.0",
"react-native": "0.74.5",
"react-native-awesome-slider": "^2.5.3",
"react-native-bottom-tabs": "^0.0.13",
"react-native-bottom-tabs": "^0.3.1",
"react-native-circular-progress": "^1.4.0",
"react-native-compressor": "^1.8.25",
"react-native-edge-to-edge": "^1.0.1",
"react-native-gesture-handler": "~2.16.1",
"react-native-get-random-values": "^1.11.0",
"react-native-google-cast": "^4.8.3",

View File

@@ -1,122 +0,0 @@
const { withAndroidStyles, withDangerousMod } = require("@expo/config-plugins");
const fs = require("fs");
const path = require("path");
function withNativeTabBarStyles(config) {
// First, apply the styles modifications
config = withAndroidStyles(config, async (config) => {
const styleContents = config.modResults;
// Find or create the AppTheme style
let appTheme = styleContents.resources.style.find(
(style) => style.$.name === "AppTheme"
);
if (!appTheme) {
appTheme = {
$: {
name: "AppTheme",
parent: "Theme.Material3.DayNight.NoActionBar",
},
item: [],
};
styleContents.resources.style.push(appTheme);
} else {
appTheme.$.parent = "Theme.Material3.DayNight.NoActionBar";
}
// Update or add items in the AppTheme style
const itemsToAdd = [
{
name: "android:editTextBackground",
value: "@drawable/rn_edit_text_material",
},
{
name: "bottomNavigationStyle",
value: "@style/Widget.Material3.BottomNavigationView",
},
{
name: "android:navigationBarColor",
value: "@android:color/transparent",
},
{ name: "android:statusBarColor", value: "@android:color/transparent" },
];
itemsToAdd.forEach(({ name, value }) => {
const existingItem = appTheme.item.find((item) => item.$.name === name);
if (existingItem) {
existingItem._ = value;
} else {
appTheme.item.push({
$: { name },
_: value,
});
}
});
// Add custom bottom navigation style
styleContents.resources.style.push({
$: {
name: "CustomBottomNavigationView",
parent: "@style/Widget.Material3.BottomNavigationView",
},
item: [
{
$: { name: "android:layout_margin" },
_: "16dp",
},
{
$: { name: "android:background" },
_: "@drawable/bottom_nav_background",
},
],
});
const bottomNavigationStyleItem = appTheme.item.find(
(item) => item.$.name === "bottomNavigationStyle"
);
if (bottomNavigationStyleItem) {
bottomNavigationStyleItem._ = "@style/CustomBottomNavigationView";
} else {
appTheme.item.push({
$: { name: "bottomNavigationStyle" },
_: "@style/CustomBottomNavigationView",
});
}
return {
...config,
modResults: styleContents,
};
});
// Then, add the drawable file creation
return withDangerousMod(config, [
"android",
async (config) => {
const drawablePath = path.join(
config.modRequest.platformProjectRoot,
"app",
"src",
"main",
"res",
"drawable"
);
const filePath = path.join(drawablePath, "bottom_nav_background.xml");
const fileContent = `<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?attr/colorSurfaceVariant" />
<corners android:radius="28dp" />
</shape>`;
await fs.promises.mkdir(drawablePath, { recursive: true });
await fs.promises.writeFile(filePath, fileContent);
return config;
},
]);
}
module.exports = withNativeTabBarStyles;