diff --git a/app.json b/app.json
index ee1e3abb..3da9786f 100644
--- a/app.json
+++ b/app.json
@@ -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
diff --git a/app/(auth)/(tabs)/_layout.tsx b/app/(auth)/(tabs)/_layout.tsx
index 49fe0752..9291fdea 100644
--- a/app/(auth)/(tabs)/_layout.tsx
+++ b/app/(auth)/(tabs)/_layout.tsx
@@ -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 (
-
-
-
- require("@/assets/icons/house.fill.png")
- : () => ({ sfSymbol: "house" }),
+ <>
+
+
-
- require("@/assets/icons/magnifyingglass.png")
- : () => ({ sfSymbol: "magnifyingglass" }),
- }}
- />
-
- require("@/assets/icons/server.rack.png")
- : () => ({ sfSymbol: "rectangle.stack" }),
- }}
- />
-
+ >
+
+
+ require("@/assets/icons/house.fill.png")
+ : () => ({ sfSymbol: "house" }),
+ }}
+ />
+
+ require("@/assets/icons/magnifyingglass.png")
+ : () => ({ sfSymbol: "magnifyingglass" }),
+ }}
+ />
+
+ require("@/assets/icons/server.rack.png")
+ : () => ({ sfSymbol: "rectangle.stack" }),
+ }}
+ />
+
+ >
);
}
diff --git a/app/(auth)/play-music.tsx b/app/(auth)/play-music.tsx
index 4138ecc2..f49f9fee 100644
--- a/app/(auth)/play-music.tsx
+++ b/app/(auth)/play-music.tsx
@@ -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"
>
-
+
-
+
{
setShowControls(!showControls);
@@ -119,7 +118,6 @@ export default function page() {
}}
/>
-
-
+
{
setShowControls(!showControls);
diff --git a/app/_layout.tsx b/app/_layout.tsx
index e37db593..c17d4804 100644
--- a/app/_layout.tsx
+++ b/app/_layout.tsx
@@ -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() {
-
+
null,
-
}}
/>
= ({ item, ...props }) => {
getDefaultPlaySettings(item, settings);
// 4. Set states
- setSelectedMediaSource(mediaSource);
+ setSelectedMediaSource(mediaSource ?? undefined);
setSelectedAudioStream(audioIndex ?? 0);
setSelectedSubtitleStream(subtitleIndex ?? -1);
setMaxBitrate(bitrate);
diff --git a/hooks/useAndroidNavigationBar.ts b/hooks/useAndroidNavigationBar.ts
deleted file mode 100644
index d8c55802..00000000
--- a/hooks/useAndroidNavigationBar.ts
+++ /dev/null
@@ -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");
- };
- }
- }, []);
-};
diff --git a/hooks/useNavigationBarVisibility.ts b/hooks/useNavigationBarVisibility.ts
deleted file mode 100644
index 5af3e5d7..00000000
--- a/hooks/useNavigationBarVisibility.ts
+++ /dev/null
@@ -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]);
-};
diff --git a/package.json b/package.json
index 8bbf2da9..81b88df2 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/plugins/withNativeStyles.js b/plugins/withNativeStyles.js
deleted file mode 100644
index 4c4b5f21..00000000
--- a/plugins/withNativeStyles.js
+++ /dev/null
@@ -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 = `
-
-
-
-`;
-
- await fs.promises.mkdir(drawablePath, { recursive: true });
- await fs.promises.writeFile(filePath, fileContent);
-
- return config;
- },
- ]);
-}
-
-module.exports = withNativeTabBarStyles;