zustand stores
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import { create } from 'zustand'
|
||||
import { createJSONStorage, persist } from 'zustand/middleware'
|
||||
import { sensitiveStorage } from '../lib/sensitive-storage'
|
||||
|
||||
/**
|
||||
* Connection details for a Sonarr / Radarr instance. The user can have
|
||||
* up to two of each: a "default" tier (1080p, regular library) and a
|
||||
* "4K" tier (separate root folder + quality profile). Many users keep
|
||||
* 4K and 1080p in separate libraries to avoid Jellyfin transcoding 4K
|
||||
* down to 1080p on weak clients.
|
||||
*/
|
||||
export interface ArrInstance {
|
||||
id: string
|
||||
kind: 'sonarr' | 'radarr'
|
||||
/** Display name shown in the request modal and Settings. */
|
||||
name: string
|
||||
baseUrl: string
|
||||
apiKey: string
|
||||
/** Distinguishes the regular tier from the 4K tier of the same kind. */
|
||||
tier: 'default' | '4k'
|
||||
/** Defaults the request modal pre-selects unless an override rule
|
||||
* fires or the user picks something else. */
|
||||
defaultQualityProfileId?: number
|
||||
defaultRootFolder?: string
|
||||
defaultLanguageProfileId?: number
|
||||
/** Sonarr-only: monitor flag + season-folder layout the requester gets. */
|
||||
defaultMonitored?: boolean
|
||||
defaultSeasonFolder?: boolean
|
||||
/** Optional connection-test verdict, refreshed when settings page tests it. */
|
||||
lastTestedAt?: string
|
||||
lastTestVersion?: string
|
||||
lastTestError?: string
|
||||
}
|
||||
|
||||
interface State {
|
||||
instances: ArrInstance[]
|
||||
upsert: (instance: ArrInstance) => void
|
||||
remove: (id: string) => void
|
||||
/** Convenience: find the instance matching kind + tier, or null. */
|
||||
pick: (kind: 'sonarr' | 'radarr', tier: 'default' | '4k') => ArrInstance | null
|
||||
}
|
||||
|
||||
function uid() {
|
||||
return 'arr_' + Math.random().toString(36).slice(2, 10) + Date.now().toString(36)
|
||||
}
|
||||
|
||||
export const useArrInstances = create<State>()(
|
||||
persist(
|
||||
(set, get) => ({
|
||||
instances: [],
|
||||
upsert: instance =>
|
||||
set(s => {
|
||||
const exists = s.instances.some(x => x.id === instance.id)
|
||||
if (exists) {
|
||||
return {
|
||||
instances: s.instances.map(x => (x.id === instance.id ? instance : x)),
|
||||
}
|
||||
}
|
||||
return { instances: [...s.instances, instance] }
|
||||
}),
|
||||
remove: id => set(s => ({ instances: s.instances.filter(x => x.id !== id) })),
|
||||
pick: (kind, tier) =>
|
||||
get().instances.find(x => x.kind === kind && x.tier === tier) || null,
|
||||
}),
|
||||
{ name: 'arr-instances-v1', storage: createJSONStorage(() => sensitiveStorage) },
|
||||
),
|
||||
)
|
||||
|
||||
export function newArrInstance(kind: 'sonarr' | 'radarr', tier: 'default' | '4k'): ArrInstance {
|
||||
return {
|
||||
id: uid(),
|
||||
kind,
|
||||
tier,
|
||||
name: `${kind === 'sonarr' ? 'Sonarr' : 'Radarr'}${tier === '4k' ? ' 4K' : ''}`,
|
||||
baseUrl: '',
|
||||
apiKey: '',
|
||||
defaultMonitored: true,
|
||||
defaultSeasonFolder: true,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user