import { useCallback, useEffect, useRef, useState } from 'react'; import { useCurrentServer } from '/@/renderer/store'; import { AuthState, ServerListItem, ServerType } from '/@/renderer/types'; import { api } from '/@/renderer/api'; import { SongListSort, SortOrder } from '/@/renderer/api/types'; import { debounce } from 'lodash'; export const useServerAuthenticated = () => { const priorServerId = useRef(); const server = useCurrentServer(); const [ready, setReady] = useState( server?.type === ServerType.NAVIDROME ? AuthState.LOADING : AuthState.VALID, ); const authenticateNavidrome = useCallback(async (server: ServerListItem) => { // This trick works because navidrome-api.ts will internally check for authentication // failures and try to log in again (where available). So, all that's necessary is // making one request first try { await api.controller.getSongList({ apiClientProps: { server }, query: { limit: 1, sortBy: SongListSort.NAME, sortOrder: SortOrder.ASC, startIndex: 0, }, }); setReady(AuthState.VALID); } catch (error) { setReady(AuthState.INVALID); } }, []); const debouncedAuth = debounce((server: ServerListItem) => { authenticateNavidrome(server).catch(console.error); }, 300); useEffect(() => { if (priorServerId.current !== server?.id) { priorServerId.current = server?.id || ''; if (server?.type === ServerType.NAVIDROME) { setReady(AuthState.LOADING); debouncedAuth(server); } else { setReady(AuthState.VALID); } } }, [debouncedAuth, server]); return ready; };