
12 January 2026
const { audioRef } = usePlayerContext();
const [_hasAudio, setHasAudio] = useState(false);
useEffect(() => {
setHasAudio(true);
}, []);
return (
<>
<audio ref={audioRef} className="hidden" />
{audioRef.current && (
<PlayerEffect audioEle={audioRef.current}>
{isOnMobile ? mobileContent : desktopContent}
</PlayerEffect>
)}
</>
);export default function PlayerEffect({ children, audioEle }: Props) {
const { isOnMobile } = useThemeContext();
usePlayerEffect();
useCountDown();
useIdle(appConfig.focusDelay, isOnMobile);
usePlayCount({ audioEle });
return useMemo(() => children, []);
}
const { setToasts, toasts } = useToastContext();
const [removing, setRemoving] = useState("");
const removeToast = (id: string) => {
setToasts((t) => t.filter((toast) => toast.id != id));
};
useEffect(() => {
if (removing) setToasts((t) => t.filter((toast) => toast.id != removing));
}, [removing]);
useEffect(() => {
if (!toasts.length) return;
const id = toasts[toasts.length - 1].id;
setTimeout(() => setRemoving(id), time);
}, [toasts]);const { controlRef } = usePlayerContext();
useImperativeHandle(controlRef, () => ({
pause,
play,
handlePlayPause,
}));const tabs = ["Favorite", "Own"] as const;
type Tab = (typeof tabs)[number];const [tab, setTab] = useState<Tab | "">("");
useEffect(() => {
const initRun = async () => {
const lastTab = getLocalStorage()["last_playlist_tab"] as Tab;
await getPlaylist(lastTab);
setTab(lastTab || 'Favorite');
};
if (!ranEffect.current) {
ranEffect.current = true;
initRun();
}
});
useEffect(() => {
if (!tab) return;
getPlaylist();
}, [tab]); const params = useParams<{id: string}>();
routeSlug = "/playlist/:id"Make with
by Nguyen Huu Dat
© 2025