songId
: song 아이디)
songId
로 supabase
에서 해당 노래를 가져온다.import { Song } from '@/types';
import { useSessionContext } from '@supabase/auth-helpers-react';
import { useEffect, useMemo, useState } from 'react';
import { toast } from 'react-hot-toast';
const useGetSongById = (id?: string) => {
const [isLoading, setIsLoading] = useState(false);
const [song, setSong] = useState<Song | undefined>(undefined);
const { supabaseClient } = useSessionContext();
useEffect(() => {
if (!id) {
return;
}
setIsLoading(true);
// 특정 아이디에 해당하는 노래를 가져온다.
const fetchSong = async () => {
const { data, error } = await supabaseClient
.from('songs')
.select('*')
.eq('id', id)
.single();
if (error) {
setIsLoading(false);
return toast.error(error.message);
}
setSong(data as Song);
setIsLoading(false);
};
fetchSong();
}, [id, supabaseClient]);
return useMemo(() => ({ isLoading, song }), [isLoading, song]);
};
export default useGetSongById;
useLoadSongUrl(song
: 특정 노래) : string
인자
로 넘겨 받는다.supabaseClient.storage
에서 해당 노래의 url을 가져온다.import { Song } from '@/types';
import { useSupabaseClient } from '@supabase/auth-helpers-react';
const useLoadSongUrl = (song: Song) => {
// useSessionContext에서 supabaseClient를 꺼낼 필요는 없다 why? 인증이 필요하지 않은 작업이기 때문.
const supabaseClient = useSupabaseClient();
if (!song) {
return '';
}
const { data: songData } = supabaseClient.storage
.from('songs')
.getPublicUrl(song.song_path);
return songData.publicUrl;
};
export default useLoadSongUrl;
useOnPlay(songs
: 노래 배열들)
useOnPlay
훅에서 넘겨받은 songs
들(현재 재생목록, 메인페이지 재생목록인지, 좋아요 페이지 재생목록인지등등)의 id들만 배열로 전역에 저장한다.usePlayer
import { create } from 'zustand';
interface PlayerStore {
ids: string[];
activeId?: string;
setId: (id: string) => void;
setIds: (ids: string[]) => void;
reset: () => void;
}
const usePlayer = create<PlayerStore>((set) => ({
// 실제 플레이할 리스트
ids: [],
// 현재 선택된 노래
activeId: undefined,
setId: (id: string) => set({ activeId: id }),
setIds: (ids: string[]) => set({ ids: ids }),
reset: () => ({ ids: [], activeId: undefined }),
}));
export default usePlayer;