mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-03 12:38:26 +01:00
chore
This commit is contained in:
2
app.json
2
app.json
@@ -2,7 +2,7 @@
|
|||||||
"expo": {
|
"expo": {
|
||||||
"name": "Streamyfin",
|
"name": "Streamyfin",
|
||||||
"slug": "streamyfin",
|
"slug": "streamyfin",
|
||||||
"version": "0.6.0",
|
"version": "0.6.1",
|
||||||
"orientation": "default",
|
"orientation": "default",
|
||||||
"icon": "./assets/images/icon.png",
|
"icon": "./assets/images/icon.png",
|
||||||
"scheme": "streamyfin",
|
"scheme": "streamyfin",
|
||||||
|
|||||||
205
app/_layout.tsx
205
app/_layout.tsx
@@ -15,6 +15,7 @@ import { useJobProcessor } from "@/utils/atoms/queue";
|
|||||||
import { JobQueueProvider } from "@/providers/JobQueueProvider";
|
import { JobQueueProvider } from "@/providers/JobQueueProvider";
|
||||||
import { useKeepAwake } from "expo-keep-awake";
|
import { useKeepAwake } from "expo-keep-awake";
|
||||||
import { useSettings } from "@/utils/atoms/settings";
|
import { useSettings } from "@/utils/atoms/settings";
|
||||||
|
import { GestureHandlerRootView } from "react-native-gesture-handler";
|
||||||
|
|
||||||
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
||||||
SplashScreen.preventAutoHideAsync();
|
SplashScreen.preventAutoHideAsync();
|
||||||
@@ -74,106 +75,108 @@ function Layout() {
|
|||||||
}, [settings]);
|
}, [settings]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<QueryClientProvider client={queryClientRef.current}>
|
<GestureHandlerRootView style={{ flex: 1 }}>
|
||||||
<JobQueueProvider>
|
<QueryClientProvider client={queryClientRef.current}>
|
||||||
<ActionSheetProvider>
|
<JobQueueProvider>
|
||||||
<JellyfinProvider>
|
<ActionSheetProvider>
|
||||||
<StatusBar style="light" backgroundColor="#000" />
|
<JellyfinProvider>
|
||||||
<ThemeProvider value={DarkTheme}>
|
<StatusBar style="light" backgroundColor="#000" />
|
||||||
<Stack initialRouteName="/home">
|
<ThemeProvider value={DarkTheme}>
|
||||||
<Stack.Screen
|
<Stack initialRouteName="/home">
|
||||||
name="(auth)/(tabs)"
|
<Stack.Screen
|
||||||
options={{
|
name="(auth)/(tabs)"
|
||||||
headerShown: false,
|
options={{
|
||||||
title: "",
|
headerShown: false,
|
||||||
}}
|
title: "",
|
||||||
/>
|
}}
|
||||||
<Stack.Screen
|
/>
|
||||||
name="(auth)/settings"
|
<Stack.Screen
|
||||||
options={{
|
name="(auth)/settings"
|
||||||
headerShown: true,
|
options={{
|
||||||
title: "Settings",
|
headerShown: true,
|
||||||
headerStyle: { backgroundColor: "black" },
|
title: "Settings",
|
||||||
headerShadowVisible: false,
|
headerStyle: { backgroundColor: "black" },
|
||||||
}}
|
headerShadowVisible: false,
|
||||||
/>
|
}}
|
||||||
<Stack.Screen
|
/>
|
||||||
name="(auth)/downloads"
|
<Stack.Screen
|
||||||
options={{
|
name="(auth)/downloads"
|
||||||
headerShown: true,
|
options={{
|
||||||
title: "Downloads",
|
headerShown: true,
|
||||||
headerStyle: { backgroundColor: "black" },
|
title: "Downloads",
|
||||||
headerShadowVisible: false,
|
headerStyle: { backgroundColor: "black" },
|
||||||
}}
|
headerShadowVisible: false,
|
||||||
/>
|
}}
|
||||||
<Stack.Screen
|
/>
|
||||||
name="(auth)/items/[id]"
|
<Stack.Screen
|
||||||
options={{
|
name="(auth)/items/[id]"
|
||||||
title: "",
|
options={{
|
||||||
headerShown: false,
|
title: "",
|
||||||
}}
|
headerShown: false,
|
||||||
/>
|
}}
|
||||||
<Stack.Screen
|
/>
|
||||||
name="(auth)/collections/[collectionId]"
|
<Stack.Screen
|
||||||
options={{
|
name="(auth)/collections/[collectionId]"
|
||||||
title: "",
|
options={{
|
||||||
headerShown: true,
|
title: "",
|
||||||
headerStyle: { backgroundColor: "black" },
|
headerShown: true,
|
||||||
headerShadowVisible: false,
|
headerStyle: { backgroundColor: "black" },
|
||||||
}}
|
headerShadowVisible: false,
|
||||||
/>
|
}}
|
||||||
<Stack.Screen
|
/>
|
||||||
name="(auth)/artists/page"
|
<Stack.Screen
|
||||||
options={{
|
name="(auth)/artists/page"
|
||||||
title: "",
|
options={{
|
||||||
headerShown: true,
|
title: "",
|
||||||
headerStyle: { backgroundColor: "black" },
|
headerShown: true,
|
||||||
headerShadowVisible: false,
|
headerStyle: { backgroundColor: "black" },
|
||||||
}}
|
headerShadowVisible: false,
|
||||||
/>
|
}}
|
||||||
<Stack.Screen
|
/>
|
||||||
name="(auth)/artists/[artistId]/page"
|
<Stack.Screen
|
||||||
options={{
|
name="(auth)/artists/[artistId]/page"
|
||||||
title: "",
|
options={{
|
||||||
headerShown: true,
|
title: "",
|
||||||
headerStyle: { backgroundColor: "black" },
|
headerShown: true,
|
||||||
headerShadowVisible: false,
|
headerStyle: { backgroundColor: "black" },
|
||||||
}}
|
headerShadowVisible: false,
|
||||||
/>
|
}}
|
||||||
<Stack.Screen
|
/>
|
||||||
name="(auth)/albums/[albumId]"
|
<Stack.Screen
|
||||||
options={{
|
name="(auth)/albums/[albumId]"
|
||||||
title: "",
|
options={{
|
||||||
headerShown: true,
|
title: "",
|
||||||
headerStyle: { backgroundColor: "black" },
|
headerShown: true,
|
||||||
headerShadowVisible: false,
|
headerStyle: { backgroundColor: "black" },
|
||||||
}}
|
headerShadowVisible: false,
|
||||||
/>
|
}}
|
||||||
<Stack.Screen
|
/>
|
||||||
name="(auth)/songs/[songId]"
|
<Stack.Screen
|
||||||
options={{
|
name="(auth)/songs/[songId]"
|
||||||
title: "",
|
options={{
|
||||||
headerShown: false,
|
title: "",
|
||||||
}}
|
headerShown: false,
|
||||||
/>
|
}}
|
||||||
<Stack.Screen
|
/>
|
||||||
name="(auth)/series/[id]"
|
<Stack.Screen
|
||||||
options={{
|
name="(auth)/series/[id]"
|
||||||
title: "",
|
options={{
|
||||||
headerShown: false,
|
title: "",
|
||||||
}}
|
headerShown: false,
|
||||||
/>
|
}}
|
||||||
<Stack.Screen
|
/>
|
||||||
name="login"
|
<Stack.Screen
|
||||||
options={{ headerShown: false, title: "Login" }}
|
name="login"
|
||||||
/>
|
options={{ headerShown: false, title: "Login" }}
|
||||||
<Stack.Screen name="+not-found" />
|
/>
|
||||||
</Stack>
|
<Stack.Screen name="+not-found" />
|
||||||
<CurrentlyPlayingBar />
|
</Stack>
|
||||||
</ThemeProvider>
|
<CurrentlyPlayingBar />
|
||||||
</JellyfinProvider>
|
</ThemeProvider>
|
||||||
</ActionSheetProvider>
|
</JellyfinProvider>
|
||||||
</JobQueueProvider>
|
</ActionSheetProvider>
|
||||||
</QueryClientProvider>
|
</JobQueueProvider>
|
||||||
|
</QueryClientProvider>
|
||||||
|
</GestureHandlerRootView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
module.exports = function (api) {
|
module.exports = function (api) {
|
||||||
api.cache(true);
|
api.cache(true);
|
||||||
return {
|
return {
|
||||||
presets: ['babel-preset-expo'],
|
presets: ["babel-preset-expo"],
|
||||||
plugins: ["nativewind/babel"],
|
plugins: ["nativewind/babel", "react-native-reanimated/plugin"],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
34
components/common/ColumnItem.tsx
Normal file
34
components/common/ColumnItem.tsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { StyleSheet, View, ViewProps } from "react-native";
|
||||||
|
|
||||||
|
const getItemStyle = (index: number, numColumns: number) => {
|
||||||
|
const alignItems = (() => {
|
||||||
|
if (numColumns < 2 || index % numColumns === 0) return "flex-start";
|
||||||
|
if ((index + 1) % numColumns === 0) return "flex-end";
|
||||||
|
|
||||||
|
return "center";
|
||||||
|
})();
|
||||||
|
|
||||||
|
return {
|
||||||
|
alignItems,
|
||||||
|
width: "100%",
|
||||||
|
} as const;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ColumnItemProps = ViewProps & {
|
||||||
|
children: React.ReactNode;
|
||||||
|
index: number;
|
||||||
|
numColumns: number;
|
||||||
|
};
|
||||||
|
export const ColumnItem = ({
|
||||||
|
children,
|
||||||
|
index,
|
||||||
|
numColumns,
|
||||||
|
...rest
|
||||||
|
}: ColumnItemProps) => (
|
||||||
|
<View
|
||||||
|
style={StyleSheet.flatten([getItemStyle(index, numColumns), rest.style])}
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
36
components/common/TouchableItemRouter.tsx
Normal file
36
components/common/TouchableItemRouter.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import {
|
||||||
|
TouchableOpacity,
|
||||||
|
TouchableOpacityProps,
|
||||||
|
View,
|
||||||
|
ViewProps,
|
||||||
|
} from "react-native";
|
||||||
|
import { Text } from "@/components/common/Text";
|
||||||
|
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||||
|
import { PropsWithChildren } from "react";
|
||||||
|
import { useRouter } from "expo-router";
|
||||||
|
|
||||||
|
interface Props extends TouchableOpacityProps {
|
||||||
|
item: BaseItemDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TouchableItemRouter: React.FC<PropsWithChildren<Props>> = ({
|
||||||
|
item,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}) => {
|
||||||
|
const router = useRouter();
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
if (item.Type === "Series") router.push(`/series/${item.Id}`);
|
||||||
|
if (item.Type === "Episode") router.push(`/items/${item.Id}`);
|
||||||
|
if (item.Type === "MusicAlbum") router.push(`/albums/${item.Id}`);
|
||||||
|
if (item.Type === "Movie") router.push(`/songs/${item.Id}`);
|
||||||
|
if (item.Type === "BoxSet") router.push(`/collections/${item.Id}`);
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
// You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
|
// You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
|
||||||
|
|
||||||
import Ionicons from '@expo/vector-icons/Ionicons';
|
import Ionicons from "@expo/vector-icons/Ionicons";
|
||||||
import { type IconProps } from '@expo/vector-icons/build/createIconSet';
|
import { type IconProps } from "@expo/vector-icons/build/createIconSet";
|
||||||
import { type ComponentProps } from 'react';
|
import { type ComponentProps } from "react";
|
||||||
|
|
||||||
export function TabBarIcon({ style, ...rest }: IconProps<ComponentProps<typeof Ionicons>['name']>) {
|
export function TabBarIcon({
|
||||||
return <Ionicons size={28} style={[{ marginBottom: -3 }, style]} {...rest} />;
|
style,
|
||||||
|
...rest
|
||||||
|
}: IconProps<ComponentProps<typeof Ionicons>["name"]>) {
|
||||||
|
return <Ionicons size={26} style={[{ marginBottom: -3 }, style]} {...rest} />;
|
||||||
}
|
}
|
||||||
|
|||||||
4
eas.json
4
eas.json
@@ -21,13 +21,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"production": {
|
"production": {
|
||||||
"channel": "0.6.0",
|
"channel": "0.6.1",
|
||||||
"android": {
|
"android": {
|
||||||
"image": "latest"
|
"image": "latest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"production-apk": {
|
"production-apk": {
|
||||||
"channel": "0.6.0",
|
"channel": "0.6.1",
|
||||||
"android": {
|
"android": {
|
||||||
"buildType": "apk",
|
"buildType": "apk",
|
||||||
"image": "latest"
|
"image": "latest"
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"@react-native-community/netinfo": "11.3.1",
|
"@react-native-community/netinfo": "11.3.1",
|
||||||
"@react-native-menu/menu": "^1.1.2",
|
"@react-native-menu/menu": "^1.1.2",
|
||||||
"@react-navigation/native": "^6.0.2",
|
"@react-navigation/native": "^6.0.2",
|
||||||
|
"@shopify/flash-list": "1.6.4",
|
||||||
"@tanstack/react-query": "^5.51.16",
|
"@tanstack/react-query": "^5.51.16",
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"axios": "^1.7.3",
|
"axios": "^1.7.3",
|
||||||
@@ -31,7 +32,7 @@
|
|||||||
"expo-blur": "~13.0.2",
|
"expo-blur": "~13.0.2",
|
||||||
"expo-build-properties": "~0.12.5",
|
"expo-build-properties": "~0.12.5",
|
||||||
"expo-constants": "~16.0.2",
|
"expo-constants": "~16.0.2",
|
||||||
"expo-dev-client": "~4.0.22",
|
"expo-dev-client": "~4.0.23",
|
||||||
"expo-device": "~6.0.2",
|
"expo-device": "~6.0.2",
|
||||||
"expo-font": "~12.0.9",
|
"expo-font": "~12.0.9",
|
||||||
"expo-haptics": "~13.0.1",
|
"expo-haptics": "~13.0.1",
|
||||||
@@ -61,6 +62,7 @@
|
|||||||
"react-native-ios-context-menu": "^2.5.1",
|
"react-native-ios-context-menu": "^2.5.1",
|
||||||
"react-native-ios-utilities": "^4.4.5",
|
"react-native-ios-utilities": "^4.4.5",
|
||||||
"react-native-reanimated": "~3.10.1",
|
"react-native-reanimated": "~3.10.1",
|
||||||
|
"react-native-reanimated-carousel": "4.0.0-alpha.12",
|
||||||
"react-native-safe-area-context": "4.10.5",
|
"react-native-safe-area-context": "4.10.5",
|
||||||
"react-native-screens": "3.31.1",
|
"react-native-screens": "3.31.1",
|
||||||
"react-native-svg": "15.2.0",
|
"react-native-svg": "15.2.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user