This commit is contained in:
Fredrik Burmester
2024-08-17 13:15:30 +02:00
parent 4a17a00f81
commit e0ca83ae1f
9 changed files with 190 additions and 112 deletions

View File

@@ -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",

View File

@@ -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>
); );
} }

View File

@@ -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"],
}; };
}; };

BIN
bun.lockb

Binary file not shown.

View 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>
);

View 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>
);
};

View File

@@ -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} />;
} }

View File

@@ -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"

View File

@@ -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",