Horizontal card list adjustments

Adding recently added albums to discover
This commit is contained in:
Violet Caulfield
2025-02-18 22:39:11 -06:00
parent 3488cb84bb
commit 2dcc855da0
10 changed files with 141 additions and 55 deletions

View File

@@ -2,6 +2,27 @@ import { BaseItemDto, BaseItemKind, ItemSortBy, SortOrder } from "@jellyfin/sdk/
import { getItemsApi } from "@jellyfin/sdk/lib/utils/api/items-api";
import { QueryConfig } from "../query.config";
import Client from "../../client";
import { getUserLibraryApi } from "@jellyfin/sdk/lib/utils/api";
export function fetchRecentlyAdded(offset?: number | undefined) : Promise<BaseItemDto[]> {
return new Promise(async (resolve, reject) => {
if (!!!Client.api)
return reject("Client not set")
if (!!!Client.library)
return reject("Library not set")
else
getUserLibraryApi(Client.api)
.getLatestMedia({
parentId: Client.library.musicLibraryId,
limit: QueryConfig.limits.recents,
})
.then(({ data }) => {
resolve(data);
});
})
}
export function fetchRecentlyPlayed(offset?: number | undefined): Promise<BaseItemDto[]> {

View File

@@ -5,11 +5,15 @@ import { FlatList, RefreshControl } from "react-native";
import { useQuery } from "@tanstack/react-query";
import { QueryKeys } from "../../enums/query-keys";
import { fetchFavoriteAlbums } from "../../api/queries/functions/favorites";
import { fetchRecentlyAdded } from "../../api/queries/functions/recents";
export default function Albums({ navigation, route }: AlbumsProps) : React.JSX.Element {
const fetchRecentlyAddedAlbums = route.params.query === QueryKeys.RecentlyAdded;
export default function Albums({ navigation }: AlbumsProps) : React.JSX.Element {
const { data: albums, refetch, isPending } = useQuery({
queryKey: [QueryKeys.FavoriteAlbums],
queryFn: () => fetchFavoriteAlbums()
queryKey: [route.params.query],
queryFn: () => fetchRecentlyAddedAlbums ? fetchRecentlyAdded(20) : fetchFavoriteAlbums()
});
const { width } = useSafeAreaFrame();

View File

@@ -1,12 +1,15 @@
import React from "react";
import { SafeAreaView } from "react-native-safe-area-context";
import { ScrollView } from "tamagui";
import RecentlyAdded from "./helpers/just-added";
import { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { StackParamList } from "../types";
export default function Index() : React.JSX.Element {
export default function Index({ navigation }: { navigation : NativeStackNavigationProp<StackParamList> }) : React.JSX.Element {
return (
<SafeAreaView>
<ScrollView removeClippedSubviews>
<RecentlyAdded navigation={navigation} />
</ScrollView>
</SafeAreaView>
)

View File

@@ -0,0 +1,45 @@
import { useQuery } from "@tanstack/react-query";
import { StackParamList } from "../../../components/types";
import { NativeStackNavigationProp } from "@react-navigation/native-stack";
import { QueryKeys } from "../../../enums/query-keys";
import { fetchRecentlyAdded } from "../../../api/queries/functions/recents";
import HorizontalCardList from "../../../components/Global/components/horizontal-list";
import { ItemCard } from "@/components/Global/components/item-card";
export default function RecentlyAdded({
navigation
} : {
navigation: NativeStackNavigationProp<StackParamList>
}) : React.JSX.Element {
const { data } = useQuery({
queryKey: [QueryKeys.RecentlyAdded],
queryFn: () => fetchRecentlyAdded()
});
return (
<HorizontalCardList
squared
data={data}
onSeeMore={() => {
navigation.navigate("Albums", {
query: QueryKeys.RecentlyAdded
})
}}
renderItem={({ item }) =>
<ItemCard
caption={item.Name}
subCaption={`${item.Artists?.join(", ")}`}
squared
width={"13"}
item={item}
onPress={() => {
navigation.navigate("Album", {
album: item
})
}}
/>
}
/>
)
}

View File

@@ -3,6 +3,7 @@ import { StackParamList } from "../types";
import Index from "./component";
import DetailsScreen from "../ItemDetail/screen";
import Player from "../Player/stack";
import Albums from "../Albums/component";
export const DiscoverStack = createNativeStackNavigator<StackParamList>();
@@ -24,6 +25,11 @@ export function Discover(): React.JSX.Element {
}
}}
/>
<DiscoverStack.Screen
name="Albums"
component={Albums}
/>
<DiscoverStack.Group screenOptions={{ presentation: "modal"}}>
<DiscoverStack.Screen

View File

@@ -1,13 +1,10 @@
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models/base-item-dto";
import React from "react";
import { FlatList, ListRenderItem } from "react-native";
import { FlatList, FlatListProps, ListRenderItem } from "react-native";
import IconCard from "../helpers/icon-card";
import { horizontalCardLimit } from "../component.config";
interface HorizontalCardListProps {
items: BaseItemDto[] | undefined;
renderItem: ListRenderItem<BaseItemDto> | null | undefined
interface HorizontalCardListProps extends FlatListProps<BaseItemDto> {
squared?: boolean | undefined;
/**
* The number of items that will be displayed before
@@ -24,20 +21,19 @@ interface HorizontalCardListProps {
* @returns
*/
export default function HorizontalCardList({
items,
renderItem,
cutoff = horizontalCardLimit,
onSeeMore,
squared = false,
...props
} : HorizontalCardListProps) : React.JSX.Element {
return (
<FlatList
horizontal
data={items?.slice(0, cutoff - 1) ?? undefined}
renderItem={renderItem}
data={props.data}
renderItem={props.renderItem}
ListFooterComponent={() => {
return items ? (
return props.data ? (
<IconCard
name={
squared

View File

@@ -18,7 +18,7 @@ export default function RecentArtists({ navigation }: { navigation: NativeStackN
<H2 marginLeft={"$2"}>Recent Artists</H2>
<HorizontalCardList
items={recentArtists}
data={recentArtists}
onSeeMore={() => {
navigation.navigate("Artists", {
query: QueryKeys.RecentlyPlayedArtists

View File

@@ -17,47 +17,54 @@ export default function RecentlyPlayed({
navigation: NativeStackNavigationProp<StackParamList>
}): React.JSX.Element {
const { usePlayNewQueue } = usePlayerContext();
const { nowPlaying, usePlayNewQueue } = usePlayerContext();
const { recentTracks } = useHomeContext();
return (
<View>
<H2 marginLeft={"$2"}>Play it again</H2>
useMemo(() => {
return (
<View>
<H2 marginLeft={"$2"}>Play it again</H2>
<HorizontalCardList
squared
items={recentTracks}
onSeeMore={() => {
navigation.navigate("Tracks", {
query: QueryKeys.RecentlyPlayed
})
}}
renderItem={({ index, item: recentlyPlayedTrack }) =>
<ItemCard
caption={recentlyPlayedTrack.Name}
subCaption={`${recentlyPlayedTrack.Artists?.join(", ")}`}
squared
width={150}
item={recentlyPlayedTrack}
onPress={() => {
usePlayNewQueue.mutate({
track: recentlyPlayedTrack,
index: index,
tracklist: recentTracks ?? [recentlyPlayedTrack],
queue: "Recently Played",
queuingType: QueuingType.FromSelection
});
}}
onLongPress={() => {
trigger("impactMedium");
navigation.navigate("Details", {
item: recentlyPlayedTrack,
isNested: false
})
}}
/>
}
/>
</View>
<HorizontalCardList
squared
data={recentTracks}
onSeeMore={() => {
navigation.navigate("Tracks", {
query: QueryKeys.RecentlyPlayed
})
}}
renderItem={({ index, item: recentlyPlayedTrack }) =>
<ItemCard
caption={recentlyPlayedTrack.Name}
subCaption={`${recentlyPlayedTrack.Artists?.join(", ")}`}
squared
width={150}
item={recentlyPlayedTrack}
onPress={() => {
usePlayNewQueue.mutate({
track: recentlyPlayedTrack,
index: index,
tracklist: recentTracks ?? [recentlyPlayedTrack],
queue: "Recently Played",
queuingType: QueuingType.FromSelection
});
}}
onLongPress={() => {
trigger("impactMedium");
navigation.navigate("Details", {
item: recentlyPlayedTrack,
isNested: false
})
}}
/>
}
/>
</View>
)
}, [
recentTracks,
nowPlaying
])
)
}

View File

@@ -32,7 +32,9 @@ export type StackParamList = {
Artists: {
query: QueryKeys.FavoriteArtists | QueryKeys.RecentlyPlayedArtists
};
Albums: undefined;
Albums: {
query: QueryKeys.FavoriteAlbums | QueryKeys.RecentlyAdded
};
Tracks: {
query: QueryKeys.FavoriteTracks | QueryKeys.RecentlyPlayed
};

View File

@@ -40,4 +40,6 @@ export enum QueryKeys {
SearchSuggestions = "SearchSuggestions",
FavoritePlaylists = "FavoritePlaylists",
UserViews = "UserViews",
Audio = "Audio",
RecentlyAdded = "RecentlyAdded",
}