diff --git a/src/api/albums.ts b/src/api/albums.ts
index 445101d..0472eed 100644
--- a/src/api/albums.ts
+++ b/src/api/albums.ts
@@ -83,6 +83,28 @@ export const useFetchAlbumSongs = (
return albumSongs;
};
+export const useFetchArtistSongs = (api: Api, artistId: string) => {
+ // TODO: would be nicer to fetch by album so the cache can be shared with useFetchAlbumSongs
+ const user = useFetchUser(api);
+ const artistSongs = useQuery({
+ queryKey: ["artistSongs", artistId],
+ queryFn: async () => {
+ const result = await getItemsApi(api).getItems({
+ userId: user?.data?.Id,
+ parentId: artistId,
+ includeItemTypes: [BaseItemKind.Audio],
+ sortBy: [ItemSortBy.ProductionYear, ItemSortBy.SortName],
+ sortOrder: [SortOrder.Ascending],
+ recursive: true,
+ });
+ return result.data;
+ },
+ enabled: !!user.isSuccess,
+ });
+
+ return artistSongs;
+};
+
export const useFetchMoreArtistAlbums = (
api: Api,
artistId: string,
diff --git a/src/components/AlbumDetails/Footer.tsx b/src/components/AlbumDetails/Footer.tsx
index 3446232..703b58f 100644
--- a/src/components/AlbumDetails/Footer.tsx
+++ b/src/components/AlbumDetails/Footer.tsx
@@ -16,13 +16,12 @@ import { AlbumCard } from "../AlbumCard";
import { Separator } from "../Separator";
import { Text } from "../Themed";
-export const AlbumFooter = ({
- albumDetails,
- albumSongs,
-}: {
+type AlbumFooterProps = {
albumDetails?: BaseItemDto;
albumSongs?: BaseItemDto[];
-}) => {
+};
+
+export const AlbumFooter = ({ albumDetails, albumSongs }: AlbumFooterProps) => {
const { styles } = useStyles(stylesheet);
const api = useApi((state) => state.api);
const moreAlbums = useFetchMoreArtistAlbums(
diff --git a/src/components/ArtistDetails/Header.tsx b/src/components/ArtistDetails/Header.tsx
index 6126df2..3446817 100644
--- a/src/components/ArtistDetails/Header.tsx
+++ b/src/components/ArtistDetails/Header.tsx
@@ -1,20 +1,43 @@
import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
import { Image } from "expo-image";
import { View } from "react-native";
-import { useStyles, createStyleSheet } from "react-native-unistyles";
+import { createStyleSheet, useStyles } from "react-native-unistyles";
+import { useFetchUser } from "../../api/user";
+import { usePlayTracks } from "../../hooks/usePlayTracks";
import { useApi } from "../../store/useJelloAuth";
import { extractPrimaryHash } from "../../util/extractPrimaryHash";
import { generateTrackArtworkUrl } from "../../util/generateTrackArtworkUrl";
+import { MusicButton } from "../MusicButton";
import { Text } from "../Themed";
+type ArtistHeaderProps = {
+ artistDetails: BaseItemDto;
+ artistSongs: BaseItemDto[];
+};
+
export const ArtistHeader = ({
artistDetails,
-}: {
- artistDetails: BaseItemDto;
-}) => {
+ artistSongs,
+}: ArtistHeaderProps) => {
const { styles } = useStyles(stylesheet);
const api = useApi((state) => state.api);
+ const playTracks = usePlayTracks();
+ const user = useFetchUser(api);
+
+ const onPressPlayArtist = () => {
+ playTracks({ tracks: artistSongs, api, userId: user.data?.Id });
+ };
+
+ const onPressShuffleArtist = () => {
+ playTracks({
+ tracks: artistSongs,
+ api,
+ userId: user.data?.Id,
+ shuffle: true,
+ });
+ };
+
return (
@@ -28,8 +51,8 @@ export const ArtistHeader = ({
{artistDetails?.Name}
- {/*
- */}
+
+
);
diff --git a/src/navigation/screens/LibraryTab/ArtistDetails.tsx b/src/navigation/screens/LibraryTab/ArtistDetails.tsx
index 60f3277..916a08b 100644
--- a/src/navigation/screens/LibraryTab/ArtistDetails.tsx
+++ b/src/navigation/screens/LibraryTab/ArtistDetails.tsx
@@ -5,6 +5,7 @@ import { useCallback } from "react";
import { Animated, SafeAreaView, View } from "react-native";
import { createStyleSheet, useStyles } from "react-native-unistyles";
+import { useFetchArtistSongs } from "../../../api/albums";
import {
useFetchArtistAlbums,
useFetchArtistDetails,
@@ -27,6 +28,8 @@ export const ArtistDetailsScreen = ({ route, navigation }: Props) => {
const api = useApi((state) => state.api);
const artistDetails = useFetchArtistDetails(api, artistId);
const artistAlbums = useFetchArtistAlbums(api, artistId);
+ const artistSongs = useFetchArtistSongs(api, artistId);
+
const headerHeight = useHeaderHeight();
const onPressArtistItem = useCallback(
@@ -51,7 +54,11 @@ export const ArtistDetailsScreen = ({ route, navigation }: Props) => {
const opacity = useFadeIn([artistDetails, artistAlbums]);
- if (artistDetails.isPending || artistAlbums.isPending) {
+ if (
+ artistDetails.isPending ||
+ artistAlbums.isPending ||
+ artistSongs.isPending
+ ) {
return ;
}
@@ -59,7 +66,10 @@ export const ArtistDetailsScreen = ({ route, navigation }: Props) => {
+
}
ListFooterComponent={}
data={artistAlbums.data?.Items}
diff --git a/src/navigation/screens/Modals/NowPlaying.tsx b/src/navigation/screens/Modals/NowPlaying.tsx
index c860530..7f66213 100644
--- a/src/navigation/screens/Modals/NowPlaying.tsx
+++ b/src/navigation/screens/Modals/NowPlaying.tsx
@@ -7,7 +7,6 @@ import { Slider } from "react-native-awesome-slider";
import {
ContextMenuButton,
MenuActionConfig,
- OnPressMenuItemEvent,
} from "react-native-ios-context-menu";
import LinearGradient from "react-native-linear-gradient";
import { useDerivedValue, useSharedValue } from "react-native-reanimated";