mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-28 22:18:14 +00:00
wip
This commit is contained in:
3
app.json
3
app.json
@@ -130,6 +130,7 @@
|
||||
},
|
||||
"updates": {
|
||||
"url": "https://u.expo.dev/e79219d1-797f-4fbe-9fa1-cfd360690a68"
|
||||
}
|
||||
},
|
||||
"newArchEnabled": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
import { ThemedText } from '../ThemedText';
|
||||
|
||||
it(`renders correctly`, () => {
|
||||
const tree = renderer.create(<ThemedText>Snapshot test!</ThemedText>).toJSON();
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
@@ -1,24 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<Text
|
||||
style={
|
||||
[
|
||||
{
|
||||
"color": "#11181C",
|
||||
},
|
||||
{
|
||||
"fontSize": 16,
|
||||
"lineHeight": 24,
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Snapshot test!
|
||||
</Text>
|
||||
`;
|
||||
@@ -1,11 +1,12 @@
|
||||
import {useRouter, useSegments} from "expo-router";
|
||||
import React, {PropsWithChildren, useCallback, useMemo} from "react";
|
||||
import {TouchableOpacity, TouchableOpacityProps} from "react-native";
|
||||
import * as ContextMenu from "zeego/context-menu";
|
||||
import {MovieResult, TvResult} from "@/utils/jellyseerr/server/models/Search";
|
||||
import {useJellyseerr} from "@/hooks/useJellyseerr";
|
||||
import {hasPermission, Permission} from "@/utils/jellyseerr/server/lib/permissions";
|
||||
import {MediaType} from "@/utils/jellyseerr/server/constants/media";
|
||||
import { useJellyseerr } from "@/hooks/useJellyseerr";
|
||||
import {
|
||||
hasPermission,
|
||||
Permission,
|
||||
} from "@/utils/jellyseerr/server/lib/permissions";
|
||||
import { MovieResult, TvResult } from "@/utils/jellyseerr/server/models/Search";
|
||||
import { useRouter, useSegments } from "expo-router";
|
||||
import React, { PropsWithChildren, useCallback, useMemo } from "react";
|
||||
import { TouchableOpacity, TouchableOpacityProps } from "react-native";
|
||||
|
||||
interface Props extends TouchableOpacityProps {
|
||||
result: MovieResult | TvResult;
|
||||
@@ -26,78 +27,49 @@ export const TouchableJellyseerrRouter: React.FC<PropsWithChildren<Props>> = ({
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
const segments = useSegments();
|
||||
const {jellyseerrApi, jellyseerrUser, requestMedia} = useJellyseerr()
|
||||
const { jellyseerrApi, jellyseerrUser, requestMedia } = useJellyseerr();
|
||||
|
||||
const from = segments[2];
|
||||
|
||||
const autoApprove = useMemo(() => {
|
||||
return jellyseerrUser && hasPermission(
|
||||
Permission.AUTO_APPROVE,
|
||||
jellyseerrUser.permissions,
|
||||
{type: 'or'}
|
||||
)
|
||||
}, [jellyseerrApi, jellyseerrUser])
|
||||
return (
|
||||
jellyseerrUser &&
|
||||
hasPermission(Permission.AUTO_APPROVE, jellyseerrUser.permissions, {
|
||||
type: "or",
|
||||
})
|
||||
);
|
||||
}, [jellyseerrApi, jellyseerrUser]);
|
||||
|
||||
const request = useCallback(() =>
|
||||
const request = useCallback(
|
||||
() =>
|
||||
requestMedia(mediaTitle, {
|
||||
mediaId: result.id,
|
||||
mediaType: result.mediaType
|
||||
}
|
||||
),
|
||||
mediaType: result.mediaType,
|
||||
}),
|
||||
[jellyseerrApi, result]
|
||||
)
|
||||
);
|
||||
|
||||
if (from === "(home)" || from === "(search)" || from === "(libraries)")
|
||||
return (
|
||||
<>
|
||||
<ContextMenu.Root>
|
||||
<ContextMenu.Trigger>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
// @ts-ignore
|
||||
router.push({pathname: `/(auth)/(tabs)/${from}/jellyseerr/page`, params: {...result, mediaTitle, releaseYear, canRequest, posterSrc}});
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</TouchableOpacity>
|
||||
</ContextMenu.Trigger>
|
||||
<ContextMenu.Content
|
||||
avoidCollisions
|
||||
alignOffset={0}
|
||||
collisionPadding={0}
|
||||
loop={false}
|
||||
key={"content"}
|
||||
>
|
||||
<ContextMenu.Label key="label-1">Actions</ContextMenu.Label>
|
||||
{canRequest && result.mediaType === MediaType.MOVIE && (
|
||||
<ContextMenu.Item
|
||||
key="item-1"
|
||||
onSelect={() => {
|
||||
if (autoApprove) {
|
||||
request()
|
||||
}
|
||||
}}
|
||||
shouldDismissMenuOnSelect
|
||||
>
|
||||
<ContextMenu.ItemTitle key="item-1-title">Request</ContextMenu.ItemTitle>
|
||||
<ContextMenu.ItemIcon
|
||||
ios={{
|
||||
name: "arrow.down.to.line",
|
||||
pointSize: 18,
|
||||
weight: "semibold",
|
||||
scale: "medium",
|
||||
hierarchicalColor: {
|
||||
dark: "purple",
|
||||
light: "purple",
|
||||
},
|
||||
}}
|
||||
androidIconName="download"
|
||||
/>
|
||||
</ContextMenu.Item>
|
||||
)}
|
||||
</ContextMenu.Content>
|
||||
</ContextMenu.Root>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
router.push({
|
||||
pathname: `/(auth)/(tabs)/${from}/jellyseerr/page`,
|
||||
params: {
|
||||
...result,
|
||||
mediaTitle,
|
||||
releaseYear,
|
||||
// @ts-expect-error
|
||||
canRequest,
|
||||
posterSrc,
|
||||
},
|
||||
});
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
import { useRouter, useSegments } from "expo-router";
|
||||
import { PropsWithChildren } from "react";
|
||||
import { TouchableOpacity, TouchableOpacityProps } from "react-native";
|
||||
import * as ContextMenu from "zeego/context-menu";
|
||||
|
||||
interface Props extends TouchableOpacityProps {
|
||||
item: BaseItemDto;
|
||||
@@ -16,8 +15,6 @@ export const itemRouter = (
|
||||
item: BaseItemDto | BaseItemPerson,
|
||||
from: string
|
||||
) => {
|
||||
console.log(item.Type, item?.CollectionType);
|
||||
|
||||
if ("CollectionType" in item && item.CollectionType === "livetv") {
|
||||
return `/(auth)/(tabs)/${from}/livetv`;
|
||||
}
|
||||
@@ -80,78 +77,15 @@ export const TouchableItemRouter: React.FC<PropsWithChildren<Props>> = ({
|
||||
from === "(favorites)"
|
||||
)
|
||||
return (
|
||||
<ContextMenu.Root>
|
||||
<ContextMenu.Trigger>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
const url = itemRouter(item, from);
|
||||
// @ts-ignore
|
||||
router.push(url);
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</TouchableOpacity>
|
||||
</ContextMenu.Trigger>
|
||||
<ContextMenu.Content
|
||||
avoidCollisions
|
||||
alignOffset={0}
|
||||
collisionPadding={0}
|
||||
loop={false}
|
||||
key={"content"}
|
||||
>
|
||||
<ContextMenu.Label key="label-1">Actions</ContextMenu.Label>
|
||||
<ContextMenu.Item
|
||||
key="item-1"
|
||||
onSelect={() => {
|
||||
markAsPlayedStatus(true);
|
||||
}}
|
||||
shouldDismissMenuOnSelect
|
||||
>
|
||||
<ContextMenu.ItemTitle key="item-1-title">
|
||||
Mark as watched
|
||||
</ContextMenu.ItemTitle>
|
||||
<ContextMenu.ItemIcon
|
||||
ios={{
|
||||
name: "checkmark.circle", // Changed to "checkmark.circle" which represents "watched"
|
||||
pointSize: 18,
|
||||
weight: "semibold",
|
||||
scale: "medium",
|
||||
hierarchicalColor: {
|
||||
dark: "green", // Changed to green for "watched"
|
||||
light: "green",
|
||||
},
|
||||
}}
|
||||
androidIconName="checkmark-circle"
|
||||
></ContextMenu.ItemIcon>
|
||||
</ContextMenu.Item>
|
||||
<ContextMenu.Item
|
||||
key="item-2"
|
||||
onSelect={() => {
|
||||
markAsPlayedStatus(false);
|
||||
}}
|
||||
shouldDismissMenuOnSelect
|
||||
destructive
|
||||
>
|
||||
<ContextMenu.ItemTitle key="item-2-title">
|
||||
Mark as not watched
|
||||
</ContextMenu.ItemTitle>
|
||||
<ContextMenu.ItemIcon
|
||||
ios={{
|
||||
name: "eye.slash", // Changed to "eye.slash" which represents "not watched"
|
||||
pointSize: 18, // Adjusted for better visibility
|
||||
weight: "semibold",
|
||||
scale: "medium",
|
||||
hierarchicalColor: {
|
||||
dark: "red", // Changed to red for "not watched"
|
||||
light: "red",
|
||||
},
|
||||
// Removed paletteColors as it's not necessary in this case
|
||||
}}
|
||||
androidIconName="eye-slash"
|
||||
></ContextMenu.ItemIcon>
|
||||
</ContextMenu.Item>
|
||||
</ContextMenu.Content>
|
||||
</ContextMenu.Root>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
const url = itemRouter(item, from);
|
||||
// @ts-ignore
|
||||
router.push(url);
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
};
|
||||
|
||||
91
package.json
91
package.json
@@ -9,13 +9,9 @@
|
||||
"android": "bun run submodule-reload && expo run:android",
|
||||
"ios": "bun run submodule-reload && expo run:ios",
|
||||
"web": "bun run submodule-reload && expo start --web",
|
||||
"test": "jest --watchAll",
|
||||
"lint": "expo lint",
|
||||
"postinstall": "patch-package"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "jest-expo"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bottom-tabs/react-navigation": "^0.7.1",
|
||||
"@config-plugins/ffmpeg-kit-react-native": "^8.0.0",
|
||||
@@ -26,71 +22,69 @@
|
||||
"@jellyfin/sdk": "^0.11.0",
|
||||
"@kesha-antonov/react-native-background-downloader": "^3.2.1",
|
||||
"@react-native-async-storage/async-storage": "1.23.1",
|
||||
"@react-native-community/netinfo": "11.3.1",
|
||||
"@react-native-community/netinfo": "11.4.1",
|
||||
"@react-native-menu/menu": "^1.1.6",
|
||||
"@react-navigation/material-top-tabs": "^6.6.14",
|
||||
"@react-navigation/native": "^6.1.18",
|
||||
"@shopify/flash-list": "1.6.4",
|
||||
"@react-navigation/native": "^7.0.14",
|
||||
"@shopify/flash-list": "1.7.1",
|
||||
"@tanstack/react-query": "^5.59.20",
|
||||
"@types/lodash": "^4.17.13",
|
||||
"@types/react-native-vector-icons": "^6.4.18",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"add": "^2.0.6",
|
||||
"axios": "^1.7.7",
|
||||
"expo": "~51.0.39",
|
||||
"expo-asset": "~10.0.10",
|
||||
"expo-background-fetch": "~12.0.1",
|
||||
"expo-blur": "~13.0.2",
|
||||
"expo-brightness": "~12.0.1",
|
||||
"expo-build-properties": "~0.12.5",
|
||||
"expo-constants": "~16.0.2",
|
||||
"expo-dev-client": "~4.0.29",
|
||||
"expo-device": "~6.0.2",
|
||||
"expo-font": "~12.0.10",
|
||||
"expo-haptics": "~13.0.1",
|
||||
"expo-image": "~1.13.0",
|
||||
"expo-keep-awake": "~13.0.2",
|
||||
"expo-linear-gradient": "~13.0.2",
|
||||
"expo-linking": "~6.3.1",
|
||||
"expo-network": "~6.0.1",
|
||||
"expo-notifications": "~0.28.19",
|
||||
"expo-router": "~3.5.24",
|
||||
"expo-screen-orientation": "~7.0.5",
|
||||
"expo-sensors": "~13.0.9",
|
||||
"expo-splash-screen": "~0.27.7",
|
||||
"expo-status-bar": "~1.12.1",
|
||||
"expo-system-ui": "^3.0.7",
|
||||
"expo-task-manager": "~11.8.2",
|
||||
"expo-updates": "~0.25.27",
|
||||
"expo-web-browser": "~13.0.3",
|
||||
"expo": "52",
|
||||
"expo-asset": "~11.0.1",
|
||||
"expo-background-fetch": "~13.0.3",
|
||||
"expo-blur": "~14.0.1",
|
||||
"expo-brightness": "~13.0.2",
|
||||
"expo-build-properties": "~0.13.1",
|
||||
"expo-constants": "~17.0.3",
|
||||
"expo-dev-client": "~5.0.8",
|
||||
"expo-device": "~7.0.1",
|
||||
"expo-font": "~13.0.2",
|
||||
"expo-haptics": "~14.0.0",
|
||||
"expo-image": "~2.0.3",
|
||||
"expo-keep-awake": "~14.0.1",
|
||||
"expo-linear-gradient": "~14.0.1",
|
||||
"expo-linking": "~7.0.3",
|
||||
"expo-network": "~7.0.4",
|
||||
"expo-notifications": "~0.29.11",
|
||||
"expo-router": "~4.0.15",
|
||||
"expo-screen-orientation": "~8.0.2",
|
||||
"expo-sensors": "~14.0.1",
|
||||
"expo-splash-screen": "~0.29.18",
|
||||
"expo-status-bar": "~2.0.0",
|
||||
"expo-system-ui": "~4.0.6",
|
||||
"expo-task-manager": "~12.0.3",
|
||||
"expo-updates": "~0.26.10",
|
||||
"expo-web-browser": "~14.0.1",
|
||||
"ffmpeg-kit-react-native": "^6.0.2",
|
||||
"install": "^0.13.0",
|
||||
"jotai": "^2.10.1",
|
||||
"lodash": "^4.17.21",
|
||||
"nativewind": "^2.0.11",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-native": "0.74.5",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-native": "0.76.5",
|
||||
"react-native-awesome-slider": "^2.5.6",
|
||||
"react-native-bottom-tabs": "0.7.1",
|
||||
"react-native-circular-progress": "^1.4.1",
|
||||
"react-native-compressor": "^1.9.0",
|
||||
"react-native-device-info": "^14.0.1",
|
||||
"react-native-edge-to-edge": "^1.1.1",
|
||||
"react-native-gesture-handler": "~2.16.1",
|
||||
"react-native-gesture-handler": "~2.20.2",
|
||||
"react-native-get-random-values": "^1.11.0",
|
||||
"react-native-google-cast": "^4.8.3",
|
||||
"react-native-image-colors": "^2.4.0",
|
||||
"react-native-ios-context-menu": "^2.5.2",
|
||||
"react-native-ios-utilities": "^4.5.1",
|
||||
"react-native-mmkv": "^2.12.2",
|
||||
"react-native-pager-view": "6.3.0",
|
||||
"react-native-mmkv": "^3.0.1",
|
||||
"react-native-pager-view": "6.5.1",
|
||||
"react-native-progress": "^5.0.1",
|
||||
"react-native-reanimated": "~3.10.1",
|
||||
"react-native-reanimated": "~3.16.1",
|
||||
"react-native-reanimated-carousel": "4.0.0-canary.22",
|
||||
"react-native-safe-area-context": "4.10.5",
|
||||
"react-native-screens": "3.31.1",
|
||||
"react-native-svg": "15.2.0",
|
||||
"react-native-safe-area-context": "4.12.0",
|
||||
"react-native-screens": "~4.4.0",
|
||||
"react-native-svg": "15.8.0",
|
||||
"react-native-tab-view": "^3.5.2",
|
||||
"react-native-uitextview": "^1.4.0",
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
@@ -98,7 +92,7 @@
|
||||
"react-native-video": "^6.7.0",
|
||||
"react-native-volume-manager": "^1.10.0",
|
||||
"react-native-web": "~0.19.13",
|
||||
"react-native-webview": "13.8.6",
|
||||
"react-native-webview": "13.12.5",
|
||||
"react-native-youtube-iframe": "^2.3.0",
|
||||
"sonner-native": "^0.14.2",
|
||||
"tailwindcss": "3.3.2",
|
||||
@@ -109,11 +103,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.26.0",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/react": "~18.2.79",
|
||||
"@types/react": "~18.3.12",
|
||||
"@types/react-test-renderer": "^18.0.7",
|
||||
"jest": "^29.2.1",
|
||||
"jest-expo": "~51.0.4",
|
||||
"patch-package": "^8.0.0",
|
||||
"postinstall-postinstall": "^2.1.0",
|
||||
"react-test-renderer": "18.2.0",
|
||||
|
||||
Reference in New Issue
Block a user