mirror of https://github.com/morpheus65535/bazarr
wip
This commit is contained in:
parent
512d97672d
commit
55da60ad2d
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { readFile } from "fs/promises";
|
||||
import { get } from "lodash";
|
||||
import YAML from "yaml";
|
||||
import { parse } from "yaml";
|
||||
|
||||
class ConfigReader {
|
||||
config: object;
|
||||
|
@ -15,7 +15,7 @@ class ConfigReader {
|
|||
async open(path: string) {
|
||||
try {
|
||||
const rawConfig = await readFile(path, "utf8");
|
||||
this.config = YAML.parse(rawConfig);
|
||||
this.config = parse(rawConfig);
|
||||
} catch (err) {
|
||||
// We don't want to catch the error here, handle it on getValue method
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ export default async function overrideEnv(env: Record<string, string>) {
|
|||
process.env["VITE_API_KEY"] = apiKey;
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`No API key found, please run the backend first, (error: ${err.message})`
|
||||
`No API key found, please run the backend first, (error: ${err.message})`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ export default async function overrideEnv(env: Record<string, string>) {
|
|||
process.env["VITE_PROXY_URL"] = url;
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`No proxy url found, please run the backend first, (error: ${err.message})`
|
||||
`No proxy url found, please run the backend first, (error: ${err.message})`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Bazarr</title>
|
||||
|
|
|
@ -84,7 +84,7 @@ function useIsActive(parent: string, route: RouteObject) {
|
|||
|
||||
const paths = useMemo(
|
||||
() => [root, ...(children?.map((v) => pathJoin(root, v.path ?? "")) ?? [])],
|
||||
[root, children]
|
||||
[root, children],
|
||||
);
|
||||
|
||||
const selection = useSelection().selection;
|
||||
|
@ -92,7 +92,7 @@ function useIsActive(parent: string, route: RouteObject) {
|
|||
() =>
|
||||
selection?.includes(root) ||
|
||||
paths.some((path) => matchPath(path, pathname)),
|
||||
[pathname, paths, root, selection]
|
||||
[pathname, paths, root, selection],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -338,7 +338,7 @@ const NavbarItem: FunctionComponent<NavbarItemProps> = ({
|
|||
clsx(classes.anchor, {
|
||||
[classes.active]: isActive,
|
||||
[classes.hover]: hovered,
|
||||
})
|
||||
}),
|
||||
)
|
||||
}
|
||||
>
|
||||
|
|
|
@ -40,8 +40,8 @@ const App: FunctionComponent = () => {
|
|||
showNotification(
|
||||
notification.info(
|
||||
"Update available",
|
||||
"A new version of Bazarr is ready, restart is required"
|
||||
)
|
||||
"A new version of Bazarr is ready, restart is required",
|
||||
),
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
|
|
|
@ -309,7 +309,7 @@ function useRoutes(): CustomRouteObject[] {
|
|||
data?.announcements,
|
||||
radarr,
|
||||
sonarr,
|
||||
]
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -321,7 +321,7 @@ export const Router: FunctionComponent = () => {
|
|||
// TODO: Move this outside the function component scope
|
||||
const router = useMemo(
|
||||
() => createBrowserRouter(routes, { basename: Environment.baseUrl }),
|
||||
[routes]
|
||||
[routes],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -19,7 +19,7 @@ const cacheEpisodes = (client: QueryClient, episodes: Item.Episode[]) => {
|
|||
QueryKeys.Episodes,
|
||||
item.sonarrEpisodeId,
|
||||
],
|
||||
item
|
||||
item,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ export function useEpisodesByIds(ids: number[]) {
|
|||
onSuccess: (data) => {
|
||||
cacheEpisodes(client, data);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -46,20 +46,20 @@ export function useEpisodesBySeriesId(id: number) {
|
|||
onSuccess: (data) => {
|
||||
cacheEpisodes(client, data);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function useEpisodeWantedPagination() {
|
||||
return usePaginationQuery([QueryKeys.Series, QueryKeys.Wanted], (param) =>
|
||||
api.episodes.wanted(param)
|
||||
api.episodes.wanted(param),
|
||||
);
|
||||
}
|
||||
|
||||
export function useEpisodeBlacklist() {
|
||||
return useQuery(
|
||||
[QueryKeys.Series, QueryKeys.Episodes, QueryKeys.Blacklist],
|
||||
() => api.episodes.blacklist()
|
||||
() => api.episodes.blacklist(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ export function useEpisodeAddBlacklist() {
|
|||
]);
|
||||
client.invalidateQueries([QueryKeys.Series, seriesId]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ export function useEpisodeDeleteBlacklist() {
|
|||
QueryKeys.Blacklist,
|
||||
]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ export function useEpisodeHistoryPagination() {
|
|||
return usePaginationQuery(
|
||||
[QueryKeys.Series, QueryKeys.Episodes, QueryKeys.History],
|
||||
(param) => api.episodes.history(param),
|
||||
false
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -121,6 +121,6 @@ export function useEpisodeHistory(episodeId?: number) {
|
|||
if (episodeId) {
|
||||
return api.episodes.historyBy(episodeId);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ export function useHistoryStats(
|
|||
time: History.TimeFrameOptions,
|
||||
action: History.ActionOptions | null,
|
||||
provider: System.Provider | null,
|
||||
language: Language.Info | null
|
||||
language: Language.Info | null,
|
||||
) {
|
||||
return useQuery(
|
||||
[QueryKeys.System, QueryKeys.History, { time, action, provider, language }],
|
||||
|
@ -15,7 +15,7 @@ export function useHistoryStats(
|
|||
time,
|
||||
action ?? undefined,
|
||||
provider?.name,
|
||||
language?.code2
|
||||
)
|
||||
language?.code2,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ export function useLanguages(history?: boolean) {
|
|||
() => api.system.languages(history),
|
||||
{
|
||||
staleTime: Infinity,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,6 @@ export function useLanguageProfiles() {
|
|||
() => api.system.languagesProfileList(),
|
||||
{
|
||||
staleTime: Infinity,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -39,13 +39,13 @@ export function useMovies() {
|
|||
onSuccess: (data) => {
|
||||
cacheMovies(client, data);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function useMoviesPagination() {
|
||||
return usePaginationQuery([QueryKeys.Movies], (param) =>
|
||||
api.movies.moviesBy(param)
|
||||
api.movies.moviesBy(param),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ export function useMovieModification() {
|
|||
// TODO: query less
|
||||
client.invalidateQueries([QueryKeys.Movies]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -75,19 +75,19 @@ export function useMovieAction() {
|
|||
onSuccess: () => {
|
||||
client.invalidateQueries([QueryKeys.Movies]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function useMovieWantedPagination() {
|
||||
return usePaginationQuery([QueryKeys.Movies, QueryKeys.Wanted], (param) =>
|
||||
api.movies.wanted(param)
|
||||
api.movies.wanted(param),
|
||||
);
|
||||
}
|
||||
|
||||
export function useMovieBlacklist() {
|
||||
return useQuery([QueryKeys.Movies, QueryKeys.Blacklist], () =>
|
||||
api.movies.blacklist()
|
||||
api.movies.blacklist(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ export function useMovieAddBlacklist() {
|
|||
client.invalidateQueries([QueryKeys.Movies, QueryKeys.Blacklist]);
|
||||
client.invalidateQueries([QueryKeys.Movies, id]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ export function useMovieDeleteBlacklist() {
|
|||
onSuccess: (_, param) => {
|
||||
client.invalidateQueries([QueryKeys.Movies, QueryKeys.Blacklist]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ export function useMovieHistoryPagination() {
|
|||
return usePaginationQuery(
|
||||
[QueryKeys.Movies, QueryKeys.History],
|
||||
(param) => api.movies.history(param),
|
||||
false
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import api from "../raw";
|
|||
export function useSystemProviders(history?: boolean) {
|
||||
return useQuery(
|
||||
[QueryKeys.System, QueryKeys.Providers, history ?? false],
|
||||
() => api.providers.providers(history)
|
||||
() => api.providers.providers(history),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ export function useMoviesProvider(radarrId?: number) {
|
|||
},
|
||||
{
|
||||
staleTime: 0,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ export function useEpisodesProvider(episodeId?: number) {
|
|||
},
|
||||
{
|
||||
staleTime: 0,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ export function useResetProvider() {
|
|||
onSuccess: () => {
|
||||
client.invalidateQueries([QueryKeys.System, QueryKeys.Providers]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -68,13 +68,13 @@ export function useDownloadEpisodeSubtitles() {
|
|||
api.providers.downloadEpisodeSubtitle(
|
||||
param.seriesId,
|
||||
param.episodeId,
|
||||
param.form
|
||||
param.form,
|
||||
),
|
||||
{
|
||||
onSuccess: (_, param) => {
|
||||
client.invalidateQueries([QueryKeys.Series, param.seriesId]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,6 @@ export function useDownloadMovieSubtitles() {
|
|||
onSuccess: (_, param) => {
|
||||
client.invalidateQueries([QueryKeys.Movies, param.radarrId]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -39,13 +39,13 @@ export function useSeries() {
|
|||
onSuccess: (data) => {
|
||||
cacheSeries(client, data);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function useSeriesPagination() {
|
||||
return usePaginationQuery([QueryKeys.Series], (param) =>
|
||||
api.series.seriesBy(param)
|
||||
api.series.seriesBy(param),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ export function useSeriesModification() {
|
|||
});
|
||||
client.invalidateQueries([QueryKeys.Series]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,6 @@ export function useSeriesAction() {
|
|||
onSuccess: () => {
|
||||
client.invalidateQueries([QueryKeys.Series]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ export function useSubtitleAction() {
|
|||
client.invalidateQueries([QueryKeys.Movies, id]);
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -42,13 +42,13 @@ export function useEpisodeSubtitleModification() {
|
|||
api.episodes.downloadSubtitles(
|
||||
param.seriesId,
|
||||
param.episodeId,
|
||||
param.form
|
||||
param.form,
|
||||
),
|
||||
{
|
||||
onSuccess: (_, param) => {
|
||||
client.invalidateQueries([QueryKeys.Series, param.seriesId]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const remove = useMutation(
|
||||
|
@ -59,7 +59,7 @@ export function useEpisodeSubtitleModification() {
|
|||
onSuccess: (_, param) => {
|
||||
client.invalidateQueries([QueryKeys.Series, param.seriesId]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const upload = useMutation(
|
||||
|
@ -70,7 +70,7 @@ export function useEpisodeSubtitleModification() {
|
|||
onSuccess: (_, { seriesId }) => {
|
||||
client.invalidateQueries([QueryKeys.Series, seriesId]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return { download, remove, upload };
|
||||
|
@ -92,7 +92,7 @@ export function useMovieSubtitleModification() {
|
|||
onSuccess: (_, param) => {
|
||||
client.invalidateQueries([QueryKeys.Movies, param.radarrId]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const remove = useMutation(
|
||||
|
@ -103,7 +103,7 @@ export function useMovieSubtitleModification() {
|
|||
onSuccess: (_, param) => {
|
||||
client.invalidateQueries([QueryKeys.Movies, param.radarrId]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const upload = useMutation(
|
||||
|
@ -114,7 +114,7 @@ export function useMovieSubtitleModification() {
|
|||
onSuccess: (_, { radarrId }) => {
|
||||
client.invalidateQueries([QueryKeys.Movies, radarrId]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return { download, remove, upload };
|
||||
|
@ -122,30 +122,30 @@ export function useMovieSubtitleModification() {
|
|||
|
||||
export function useSubtitleInfos(names: string[]) {
|
||||
return useQuery([QueryKeys.Subtitles, QueryKeys.Infos, names], () =>
|
||||
api.subtitles.info(names)
|
||||
api.subtitles.info(names),
|
||||
);
|
||||
}
|
||||
|
||||
export function useRefTracksByEpisodeId(
|
||||
subtitlesPath: string,
|
||||
sonarrEpisodeId: number,
|
||||
isEpisode: boolean
|
||||
isEpisode: boolean,
|
||||
) {
|
||||
return useQuery(
|
||||
[QueryKeys.Episodes, sonarrEpisodeId, QueryKeys.Subtitles, subtitlesPath],
|
||||
() => api.subtitles.getRefTracksByEpisodeId(subtitlesPath, sonarrEpisodeId),
|
||||
{ enabled: isEpisode }
|
||||
{ enabled: isEpisode },
|
||||
);
|
||||
}
|
||||
|
||||
export function useRefTracksByMovieId(
|
||||
subtitlesPath: string,
|
||||
radarrMovieId: number,
|
||||
isMovie: boolean
|
||||
isMovie: boolean,
|
||||
) {
|
||||
return useQuery(
|
||||
[QueryKeys.Movies, radarrMovieId, QueryKeys.Subtitles, subtitlesPath],
|
||||
() => api.subtitles.getRefTracksByMovieId(subtitlesPath, radarrMovieId),
|
||||
{ enabled: isMovie }
|
||||
{ enabled: isMovie },
|
||||
);
|
||||
}
|
||||
|
|
|
@ -13,14 +13,14 @@ export function useBadges() {
|
|||
refetchOnWindowFocus: "always",
|
||||
refetchInterval: 1000 * 60,
|
||||
staleTime: 1000 * 10,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function useFileSystem(
|
||||
type: "bazarr" | "sonarr" | "radarr",
|
||||
path: string,
|
||||
enabled: boolean
|
||||
enabled: boolean,
|
||||
) {
|
||||
return useQuery(
|
||||
[QueryKeys.FileSystem, type, path],
|
||||
|
@ -35,7 +35,7 @@ export function useFileSystem(
|
|||
},
|
||||
{
|
||||
enabled,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ export function useSystemSettings() {
|
|||
() => api.system.settings(),
|
||||
{
|
||||
staleTime: Infinity,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ export function useSettingsMutation() {
|
|||
client.invalidateQueries([QueryKeys.Wanted]);
|
||||
client.invalidateQueries([QueryKeys.Badges]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ export function useServerSearch(query: string, enabled: boolean) {
|
|||
() => api.system.search(query),
|
||||
{
|
||||
enabled,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ export function useDeleteLogs() {
|
|||
onSuccess: () => {
|
||||
client.invalidateQueries([QueryKeys.System, QueryKeys.Logs]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ export function useSystemAnnouncements() {
|
|||
refetchOnWindowFocus: "always",
|
||||
refetchInterval: 1000 * 60,
|
||||
staleTime: 1000 * 10,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ export function useSystemAnnouncementsAddDismiss() {
|
|||
client.invalidateQueries([QueryKeys.System, QueryKeys.Announcements]);
|
||||
client.invalidateQueries([QueryKeys.System, QueryKeys.Badges]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ export function useSystemTasks() {
|
|||
refetchOnWindowFocus: "always",
|
||||
refetchInterval: 1000 * 60,
|
||||
staleTime: 1000 * 10,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ export function useRunTask() {
|
|||
client.invalidateQueries([QueryKeys.System, QueryKeys.Tasks]);
|
||||
client.invalidateQueries([QueryKeys.System, QueryKeys.Backups]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ export function useCreateBackups() {
|
|||
onSuccess: () => {
|
||||
client.invalidateQueries([QueryKeys.System, QueryKeys.Backups]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ export function useRestoreBackups() {
|
|||
onSuccess: () => {
|
||||
client.invalidateQueries([QueryKeys.System, QueryKeys.Backups]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ export function useDeleteBackups() {
|
|||
onSuccess: () => {
|
||||
client.invalidateQueries([QueryKeys.System, QueryKeys.Backups]);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ export function useSystem() {
|
|||
setAuthenticated(false);
|
||||
client.clear();
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const { mutate: login, isLoading: isLoggingIn } = useMutation(
|
||||
|
@ -230,7 +230,7 @@ export function useSystem() {
|
|||
// TODO: Hard-coded value
|
||||
window.location.replace(Environment.baseUrl);
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const { mutate: shutdown, isLoading: isShuttingDown } = useMutation(
|
||||
|
@ -240,7 +240,7 @@ export function useSystem() {
|
|||
onSuccess: () => {
|
||||
client.clear();
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const { mutate: restart, isLoading: isRestarting } = useMutation(
|
||||
|
@ -250,7 +250,7 @@ export function useSystem() {
|
|||
onSuccess: () => {
|
||||
client.clear();
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return useMemo(
|
||||
|
@ -270,6 +270,6 @@ export function useSystem() {
|
|||
logout,
|
||||
restart,
|
||||
shutdown,
|
||||
]
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ export type UsePaginationQueryResult<T extends object> = UseQueryResult<
|
|||
|
||||
export function usePaginationQuery<
|
||||
TObject extends object = object,
|
||||
TQueryKey extends QueryKey = QueryKey
|
||||
TQueryKey extends QueryKey = QueryKey,
|
||||
>(
|
||||
queryKey: TQueryKey,
|
||||
queryFn: RangeQuery<TObject>,
|
||||
cacheIndividual = true
|
||||
cacheIndividual = true,
|
||||
): UsePaginationQueryResult<TObject> {
|
||||
const client = useQueryClient();
|
||||
|
||||
|
@ -59,7 +59,7 @@ export function usePaginationQuery<
|
|||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const { data } = results;
|
||||
|
@ -73,7 +73,7 @@ export function usePaginationQuery<
|
|||
setIndex(idx);
|
||||
}
|
||||
},
|
||||
[pageCount]
|
||||
[pageCount],
|
||||
);
|
||||
|
||||
const [isPageLoading, setIsPageLoading] = useState(false);
|
||||
|
|
|
@ -64,7 +64,7 @@ class BazarrClient {
|
|||
(error: AxiosError) => {
|
||||
const message = GetErrorMessage(
|
||||
error.response?.data,
|
||||
"You have disconnected from the server"
|
||||
"You have disconnected from the server",
|
||||
);
|
||||
|
||||
const backendError: BackendError = {
|
||||
|
@ -76,7 +76,7 @@ class BazarrClient {
|
|||
this.handleError(backendError);
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class EpisodeApi extends BaseApi {
|
|||
async wanted(params: Parameter.Range) {
|
||||
const response = await this.get<DataWrapperWithTotal<Wanted.Episode>>(
|
||||
"/wanted",
|
||||
params
|
||||
params,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ class EpisodeApi extends BaseApi {
|
|||
async wantedBy(episodeid: number[]) {
|
||||
const response = await this.get<DataWrapperWithTotal<Wanted.Episode>>(
|
||||
"/wanted",
|
||||
{ episodeid }
|
||||
{ episodeid },
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ class EpisodeApi extends BaseApi {
|
|||
async history(params: Parameter.Range) {
|
||||
const response = await this.get<DataWrapperWithTotal<History.Episode>>(
|
||||
"/history",
|
||||
params
|
||||
params,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class EpisodeApi extends BaseApi {
|
|||
async historyBy(episodeid: number) {
|
||||
const response = await this.get<DataWrapperWithTotal<History.Episode>>(
|
||||
"/history",
|
||||
{ episodeid }
|
||||
{ episodeid },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class EpisodeApi extends BaseApi {
|
|||
async downloadSubtitles(
|
||||
seriesid: number,
|
||||
episodeid: number,
|
||||
form: FormType.Subtitle
|
||||
form: FormType.Subtitle,
|
||||
) {
|
||||
await this.patch("/subtitles", form, { seriesid, episodeid });
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ class EpisodeApi extends BaseApi {
|
|||
async uploadSubtitles(
|
||||
seriesid: number,
|
||||
episodeid: number,
|
||||
form: FormType.UploadSubtitle
|
||||
form: FormType.UploadSubtitle,
|
||||
) {
|
||||
await this.post("/subtitles", form, { seriesid, episodeid });
|
||||
}
|
||||
|
@ -70,22 +70,21 @@ class EpisodeApi extends BaseApi {
|
|||
async deleteSubtitles(
|
||||
seriesid: number,
|
||||
episodeid: number,
|
||||
form: FormType.DeleteSubtitle
|
||||
form: FormType.DeleteSubtitle,
|
||||
) {
|
||||
await this.delete("/subtitles", form, { seriesid, episodeid });
|
||||
}
|
||||
|
||||
async blacklist() {
|
||||
const response = await this.get<DataWrapper<Blacklist.Episode[]>>(
|
||||
"/blacklist"
|
||||
);
|
||||
const response =
|
||||
await this.get<DataWrapper<Blacklist.Episode[]>>("/blacklist");
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async addBlacklist(
|
||||
seriesid: number,
|
||||
episodeid: number,
|
||||
form: FormType.AddBlacklist
|
||||
form: FormType.AddBlacklist,
|
||||
) {
|
||||
await this.post("/blacklist", form, { seriesid, episodeid });
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ class HistoryApi extends BaseApi {
|
|||
timeFrame?: History.TimeFrameOptions,
|
||||
action?: History.ActionOptions,
|
||||
provider?: string,
|
||||
language?: Language.CodeType
|
||||
language?: Language.CodeType,
|
||||
) {
|
||||
const response = await this.get<History.Stat>("/stats", {
|
||||
timeFrame,
|
||||
|
|
|
@ -6,9 +6,8 @@ class MovieApi extends BaseApi {
|
|||
}
|
||||
|
||||
async blacklist() {
|
||||
const response = await this.get<DataWrapper<Blacklist.Movie[]>>(
|
||||
"/blacklist"
|
||||
);
|
||||
const response =
|
||||
await this.get<DataWrapper<Blacklist.Movie[]>>("/blacklist");
|
||||
return response.data;
|
||||
}
|
||||
|
||||
|
@ -30,7 +29,7 @@ class MovieApi extends BaseApi {
|
|||
async moviesBy(params: Parameter.Range) {
|
||||
const response = await this.get<DataWrapperWithTotal<Item.Movie>>(
|
||||
"",
|
||||
params
|
||||
params,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
@ -42,7 +41,7 @@ class MovieApi extends BaseApi {
|
|||
async wanted(params: Parameter.Range) {
|
||||
const response = await this.get<DataWrapperWithTotal<Wanted.Movie>>(
|
||||
"/wanted",
|
||||
params
|
||||
params,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
@ -52,7 +51,7 @@ class MovieApi extends BaseApi {
|
|||
"/wanted",
|
||||
{
|
||||
radarrid,
|
||||
}
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
@ -60,7 +59,7 @@ class MovieApi extends BaseApi {
|
|||
async history(params: Parameter.Range) {
|
||||
const response = await this.get<DataWrapperWithTotal<History.Movie>>(
|
||||
"/history",
|
||||
params
|
||||
params,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
@ -68,7 +67,7 @@ class MovieApi extends BaseApi {
|
|||
async historyBy(radarrid: number) {
|
||||
const response = await this.get<DataWrapperWithTotal<History.Movie>>(
|
||||
"/history",
|
||||
{ radarrid }
|
||||
{ radarrid },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class ProviderApi extends BaseApi {
|
|||
async movies(id: number) {
|
||||
const response = await this.get<DataWrapper<SearchResultType[]>>(
|
||||
"/movies",
|
||||
{ radarrid: id }
|
||||
{ radarrid: id },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ class ProviderApi extends BaseApi {
|
|||
"/episodes",
|
||||
{
|
||||
episodeid,
|
||||
}
|
||||
},
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ class ProviderApi extends BaseApi {
|
|||
async downloadEpisodeSubtitle(
|
||||
seriesid: number,
|
||||
episodeid: number,
|
||||
form: FormType.ManualDownload
|
||||
form: FormType.ManualDownload,
|
||||
) {
|
||||
await this.post("/episodes", form, { seriesid, episodeid });
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ class SeriesApi extends BaseApi {
|
|||
async seriesBy(params: Parameter.Range) {
|
||||
const response = await this.get<DataWrapperWithTotal<Item.Series>>(
|
||||
"",
|
||||
params
|
||||
params,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ class SubtitlesApi extends BaseApi {
|
|||
|
||||
async getRefTracksByEpisodeId(
|
||||
subtitlesPath: string,
|
||||
sonarrEpisodeId: number
|
||||
sonarrEpisodeId: number,
|
||||
) {
|
||||
const response = await this.get<DataWrapper<Item.RefTracks>>("", {
|
||||
subtitlesPath,
|
||||
|
@ -18,7 +18,7 @@ class SubtitlesApi extends BaseApi {
|
|||
|
||||
async getRefTracksByMovieId(
|
||||
subtitlesPath: string,
|
||||
radarrMovieId?: number | undefined
|
||||
radarrMovieId?: number | undefined,
|
||||
) {
|
||||
const response = await this.get<DataWrapper<Item.RefTracks>>("", {
|
||||
subtitlesPath,
|
||||
|
|
|
@ -88,9 +88,8 @@ class SystemApi extends BaseApi {
|
|||
}
|
||||
|
||||
async announcements() {
|
||||
const response = await this.get<DataWrapper<System.Announcements[]>>(
|
||||
"/announcements"
|
||||
);
|
||||
const response =
|
||||
await this.get<DataWrapper<System.Announcements[]>>("/announcements");
|
||||
return response.data;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ class RequestUtils {
|
|||
try {
|
||||
const result = await client.axios.get<UrlTestResponse>(
|
||||
`../test/${protocol}/${url}api/system/status`,
|
||||
{ params }
|
||||
{ params },
|
||||
);
|
||||
const { data } = result;
|
||||
if (data.status && data.version) {
|
||||
|
@ -26,7 +26,7 @@ class RequestUtils {
|
|||
} catch (e) {
|
||||
const result = await client.axios.get<UrlTestResponse>(
|
||||
`../test/${protocol}/${url}api/v3/system/status`,
|
||||
{ params }
|
||||
{ params },
|
||||
);
|
||||
return result.data;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ function useSearch(query: string) {
|
|||
link,
|
||||
};
|
||||
}) ?? [],
|
||||
[data]
|
||||
[data],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ const ResultComponent = forwardRef<HTMLDivElement, ResultCompProps>(
|
|||
{value}
|
||||
</Anchor>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const Search: FunctionComponent = () => {
|
||||
|
|
|
@ -100,7 +100,7 @@ export function useTools() {
|
|||
modal: TranslationModal,
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ const SubtitleToolsMenu: FunctionComponent<Props> = ({
|
|||
task.create(s.path, name, mutateAsync, { action, form });
|
||||
});
|
||||
},
|
||||
[mutateAsync, selections]
|
||||
[mutateAsync, selections],
|
||||
);
|
||||
|
||||
const tools = useTools();
|
||||
|
|
|
@ -53,7 +53,7 @@ describe("Language text", () => {
|
|||
|
||||
it("should show long text with Forced", () => {
|
||||
rawRender(
|
||||
<Language.Text value={testLanguageWithForced} long></Language.Text>
|
||||
<Language.Text value={testLanguageWithForced} long></Language.Text>,
|
||||
);
|
||||
|
||||
const expectedText = `${testLanguageWithHi.name} Forced`;
|
||||
|
|
|
@ -14,7 +14,7 @@ const LanguageProfileName: FunctionComponent<Props> = ({
|
|||
|
||||
const name = useMemo(
|
||||
() => data?.find((v) => v.profileId === index)?.name ?? empty,
|
||||
[data, empty, index]
|
||||
[data, empty, index],
|
||||
);
|
||||
|
||||
return <>{name}</>;
|
||||
|
|
|
@ -25,7 +25,7 @@ const LanguageSelector: FunctionComponent<LanguageSelectorProps> = ({
|
|||
const options = useSelectorOptions(
|
||||
filteredData ?? [],
|
||||
(value) => value.name,
|
||||
(value) => value.code3
|
||||
(value) => value.code3,
|
||||
);
|
||||
|
||||
return <Selector {...options} searchable {...selector}></Selector>;
|
||||
|
|
|
@ -96,7 +96,7 @@ const ColorToolForm: FunctionComponent<Props> = ({ selections, onSubmit }) => {
|
|||
validate: {
|
||||
color: FormUtils.validation(
|
||||
(value) => colorOptions.find((op) => op.value === value) !== undefined,
|
||||
"Must select a color"
|
||||
"Must select a color",
|
||||
),
|
||||
},
|
||||
});
|
||||
|
@ -110,7 +110,7 @@ const ColorToolForm: FunctionComponent<Props> = ({ selections, onSubmit }) => {
|
|||
task.create(s.path, TaskName, mutateAsync, {
|
||||
action,
|
||||
form: s,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
onSubmit?.();
|
||||
|
|
|
@ -29,11 +29,11 @@ const FrameRateForm: FunctionComponent<Props> = ({ selections, onSubmit }) => {
|
|||
validate: {
|
||||
from: FormUtils.validation(
|
||||
(value) => value > 0,
|
||||
"The From value must be larger than 0"
|
||||
"The From value must be larger than 0",
|
||||
),
|
||||
to: FormUtils.validation(
|
||||
(value) => value > 0,
|
||||
"The To value must be larger than 0"
|
||||
"The To value must be larger than 0",
|
||||
),
|
||||
},
|
||||
});
|
||||
|
@ -47,7 +47,7 @@ const FrameRateForm: FunctionComponent<Props> = ({ selections, onSubmit }) => {
|
|||
task.create(s.path, TaskName, mutateAsync, {
|
||||
action,
|
||||
form: s,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
onSubmit?.();
|
||||
|
|
|
@ -27,12 +27,12 @@ const ItemEditForm: FunctionComponent<Props> = ({
|
|||
const profileOptions = useSelectorOptions(
|
||||
data ?? [],
|
||||
(v) => v.name ?? "Unknown",
|
||||
(v) => v.profileId.toString() ?? "-1"
|
||||
(v) => v.profileId.toString() ?? "-1",
|
||||
);
|
||||
|
||||
const profile = useMemo(
|
||||
() => data?.find((v) => v.profileId === item?.profileId) ?? null,
|
||||
[data, item?.profileId]
|
||||
[data, item?.profileId],
|
||||
);
|
||||
|
||||
const form = useForm({
|
||||
|
@ -44,7 +44,7 @@ const ItemEditForm: FunctionComponent<Props> = ({
|
|||
const options = useSelectorOptions(
|
||||
item?.audio_language ?? [],
|
||||
(v) => v.name,
|
||||
(v) => v.code2
|
||||
(v) => v.code2,
|
||||
);
|
||||
|
||||
const isOverlayVisible = isLoading || isFetching || item === null;
|
||||
|
|
|
@ -47,7 +47,7 @@ type SubtitleValidateResult = {
|
|||
|
||||
const validator = (
|
||||
movie: Item.Movie,
|
||||
file: SubtitleFile
|
||||
file: SubtitleFile,
|
||||
): SubtitleValidateResult => {
|
||||
if (file.language === null) {
|
||||
return {
|
||||
|
@ -57,7 +57,7 @@ const validator = (
|
|||
} else {
|
||||
const { subtitles } = movie;
|
||||
const existing = subtitles.find(
|
||||
(v) => v.code2 === file.language?.code2 && isString(v.path)
|
||||
(v) => v.code2 === file.language?.code2 && isString(v.path),
|
||||
);
|
||||
if (existing !== undefined) {
|
||||
return {
|
||||
|
@ -91,12 +91,12 @@ const MovieUploadForm: FunctionComponent<Props> = ({
|
|||
const languageOptions = useSelectorOptions(
|
||||
languages,
|
||||
(v) => v.name,
|
||||
(v) => v.code2
|
||||
(v) => v.code2,
|
||||
);
|
||||
|
||||
const defaultLanguage = useMemo(
|
||||
() => (languages.length > 0 ? languages[0] : null),
|
||||
[languages]
|
||||
[languages],
|
||||
);
|
||||
|
||||
const form = useForm({
|
||||
|
@ -120,7 +120,7 @@ const MovieUploadForm: FunctionComponent<Props> = ({
|
|||
(v) =>
|
||||
v.language === null ||
|
||||
v.validateResult === undefined ||
|
||||
v.validateResult.state === "error"
|
||||
v.validateResult.state === "error",
|
||||
) === undefined
|
||||
);
|
||||
}, "Some files cannot be uploaded, please check"),
|
||||
|
@ -254,7 +254,7 @@ const MovieUploadForm: FunctionComponent<Props> = ({
|
|||
},
|
||||
},
|
||||
],
|
||||
[action, languageOptions]
|
||||
[action, languageOptions],
|
||||
);
|
||||
|
||||
const { upload } = useMovieSubtitleModification();
|
||||
|
@ -294,7 +294,7 @@ export const MovieUploadModal = withModal(
|
|||
{
|
||||
title: "Upload Subtitles",
|
||||
size: "xl",
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export default MovieUploadForm;
|
||||
|
|
|
@ -69,11 +69,11 @@ const ProfileEditForm: FunctionComponent<Props> = ({
|
|||
validate: {
|
||||
name: FormUtils.validation(
|
||||
(value) => value.length > 0,
|
||||
"Must have a name"
|
||||
"Must have a name",
|
||||
),
|
||||
items: FormUtils.validation(
|
||||
(value) => value.length > 0,
|
||||
"Must contain at lease 1 language"
|
||||
"Must contain at lease 1 language",
|
||||
),
|
||||
},
|
||||
});
|
||||
|
@ -83,7 +83,7 @@ const ProfileEditForm: FunctionComponent<Props> = ({
|
|||
const itemCutoffOptions = useSelectorOptions(
|
||||
form.values.items,
|
||||
(v) => v.language,
|
||||
(v) => String(v.id)
|
||||
(v) => String(v.id),
|
||||
);
|
||||
|
||||
const cutoffOptions = useMemo(
|
||||
|
@ -91,24 +91,24 @@ const ProfileEditForm: FunctionComponent<Props> = ({
|
|||
...itemCutoffOptions,
|
||||
options: [...itemCutoffOptions.options, ...defaultCutoffOptions],
|
||||
}),
|
||||
[itemCutoffOptions]
|
||||
[itemCutoffOptions],
|
||||
);
|
||||
|
||||
const selectedCutoff = useMemo(
|
||||
() =>
|
||||
cutoffOptions.options.find((v) => v.value.id === form.values.cutoff)
|
||||
?.value ?? null,
|
||||
[cutoffOptions, form.values.cutoff]
|
||||
[cutoffOptions, form.values.cutoff],
|
||||
);
|
||||
|
||||
const mustContainOptions = useSelectorOptions(
|
||||
form.values.mustContain,
|
||||
(v) => v
|
||||
(v) => v,
|
||||
);
|
||||
|
||||
const mustNotContainOptions = useSelectorOptions(
|
||||
form.values.mustNotContain,
|
||||
(v) => v
|
||||
(v) => v,
|
||||
);
|
||||
|
||||
const action = useArrayAction<Language.ProfileItem>((fn) => {
|
||||
|
@ -120,7 +120,7 @@ const ProfileEditForm: FunctionComponent<Props> = ({
|
|||
1 +
|
||||
form.values.items.reduce<number>(
|
||||
(val, item) => Math.max(item.id, val),
|
||||
0
|
||||
0,
|
||||
);
|
||||
|
||||
if (languages.length > 0) {
|
||||
|
@ -154,7 +154,7 @@ const ProfileEditForm: FunctionComponent<Props> = ({
|
|||
() =>
|
||||
languageOptions.options.find((l) => l.value.code2 === code)
|
||||
?.value ?? null,
|
||||
[code]
|
||||
[code],
|
||||
);
|
||||
|
||||
const { classes } = useTableStyles();
|
||||
|
@ -238,7 +238,7 @@ const ProfileEditForm: FunctionComponent<Props> = ({
|
|||
},
|
||||
},
|
||||
],
|
||||
[action, languageOptions]
|
||||
[action, languageOptions],
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -332,5 +332,5 @@ export const ProfileEditModal = withModal(
|
|||
{
|
||||
title: "Edit Languages Profile",
|
||||
size: "xl",
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
@ -64,7 +64,7 @@ const validator = (file: SubtitleFile): SubtitleValidateResult => {
|
|||
} else {
|
||||
const { subtitles } = file.episode;
|
||||
const existing = subtitles.find(
|
||||
(v) => v.code2 === file.language?.code2 && isString(v.path)
|
||||
(v) => v.code2 === file.language?.code2 && isString(v.path),
|
||||
);
|
||||
if (existing !== undefined) {
|
||||
return {
|
||||
|
@ -95,7 +95,7 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
|
|||
const episodeOptions = useSelectorOptions(
|
||||
episodes.data ?? [],
|
||||
(v) => `(${v.season}x${v.episode}) ${v.title}`,
|
||||
(v) => v.sonarrEpisodeId.toString()
|
||||
(v) => v.sonarrEpisodeId.toString(),
|
||||
);
|
||||
|
||||
const profile = useLanguageProfileBy(series.profileId);
|
||||
|
@ -103,12 +103,12 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
|
|||
const languageOptions = useSelectorOptions(
|
||||
languages,
|
||||
(v) => v.name,
|
||||
(v) => v.code2
|
||||
(v) => v.code2,
|
||||
);
|
||||
|
||||
const defaultLanguage = useMemo(
|
||||
() => (languages.length > 0 ? languages[0] : null),
|
||||
[languages]
|
||||
[languages],
|
||||
);
|
||||
|
||||
const form = useForm({
|
||||
|
@ -134,9 +134,9 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
|
|||
v.language === null ||
|
||||
v.episode === null ||
|
||||
v.validateResult === undefined ||
|
||||
v.validateResult.state === "error"
|
||||
v.validateResult.state === "error",
|
||||
) === undefined,
|
||||
"Some files cannot be uploaded, please check"
|
||||
"Some files cannot be uploaded, please check",
|
||||
),
|
||||
},
|
||||
});
|
||||
|
@ -162,7 +162,7 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
|
|||
if (info) {
|
||||
item.episode =
|
||||
episodes.data?.find(
|
||||
(v) => v.season === info.season && v.episode === info.episode
|
||||
(v) => v.season === info.season && v.episode === info.episode,
|
||||
) ?? item.episode;
|
||||
}
|
||||
return item;
|
||||
|
@ -320,7 +320,7 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
|
|||
},
|
||||
},
|
||||
],
|
||||
[action, episodeOptions, languageOptions]
|
||||
[action, episodeOptions, languageOptions],
|
||||
);
|
||||
|
||||
const { upload } = useEpisodeSubtitleModification();
|
||||
|
@ -335,7 +335,7 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
|
|||
|
||||
if (language === null || episode === null) {
|
||||
throw new Error(
|
||||
"Invalid language or episode. This shouldn't happen, please report this bug."
|
||||
"Invalid language or episode. This shouldn't happen, please report this bug.",
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -370,7 +370,7 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
|
|||
export const SeriesUploadModal = withModal(
|
||||
SeriesUploadForm,
|
||||
"upload-series-subtitles",
|
||||
{ title: "Upload Subtitles", size: "xl" }
|
||||
{ title: "Upload Subtitles", size: "xl" },
|
||||
);
|
||||
|
||||
export default SeriesUploadForm;
|
||||
|
|
|
@ -21,18 +21,18 @@ const TaskName = "Syncing Subtitle";
|
|||
function useReferencedSubtitles(
|
||||
mediaType: "episode" | "movie",
|
||||
mediaId: number,
|
||||
subtitlesPath: string
|
||||
subtitlesPath: string,
|
||||
) {
|
||||
// We cannot call hooks conditionally, we rely on useQuery "enabled" option to do only the required API call
|
||||
const episodeData = useRefTracksByEpisodeId(
|
||||
subtitlesPath,
|
||||
mediaId,
|
||||
mediaType === "episode"
|
||||
mediaType === "episode",
|
||||
);
|
||||
const movieData = useRefTracksByMovieId(
|
||||
subtitlesPath,
|
||||
mediaId,
|
||||
mediaType === "movie"
|
||||
mediaType === "movie",
|
||||
);
|
||||
|
||||
const mediaData = mediaType === "episode" ? episodeData : movieData;
|
||||
|
@ -108,7 +108,7 @@ const SyncSubtitleForm: FunctionComponent<Props> = ({
|
|||
const subtitles: SelectorOption<string>[] = useReferencedSubtitles(
|
||||
mediaType,
|
||||
mediaId,
|
||||
subtitlesPath
|
||||
subtitlesPath,
|
||||
);
|
||||
|
||||
const form = useForm<FormValues>({
|
||||
|
|
|
@ -37,7 +37,7 @@ const TimeOffsetForm: FunctionComponent<Props> = ({ selections, onSubmit }) => {
|
|||
sec: FormUtils.validation((v) => v >= 0, "Second must be larger than 0"),
|
||||
ms: FormUtils.validation(
|
||||
(v) => v >= 0,
|
||||
"Millisecond must be larger than 0"
|
||||
"Millisecond must be larger than 0",
|
||||
),
|
||||
},
|
||||
});
|
||||
|
@ -62,7 +62,7 @@ const TimeOffsetForm: FunctionComponent<Props> = ({ selections, onSubmit }) => {
|
|||
task.create(s.path, TaskName, mutateAsync, {
|
||||
action,
|
||||
form: s,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
onSubmit?.();
|
||||
|
|
|
@ -146,13 +146,13 @@ const TranslationForm: FunctionComponent<Props> = ({
|
|||
|
||||
const available = useMemo(
|
||||
() => languages.filter((v) => v.code2 in translations),
|
||||
[languages]
|
||||
[languages],
|
||||
);
|
||||
|
||||
const options = useSelectorOptions(
|
||||
available,
|
||||
(v) => v.name,
|
||||
(v) => v.code2
|
||||
(v) => v.code2,
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -166,7 +166,7 @@ const TranslationForm: FunctionComponent<Props> = ({
|
|||
...s,
|
||||
language: language.code2,
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
onSubmit?.();
|
||||
|
|
|
@ -28,7 +28,7 @@ describe("Action button", () => {
|
|||
it("should call on-click event when clicked", async () => {
|
||||
const onClickFn = vitest.fn();
|
||||
rawRender(
|
||||
<Action icon={testIcon} label={testLabel} onClick={onClickFn}></Action>
|
||||
<Action icon={testIcon} label={testLabel} onClick={onClickFn}></Action>,
|
||||
);
|
||||
|
||||
await userEvent.click(screen.getByRole("button", { name: testLabel }));
|
||||
|
|
|
@ -27,7 +27,7 @@ const Action = forwardRef<HTMLButtonElement, ActionProps>(
|
|||
</ActionIcon>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export default Action;
|
||||
|
|
|
@ -30,7 +30,7 @@ describe("ChipInput", () => {
|
|||
});
|
||||
|
||||
rawRender(
|
||||
<ChipInput value={existedValues} onChange={mockedFn}></ChipInput>
|
||||
<ChipInput value={existedValues} onChange={mockedFn}></ChipInput>,
|
||||
);
|
||||
|
||||
const element = screen.getByRole("searchbox");
|
||||
|
|
|
@ -53,7 +53,7 @@ export const FileBrowser: FunctionComponent<FileBrowserProps> = ({
|
|||
item: v,
|
||||
})) ?? []),
|
||||
],
|
||||
[tree]
|
||||
[tree],
|
||||
);
|
||||
|
||||
const parent = useMemo(() => {
|
||||
|
|
|
@ -19,7 +19,7 @@ describe("Selector", () => {
|
|||
describe("options", () => {
|
||||
it("should work with the SelectorOption", () => {
|
||||
rawRender(
|
||||
<Selector name={selectorName} options={testOptions}></Selector>
|
||||
<Selector name={selectorName} options={testOptions}></Selector>,
|
||||
);
|
||||
|
||||
// TODO: selectorName
|
||||
|
@ -28,7 +28,7 @@ describe("Selector", () => {
|
|||
|
||||
it("should display when clicked", async () => {
|
||||
rawRender(
|
||||
<Selector name={selectorName} options={testOptions}></Selector>
|
||||
<Selector name={selectorName} options={testOptions}></Selector>,
|
||||
);
|
||||
|
||||
const element = screen.getByRole("searchbox");
|
||||
|
@ -49,7 +49,7 @@ describe("Selector", () => {
|
|||
name={selectorName}
|
||||
options={testOptions}
|
||||
defaultValue={option.value}
|
||||
></Selector>
|
||||
></Selector>,
|
||||
);
|
||||
|
||||
expect(screen.getByDisplayValue(option.label)).toBeDefined();
|
||||
|
@ -62,7 +62,7 @@ describe("Selector", () => {
|
|||
name={selectorName}
|
||||
options={testOptions}
|
||||
value={option.value}
|
||||
></Selector>
|
||||
></Selector>,
|
||||
);
|
||||
|
||||
expect(screen.getByDisplayValue(option.label)).toBeDefined();
|
||||
|
@ -80,7 +80,7 @@ describe("Selector", () => {
|
|||
name={selectorName}
|
||||
options={testOptions}
|
||||
onChange={mockedFn}
|
||||
></Selector>
|
||||
></Selector>,
|
||||
);
|
||||
|
||||
const element = screen.getByRole("searchbox");
|
||||
|
@ -121,7 +121,7 @@ describe("Selector", () => {
|
|||
options={objectOptions}
|
||||
onChange={mockedFn}
|
||||
getkey={(v) => v.name}
|
||||
></Selector>
|
||||
></Selector>,
|
||||
);
|
||||
|
||||
const element = screen.getByRole("searchbox");
|
||||
|
@ -142,7 +142,7 @@ describe("Selector", () => {
|
|||
name={selectorName}
|
||||
options={testOptions}
|
||||
placeholder={placeholder}
|
||||
></Selector>
|
||||
></Selector>,
|
||||
);
|
||||
|
||||
expect(screen.getByPlaceholderText(placeholder)).toBeDefined();
|
||||
|
|
|
@ -29,7 +29,7 @@ function DefaultKeyBuilder<T>(value: T) {
|
|||
} else {
|
||||
LOG("error", "Unknown value type", value);
|
||||
throw new Error(
|
||||
`Invalid type (${typeof value}) in the SelectorOption, please provide a label builder`
|
||||
`Invalid type (${typeof value}) in the SelectorOption, please provide a label builder`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ export function Selector<T>({
|
|||
payload: value,
|
||||
...option,
|
||||
})),
|
||||
[keyRef, options]
|
||||
[keyRef, options],
|
||||
);
|
||||
|
||||
const wrappedValue = useMemo(() => {
|
||||
|
@ -88,7 +88,7 @@ export function Selector<T>({
|
|||
const payload = data.find((v) => v.value === value)?.payload ?? null;
|
||||
onChange?.(payload);
|
||||
},
|
||||
[data, onChange]
|
||||
[data, onChange],
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -137,16 +137,16 @@ export function MultiSelector<T>({
|
|||
payload: value,
|
||||
...option,
|
||||
})),
|
||||
[options]
|
||||
[options],
|
||||
);
|
||||
|
||||
const wrappedValue = useMemo(
|
||||
() => value && value.map(labelRef.current),
|
||||
[value]
|
||||
[value],
|
||||
);
|
||||
const wrappedDefaultValue = useMemo(
|
||||
() => defaultValue && defaultValue.map(labelRef.current),
|
||||
[defaultValue]
|
||||
[defaultValue],
|
||||
);
|
||||
|
||||
const wrappedOnChange = useCallback(
|
||||
|
@ -162,7 +162,7 @@ export function MultiSelector<T>({
|
|||
}
|
||||
onChange?.(payloads);
|
||||
},
|
||||
[data, onChange]
|
||||
[data, onChange],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -123,7 +123,7 @@ const MovieHistoryView: FunctionComponent<MovieHistoryViewProps> = ({
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -263,7 +263,7 @@ const EpisodeHistoryView: FunctionComponent<EpisodeHistoryViewProps> = ({
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -280,5 +280,5 @@ const EpisodeHistoryView: FunctionComponent<EpisodeHistoryViewProps> = ({
|
|||
export const EpisodeHistoryModal = withModal(
|
||||
EpisodeHistoryView,
|
||||
"episode-history",
|
||||
{ size: "xl" }
|
||||
{ size: "xl" },
|
||||
);
|
||||
|
|
|
@ -32,7 +32,7 @@ type SupportType = Item.Movie | Item.Episode;
|
|||
interface Props<T extends SupportType> {
|
||||
download: (item: T, result: SearchResultType) => Promise<void>;
|
||||
query: (
|
||||
id?: number
|
||||
id?: number,
|
||||
) => UseQueryResult<SearchResultType[] | undefined, unknown>;
|
||||
item: T;
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ function ManualSearchView<T extends SupportType>(props: Props<T>) {
|
|||
|
||||
const items = useMemo(
|
||||
() => value.slice(1).map((v, idx) => <Text key={idx}>{v}</Text>),
|
||||
[value]
|
||||
[value],
|
||||
);
|
||||
|
||||
if (value.length === 0) {
|
||||
|
@ -176,7 +176,7 @@ function ManualSearchView<T extends SupportType>(props: Props<T>) {
|
|||
TaskGroup.DownloadSubtitle,
|
||||
download,
|
||||
item,
|
||||
result
|
||||
result,
|
||||
);
|
||||
}}
|
||||
></Action>
|
||||
|
@ -184,7 +184,7 @@ function ManualSearchView<T extends SupportType>(props: Props<T>) {
|
|||
},
|
||||
},
|
||||
],
|
||||
[download, item]
|
||||
[download, item],
|
||||
);
|
||||
|
||||
const bSceneNameAvailable =
|
||||
|
@ -228,10 +228,10 @@ function ManualSearchView<T extends SupportType>(props: Props<T>) {
|
|||
export const MovieSearchModal = withModal<Props<Item.Movie>>(
|
||||
ManualSearchView,
|
||||
"movie-manual-search",
|
||||
{ title: "Search Subtitles", size: "calc(100vw - 4rem)" }
|
||||
{ title: "Search Subtitles", size: "calc(100vw - 4rem)" },
|
||||
);
|
||||
export const EpisodeSearchModal = withModal<Props<Item.Episode>>(
|
||||
ManualSearchView,
|
||||
"episode-manual-search",
|
||||
{ title: "Search Subtitles", size: "calc(100vw - 4rem)" }
|
||||
{ title: "Search Subtitles", size: "calc(100vw - 4rem)" },
|
||||
);
|
||||
|
|
|
@ -67,7 +67,7 @@ const SubtitleToolView: FunctionComponent<SubtitleToolViewProps> = ({
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
const data = useMemo<TableColumnType[]>(
|
||||
|
@ -91,7 +91,7 @@ const SubtitleToolView: FunctionComponent<SubtitleToolViewProps> = ({
|
|||
}
|
||||
});
|
||||
}),
|
||||
[payload]
|
||||
[payload],
|
||||
);
|
||||
|
||||
const plugins = [useRowSelect, useCustomSelection];
|
||||
|
|
|
@ -33,7 +33,7 @@ const useStyles = createStyles((theme) => {
|
|||
});
|
||||
|
||||
function DefaultHeaderRenderer<T extends object>(
|
||||
headers: HeaderGroup<T>[]
|
||||
headers: HeaderGroup<T>[],
|
||||
): JSX.Element[] {
|
||||
return headers.map((col) => (
|
||||
<th style={{ whiteSpace: "nowrap" }} {...col.getHeaderProps()}>
|
||||
|
@ -71,7 +71,7 @@ export default function BaseTable<T extends object>(props: BaseTableProps<T>) {
|
|||
const colCount = useMemo(() => {
|
||||
return headerGroups.reduce(
|
||||
(prev, curr) => (curr.headers.length > prev ? curr.headers.length : prev),
|
||||
0
|
||||
0,
|
||||
);
|
||||
}, [headerGroups]);
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ function renderRow<T extends object>(row: Row<T>) {
|
|||
}
|
||||
|
||||
function renderHeaders<T extends object>(
|
||||
headers: HeaderGroup<T>[]
|
||||
headers: HeaderGroup<T>[],
|
||||
): JSX.Element[] {
|
||||
return headers
|
||||
.filter((col) => !col.isGrouped)
|
||||
|
|
|
@ -20,7 +20,7 @@ export default function PageTable<T extends object>(props: Props<T>) {
|
|||
options,
|
||||
useDefaultSettings,
|
||||
...tablePlugins,
|
||||
...(plugins ?? [])
|
||||
...(plugins ?? []),
|
||||
);
|
||||
|
||||
// use page size as specified in UI settings
|
||||
|
|
|
@ -9,7 +9,7 @@ export type SimpleTableProps<T extends object> = TableOptions<T> & {
|
|||
};
|
||||
|
||||
export default function SimpleTable<T extends object>(
|
||||
props: SimpleTableProps<T>
|
||||
props: SimpleTableProps<T>,
|
||||
) {
|
||||
const { plugins, instanceRef, tableStyles, ...options } = props;
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ function useInstance<T extends object>(instance: TableInstance<T>) {
|
|||
useEffect(() => {
|
||||
// Performance
|
||||
let items = Object.keys(selectedRowIds).flatMap(
|
||||
(v) => rows.find((n) => n.id === v)?.original ?? []
|
||||
(v) => rows.find((n) => n.id === v)?.original ?? [],
|
||||
);
|
||||
|
||||
if (canSelect) {
|
||||
|
@ -84,7 +84,7 @@ function useInstance<T extends object>(instance: TableInstance<T>) {
|
|||
|
||||
function visibleColumns<T extends object>(
|
||||
columns: ColumnInstance<T>[],
|
||||
meta: MetaBase<T>
|
||||
meta: MetaBase<T>,
|
||||
): Column<T>[] {
|
||||
const { instance } = meta;
|
||||
const checkbox: Column<T> = {
|
||||
|
|
|
@ -38,7 +38,7 @@ type ToolboxMutateButtonProps<R, T extends () => Promise<R>> = {
|
|||
} & Omit<ToolboxButtonProps, "onClick" | "loading">;
|
||||
|
||||
export function ToolboxMutateButton<R, T extends () => Promise<R>>(
|
||||
props: PropsWithChildren<ToolboxMutateButtonProps<R, T>>
|
||||
props: PropsWithChildren<ToolboxMutateButtonProps<R, T>>,
|
||||
): JSX.Element {
|
||||
const { promise, onSuccess, ...button } = props;
|
||||
|
||||
|
|
|
@ -14,6 +14,6 @@ if (container === null) {
|
|||
<AllProviders>
|
||||
<Router />
|
||||
</AllProviders>
|
||||
</StrictMode>
|
||||
</StrictMode>,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ const ModalsProvider: FunctionComponent<PropsWithChildren> = ({ children }) => {
|
|||
prev[curr.modalKey] = curr;
|
||||
return prev;
|
||||
}, {}),
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -17,7 +17,7 @@ export const ModalIdContext = createContext<string | null>(null);
|
|||
export default function withModal<T extends {}>(
|
||||
Content: FunctionComponent<T>,
|
||||
key: string,
|
||||
defaultSettings?: ModalSettings
|
||||
defaultSettings?: ModalSettings,
|
||||
) {
|
||||
const Comp: ModalComponent<T> = (props) => {
|
||||
const { id, innerProps } = props;
|
||||
|
|
|
@ -15,7 +15,7 @@ export function useModals() {
|
|||
<ARGS extends {}>(
|
||||
modal: ModalComponent<ARGS>,
|
||||
props: ARGS,
|
||||
settings?: ModalSettings
|
||||
settings?: ModalSettings,
|
||||
) => {
|
||||
openMantineContextModal(modal.modalKey, {
|
||||
...modal.settings,
|
||||
|
@ -23,14 +23,14 @@ export function useModals() {
|
|||
innerProps: props,
|
||||
});
|
||||
},
|
||||
[openMantineContextModal]
|
||||
[openMantineContextModal],
|
||||
);
|
||||
|
||||
const closeContextModal = useCallback(
|
||||
(modal: ModalComponent) => {
|
||||
rest.closeModal(modal.modalKey);
|
||||
},
|
||||
[rest]
|
||||
[rest],
|
||||
);
|
||||
|
||||
const id = useContext(ModalIdContext);
|
||||
|
@ -44,6 +44,6 @@ export function useModals() {
|
|||
// TODO: Performance
|
||||
return useMemo(
|
||||
() => ({ openContextModal, closeContextModal, closeSelf, ...rest }),
|
||||
[closeContextModal, closeSelf, openContextModal, rest]
|
||||
[closeContextModal, closeSelf, openContextModal, rest],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ declare namespace SocketIO {
|
|||
type ReducerGroup<
|
||||
E extends EventType,
|
||||
U extends PayloadType | undefined,
|
||||
D = U
|
||||
D = U,
|
||||
> = ValueOf<{
|
||||
[P in E]: {
|
||||
key: P;
|
||||
|
|
|
@ -59,7 +59,7 @@ class TaskDispatcher {
|
|||
group,
|
||||
task.description,
|
||||
index,
|
||||
tasks.length
|
||||
tasks.length,
|
||||
);
|
||||
updateNotification(notifyInProgress);
|
||||
|
||||
|
@ -120,8 +120,8 @@ class TaskDispatcher {
|
|||
item.header,
|
||||
item.name,
|
||||
item.value,
|
||||
item.count
|
||||
)
|
||||
item.count,
|
||||
),
|
||||
);
|
||||
} else if (item.value > 1 && this.progress[item.id] === undefined) {
|
||||
showNotification(notification.progress.pending(item.id, item.header));
|
||||
|
@ -134,7 +134,7 @@ class TaskDispatcher {
|
|||
public removeProgress(ids: string[]) {
|
||||
setTimeout(
|
||||
() => ids.forEach(hideNotification),
|
||||
notification.PROGRESS_TIMEOUT
|
||||
notification.PROGRESS_TIMEOUT,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ export const notification = {
|
|||
progress: {
|
||||
pending: (
|
||||
id: string,
|
||||
header: string
|
||||
header: string,
|
||||
): NotificationProps & { id: string } => {
|
||||
return {
|
||||
id,
|
||||
|
@ -47,7 +47,7 @@ export const notification = {
|
|||
header: string,
|
||||
body: string,
|
||||
current: number,
|
||||
total: number
|
||||
total: number,
|
||||
): NotificationProps & { id: string } => {
|
||||
return {
|
||||
id,
|
||||
|
|
|
@ -84,7 +84,7 @@ const Table: FunctionComponent<Props> = ({ blacklist }) => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
return (
|
||||
<PageTable
|
||||
|
|
|
@ -91,7 +91,7 @@ const Table: FunctionComponent<Props> = ({ blacklist }) => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
return (
|
||||
<PageTable
|
||||
|
|
|
@ -81,7 +81,7 @@ export const Subtitle: FunctionComponent<Props> = ({
|
|||
hi: subtitle.hi,
|
||||
forced: subtitle.forced,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
} else if (action === "delete" && subtitle.path) {
|
||||
task.create(
|
||||
|
@ -97,7 +97,7 @@ export const Subtitle: FunctionComponent<Props> = ({
|
|||
forced: subtitle.forced,
|
||||
path: subtitle.path,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}}
|
||||
|
|
|
@ -72,7 +72,7 @@ const SeriesEpisodesView: FunctionComponent = () => {
|
|||
text: series?.seriesType ?? "",
|
||||
},
|
||||
],
|
||||
[series]
|
||||
[series],
|
||||
);
|
||||
|
||||
const modals = useModals();
|
||||
|
@ -92,12 +92,12 @@ const SeriesEpisodesView: FunctionComponent = () => {
|
|||
showNotification(
|
||||
notification.warn(
|
||||
"Cannot Upload Files",
|
||||
"series or language profile is not ready"
|
||||
)
|
||||
"series or language profile is not ready",
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
[modals, profile, series]
|
||||
[modals, profile, series],
|
||||
);
|
||||
|
||||
useDocumentTitle(`${series?.title ?? "Unknown Series"} - Bazarr (Series)`);
|
||||
|
@ -202,7 +202,7 @@ const SeriesEpisodesView: FunctionComponent = () => {
|
|||
item: series,
|
||||
mutation,
|
||||
},
|
||||
{ title: series.title }
|
||||
{ title: series.title },
|
||||
);
|
||||
}
|
||||
}}
|
||||
|
|
|
@ -73,7 +73,7 @@ const Table: FunctionComponent<Props> = ({
|
|||
},
|
||||
});
|
||||
},
|
||||
[mutateAsync]
|
||||
[mutateAsync],
|
||||
);
|
||||
|
||||
const columns: Column<Item.Episode>[] = useMemo<Column<Item.Episode>[]>(
|
||||
|
@ -194,7 +194,7 @@ const Table: FunctionComponent<Props> = ({
|
|||
},
|
||||
{
|
||||
title: `History - ${row.original.title}`,
|
||||
}
|
||||
},
|
||||
);
|
||||
}}
|
||||
icon={faHistory}
|
||||
|
@ -204,16 +204,16 @@ const Table: FunctionComponent<Props> = ({
|
|||
},
|
||||
},
|
||||
],
|
||||
[onlyDesired, profileItems, disabled, download]
|
||||
[onlyDesired, profileItems, disabled, download],
|
||||
);
|
||||
|
||||
const maxSeason = useMemo(
|
||||
() =>
|
||||
episodes?.reduce<number>(
|
||||
(prev, curr) => Math.max(prev, curr.season),
|
||||
0
|
||||
0,
|
||||
) ?? 0,
|
||||
[episodes]
|
||||
[episodes],
|
||||
);
|
||||
|
||||
const instance = useRef<TableInstance<Item.Episode> | null>(null);
|
||||
|
|
|
@ -144,7 +144,7 @@ const MoviesHistoryView: FunctionComponent = () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
const query = useMovieHistoryPagination();
|
||||
|
|
|
@ -167,7 +167,7 @@ const SeriesHistoryView: FunctionComponent = () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
const query = useEpisodeHistoryPagination();
|
||||
|
|
|
@ -50,7 +50,7 @@ const HistoryStats: FunctionComponent = () => {
|
|||
|
||||
const languageOptions = useSelectorOptions(
|
||||
historyLanguages ?? [],
|
||||
(value) => value.name
|
||||
(value) => value.name,
|
||||
);
|
||||
|
||||
const [timeFrame, setTimeFrame] = useState<History.TimeFrameOptions>("month");
|
||||
|
|
|
@ -78,7 +78,7 @@ const MovieDetailView: FunctionComponent = () => {
|
|||
},
|
||||
});
|
||||
},
|
||||
[downloadAsync]
|
||||
[downloadAsync],
|
||||
);
|
||||
|
||||
const onDrop = useCallback(
|
||||
|
@ -92,12 +92,12 @@ const MovieDetailView: FunctionComponent = () => {
|
|||
showNotification(
|
||||
notification.warn(
|
||||
"Cannot Upload Files",
|
||||
"movie or language profile is not ready"
|
||||
)
|
||||
"movie or language profile is not ready",
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
[modals, movie, profile]
|
||||
[modals, movie, profile],
|
||||
);
|
||||
|
||||
const hasTask = useIsMovieActionRunning();
|
||||
|
@ -187,7 +187,7 @@ const MovieDetailView: FunctionComponent = () => {
|
|||
item: movie,
|
||||
mutation,
|
||||
},
|
||||
{ title: movie.title }
|
||||
{ title: movie.title },
|
||||
);
|
||||
}
|
||||
}}
|
||||
|
|
|
@ -126,7 +126,7 @@ const Table: FunctionComponent<Props> = ({ movie, profile, disabled }) => {
|
|||
forced,
|
||||
hi,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}}
|
||||
></Action>
|
||||
|
@ -150,11 +150,11 @@ const Table: FunctionComponent<Props> = ({ movie, profile, disabled }) => {
|
|||
hi,
|
||||
path,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
} else if (action === "search") {
|
||||
throw new Error(
|
||||
"This shouldn't happen, please report the bug"
|
||||
"This shouldn't happen, please report the bug",
|
||||
);
|
||||
}
|
||||
}}
|
||||
|
@ -170,7 +170,7 @@ const Table: FunctionComponent<Props> = ({ movie, profile, disabled }) => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[movie, disabled]
|
||||
[movie, disabled],
|
||||
);
|
||||
|
||||
const data: Subtitle[] = useMemo(() => {
|
||||
|
|
|
@ -32,7 +32,7 @@ const MovieMassEditor: FunctionComponent = () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
useDocumentTitle("Movies - Bazarr (Mass Editor)");
|
||||
|
|
|
@ -99,7 +99,7 @@ const MovieView: FunctionComponent = () => {
|
|||
},
|
||||
{
|
||||
title: row.original.title,
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
icon={faWrench}
|
||||
|
@ -108,7 +108,7 @@ const MovieView: FunctionComponent = () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
useDocumentTitle("Movies - Bazarr");
|
||||
|
|
|
@ -32,7 +32,7 @@ const SeriesMassEditor: FunctionComponent = () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
useDocumentTitle("Series - Bazarr (Mass Editor)");
|
||||
|
|
|
@ -106,7 +106,7 @@ const SeriesView: FunctionComponent = () => {
|
|||
},
|
||||
{
|
||||
title: original.title,
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
icon={faWrench}
|
||||
|
@ -115,7 +115,7 @@ const SeriesView: FunctionComponent = () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[mutation]
|
||||
[mutation],
|
||||
);
|
||||
|
||||
useDocumentTitle("Series - Bazarr");
|
||||
|
|
|
@ -35,7 +35,7 @@ export const LanguageSelector: FunctionComponent<
|
|||
searchable
|
||||
onChange={(val) => {
|
||||
setValue(val, settingKey, (value: Language.Info[]) =>
|
||||
value.map((v) => v.code2)
|
||||
value.map((v) => v.code2),
|
||||
);
|
||||
}}
|
||||
></MultiSelector>
|
||||
|
@ -53,7 +53,7 @@ export const ProfileSelector: FunctionComponent<
|
|||
profiles.map((v) => {
|
||||
return { label: v.name, value: v.profileId };
|
||||
}),
|
||||
[profiles]
|
||||
[profiles],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -15,7 +15,7 @@ describe("Equals Parser", () => {
|
|||
|
||||
function testParsedResult(
|
||||
text: string,
|
||||
expected: LanguageEqualImmediateData
|
||||
expected: LanguageEqualImmediateData,
|
||||
) {
|
||||
const result = decodeEqualData(text);
|
||||
|
||||
|
@ -26,7 +26,7 @@ describe("Equals Parser", () => {
|
|||
|
||||
expect(
|
||||
result,
|
||||
`${text} does not match with the expected equal data`
|
||||
`${text} does not match with the expected equal data`,
|
||||
).toStrictEqual(expected);
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@ describe("Equals Parser", () => {
|
|||
|
||||
expect(
|
||||
encoded,
|
||||
`Encoded result '${encoded}' is not matched to '${expected}'`
|
||||
`Encoded result '${encoded}' is not matched to '${expected}'`,
|
||||
).toEqual(expected);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ export type LanguageEqualImmediateData =
|
|||
export type LanguageEqualData = LanguageEqualGenericData<Language.Server>;
|
||||
|
||||
function decodeEqualTarget(
|
||||
text: string
|
||||
text: string,
|
||||
): GenericEqualTarget<Language.CodeType> | undefined {
|
||||
const [code, decoration] = text.split("@");
|
||||
|
||||
|
@ -47,7 +47,7 @@ function decodeEqualTarget(
|
|||
}
|
||||
|
||||
export function decodeEqualData(
|
||||
text: string
|
||||
text: string,
|
||||
): LanguageEqualImmediateData | undefined {
|
||||
const [first, second] = text.split(":");
|
||||
|
||||
|
@ -97,10 +97,10 @@ export function useLatestLanguageEquals(): LanguageEqualData[] {
|
|||
}
|
||||
|
||||
const source = data?.find(
|
||||
(value) => value.code3 === parsed.source.content
|
||||
(value) => value.code3 === parsed.source.content,
|
||||
);
|
||||
const target = data?.find(
|
||||
(value) => value.code3 === parsed.target.content
|
||||
(value) => value.code3 === parsed.target.content,
|
||||
);
|
||||
|
||||
if (source === undefined || target === undefined) {
|
||||
|
@ -113,7 +113,7 @@ export function useLatestLanguageEquals(): LanguageEqualData[] {
|
|||
};
|
||||
})
|
||||
.filter((v): v is LanguageEqualData => v !== undefined) ?? [],
|
||||
[data, latest]
|
||||
[data, latest],
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ const EqualsTable: FunctionComponent<EqualsTableProps> = () => {
|
|||
LOG("info", "updating language equals data", values);
|
||||
setValue(encodedValues, languageEqualsKey);
|
||||
},
|
||||
[setValue]
|
||||
[setValue],
|
||||
);
|
||||
|
||||
const add = useCallback(() => {
|
||||
|
@ -178,7 +178,7 @@ const EqualsTable: FunctionComponent<EqualsTableProps> = () => {
|
|||
newValue[index] = { ...value };
|
||||
setEquals(newValue);
|
||||
},
|
||||
[equals, setEquals]
|
||||
[equals, setEquals],
|
||||
);
|
||||
|
||||
const remove = useCallback(
|
||||
|
@ -193,7 +193,7 @@ const EqualsTable: FunctionComponent<EqualsTableProps> = () => {
|
|||
|
||||
setEquals(newValue);
|
||||
},
|
||||
[equals, setEquals]
|
||||
[equals, setEquals],
|
||||
);
|
||||
|
||||
const columns = useMemo<Column<LanguageEqualData>[]>(
|
||||
|
@ -349,7 +349,7 @@ const EqualsTable: FunctionComponent<EqualsTableProps> = () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[remove, update]
|
||||
[remove, update],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -23,7 +23,7 @@ const Table: FunctionComponent = () => {
|
|||
() =>
|
||||
1 +
|
||||
profiles.reduce<number>((val, prof) => Math.max(prof.profileId, val), 0),
|
||||
[profiles]
|
||||
[profiles],
|
||||
);
|
||||
|
||||
const { setValue } = useFormActions();
|
||||
|
@ -34,7 +34,7 @@ const Table: FunctionComponent = () => {
|
|||
(list: Language.Profile[]) => {
|
||||
setValue(list, languageProfileKey, (value) => JSON.stringify(value));
|
||||
},
|
||||
[setValue]
|
||||
[setValue],
|
||||
);
|
||||
|
||||
const updateProfile = useCallback(
|
||||
|
@ -49,7 +49,7 @@ const Table: FunctionComponent = () => {
|
|||
}
|
||||
submitProfiles(list);
|
||||
},
|
||||
[profiles, submitProfiles]
|
||||
[profiles, submitProfiles],
|
||||
);
|
||||
|
||||
const action = useArrayAction<Language.Profile>((fn) => {
|
||||
|
@ -152,7 +152,7 @@ const Table: FunctionComponent = () => {
|
|||
},
|
||||
],
|
||||
// TODO: Optimize this
|
||||
[action, languages, modals, updateProfile]
|
||||
[action, languages, modals, updateProfile],
|
||||
);
|
||||
|
||||
const canAdd = languages.length !== 0;
|
||||
|
|
|
@ -37,7 +37,7 @@ const NotificationForm: FunctionComponent<Props> = ({
|
|||
}) => {
|
||||
const availableSelections = useMemo(
|
||||
() => selections.filter((v) => !v.enabled || v.name === payload?.name),
|
||||
[payload?.name, selections]
|
||||
[payload?.name, selections],
|
||||
);
|
||||
const options = useSelectorOptions(availableSelections, (v) => v.name);
|
||||
|
||||
|
@ -51,11 +51,11 @@ const NotificationForm: FunctionComponent<Props> = ({
|
|||
validate: {
|
||||
selection: FormUtils.validation(
|
||||
isObject,
|
||||
"Please select a notification provider"
|
||||
"Please select a notification provider",
|
||||
),
|
||||
url: FormUtils.validation(
|
||||
(value) => value.trim().length !== 0,
|
||||
"URL must not be empty"
|
||||
"URL must not be empty",
|
||||
),
|
||||
},
|
||||
});
|
||||
|
@ -123,20 +123,20 @@ export const NotificationView: FunctionComponent = () => {
|
|||
{
|
||||
onLoaded: (settings) => settings.notifications.providers,
|
||||
onSubmit: (value) => value.map((v) => JSON.stringify(v)),
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const update = useUpdateArray<Settings.NotificationInfo>(
|
||||
notificationsKey,
|
||||
notifications ?? [],
|
||||
"name"
|
||||
"name",
|
||||
);
|
||||
|
||||
const updateWrapper = useCallback(
|
||||
(info: Settings.NotificationInfo) => {
|
||||
update(info, notificationHook);
|
||||
},
|
||||
[update]
|
||||
[update],
|
||||
);
|
||||
|
||||
const modals = useModals();
|
||||
|
|
|
@ -63,7 +63,7 @@ export const ProviderView: FunctionComponent = () => {
|
|||
});
|
||||
}
|
||||
},
|
||||
[modals, providers, settings, staged, update]
|
||||
[modals, providers, settings, staged, update],
|
||||
);
|
||||
|
||||
const cards = useMemo(() => {
|
||||
|
@ -171,7 +171,7 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
|
|||
modals.closeAll();
|
||||
}
|
||||
},
|
||||
[info, enabledProviders, modals]
|
||||
[info, enabledProviders, modals],
|
||||
);
|
||||
|
||||
const canSave = info !== null;
|
||||
|
@ -192,14 +192,14 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
|
|||
ProviderList.filter(
|
||||
(v) =>
|
||||
enabledProviders?.find((p) => p === v.key && p !== info?.key) ===
|
||||
undefined
|
||||
undefined,
|
||||
),
|
||||
[info?.key, enabledProviders]
|
||||
[info?.key, enabledProviders],
|
||||
);
|
||||
|
||||
const options = useSelectorOptions(
|
||||
availableOptions,
|
||||
(v) => v.name ?? capitalize(v.key)
|
||||
(v) => v.name ?? capitalize(v.key),
|
||||
);
|
||||
|
||||
const inputs = useMemo(() => {
|
||||
|
@ -223,7 +223,7 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
|
|||
key={BuildKey(itemKey, key)}
|
||||
label={label}
|
||||
settingKey={`settings-${itemKey}-${key}`}
|
||||
></Text>
|
||||
></Text>,
|
||||
);
|
||||
return;
|
||||
case "password":
|
||||
|
@ -232,7 +232,7 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
|
|||
key={BuildKey(itemKey, key)}
|
||||
label={label}
|
||||
settingKey={`settings-${itemKey}-${key}`}
|
||||
></Password>
|
||||
></Password>,
|
||||
);
|
||||
return;
|
||||
case "switch":
|
||||
|
@ -242,7 +242,7 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
|
|||
inline
|
||||
label={label}
|
||||
settingKey={`settings-${itemKey}-${key}`}
|
||||
></Check>
|
||||
></Check>,
|
||||
);
|
||||
return;
|
||||
case "select":
|
||||
|
@ -252,7 +252,7 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
|
|||
label={label}
|
||||
settingKey={`settings-${itemKey}-${key}`}
|
||||
options={options}
|
||||
></GlobalSelector>
|
||||
></GlobalSelector>,
|
||||
);
|
||||
return;
|
||||
case "chips":
|
||||
|
@ -261,7 +261,7 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
|
|||
key={key}
|
||||
label={label}
|
||||
settingKey={`settings-${itemKey}-${key}`}
|
||||
></Chips>
|
||||
></Chips>,
|
||||
);
|
||||
return;
|
||||
default:
|
||||
|
|
|
@ -160,7 +160,7 @@ export const providerOptions: SelectorOption<string>[] = ProviderList.map(
|
|||
(v) => ({
|
||||
label: v.key,
|
||||
value: v.key,
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
export const syncMaxOffsetSecondsOptions: SelectorOption<number>[] = [
|
||||
|
|
|
@ -8,7 +8,7 @@ describe("Settings layout", () => {
|
|||
render(
|
||||
<Layout name="Test Settings">
|
||||
<Text>Value</Text>
|
||||
</Layout>
|
||||
</Layout>,
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -16,7 +16,7 @@ describe("Settings layout", () => {
|
|||
render(
|
||||
<Layout name="Test Settings">
|
||||
<Text>Value</Text>
|
||||
</Layout>
|
||||
</Layout>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole("button", { name: "Save" })).toBeDisabled();
|
||||
|
|
|
@ -47,7 +47,7 @@ const Layout: FunctionComponent<Props> = (props) => {
|
|||
mutate(settingsToSubmit);
|
||||
}
|
||||
},
|
||||
[mutate]
|
||||
[mutate],
|
||||
);
|
||||
|
||||
const totalStagedCount = useMemo(() => {
|
||||
|
@ -56,7 +56,7 @@ const Layout: FunctionComponent<Props> = (props) => {
|
|||
|
||||
usePrompt(
|
||||
totalStagedCount > 0,
|
||||
`You have ${totalStagedCount} unsaved changes, are you sure you want to leave?`
|
||||
`You have ${totalStagedCount} unsaved changes, are you sure you want to leave?`,
|
||||
);
|
||||
|
||||
useDocumentTitle(`${name} - Bazarr (Settings)`);
|
||||
|
|
|
@ -54,7 +54,7 @@ const LayoutModal: FunctionComponent<Props> = (props) => {
|
|||
}, 500);
|
||||
}
|
||||
},
|
||||
[mutate, callbackModal]
|
||||
[mutate, callbackModal],
|
||||
);
|
||||
|
||||
const totalStagedCount = useMemo(() => {
|
||||
|
|
|
@ -17,7 +17,7 @@ describe("Settings section", () => {
|
|||
rawRender(
|
||||
<Section header="Section Header">
|
||||
<Text>{text}</Text>
|
||||
</Section>
|
||||
</Section>,
|
||||
);
|
||||
|
||||
expect(screen.getByText(header)).toBeDefined();
|
||||
|
@ -29,7 +29,7 @@ describe("Settings section", () => {
|
|||
rawRender(
|
||||
<Section header="Section Header" hidden>
|
||||
<Text>{text}</Text>
|
||||
</Section>
|
||||
</Section>,
|
||||
);
|
||||
|
||||
expect(screen.getByText(header)).not.toBeVisible();
|
||||
|
|
|
@ -17,7 +17,7 @@ const FormSupport: FunctionComponent<PropsWithChildren> = ({ children }) => {
|
|||
|
||||
const formRender = (
|
||||
ui: ReactElement,
|
||||
options?: Omit<RenderOptions, "wrapper">
|
||||
options?: Omit<RenderOptions, "wrapper">,
|
||||
) => rawRender(ui, { wrapper: FormSupport, ...options });
|
||||
|
||||
describe("Settings form", () => {
|
||||
|
|
|
@ -115,7 +115,7 @@ export type MultiSelectorProps<T extends string | number> = BaseInput<T[]> &
|
|||
GlobalMultiSelectorProps<T>;
|
||||
|
||||
export function MultiSelector<T extends string | number>(
|
||||
props: MultiSelectorProps<T>
|
||||
props: MultiSelectorProps<T>,
|
||||
) {
|
||||
const { value, update, rest } = useBaseInput(props);
|
||||
|
||||
|
@ -187,7 +187,7 @@ export const Action: FunctionComponent<
|
|||
interface FileProps extends BaseInput<string> {}
|
||||
|
||||
export const File: FunctionComponent<Override<FileProps, FileBrowserProps>> = (
|
||||
props
|
||||
props,
|
||||
) => {
|
||||
const { value, update, rest } = useBaseInput(props);
|
||||
|
||||
|
|
|
@ -56,10 +56,10 @@ export const PathMappingTable: FunctionComponent<TableProps> = ({ type }) => {
|
|||
(newItems: PathMappingItem[]) => {
|
||||
setValue(
|
||||
newItems.map((v) => [v.from, v.to]),
|
||||
key
|
||||
key,
|
||||
);
|
||||
},
|
||||
[key, setValue]
|
||||
[key, setValue],
|
||||
);
|
||||
|
||||
const addRow = useCallback(() => {
|
||||
|
@ -71,7 +71,7 @@ export const PathMappingTable: FunctionComponent<TableProps> = ({ type }) => {
|
|||
|
||||
const data = useMemo<PathMappingItem[]>(
|
||||
() => items?.map((v) => ({ from: v[0], to: v[1] })) ?? [],
|
||||
[items]
|
||||
[items],
|
||||
);
|
||||
|
||||
const action = useArrayAction<PathMappingItem>((fn) => {
|
||||
|
@ -130,7 +130,7 @@ export const PathMappingTable: FunctionComponent<TableProps> = ({ type }) => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[action, type]
|
||||
[action, type],
|
||||
);
|
||||
|
||||
if (enabled) {
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { UseFormReturnType } from "@mantine/form";
|
|||
import { createContext, useCallback, useContext, useRef } from "react";
|
||||
|
||||
export const FormContext = createContext<UseFormReturnType<FormValues> | null>(
|
||||
null
|
||||
null,
|
||||
);
|
||||
|
||||
export function useFormValues() {
|
||||
|
@ -44,7 +44,7 @@ export function useFormActions() {
|
|||
if (hook) {
|
||||
LOG(
|
||||
"info",
|
||||
`Adding submit hook ${key}, will be executed before submitting`
|
||||
`Adding submit hook ${key}, will be executed before submitting`,
|
||||
);
|
||||
hooks[key] = hook;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ export type FormValues = {
|
|||
|
||||
export function runHooks(
|
||||
hooks: FormValues["hooks"],
|
||||
settings: FormValues["settings"]
|
||||
settings: FormValues["settings"],
|
||||
) {
|
||||
for (const key in settings) {
|
||||
if (key in hooks) {
|
||||
|
|
|
@ -36,7 +36,7 @@ export function useBaseInput<T, V>(props: T & BaseInput<V>) {
|
|||
|
||||
setValue(moddedValue, settingKey, settingOptions?.onSubmit);
|
||||
},
|
||||
[settingOptions, setValue, settingKey]
|
||||
[settingOptions, setValue, settingKey],
|
||||
);
|
||||
|
||||
return { value, update, rest };
|
||||
|
@ -44,7 +44,7 @@ export function useBaseInput<T, V>(props: T & BaseInput<V>) {
|
|||
|
||||
export function useSettingValue<T>(
|
||||
key: string,
|
||||
options?: SettingValueOptions<T>
|
||||
options?: SettingValueOptions<T>,
|
||||
): Readonly<Nullable<T>> {
|
||||
const settings = useSettings();
|
||||
|
||||
|
@ -85,7 +85,7 @@ export function useSettingValue<T>(
|
|||
export function useUpdateArray<T>(
|
||||
key: string,
|
||||
current: Readonly<T[]>,
|
||||
compare: keyof T
|
||||
compare: keyof T,
|
||||
) {
|
||||
const { setValue } = useFormActions();
|
||||
const stagedValue = useStagedValues();
|
||||
|
@ -106,6 +106,6 @@ export function useUpdateArray<T>(
|
|||
const newArray = uniqBy([v, ...staged], compareRef.current);
|
||||
setValue(newArray, key, hook);
|
||||
},
|
||||
[staged, setValue, key]
|
||||
[staged, setValue, key],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ const Table: FunctionComponent<Props> = ({ announcements }) => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -100,7 +100,7 @@ const Table: FunctionComponent<Props> = ({ backups }) => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
return <PageTable columns={columns} data={backups}></PageTable>;
|
||||
|
|
|
@ -14,7 +14,7 @@ const SystemLogModal: FunctionComponent<Props> = ({ stack }) => {
|
|||
{v}
|
||||
</Text>
|
||||
)),
|
||||
[stack]
|
||||
[stack],
|
||||
);
|
||||
|
||||
return <Code block>{result}</Code>;
|
||||
|
|
|
@ -70,7 +70,7 @@ const Table: FunctionComponent<Props> = ({ logs }) => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -22,7 +22,7 @@ const Table: FunctionComponent<Props> = (props) => {
|
|||
accessor: "retry",
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
return <SimpleTable columns={columns} data={props.providers}></SimpleTable>;
|
||||
|
|
|
@ -42,7 +42,7 @@ const ReleaseCard: FunctionComponent<ReleaseInfo> = ({
|
|||
}) => {
|
||||
const infos = useMemo(
|
||||
() => body.map((v) => v.replace(/(\s\[.*?\])\(.*?\)/, "")),
|
||||
[body]
|
||||
[body],
|
||||
);
|
||||
return (
|
||||
<Card shadow="md" p="lg">
|
||||
|
|
|
@ -86,7 +86,7 @@ const SystemStatusView: FunctionComponent = () => {
|
|||
if (startTime) {
|
||||
const duration = moment.duration(
|
||||
moment().utc().unix() - startTime,
|
||||
"seconds"
|
||||
"seconds",
|
||||
),
|
||||
days = duration.days(),
|
||||
hours = duration.hours().toString().padStart(2, "0"),
|
||||
|
|
|
@ -28,7 +28,7 @@ const Table: FunctionComponent<Props> = ({ health }) => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -52,7 +52,7 @@ const Table: FunctionComponent<Props> = ({ tasks }) => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -58,7 +58,7 @@ const WantedMoviesView: FunctionComponent = () => {
|
|||
hi: item.hi,
|
||||
forced: item.forced,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}}
|
||||
>
|
||||
|
@ -70,7 +70,7 @@ const WantedMoviesView: FunctionComponent = () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
const { mutateAsync } = useMovieAction();
|
||||
|
|
|
@ -74,7 +74,7 @@ const WantedSeriesView: FunctionComponent = () => {
|
|||
hi: item.hi,
|
||||
forced: item.forced,
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
}}
|
||||
>
|
||||
|
@ -86,7 +86,7 @@ const WantedSeriesView: FunctionComponent = () => {
|
|||
},
|
||||
},
|
||||
],
|
||||
[]
|
||||
[],
|
||||
);
|
||||
|
||||
const { mutateAsync } = useSeriesAction();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue