From 27609e7789ea160bcb7b41cd31e476af70b7e0c2 Mon Sep 17 00:00:00 2001 From: Fredrik Burmester Date: Wed, 1 Jan 2025 15:46:22 +0100 Subject: [PATCH 1/2] feat: favorites tab --- app/(auth)/(tabs)/(favorites)/_layout.tsx | 24 ++++ app/(auth)/(tabs)/(favorites)/index.tsx | 34 +++++ .../actors/[actorId].tsx | 0 .../albums/[albumId].tsx | 0 .../artists/[artistId].tsx | 0 .../artists/index.tsx | 0 .../collections/[collectionId].tsx | 0 .../items/page.tsx | 0 .../jellyseerr/page.tsx | 0 .../livetv/_layout.tsx | 0 .../livetv/channels.tsx | 0 .../livetv/guide.tsx | 0 .../livetv/programs.tsx | 0 .../livetv/recordings.tsx | 0 .../series/[id].tsx | 0 app/(auth)/(tabs)/(search)/index.tsx | 4 +- app/(auth)/(tabs)/_layout.tsx | 11 ++ assets/icons/heart.png | Bin 0 -> 21969 bytes components/common/TouchableItemRouter.tsx | 7 +- components/home/Favorites.tsx | 119 ++++++++++++++++++ components/home/ScrollingCollectionList.tsx | 15 +-- 21 files changed, 204 insertions(+), 10 deletions(-) create mode 100644 app/(auth)/(tabs)/(favorites)/_layout.tsx create mode 100644 app/(auth)/(tabs)/(favorites)/index.tsx rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/actors/[actorId].tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/albums/[albumId].tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/artists/[artistId].tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/artists/index.tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/collections/[collectionId].tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/items/page.tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/jellyseerr/page.tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/livetv/_layout.tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/livetv/channels.tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/livetv/guide.tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/livetv/programs.tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/livetv/recordings.tsx (100%) rename app/(auth)/(tabs)/{(home,libraries,search) => (home,libraries,search,favorites)}/series/[id].tsx (100%) create mode 100644 assets/icons/heart.png create mode 100644 components/home/Favorites.tsx diff --git a/app/(auth)/(tabs)/(favorites)/_layout.tsx b/app/(auth)/(tabs)/(favorites)/_layout.tsx new file mode 100644 index 00000000..f96cd516 --- /dev/null +++ b/app/(auth)/(tabs)/(favorites)/_layout.tsx @@ -0,0 +1,24 @@ +import { nestedTabPageScreenOptions } from "@/components/stacks/NestedTabPageStack"; +import { Stack } from "expo-router"; +import { Platform } from "react-native"; + +export default function SearchLayout() { + return ( + + + {Object.entries(nestedTabPageScreenOptions).map(([name, options]) => ( + + ))} + + ); +} diff --git a/app/(auth)/(tabs)/(favorites)/index.tsx b/app/(auth)/(tabs)/(favorites)/index.tsx new file mode 100644 index 00000000..e01f975e --- /dev/null +++ b/app/(auth)/(tabs)/(favorites)/index.tsx @@ -0,0 +1,34 @@ +import { Favorites } from "@/components/home/Favorites"; +import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache"; +import React, { useCallback, useState } from "react"; +import { RefreshControl, ScrollView, View } from "react-native"; +import { useSafeAreaInsets } from "react-native-safe-area-context"; + +export default function favorites() { + const invalidateCache = useInvalidatePlaybackProgressCache(); + + const [loading, setLoading] = useState(false); + const refetch = useCallback(async () => { + setLoading(true); + await invalidateCache(); + setLoading(false); + }, []); + const insets = useSafeAreaInsets(); + + return ( + + } + contentContainerStyle={{ + paddingLeft: insets.left, + paddingRight: insets.right, + paddingBottom: 16, + }} + > + + + ); +} diff --git a/app/(auth)/(tabs)/(home,libraries,search)/actors/[actorId].tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/actors/[actorId].tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/actors/[actorId].tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/actors/[actorId].tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/albums/[albumId].tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/albums/[albumId].tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/albums/[albumId].tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/albums/[albumId].tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/artists/[artistId].tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/artists/[artistId].tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/artists/[artistId].tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/artists/[artistId].tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/artists/index.tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/artists/index.tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/artists/index.tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/artists/index.tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/collections/[collectionId].tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/collections/[collectionId].tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/collections/[collectionId].tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/collections/[collectionId].tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/items/page.tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/items/page.tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/items/page.tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/items/page.tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/jellyseerr/page.tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/jellyseerr/page.tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/jellyseerr/page.tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/jellyseerr/page.tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/livetv/_layout.tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/livetv/_layout.tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/livetv/_layout.tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/livetv/_layout.tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/livetv/channels.tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/livetv/channels.tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/livetv/channels.tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/livetv/channels.tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/livetv/guide.tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/livetv/guide.tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/livetv/guide.tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/livetv/guide.tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/livetv/programs.tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/livetv/programs.tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/livetv/programs.tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/livetv/programs.tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/livetv/recordings.tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/livetv/recordings.tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/livetv/recordings.tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/livetv/recordings.tsx diff --git a/app/(auth)/(tabs)/(home,libraries,search)/series/[id].tsx b/app/(auth)/(tabs)/(home,libraries,search,favorites)/series/[id].tsx similarity index 100% rename from app/(auth)/(tabs)/(home,libraries,search)/series/[id].tsx rename to app/(auth)/(tabs)/(home,libraries,search,favorites)/series/[id].tsx diff --git a/app/(auth)/(tabs)/(search)/index.tsx b/app/(auth)/(tabs)/(search)/index.tsx index ac3d83fe..48507dbe 100644 --- a/app/(auth)/(tabs)/(search)/index.tsx +++ b/app/(auth)/(tabs)/(search)/index.tsx @@ -318,7 +318,7 @@ export default function search() { text="Library" textClass="p-1" className={ - searchType === "Library" ? "bg-neutral-600" : undefined + searchType === "Library" ? "bg-purple-600" : undefined } /> @@ -327,7 +327,7 @@ export default function search() { text="Discover" textClass="p-1" className={ - searchType === "Discover" ? "bg-neutral-600" : undefined + searchType === "Discover" ? "bg-purple-600" : undefined } /> diff --git a/app/(auth)/(tabs)/_layout.tsx b/app/(auth)/(tabs)/_layout.tsx index f256ab50..11fa4b67 100644 --- a/app/(auth)/(tabs)/_layout.tsx +++ b/app/(auth)/(tabs)/_layout.tsx @@ -62,6 +62,17 @@ export default function TabLayout() { : () => ({ sfSymbol: "magnifyingglass" }), }} /> + + require("@/assets/icons/heart.png") + : () => ({ sfSymbol: "heart" }), + }} + /> 5{-znC}A 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 = ({ const markAsPlayedStatus = useMarkAsPlayed(item); - if (from === "(home)" || from === "(search)" || from === "(libraries)") + if ( + from === "(home)" || + from === "(search)" || + from === "(libraries)" || + from === "(favorites)" + ) return ( diff --git a/components/home/Favorites.tsx b/components/home/Favorites.tsx new file mode 100644 index 00000000..90e55b1a --- /dev/null +++ b/components/home/Favorites.tsx @@ -0,0 +1,119 @@ +import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; +import { getItemsApi } from "@jellyfin/sdk/lib/utils/api"; +import { useAtom } from "jotai"; +import { View } from "react-native"; +import { ScrollingCollectionList } from "./ScrollingCollectionList"; +import { useCallback } from "react"; +import { BaseItemKind } from "@jellyfin/sdk/lib/generated-client"; + +export const Favorites = () => { + const [api] = useAtom(apiAtom); + const [user] = useAtom(userAtom); + + const fetchFavoritesByType = useCallback( + async (itemType: BaseItemKind) => { + const response = await getItemsApi(api!).getItems({ + userId: user?.Id!, + sortBy: ["SeriesSortName", "SortName"], + sortOrder: ["Ascending"], + filters: ["IsFavorite"], + recursive: true, + fields: ["PrimaryImageAspectRatio"], + collapseBoxSetItems: false, + excludeLocationTypes: ["Virtual"], + enableTotalRecordCount: false, + limit: 20, + includeItemTypes: [itemType], + }); + return response.data.Items || []; + }, + [api, user] + ); + + const fetchFavoriteSeries = useCallback( + () => fetchFavoritesByType("Series"), + [fetchFavoritesByType] + ); + const fetchFavoriteMovies = useCallback( + () => fetchFavoritesByType("Movie"), + [fetchFavoritesByType] + ); + const fetchFavoriteEpisodes = useCallback( + () => fetchFavoritesByType("Episode"), + [fetchFavoritesByType] + ); + const fetchFavoriteVideos = useCallback( + () => fetchFavoritesByType("Video"), + [fetchFavoritesByType] + ); + const fetchFavoriteBoxsets = useCallback( + () => fetchFavoritesByType("BoxSet"), + [fetchFavoritesByType] + ); + const fetchFavoritePlaylists = useCallback( + () => fetchFavoritesByType("Playlist"), + [fetchFavoritesByType] + ); + const fetchFavoriteMusicAlbum = useCallback( + () => fetchFavoritesByType("MusicAlbum"), + [fetchFavoritesByType] + ); + const fetchFavoriteAudio = useCallback( + () => fetchFavoritesByType("Audio"), + [fetchFavoritesByType] + ); + + return ( + + + + + + + + + + + ); +}; diff --git a/components/home/ScrollingCollectionList.tsx b/components/home/ScrollingCollectionList.tsx index 04dd6004..2fddec7f 100644 --- a/components/home/ScrollingCollectionList.tsx +++ b/components/home/ScrollingCollectionList.tsx @@ -11,6 +11,7 @@ import ContinueWatchingPoster from "../ContinueWatchingPoster"; import { ItemCardText } from "../ItemCardText"; import { TouchableItemRouter } from "../common/TouchableItemRouter"; import SeriesPoster from "../posters/SeriesPoster"; +import { useEffect } from "react"; interface Props extends ViewProps { title?: string | null; @@ -18,6 +19,7 @@ interface Props extends ViewProps { disabled?: boolean; queryKey: QueryKey; queryFn: QueryFunction; + hideIfEmpty?: boolean; } export const ScrollingCollectionList: React.FC = ({ @@ -26,10 +28,9 @@ export const ScrollingCollectionList: React.FC = ({ disabled = false, queryFn, queryKey, + hideIfEmpty = false, ...props }) => { - // console.log(queryKey); - const { data, isLoading } = useQuery({ queryKey: queryKey, queryFn, @@ -41,6 +42,8 @@ export const ScrollingCollectionList: React.FC = ({ if (disabled || !title) return null; + if (hideIfEmpty === true && data?.length === 0) return null; + return ( @@ -86,11 +89,9 @@ export const ScrollingCollectionList: React.FC = ({ {item.Type === "Episode" && orientation === "horizontal" && ( From ece3bc001fef36358cb34e1e99316d59867d90a9 Mon Sep 17 00:00:00 2001 From: Fredrik Burmester Date: Wed, 1 Jan 2025 16:11:04 +0100 Subject: [PATCH 2/2] fix: id collision --- app/(auth)/(tabs)/(home)/_layout.tsx | 2 +- app/(auth)/(tabs)/(home)/index.tsx | 6 ++-- app/(auth)/(tabs)/_layout.tsx | 31 +++++++++++++++----- app/_layout.tsx | 3 +- assets/icons/heart.fill.png | Bin 0 -> 15170 bytes components/home/ScrollingCollectionList.tsx | 7 ++--- 6 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 assets/icons/heart.fill.png diff --git a/app/(auth)/(tabs)/(home)/_layout.tsx b/app/(auth)/(tabs)/(home)/_layout.tsx index d3ef928a..a7cc3cb3 100644 --- a/app/(auth)/(tabs)/(home)/_layout.tsx +++ b/app/(auth)/(tabs)/(home)/_layout.tsx @@ -1,6 +1,6 @@ import { Chromecast } from "@/components/Chromecast"; import { nestedTabPageScreenOptions } from "@/components/stacks/NestedTabPageStack"; -import { Feather } from "@expo/vector-icons"; +import { Feather, Ionicons } from "@expo/vector-icons"; import { Stack, useRouter } from "expo-router"; import { Platform, TouchableOpacity, View } from "react-native"; diff --git a/app/(auth)/(tabs)/(home)/index.tsx b/app/(auth)/(tabs)/(home)/index.tsx index 2a9cd1ab..0f777a45 100644 --- a/app/(auth)/(tabs)/(home)/index.tsx +++ b/app/(auth)/(tabs)/(home)/index.tsx @@ -107,9 +107,9 @@ export default function index() { setIsConnected(state.isConnected); }); - cleanCacheDirectory() - .then(r => console.log("Cache directory cleaned")) - .catch(e => console.error("Something went wrong cleaning cache directory")) + cleanCacheDirectory().catch((e) => + console.error("Something went wrong cleaning cache directory") + ); return () => { unsubscribe(); }; diff --git a/app/(auth)/(tabs)/_layout.tsx b/app/(auth)/(tabs)/_layout.tsx index 11fa4b67..47e5bfaa 100644 --- a/app/(auth)/(tabs)/_layout.tsx +++ b/app/(auth)/(tabs)/_layout.tsx @@ -48,7 +48,10 @@ export default function TabLayout() { Platform.OS == "android" ? ({ color, focused, size }) => require("@/assets/icons/house.fill.png") - : () => ({ sfSymbol: "house" }), + : ({ focused }) => + focused + ? { sfSymbol: "house.fill" } + : { sfSymbol: "house" }, }} /> require("@/assets/icons/magnifyingglass.png") - : () => ({ sfSymbol: "magnifyingglass" }), + : ({ focused }) => + focused + ? { sfSymbol: "magnifyingglass" } + : { sfSymbol: "magnifyingglass" }, }} /> - require("@/assets/icons/heart.png") - : () => ({ sfSymbol: "heart" }), + focused + ? require("@/assets/icons/heart.fill.png") + : require("@/assets/icons/heart.png") + : ({ focused }) => + focused + ? { sfSymbol: "heart.fill" } + : { sfSymbol: "heart" }, }} /> require("@/assets/icons/server.rack.png") - : () => ({ sfSymbol: "rectangle.stack" }), + : ({ focused }) => + focused + ? { sfSymbol: "rectangle.stack.fill" } + : { sfSymbol: "rectangle.stack" }, }} /> require("@/assets/icons/list.png") - : () => ({ sfSymbol: "list.dash" }), + ? ({ focused }) => require("@/assets/icons/list.png") + : ({ focused }) => + focused + ? { sfSymbol: "list.dash.fill" } + : { sfSymbol: "list.dash" }, }} /> diff --git a/app/_layout.tsx b/app/_layout.tsx index 8c9da2f7..bf779be5 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,4 +1,5 @@ import "@/augmentations"; +import { Text } from "@/components/common/Text"; import { DownloadProvider } from "@/providers/DownloadProvider"; import { getOrSetDeviceId, @@ -36,7 +37,7 @@ import * as SplashScreen from "expo-splash-screen"; import * as TaskManager from "expo-task-manager"; import { Provider as JotaiProvider, useAtom } from "jotai"; import { useEffect, useRef } from "react"; -import { Appearance, AppState } from "react-native"; +import { Appearance, AppState, TouchableOpacity } from "react-native"; import { SystemBars } from "react-native-edge-to-edge"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import "react-native-reanimated"; diff --git a/assets/icons/heart.fill.png b/assets/icons/heart.fill.png new file mode 100644 index 0000000000000000000000000000000000000000..25bb2527a50a78776c80012adb42ea11c3be1b2e GIT binary patch literal 15170 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 b>)Yz{4r{&Tg8!s = ({ if (hideIfEmpty === true && data?.length === 0) return null; return ( - + {title} @@ -85,10 +84,10 @@ export const ScrollingCollectionList: React.FC = ({ ) : ( - {data?.map((item, index) => ( + {data?.map((item) => (