summaryrefslogtreecommitdiffhomepage
path: root/frontend/src/utilities
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/utilities')
-rw-r--r--frontend/src/utilities/async.ts78
-rw-r--r--frontend/src/utilities/constants.ts1
-rw-r--r--frontend/src/utilities/entity.ts63
-rw-r--r--frontend/src/utilities/env.ts6
-rw-r--r--frontend/src/utilities/index.ts12
-rw-r--r--frontend/src/utilities/languages.ts49
-rw-r--r--frontend/src/utilities/storage.ts17
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);
+}