()
| 67 | }; |
| 68 | |
| 69 | export const useRemoteState = (): RemoteState => { |
| 70 | const [source, connectionStatus] = useEventSource('/api/events'); |
| 71 | |
| 72 | const setConnectionStatus = useRemoteStore( |
| 73 | (state) => state.setConnectionStatus, |
| 74 | ); |
| 75 | useEffect(() => { |
| 76 | setConnectionStatus(connectionStatus); |
| 77 | }, [connectionStatus, setConnectionStatus]); |
| 78 | |
| 79 | useInitialSync(connectionStatus); |
| 80 | useSSESync(source); |
| 81 | |
| 82 | const queue = useRemoteStore((state) => state.queue); |
| 83 | const playback = useRemoteStore((state) => state.playback); |
| 84 | const settings = useRemoteStore((state) => state.settings); |
| 85 | const synced = useRemoteStore((state) => state.synced); |
| 86 | |
| 87 | useEffect(() => { |
| 88 | void i18n.changeLanguage(settings.language); |
| 89 | }, [settings.language]); |
| 90 | |
| 91 | useEffect(() => { |
| 92 | if (settings.dark) { |
| 93 | document.documentElement.setAttribute('data-theme', 'dark'); |
| 94 | } else { |
| 95 | document.documentElement.removeAttribute('data-theme'); |
| 96 | } |
| 97 | }, [settings.dark]); |
| 98 | |
| 99 | useEffect(() => { |
| 100 | setThemeId(settings.themeId); |
| 101 | }, [settings.themeId]); |
| 102 | |
| 103 | const current = deriveCurrentTrack(queue); |
| 104 | const playbackState = derivePlayback(playback); |
| 105 | |
| 106 | return { |
| 107 | connectionStatus, |
| 108 | synced, |
| 109 | currentTrack: current?.track, |
| 110 | isLoading: current?.isLoading ?? false, |
| 111 | ...playbackState, |
| 112 | settings, |
| 113 | queue: { |
| 114 | items: queue?.items ?? [], |
| 115 | currentItemId: queue?.items[queue.currentIndex]?.id, |
| 116 | }, |
| 117 | hasQueue: queue !== null && queue.items.length > 0, |
| 118 | }; |
| 119 | }; |
no test coverage detected