mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-03-09 11:16:17 +00:00
Compare commits
2 Commits
copilot/fi
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61b9e58774 | ||
|
|
2290616b22 |
6
.github/workflows/ci-codeql.yml
vendored
6
.github/workflows/ci-codeql.yml
vendored
@@ -31,13 +31,13 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: 🏁 Initialize CodeQL
|
- name: 🏁 Initialize CodeQL
|
||||||
uses: github/codeql-action/init@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3.30.0
|
uses: github/codeql-action/init@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
queries: +security-extended,security-and-quality
|
queries: +security-extended,security-and-quality
|
||||||
|
|
||||||
- name: 🛠️ Autobuild
|
- name: 🛠️ Autobuild
|
||||||
uses: github/codeql-action/autobuild@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3.30.0
|
uses: github/codeql-action/autobuild@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
|
||||||
|
|
||||||
- name: 🧪 Perform CodeQL Analysis
|
- name: 🧪 Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@2d92b76c45b91eb80fc44c74ce3fce0ee94e8f9d # v3.30.0
|
uses: github/codeql-action/analyze@3c3833e0f8c1c83d449a7478aa59c036a9165498 # v3.29.11
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import type React from "react";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { View, type ViewProps } from "react-native";
|
import { View, type ViewProps } from "react-native";
|
||||||
import { HorizontalScroll } from "@/components/common/HorrizontalScroll";
|
import { HorizontalScroll } from "@/components/common/HorrizontalScroll";
|
||||||
import { SimpleTouchableItemRouter } from "@/components/common/SimpleTouchableItemRouter";
|
|
||||||
import { Text } from "@/components/common/Text";
|
import { Text } from "@/components/common/Text";
|
||||||
|
import { TouchableItemRouter } from "@/components/common/TouchableItemRouter";
|
||||||
import { ItemCardText } from "@/components/ItemCardText";
|
import { ItemCardText } from "@/components/ItemCardText";
|
||||||
import MoviePoster from "@/components/posters/MoviePoster";
|
import MoviePoster from "@/components/posters/MoviePoster";
|
||||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||||
@@ -83,9 +83,8 @@ export const MoreMoviesWithActor: React.FC<Props> = ({
|
|||||||
data={items}
|
data={items}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
height={247}
|
height={247}
|
||||||
estimatedItemSize={112}
|
|
||||||
renderItem={(item: BaseItemDto, idx: number) => (
|
renderItem={(item: BaseItemDto, idx: number) => (
|
||||||
<SimpleTouchableItemRouter
|
<TouchableItemRouter
|
||||||
key={idx}
|
key={idx}
|
||||||
item={item}
|
item={item}
|
||||||
className='flex flex-col w-28'
|
className='flex flex-col w-28'
|
||||||
@@ -94,7 +93,7 @@ export const MoreMoviesWithActor: React.FC<Props> = ({
|
|||||||
<MoviePoster item={item} />
|
<MoviePoster item={item} />
|
||||||
<ItemCardText item={item} />
|
<ItemCardText item={item} />
|
||||||
</View>
|
</View>
|
||||||
</SimpleTouchableItemRouter>
|
</TouchableItemRouter>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import { View, type ViewProps } from "react-native";
|
|||||||
import MoviePoster from "@/components/posters/MoviePoster";
|
import MoviePoster from "@/components/posters/MoviePoster";
|
||||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||||
import { HorizontalScroll } from "./common/HorrizontalScroll";
|
import { HorizontalScroll } from "./common/HorrizontalScroll";
|
||||||
import { SimpleTouchableItemRouter } from "./common/SimpleTouchableItemRouter";
|
|
||||||
import { Text } from "./common/Text";
|
import { Text } from "./common/Text";
|
||||||
|
import { TouchableItemRouter } from "./common/TouchableItemRouter";
|
||||||
import { ItemCardText } from "./ItemCardText";
|
import { ItemCardText } from "./ItemCardText";
|
||||||
|
|
||||||
interface SimilarItemsProps extends ViewProps {
|
interface SimilarItemsProps extends ViewProps {
|
||||||
@@ -54,10 +54,9 @@ export const SimilarItems: React.FC<SimilarItemsProps> = ({
|
|||||||
data={movies}
|
data={movies}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
height={247}
|
height={247}
|
||||||
estimatedItemSize={112}
|
|
||||||
noItemsText={t("item_card.no_similar_items_found")}
|
noItemsText={t("item_card.no_similar_items_found")}
|
||||||
renderItem={(item: BaseItemDto, idx: number) => (
|
renderItem={(item: BaseItemDto, idx: number) => (
|
||||||
<SimpleTouchableItemRouter
|
<TouchableItemRouter
|
||||||
key={idx}
|
key={idx}
|
||||||
item={item}
|
item={item}
|
||||||
className='flex flex-col w-28'
|
className='flex flex-col w-28'
|
||||||
@@ -66,7 +65,7 @@ export const SimilarItems: React.FC<SimilarItemsProps> = ({
|
|||||||
<MoviePoster item={item} />
|
<MoviePoster item={item} />
|
||||||
<ItemCardText item={item} />
|
<ItemCardText item={item} />
|
||||||
</View>
|
</View>
|
||||||
</SimpleTouchableItemRouter>
|
</TouchableItemRouter>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { MediaSourceInfo } from "@jellyfin/sdk/lib/generated-client/models";
|
import type { MediaSourceInfo } from "@jellyfin/sdk/lib/generated-client/models";
|
||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import { Platform, TouchableOpacity, View } from "react-native";
|
import { Platform, TouchableOpacity, View } from "react-native";
|
||||||
import { tc } from "@/utils/textTools";
|
|
||||||
|
|
||||||
const DropdownMenu = !Platform.isTV ? require("zeego/dropdown-menu") : null;
|
const DropdownMenu = !Platform.isTV ? require("zeego/dropdown-menu") : null;
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@ export const SubtitleTrackSelector: React.FC<Props> = ({
|
|||||||
className='flex col shrink justify-start place-self-start items-start'
|
className='flex col shrink justify-start place-self-start items-start'
|
||||||
style={{
|
style={{
|
||||||
minWidth: 60,
|
minWidth: 60,
|
||||||
maxWidth: 200,
|
maxWidth: 220,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
@@ -47,10 +46,8 @@ export const SubtitleTrackSelector: React.FC<Props> = ({
|
|||||||
{t("item_card.subtitles")}
|
{t("item_card.subtitles")}
|
||||||
</Text>
|
</Text>
|
||||||
<TouchableOpacity className='bg-neutral-900 h-10 rounded-xl border-neutral-800 border px-3 py-2 flex flex-row items-center justify-between'>
|
<TouchableOpacity className='bg-neutral-900 h-10 rounded-xl border-neutral-800 border px-3 py-2 flex flex-row items-center justify-between'>
|
||||||
<Text className=' '>
|
<Text className=' ' numberOfLines={1}>
|
||||||
{selectedSubtitleSteam
|
{selectedSubtitleSteam?.DisplayTitle || t("item_card.none")}
|
||||||
? tc(selectedSubtitleSteam?.DisplayTitle, 7)
|
|
||||||
: t("item_card.none")}
|
|
||||||
</Text>
|
</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
import type {
|
|
||||||
BaseItemDto,
|
|
||||||
BaseItemPerson,
|
|
||||||
} from "@jellyfin/sdk/lib/generated-client/models";
|
|
||||||
import { useRouter, useSegments } from "expo-router";
|
|
||||||
import { type PropsWithChildren } from "react";
|
|
||||||
import { TouchableOpacity, type TouchableOpacityProps } from "react-native";
|
|
||||||
|
|
||||||
interface Props extends TouchableOpacityProps {
|
|
||||||
item: BaseItemDto;
|
|
||||||
isOffline?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const itemRouter = (
|
|
||||||
item: BaseItemDto | BaseItemPerson,
|
|
||||||
from: string,
|
|
||||||
) => {
|
|
||||||
if ("CollectionType" in item && item.CollectionType === "livetv") {
|
|
||||||
return `/(auth)/(tabs)/${from}/livetv`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Type === "Series") {
|
|
||||||
return `/(auth)/(tabs)/${from}/series/${item.Id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Type === "Person" || item.Type === "Actor") {
|
|
||||||
return `/(auth)/(tabs)/${from}/actors/${item.Id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Type === "BoxSet") {
|
|
||||||
return `/(auth)/(tabs)/${from}/collections/${item.Id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Type === "UserView") {
|
|
||||||
return `/(auth)/(tabs)/${from}/collections/${item.Id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Type === "CollectionFolder") {
|
|
||||||
return `/(auth)/(tabs)/(libraries)/${item.Id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.Type === "Playlist") {
|
|
||||||
return `/(auth)/(tabs)/(libraries)/${item.Id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `/(auth)/(tabs)/${from}/items/page?id=${item.Id}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simplified TouchableItemRouter that doesn't use hooks that might trigger API calls.
|
|
||||||
* Intended for use in similar items rows where we want to avoid unnecessary requests.
|
|
||||||
*/
|
|
||||||
export const SimpleTouchableItemRouter: React.FC<PropsWithChildren<Props>> = ({
|
|
||||||
item,
|
|
||||||
isOffline = false,
|
|
||||||
children,
|
|
||||||
...props
|
|
||||||
}) => {
|
|
||||||
const router = useRouter();
|
|
||||||
const segments = useSegments();
|
|
||||||
const from = segments[2] || "(home)";
|
|
||||||
|
|
||||||
if (
|
|
||||||
from === "(home)" ||
|
|
||||||
from === "(search)" ||
|
|
||||||
from === "(libraries)" ||
|
|
||||||
from === "(favorites)"
|
|
||||||
)
|
|
||||||
return (
|
|
||||||
<TouchableOpacity
|
|
||||||
onPress={() => {
|
|
||||||
let url = itemRouter(item, from);
|
|
||||||
if (isOffline) {
|
|
||||||
url += `&offline=true`;
|
|
||||||
}
|
|
||||||
// @ts-expect-error
|
|
||||||
router.push(url);
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</TouchableOpacity>
|
|
||||||
);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
@@ -3,7 +3,6 @@ import { useJellyseerr } from "@/hooks/useJellyseerr";
|
|||||||
import {
|
import {
|
||||||
MediaRequestStatus,
|
MediaRequestStatus,
|
||||||
MediaStatus,
|
MediaStatus,
|
||||||
MediaType,
|
|
||||||
} from "@/utils/jellyseerr/server/constants/media";
|
} from "@/utils/jellyseerr/server/constants/media";
|
||||||
import {
|
import {
|
||||||
hasPermission,
|
hasPermission,
|
||||||
@@ -41,7 +40,7 @@ export const useJellyseerrCanRequest = (
|
|||||||
const userHasPermission = hasPermission(
|
const userHasPermission = hasPermission(
|
||||||
[
|
[
|
||||||
Permission.REQUEST,
|
Permission.REQUEST,
|
||||||
item?.mediaInfo?.mediaType === MediaType.MOVIE
|
item?.mediaInfo?.mediaType
|
||||||
? Permission.REQUEST_MOVIE
|
? Permission.REQUEST_MOVIE
|
||||||
: Permission.REQUEST_TV,
|
: Permission.REQUEST_TV,
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user