mirror of
https://github.com/qier222/YesPlayMusic.git
synced 2025-02-28 21:19:47 +08:00
136 lines
4.5 KiB
TypeScript
136 lines
4.5 KiB
TypeScript
import { likeAPlaylist } from '@/web/api/playlist'
|
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
|
import useUser from './useUser'
|
|
import { IpcChannels } from '@/shared/IpcChannels'
|
|
import { CacheAPIs } from '@/shared/CacheAPIs'
|
|
import { fetchUserPlaylists } from '@/web/api/user'
|
|
import { FetchUserPlaylistsResponse, UserApiNames } from '@/shared/api/User'
|
|
import toast from 'react-hot-toast'
|
|
import reactQueryClient from '@/web/utils/reactQueryClient'
|
|
import { cloneDeep } from 'lodash-es'
|
|
import { FetchPlaylistResponse, PlaylistApiNames } from '@/shared/api/Playlists'
|
|
|
|
export default function useUserPlaylists() {
|
|
const { data: user } = useUser()
|
|
const uid = user?.profile?.userId ?? 0
|
|
|
|
const params = {
|
|
uid: uid,
|
|
offset: 0,
|
|
limit: 2000,
|
|
}
|
|
|
|
const key = [UserApiNames.FetchUserPlaylists, uid]
|
|
|
|
return useQuery(
|
|
key,
|
|
async () => {
|
|
if (!params.uid) {
|
|
throw new Error('请登录后再请求用户收藏的歌单')
|
|
}
|
|
|
|
const existsQueryData = reactQueryClient.getQueryData(key)
|
|
if (!existsQueryData) {
|
|
window.ipcRenderer
|
|
?.invoke(IpcChannels.GetApiCache, {
|
|
api: CacheAPIs.UserPlaylist,
|
|
query: {
|
|
uid: params.uid,
|
|
},
|
|
})
|
|
.then(cache => {
|
|
if (cache) reactQueryClient.setQueryData(key, cache)
|
|
})
|
|
}
|
|
|
|
return fetchUserPlaylists(params)
|
|
},
|
|
{
|
|
enabled: !!(!!params.uid && params.uid !== 0 && params.offset !== undefined),
|
|
refetchOnWindowFocus: true,
|
|
}
|
|
)
|
|
}
|
|
|
|
export const useMutationLikeAPlaylist = () => {
|
|
const { data: user } = useUser()
|
|
const { data: userPlaylists } = useUserPlaylists()
|
|
const uid = user?.account?.id ?? 0
|
|
const key = [UserApiNames.FetchUserPlaylists, uid]
|
|
|
|
return useMutation(
|
|
async (playlistID: number) => {
|
|
if (!playlistID || userPlaylists?.playlist === undefined) {
|
|
throw new Error('playlist id is required or userPlaylists is undefined')
|
|
}
|
|
const response = await likeAPlaylist({
|
|
id: playlistID,
|
|
t: userPlaylists.playlist.findIndex(p => p.id === playlistID) > -1 ? 2 : 1,
|
|
})
|
|
if (response.code !== 200) throw new Error((response as any).msg)
|
|
return response
|
|
},
|
|
{
|
|
onMutate: async playlistID => {
|
|
// Cancel any outgoing refetches (so they don't overwrite our optimistic update)
|
|
await reactQueryClient.cancelQueries(key)
|
|
|
|
console.log(reactQueryClient.getQueryData(key))
|
|
|
|
// 如果还未获取用户收藏的专辑列表,则获取一次
|
|
if (!reactQueryClient.getQueryData(key)) {
|
|
await reactQueryClient.fetchQuery(key)
|
|
}
|
|
|
|
// Snapshot the previous value
|
|
const previousData = reactQueryClient.getQueryData(key) as FetchUserPlaylistsResponse
|
|
|
|
const isLiked = !!previousData?.playlist.find(p => p.id === playlistID)
|
|
const newPlaylists = cloneDeep(previousData!)
|
|
|
|
console.log({ isLiked })
|
|
|
|
if (isLiked) {
|
|
newPlaylists.playlist = previousData.playlist.filter(p => p.id !== playlistID)
|
|
} else {
|
|
// 从react-query缓存获取歌单信息
|
|
|
|
const playlistFromCache: FetchPlaylistResponse | undefined =
|
|
reactQueryClient.getQueryData([PlaylistApiNames.FetchPlaylist, { id: playlistID }])
|
|
|
|
// 从api获取歌单信息
|
|
const playlist: FetchPlaylistResponse | undefined = playlistFromCache
|
|
? playlistFromCache
|
|
: await reactQueryClient.fetchQuery([
|
|
PlaylistApiNames.FetchPlaylist,
|
|
{ id: playlistID },
|
|
])
|
|
|
|
if (!playlist?.playlist) {
|
|
toast.error('Failed to like playlist: unable to fetch playlist info')
|
|
throw new Error('unable to fetch playlist info')
|
|
}
|
|
newPlaylists.playlist.splice(1, 0, playlist.playlist)
|
|
|
|
// Optimistically update to the new value
|
|
reactQueryClient.setQueriesData(key, newPlaylists)
|
|
}
|
|
|
|
reactQueryClient.setQueriesData(key, newPlaylists)
|
|
|
|
console.log({ newPlaylists })
|
|
|
|
// Return a context object with the snapshotted value
|
|
return { previousData }
|
|
},
|
|
// If the mutation fails, use the context returned from onMutate to roll back
|
|
onSettled: (data, error, playlistID, context) => {
|
|
if (data?.code !== 200) {
|
|
reactQueryClient.setQueryData(key, (context as any).previousData)
|
|
toast((error as any).toString())
|
|
}
|
|
},
|
|
}
|
|
)
|
|
}
|