mirror of
https://github.com/Jellify-Music/App.git
synced 2025-12-30 15:29:49 -06:00
Horizontal card list adjustments
Adding recently added albums to discover
This commit is contained in:
@@ -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[]> {
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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
|
||||
})
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
])
|
||||
)
|
||||
}
|
||||
4
components/types.d.ts
vendored
4
components/types.d.ts
vendored
@@ -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
|
||||
};
|
||||
|
||||
@@ -40,4 +40,6 @@ export enum QueryKeys {
|
||||
SearchSuggestions = "SearchSuggestions",
|
||||
FavoritePlaylists = "FavoritePlaylists",
|
||||
UserViews = "UserViews",
|
||||
Audio = "Audio",
|
||||
RecentlyAdded = "RecentlyAdded",
|
||||
}
|
||||
Reference in New Issue
Block a user