import type { AuthState } from './authStoreTypes'; import { generateId } from './authStoreHelpers'; import { usePlayerStore } from './playerStore'; import { clearQueueServerForPlayback } from '../utils/playback/playbackServer'; import { resolveServerIdForIndexKey } from '../utils/server/serverLookup'; type SetState = ( partial: Partial | ((state: AuthState) => Partial), ) => void; /** * Server profile + connection lifecycle. `removeServer` is the * non-trivial one: when the active server is the one being removed it * also drops every per-server map entry tied to that id and switches * the active id to the next available server (or null) so the rest of * the app doesn't end up reading stale state. */ export function createServerProfileActions(set: SetState): Pick< AuthState, | 'addServer' | 'updateServer' | 'removeServer' | 'setServers' | 'setActiveServer' | 'setLoggedIn' | 'setConnecting' | 'setConnectionError' | 'logout' > { return { addServer: (profile) => { const id = generateId(); set(s => ({ servers: [...s.servers, { ...profile, id }] })); return id; }, updateServer: (id, data) => { set(s => ({ servers: s.servers.map(srv => srv.id === id ? { ...srv, ...data } : srv), })); }, removeServer: (id) => { // queueServerId is the canonical index key (B1); resolve the // canonical id back to a server UUID before comparing so a profile // delete still clears the matching queue binding. const queueSid = usePlayerStore.getState().queueServerId; if (queueSid && resolveServerIdForIndexKey(queueSid) === id) { clearQueueServerForPlayback(); } set(s => { const newServers = s.servers.filter(srv => srv.id !== id); const switchedAway = s.activeServerId === id; const { [id]: _r, ...entityRatingRest } = s.entityRatingSupportByServer; const { [id]: _a, ...audiomuseRest } = s.audiomuseNavidromeByServer; const { [id]: _idn, ...identityRest } = s.subsonicServerIdentityByServer; const { [id]: _iss, ...issueRest } = s.audiomuseNavidromeIssueByServer; const { [id]: _pr, ...probeRest } = s.instantMixProbeByServer; return { servers: newServers, activeServerId: switchedAway ? (newServers[0]?.id ?? null) : s.activeServerId, isLoggedIn: switchedAway ? false : s.isLoggedIn, entityRatingSupportByServer: entityRatingRest, audiomuseNavidromeByServer: audiomuseRest, subsonicServerIdentityByServer: identityRest, audiomuseNavidromeIssueByServer: issueRest, instantMixProbeByServer: probeRest, }; }); }, setServers: (servers) => set({ servers }), setActiveServer: (id) => set({ activeServerId: id, musicFolders: [] }), setLoggedIn: (v) => set({ isLoggedIn: v }), setConnecting: (v) => set({ isConnecting: v }), setConnectionError: (e) => set({ connectionError: e }), logout: () => set({ isLoggedIn: false, musicFolders: [] }), }; }