mirror of
https://github.com/Jellify-Music/App.git
synced 2026-05-02 08:39:23 -05:00
updates to how frequent artists are retrieved so that it's more accurate
better display support on home screen for larger displays (iPad, Mac)
This commit is contained in:
@@ -8,6 +8,7 @@ import { getItemsApi } from '@jellyfin/sdk/lib/utils/api'
|
||||
import { Api } from '@jellyfin/sdk'
|
||||
import { isUndefined } from 'lodash'
|
||||
import { JellifyLibrary } from '../../types/JellifyLibrary'
|
||||
import { fetchItem } from './item'
|
||||
|
||||
/**
|
||||
* Fetches the 100 most frequently played items from the user's library
|
||||
@@ -66,26 +67,41 @@ export function fetchFrequentlyPlayedArtists(
|
||||
if (isUndefined(api)) return reject('Client instance not set')
|
||||
if (isUndefined(library)) return reject('Library instance not set')
|
||||
|
||||
getItemsApi(api!)
|
||||
.getItems({
|
||||
includeItemTypes: [BaseItemKind.MusicArtist],
|
||||
parentId: library!.musicLibraryId,
|
||||
recursive: true,
|
||||
limit: 100,
|
||||
startIndex: page * 100,
|
||||
sortBy: [ItemSortBy.PlayCount],
|
||||
sortOrder: [SortOrder.Descending],
|
||||
fetchFrequentlyPlayed(api, library, 0)
|
||||
.then((frequentTracks) => {
|
||||
return frequentTracks
|
||||
.filter((track) => !isUndefined(track.AlbumArtists))
|
||||
.map((track) => {
|
||||
return {
|
||||
artistId: track.AlbumArtists![0].Id!,
|
||||
playCount: track.UserData?.PlayCount ?? 0,
|
||||
}
|
||||
})
|
||||
})
|
||||
.then(({ data }) => {
|
||||
if (data.Items) return data.Items
|
||||
else return []
|
||||
.then((albumArtistsWithPlayCounts) => {
|
||||
return albumArtistsWithPlayCounts.reduce(
|
||||
(acc, { artistId, playCount }) => {
|
||||
const existing = acc.find((a) => a.artistId === artistId)
|
||||
if (existing) {
|
||||
existing.playCount += playCount
|
||||
} else {
|
||||
acc.push({ artistId, playCount })
|
||||
}
|
||||
return acc
|
||||
},
|
||||
[] as { artistId: string; playCount: number }[],
|
||||
)
|
||||
})
|
||||
.then((artistsWithPlayCounts) => {
|
||||
console.debug('Fetching artists', artistsWithPlayCounts)
|
||||
const artists = artistsWithPlayCounts.map((artist) => {
|
||||
return fetchItem(api, artist.artistId)
|
||||
})
|
||||
|
||||
return Promise.all(artists)
|
||||
})
|
||||
.then((artists) => {
|
||||
resolve(
|
||||
artists.filter((item, index, artists) => {
|
||||
return index === artists.findIndex((artist) => artist.Id === item.Id)
|
||||
}),
|
||||
)
|
||||
return resolve(artists.filter((artist) => !isUndefined(artist)))
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import HorizontalCardList from '../../../components/Global/components/horizontal-list'
|
||||
import { StackParamList } from '../../../components/types'
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
import React from 'react'
|
||||
import React, { useEffect } from 'react'
|
||||
import { ItemCard } from '../../../components/Global/components/item-card'
|
||||
import { View, XStack } from 'tamagui'
|
||||
import { H2, H4, Text } from '../../../components/Global/helpers/text'
|
||||
import Icon from '../../Global/components/icon'
|
||||
import { useHomeContext } from '../../../providers/Home'
|
||||
import { ActivityIndicator } from 'react-native'
|
||||
import { useDisplayContext } from '../../../providers/Display/display-provider'
|
||||
|
||||
export default function FrequentArtists({
|
||||
navigation,
|
||||
@@ -21,6 +22,8 @@ export default function FrequentArtists({
|
||||
isFetchingFrequentArtists,
|
||||
} = useHomeContext()
|
||||
|
||||
const { horizontalItems } = useDisplayContext()
|
||||
|
||||
return (
|
||||
<View>
|
||||
<XStack
|
||||
@@ -39,7 +42,7 @@ export default function FrequentArtists({
|
||||
</XStack>
|
||||
|
||||
<HorizontalCardList
|
||||
data={frequentArtists?.slice(0, 10) ?? []}
|
||||
data={frequentArtists?.slice(0, horizontalItems) ?? []}
|
||||
renderItem={({ item: artist }) => (
|
||||
<ItemCard
|
||||
item={artist}
|
||||
|
||||
@@ -10,6 +10,7 @@ import Icon from '../../Global/components/icon'
|
||||
import { useQueueContext } from '../../../providers/Player/queue'
|
||||
import { usePlayerContext } from '../../../providers/Player'
|
||||
import { H4 } from '../../../components/Global/helpers/text'
|
||||
import { useDisplayContext } from '../../../providers/Display/display-provider'
|
||||
export default function FrequentlyPlayedTracks({
|
||||
navigation,
|
||||
}: {
|
||||
@@ -24,6 +25,7 @@ export default function FrequentlyPlayedTracks({
|
||||
|
||||
const { useStartPlayback } = usePlayerContext()
|
||||
const { useLoadNewQueue } = useQueueContext()
|
||||
const { horizontalItems } = useDisplayContext()
|
||||
|
||||
return (
|
||||
<View>
|
||||
@@ -44,8 +46,8 @@ export default function FrequentlyPlayedTracks({
|
||||
|
||||
<HorizontalCardList
|
||||
data={
|
||||
(frequentlyPlayed?.pages.flatMap((page) => page).length ?? 0 > 10)
|
||||
? frequentlyPlayed?.pages.flatMap((page) => page).slice(0, 10)
|
||||
(frequentlyPlayed?.pages.flatMap((page) => page).length ?? 0 > horizontalItems)
|
||||
? frequentlyPlayed?.pages.flatMap((page) => page).slice(0, horizontalItems)
|
||||
: frequentlyPlayed?.pages.flatMap((page) => page)
|
||||
}
|
||||
renderItem={({ item: track, index }) => (
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import React from 'react'
|
||||
import { View, XStack } from 'tamagui'
|
||||
import { useHomeContext } from '../../../providers/Home'
|
||||
import { H2, H4 } from '../../Global/helpers/text'
|
||||
import { H4 } from '../../Global/helpers/text'
|
||||
import { StackParamList } from '../../types'
|
||||
import { ItemCard } from '../../Global/components/item-card'
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
import HorizontalCardList from '../../../components/Global/components/horizontal-list'
|
||||
import Icon from '../../Global/components/icon'
|
||||
import { useDisplayContext } from '../../../providers/Display/display-provider'
|
||||
|
||||
export default function RecentArtists({
|
||||
navigation,
|
||||
@@ -16,6 +17,7 @@ export default function RecentArtists({
|
||||
const { recentArtists, fetchNextRecentArtists, hasNextRecentArtists, isFetchingRecentArtists } =
|
||||
useHomeContext()
|
||||
|
||||
const { horizontalItems } = useDisplayContext()
|
||||
return (
|
||||
<View>
|
||||
<XStack
|
||||
@@ -34,7 +36,7 @@ export default function RecentArtists({
|
||||
</XStack>
|
||||
|
||||
<HorizontalCardList
|
||||
data={recentArtists?.slice(0, 10) ?? []}
|
||||
data={recentArtists?.slice(0, horizontalItems) ?? []}
|
||||
renderItem={({ item: recentArtist }) => (
|
||||
<ItemCard
|
||||
item={recentArtist}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useMemo } from 'react'
|
||||
import { View, XStack } from 'tamagui'
|
||||
import { useHomeContext } from '../../../providers/Home'
|
||||
import { H2, H4 } from '../../Global/helpers/text'
|
||||
import { H4 } from '../../Global/helpers/text'
|
||||
import { ItemCard } from '../../Global/components/item-card'
|
||||
import { usePlayerContext } from '../../../providers/Player'
|
||||
import { StackParamList } from '../../../components/types'
|
||||
@@ -11,6 +11,7 @@ import { QueuingType } from '../../../enums/queuing-type'
|
||||
import HorizontalCardList from '../../../components/Global/components/horizontal-list'
|
||||
import Icon from '../../Global/components/icon'
|
||||
import { useQueueContext } from '../../../providers/Player/queue'
|
||||
import { useDisplayContext } from '../../../providers/Display/display-provider'
|
||||
|
||||
export default function RecentlyPlayed({
|
||||
navigation,
|
||||
@@ -18,10 +19,13 @@ export default function RecentlyPlayed({
|
||||
navigation: NativeStackNavigationProp<StackParamList>
|
||||
}): React.JSX.Element {
|
||||
const { nowPlaying, useStartPlayback } = usePlayerContext()
|
||||
|
||||
const { useLoadNewQueue } = useQueueContext()
|
||||
|
||||
const { recentTracks, fetchNextRecentTracks, hasNextRecentTracks, isFetchingRecentTracks } =
|
||||
useHomeContext()
|
||||
|
||||
const { horizontalItems } = useDisplayContext()
|
||||
return useMemo(() => {
|
||||
return (
|
||||
<View>
|
||||
@@ -42,8 +46,8 @@ export default function RecentlyPlayed({
|
||||
|
||||
<HorizontalCardList
|
||||
data={
|
||||
(recentTracks?.pages.flatMap((page) => page).length ?? 0 > 10)
|
||||
? recentTracks?.pages.flatMap((page) => page).slice(0, 10)
|
||||
(recentTracks?.pages.flatMap((page) => page).length ?? 0 > horizontalItems)
|
||||
? recentTracks?.pages.flatMap((page) => page).slice(0, horizontalItems)
|
||||
: recentTracks?.pages.flatMap((page) => page)
|
||||
}
|
||||
renderItem={({ index, item: recentlyPlayedTrack }) => (
|
||||
|
||||
@@ -4,6 +4,7 @@ import { getTokens } from 'tamagui'
|
||||
|
||||
interface DisplayContext {
|
||||
numberOfColumns: number
|
||||
horizontalItems: number
|
||||
|
||||
display: 'grid' | 'list'
|
||||
|
||||
@@ -19,8 +20,11 @@ const DisplayContextInitializer = () => {
|
||||
|
||||
const [display, setDisplay] = useState<'grid' | 'list'>('grid')
|
||||
|
||||
const [horizontalItems, setHorizontalItems] = useState<number>(width > 800 ? 30 : 15)
|
||||
|
||||
return {
|
||||
numberOfColumns,
|
||||
horizontalItems,
|
||||
display,
|
||||
setDisplay,
|
||||
}
|
||||
@@ -28,6 +32,7 @@ const DisplayContextInitializer = () => {
|
||||
|
||||
const DisplayContext = createContext<DisplayContext>({
|
||||
numberOfColumns: 0,
|
||||
horizontalItems: 0,
|
||||
display: 'grid',
|
||||
setDisplay: () => {},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user