diff options
Diffstat (limited to 'frontend/src/utilities')
-rw-r--r-- | frontend/src/utilities/async.ts | 78 | ||||
-rw-r--r-- | frontend/src/utilities/constants.ts | 1 | ||||
-rw-r--r-- | frontend/src/utilities/entity.ts | 63 | ||||
-rw-r--r-- | frontend/src/utilities/env.ts | 6 | ||||
-rw-r--r-- | frontend/src/utilities/index.ts | 12 | ||||
-rw-r--r-- | frontend/src/utilities/languages.ts | 49 | ||||
-rw-r--r-- | frontend/src/utilities/storage.ts | 17 |
7 files changed, 81 insertions, 145 deletions
diff --git a/frontend/src/utilities/async.ts b/frontend/src/utilities/async.ts deleted file mode 100644 index de363de32..000000000 --- a/frontend/src/utilities/async.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { difference, intersection, isString } from "lodash"; -import { useEffect, useMemo, useState } from "react"; -import { useEffectOnceWhen } from "rooks"; -import { useEntityIdByRange, useEntityToItem } from "./entity"; - -export async function waitFor(time: number) { - return new Promise((resolved) => { - setTimeout(resolved, time); - }); -} - -export function useNewEntityIds(entity: Async.Entity<any>) { - return useMemo(() => { - const dirtyEntities = entity.dirtyEntities; - const rawIds = entity.content.ids; - - const ids = rawIds.filter(isString); - - return difference(dirtyEntities, ids); - }, [entity.dirtyEntities, entity.content.ids]); -} - -export function useDirtyEntityIds( - entity: Async.Entity<any>, - start: number, - end: number -) { - const ids = useEntityIdByRange(entity.content, start, end); - - return useMemo(() => { - const dirtyIds = entity.dirtyEntities; - return intersection(ids, dirtyIds); - }, [ids, entity.dirtyEntities]); -} - -export function useEntityItemById<T>( - entity: Async.Entity<T>, - id: string -): Async.Item<T> { - const { content, dirtyEntities, didLoaded, error, state } = entity; - const item = useEntityToItem(content, id); - - const newState = useMemo<Async.State>(() => { - switch (state) { - case "loading": - return state; - default: - if (dirtyEntities.find((v) => v === id)) { - return "dirty"; - } else if (!didLoaded.find((v) => v === id)) { - return "uninitialized"; - } else { - return state; - } - } - }, [dirtyEntities, id, state, didLoaded]); - - return useMemo( - () => ({ content: item, state: newState, error }), - [error, newState, item] - ); -} - -export function useOnLoadedOnce(callback: () => void, entity: Async.Base<any>) { - const [didLoaded, setLoaded] = useState(false); - - const { state } = entity; - - const isLoaded = state !== "loading"; - - useEffect(() => { - if (!isLoaded) { - setLoaded(true); - } - }, [isLoaded]); - - useEffectOnceWhen(callback, didLoaded && isLoaded); -} diff --git a/frontend/src/utilities/constants.ts b/frontend/src/utilities/constants.ts new file mode 100644 index 000000000..6320fa4f3 --- /dev/null +++ b/frontend/src/utilities/constants.ts @@ -0,0 +1 @@ +export const GithubRepoRoot = "https://github.com/morpheus65535/bazarr"; diff --git a/frontend/src/utilities/entity.ts b/frontend/src/utilities/entity.ts deleted file mode 100644 index 8326b20ff..000000000 --- a/frontend/src/utilities/entity.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { isNull, isString } from "lodash"; -import { useMemo } from "react"; - -export function useIsEntityLoaded( - entity: EntityStruct<any>, - start: number, - end: number -): boolean { - return useMemo( - () => entity.ids.slice(start, end).filter(isNull).length === 0, - [entity.ids, start, end] - ); -} - -export function useEntityIdByRange( - entity: EntityStruct<any>, - start: number, - end: number -): string[] { - return useMemo(() => { - const ids = entity.ids; - return ids.slice(start, end).flatMap((v) => { - if (isString(v)) { - return [v]; - } else { - return []; - } - }); - }, [entity.ids, start, end]); -} - -export function useEntityByRange<T>( - entity: EntityStruct<T>, - start: number, - end: number -): T[] { - const filteredIds = useEntityIdByRange(entity, start, end); - const content = useMemo<T[]>(() => { - const entities = entity.entities; - return filteredIds.map((v) => entities[v]); - }, [entity.entities, filteredIds]); - return content; -} - -export function useEntityToList<T>(entity: EntityStruct<T>): T[] { - return useMemo( - () => entity.ids.filter(isString).map((v) => entity.entities[v]), - [entity] - ); -} - -export function useEntityToItem<T>( - entity: EntityStruct<T>, - id: string -): T | null { - return useMemo(() => { - if (id in entity.entities) { - return entity.entities[id]; - } else { - return null; - } - }, [entity.entities, id]); -} diff --git a/frontend/src/utilities/env.ts b/frontend/src/utilities/env.ts index 12a4f03e6..f21576a0b 100644 --- a/frontend/src/utilities/env.ts +++ b/frontend/src/utilities/env.ts @@ -42,4 +42,10 @@ export const Environment = { return url; } }, + get queryDev(): boolean { + if (isDevEnv) { + return process.env["REACT_APP_QUERY_DEV"] === "true"; + } + return false; + }, }; diff --git a/frontend/src/utilities/index.ts b/frontend/src/utilities/index.ts index 9b65c53f2..b84c5cf3d 100644 --- a/frontend/src/utilities/index.ts +++ b/frontend/src/utilities/index.ts @@ -25,7 +25,7 @@ export function submodProcessColor(s: string) { return `color(name=${s})`; } -export function GetItemId<T extends object>(item: T): number { +export function GetItemId<T extends object>(item: T): number | undefined { if (isMovie(item)) { return item.radarrId; } else if (isEpisode(item)) { @@ -33,7 +33,7 @@ export function GetItemId<T extends object>(item: T): number { } else if (isSeries(item)) { return item.sonarrSeriesId; } else { - return -1; + return undefined; } } @@ -67,8 +67,12 @@ export function filterSubtitleBy( } } -export * from "./async"; -export * from "./entity"; +export async function waitFor(time: number) { + return new Promise((resolved) => { + setTimeout(resolved, time); + }); +} + export * from "./env"; export * from "./hooks"; export * from "./validate"; diff --git a/frontend/src/utilities/languages.ts b/frontend/src/utilities/languages.ts new file mode 100644 index 000000000..7077da959 --- /dev/null +++ b/frontend/src/utilities/languages.ts @@ -0,0 +1,49 @@ +import { useLanguageProfiles, useLanguages } from "apis/hooks"; +import { useMemo } from "react"; + +export function useLanguageProfileBy(id: number | null | undefined) { + const { data } = useLanguageProfiles(); + return useMemo(() => data?.find((v) => v.profileId === id), [id, data]); +} + +export function useEnabledLanguages() { + const query = useLanguages(); + + const enabled = useMemo(() => { + const data = + query.data + ?.filter((v) => v.enabled) + .map((v) => ({ code2: v.code2, name: v.name })) ?? []; + + return { + ...query, + data, + }; + }, [query]); + + return enabled; +} + +export function useLanguageBy(code?: string) { + const { data } = useLanguages(); + return useMemo(() => data?.find((v) => v.code2 === code), [data, code]); +} + +// Convert languageprofile items to language +export function useProfileItemsToLanguages(profile?: Language.Profile) { + const { data } = useLanguages(); + + return useMemo( + () => + profile?.items.map<Language.Info>(({ language: code, hi, forced }) => { + const name = data?.find((v) => v.code2 === code)?.name ?? ""; + return { + hi: hi === "True", + forced: forced === "True", + code2: code, + name, + }; + }) ?? [], + [data, profile?.items] + ); +} diff --git a/frontend/src/utilities/storage.ts b/frontend/src/utilities/storage.ts new file mode 100644 index 000000000..1d7e39d97 --- /dev/null +++ b/frontend/src/utilities/storage.ts @@ -0,0 +1,17 @@ +import { useCallback } from "react"; +import { useLocalstorageState } from "rooks"; + +export const uiPageSizeKey = "storage-ui-pageSize"; + +export function useUpdateLocalStorage() { + return useCallback((newVals: LooseObject) => { + for (const key in newVals) { + const value = newVals[key]; + localStorage.setItem(key, value); + } + }, []); +} + +export function usePageSize() { + return useLocalstorageState(uiPageSizeKey, 50); +} |