✨ Add translation for module, fix language changer
This commit is contained in:
42 files changed
+138
-117
No files matched your search
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"states": {
|
||||
"online": "Online {{response}}",
|
||||
"offline": "Offline {{response}}",
|
||||
"loading": "Loading..."
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"descriptor": {
|
||||
"name": "Ping",
|
||||
"description": "Allows you to check if the service is up or returns a specific HTTP status code."
|
||||
},
|
||||
"states": {
|
||||
"online": "Online {{response}}",
|
||||
"offline": "Offline {{response}}",
|
||||
"loading": "Loading..."
|
||||
}
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -126,7 +126,7 @@ const AppShelf = (props: any) => {
|
||||
const noCategory = config.services.filter(
|
||||
(e) => e.category === undefined || e.category === null
|
||||
);
|
||||
const downloadEnabled = config.modules?.[DownloadsModule.title]?.enabled ?? false;
|
||||
const downloadEnabled = config.modules?.[DownloadsModule.id]?.enabled ?? false;
|
||||
// Create an item with 0: true, 1: true, 2: true... For each category
|
||||
return (
|
||||
// TODO: Style accordion so that the bar is transparent to the user settings
|
||||
|
||||
@@ -4,14 +4,17 @@ import { showNotification } from '@mantine/notifications';
|
||||
import { forwardRef, useState } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useRouter } from 'next/router';
|
||||
import { getCookie, setCookie } from 'cookies-next';
|
||||
import { getLanguageByCode, Language } from '../../languages/language';
|
||||
|
||||
export default function LanguageSwitch() {
|
||||
const { t, i18n } = useTranslation('settings/general/internationalization');
|
||||
const { changeLanguage } = i18n;
|
||||
|
||||
const configLocale = getCookie('config-locale');
|
||||
const { locale, locales } = useRouter();
|
||||
const [selectedLanguage, setSelectedLanguage] = useState<string | null | undefined>(locale);
|
||||
const [selectedLanguage, setSelectedLanguage] = useState<string | undefined>(
|
||||
(configLocale as string) ?? locale
|
||||
);
|
||||
|
||||
const data = locales
|
||||
? locales.map((localeItem) => ({
|
||||
@@ -26,9 +29,13 @@ export default function LanguageSwitch() {
|
||||
setSelectedLanguage(value);
|
||||
|
||||
const newLanguage = getLanguageByCode(value);
|
||||
|
||||
changeLanguage(value)
|
||||
.then(() => {
|
||||
setCookie('config-locale', value, {
|
||||
maxAge: 60 * 60 * 24 * 30,
|
||||
sameSite: 'strict',
|
||||
});
|
||||
|
||||
showNotification({
|
||||
title: 'Language changed',
|
||||
message: `You changed the language to '${newLanguage.originalName}'`,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Checkbox, Popover, SimpleGrid, Stack, Text, Title } from '@mantine/core';
|
||||
import { useDisclosure } from '@mantine/hooks';
|
||||
import { Checkbox, HoverCard, SimpleGrid, Stack, Text, Title } from '@mantine/core';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import * as Modules from '../../modules';
|
||||
import { IModule } from '../../modules/ModuleTypes';
|
||||
@@ -11,9 +10,9 @@ export default function ModuleEnabler(props: any) {
|
||||
return (
|
||||
<Stack>
|
||||
<Title order={4}>{t('title')}</Title>
|
||||
<SimpleGrid cols={3} spacing="xs">
|
||||
<SimpleGrid cols={3} spacing="sm">
|
||||
{modules.map((module) => (
|
||||
<ModuleToggle module={module} />
|
||||
<ModuleToggle key={module.id} module={module} />
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
@@ -22,39 +21,36 @@ export default function ModuleEnabler(props: any) {
|
||||
|
||||
const ModuleToggle = ({ module }: { module: IModule }) => {
|
||||
const { config, setConfig } = useConfig();
|
||||
const { t: translationModules } = useTranslation(module.translationNamespace);
|
||||
const [opened, { close, open }] = useDisclosure(false);
|
||||
const { t } = useTranslation(`modules/${module.id}`);
|
||||
|
||||
return (
|
||||
<Popover opened={opened} withArrow withinPortal width={200}>
|
||||
<Popover.Target>
|
||||
<div onMouseEnter={open} onMouseLeave={close}>
|
||||
<Checkbox
|
||||
key={module.title}
|
||||
size="md"
|
||||
checked={config.modules?.[module.title]?.enabled ?? false}
|
||||
label={translationModules('descriptor.name', {
|
||||
defaultValue: 'Unknown',
|
||||
})}
|
||||
onChange={(e) => {
|
||||
setConfig({
|
||||
...config,
|
||||
modules: {
|
||||
...config.modules,
|
||||
[module.title]: {
|
||||
...config.modules?.[module.title],
|
||||
enabled: e.currentTarget.checked,
|
||||
},
|
||||
<HoverCard withArrow withinPortal width={200} shadow="md" openDelay={200}>
|
||||
<HoverCard.Target>
|
||||
<Checkbox
|
||||
key={module.id}
|
||||
size="md"
|
||||
checked={config.modules?.[module.id]?.enabled ?? false}
|
||||
label={t('descriptor.name', {
|
||||
defaultValue: 'Unknown',
|
||||
})}
|
||||
onChange={(e) => {
|
||||
setConfig({
|
||||
...config,
|
||||
modules: {
|
||||
...config.modules,
|
||||
[module.id]: {
|
||||
...config.modules?.[module.id],
|
||||
enabled: e.currentTarget.checked,
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Popover.Target>
|
||||
<Popover.Dropdown>
|
||||
<Text weight="bold">{translationModules('descriptor.name')}</Text>
|
||||
<Text>{translationModules('descriptor.description')}</Text>
|
||||
</Popover.Dropdown>
|
||||
</Popover>
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</HoverCard.Target>
|
||||
<HoverCard.Dropdown>
|
||||
<Title order={4}>{t('descriptor.name')}</Title>
|
||||
<Text size="sm">{t('descriptor.description')}</Text>
|
||||
</HoverCard.Dropdown>
|
||||
</HoverCard>
|
||||
);
|
||||
};
|
||||
Vendored
+1
-1
@@ -6,11 +6,11 @@ import { TablerIcon } from '@tabler/icons';
|
||||
|
||||
// Note: Maybe use context to keep track of the modules
|
||||
export interface IModule {
|
||||
id: string;
|
||||
title: string;
|
||||
icon: TablerIcon;
|
||||
component: React.ComponentType;
|
||||
options?: Option;
|
||||
translationNamespace: string;
|
||||
}
|
||||
|
||||
interface Option {
|
||||
|
||||
@@ -34,7 +34,7 @@ export const CalendarModule: IModule = {
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
translationNamespace: 'modules/calendar-module',
|
||||
id: 'calendar',
|
||||
};
|
||||
|
||||
export default function CalendarComponent(props: any) {
|
||||
@@ -127,7 +127,7 @@ export default function CalendarComponent(props: any) {
|
||||
}, [config.services]);
|
||||
|
||||
const weekStartsAtSunday =
|
||||
(config?.modules?.[CalendarModule.title]?.options?.sundaystart?.value as boolean) ?? false;
|
||||
(config?.modules?.[CalendarModule.id]?.options?.sundaystart?.value as boolean) ?? false;
|
||||
return (
|
||||
<Calendar
|
||||
firstDayOfWeek={weekStartsAtSunday ? 'sunday' : 'monday'}
|
||||
|
||||
@@ -160,7 +160,7 @@ export function SonarrMediaDisplay(props: any) {
|
||||
export function MediaDisplay({ media }: { media: IMedia }) {
|
||||
const [opened, setOpened] = useState(false);
|
||||
const { secondaryColor } = useColorTheme();
|
||||
const { t } = useTranslation('modules/common-media-cards-module');
|
||||
const { t } = useTranslation('modules/common-media-cards');
|
||||
|
||||
return (
|
||||
<Group mr="xs" align="stretch" noWrap style={{ maxHeight: 200 }}>
|
||||
|
||||
@@ -41,7 +41,7 @@ export const DashdotModule = asModule({
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
translationNamespace: 'modules/dashdot-module',
|
||||
id: 'dashdot',
|
||||
});
|
||||
|
||||
const useStyles = createStyles((theme, _params) => ({
|
||||
@@ -126,7 +126,7 @@ export function DashdotComponent() {
|
||||
const { classes } = useStyles();
|
||||
const { colorScheme } = useMantineColorScheme();
|
||||
|
||||
const dashConfig = config.modules?.[DashdotModule.title]
|
||||
const dashConfig = config.modules?.[DashdotModule.id]
|
||||
.options as typeof DashdotModule['options'];
|
||||
const isCompact = dashConfig?.useCompactView?.value ?? false;
|
||||
const dashdotService: serviceItem | undefined = config.services.filter(
|
||||
@@ -148,7 +148,7 @@ export function DashdotComponent() {
|
||||
const totalSize =
|
||||
(info?.storage?.layout as any[])?.reduce((acc, curr) => (curr.size ?? 0) + acc, 0) ?? 0;
|
||||
|
||||
const { t } = useTranslation('modules/dashdot-module');
|
||||
const { t } = useTranslation('modules/dashdot');
|
||||
|
||||
const graphs = [
|
||||
{
|
||||
|
||||
@@ -16,14 +16,14 @@ export const DateModule: IModule = {
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
translationNamespace: 'modules/date-module',
|
||||
id: 'date',
|
||||
};
|
||||
|
||||
export default function DateComponent(props: any) {
|
||||
const [date, setDate] = useState(new Date());
|
||||
const setSafeInterval = useSetSafeInterval();
|
||||
const { config } = useConfig();
|
||||
const isFullTime = config?.modules?.[DateModule.title]?.options?.full?.value ?? true;
|
||||
const isFullTime = config?.modules?.[DateModule.id]?.options?.full?.value ?? true;
|
||||
const formatString = isFullTime ? 'HH:mm' : 'h:mm A';
|
||||
// Change date on minute change
|
||||
// Note: Using 10 000ms instead of 1000ms to chill a little :)
|
||||
|
||||
@@ -22,7 +22,7 @@ function sendDockerCommand(
|
||||
containerName: string,
|
||||
reload: () => void
|
||||
) {
|
||||
const { t } = useTranslation('modules/docker-module');
|
||||
const { t } = useTranslation('modules/docker');
|
||||
|
||||
showNotification({
|
||||
id: containerId,
|
||||
@@ -64,7 +64,7 @@ export interface ContainerActionBarProps {
|
||||
|
||||
export default function ContainerActionBar({ selected, reload }: ContainerActionBarProps) {
|
||||
const [opened, setOpened] = useState<boolean>(false);
|
||||
const { t } = useTranslation('modules/docker-module');
|
||||
const { t } = useTranslation('modules/docker');
|
||||
|
||||
return (
|
||||
<Group>
|
||||
|
||||
@@ -9,7 +9,7 @@ export interface ContainerStateProps {
|
||||
export default function ContainerState(props: ContainerStateProps) {
|
||||
const { state } = props;
|
||||
|
||||
const { t } = useTranslation('modules/docker-module');
|
||||
const { t } = useTranslation('modules/docker');
|
||||
|
||||
const options: {
|
||||
size: MantineSize;
|
||||
|
||||
@@ -15,7 +15,7 @@ export const DockerModule: IModule = {
|
||||
title: 'Docker',
|
||||
icon: IconBrandDocker,
|
||||
component: DockerMenuButton,
|
||||
translationNamespace: 'modules/docker-module',
|
||||
id: 'docker',
|
||||
};
|
||||
|
||||
export default function DockerMenuButton(props: any) {
|
||||
@@ -23,9 +23,9 @@ export default function DockerMenuButton(props: any) {
|
||||
const [containers, setContainers] = useState<Docker.ContainerInfo[]>([]);
|
||||
const [selection, setSelection] = useState<Docker.ContainerInfo[]>([]);
|
||||
const { config } = useConfig();
|
||||
const moduleEnabled = config.modules?.[DockerModule.title]?.enabled ?? false;
|
||||
const moduleEnabled = config.modules?.[DockerModule.id]?.enabled ?? false;
|
||||
|
||||
const { t } = useTranslation('modules/docker-module');
|
||||
const { t } = useTranslation('modules/docker');
|
||||
|
||||
useEffect(() => {
|
||||
reload();
|
||||
@@ -54,7 +54,7 @@ export default function DockerMenuButton(props: any) {
|
||||
);
|
||||
}, 300);
|
||||
}
|
||||
const exists = config.modules?.[DockerModule.title]?.enabled ?? false;
|
||||
const exists = config.modules?.[DockerModule.id]?.enabled ?? false;
|
||||
if (!exists) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function DockerTable({
|
||||
const { classes, cx } = useStyles();
|
||||
const [search, setSearch] = useState('');
|
||||
|
||||
const { t } = useTranslation('modules/docker-module');
|
||||
const { t } = useTranslation('modules/docker');
|
||||
|
||||
useEffect(() => {
|
||||
setContainers(containers);
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
Skeleton,
|
||||
ScrollArea,
|
||||
Center,
|
||||
Stack,
|
||||
} from '@mantine/core';
|
||||
import { IconDownload as Download } from '@tabler/icons';
|
||||
import { useEffect, useState } from 'react';
|
||||
@@ -32,7 +33,7 @@ export const DownloadsModule: IModule = {
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
translationNamespace: 'modules/downloads-module',
|
||||
id: 'torrents-status',
|
||||
};
|
||||
|
||||
export default function DownloadComponent() {
|
||||
@@ -46,12 +47,12 @@ export default function DownloadComponent() {
|
||||
service.type === 'Deluge'
|
||||
) ?? [];
|
||||
const hideComplete: boolean =
|
||||
(config?.modules?.[DownloadsModule.title]?.options?.hidecomplete?.value as boolean) ?? false;
|
||||
(config?.modules?.[DownloadsModule.id]?.options?.hidecomplete?.value as boolean) ?? false;
|
||||
const [torrents, setTorrents] = useState<NormalizedTorrent[]>([]);
|
||||
const setSafeInterval = useSetSafeInterval();
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const { t } = useTranslation('modules/downloads-module');
|
||||
const { t } = useTranslation(`modules/${DownloadsModule.id}`);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
@@ -85,13 +86,13 @@ export default function DownloadComponent() {
|
||||
|
||||
if (downloadServices.length === 0) {
|
||||
return (
|
||||
<Group>
|
||||
<Stack>
|
||||
<Title order={3}>{t('card.errors.noDownloadClients.title')}</Title>
|
||||
<Group>
|
||||
<Text>{t('card.errors.noDownloadClients.text')}</Text>
|
||||
<AddItemShelfButton />
|
||||
</Group>
|
||||
</Group>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ export const TotalDownloadsModule: IModule = {
|
||||
title: 'Download Speed',
|
||||
icon: Download,
|
||||
component: TotalDownloadsComponent,
|
||||
translationNamespace: 'modules/total-downloads-module',
|
||||
id: 'dlspeed',
|
||||
};
|
||||
|
||||
interface torrentHistory {
|
||||
@@ -37,7 +37,7 @@ export default function TotalDownloadsComponent() {
|
||||
service.type === 'Transmission' ||
|
||||
service.type === 'Deluge'
|
||||
) ?? [];
|
||||
const { t } = useTranslation('modules/downloads-module');
|
||||
const { t } = useTranslation(`modules/${TotalDownloadsModule.id}`);
|
||||
|
||||
const [torrentHistory, torrentHistoryHandlers] = useListState<torrentHistory>([]);
|
||||
const [torrents, setTorrents] = useState<NormalizedTorrent[]>([]);
|
||||
|
||||
@@ -18,7 +18,7 @@ import { IModule } from './ModuleTypes';
|
||||
|
||||
function getItems(module: IModule) {
|
||||
const { config, setConfig } = useConfig();
|
||||
const { t } = useTranslation(module.translationNamespace);
|
||||
const { t } = useTranslation([module.id, 'common']);
|
||||
|
||||
const items: JSX.Element[] = [];
|
||||
if (module.options) {
|
||||
@@ -28,8 +28,8 @@ function getItems(module: IModule) {
|
||||
const types = values.map((v) => typeof v.value);
|
||||
// Loop over all the types with a for each loop
|
||||
types.forEach((type, index) => {
|
||||
const optionName = `${module.title}.${keys[index]}`;
|
||||
const moduleInConfig = config.modules?.[module.title];
|
||||
const optionName = `${module.id}.${keys[index]}`;
|
||||
const moduleInConfig = config.modules?.[module.id];
|
||||
if (type === 'object') {
|
||||
items.push(
|
||||
<MultiSelect
|
||||
@@ -46,7 +46,7 @@ function getItems(module: IModule) {
|
||||
...config,
|
||||
modules: {
|
||||
...config.modules,
|
||||
[module.title]: {
|
||||
[module.id]: {
|
||||
...moduleInConfig,
|
||||
options: {
|
||||
...moduleInConfig?.options,
|
||||
@@ -71,12 +71,12 @@ function getItems(module: IModule) {
|
||||
...config,
|
||||
modules: {
|
||||
...config.modules,
|
||||
[module.title]: {
|
||||
...config.modules[module.title],
|
||||
[module.id]: {
|
||||
...config.modules[module.id],
|
||||
options: {
|
||||
...config.modules[module.title].options,
|
||||
...config.modules[module.id].options,
|
||||
[keys[index]]: {
|
||||
...config.modules[module.title].options?.[keys[index]],
|
||||
...config.modules[module.id].options?.[keys[index]],
|
||||
value: (e.target as any)[0].value,
|
||||
},
|
||||
},
|
||||
@@ -99,7 +99,7 @@ function getItems(module: IModule) {
|
||||
onChange={(e) => {}}
|
||||
/>
|
||||
|
||||
<Button type="submit">Save</Button>
|
||||
<Button type="submit">{t('actions.save')}</Button>
|
||||
</Group>
|
||||
</form>
|
||||
);
|
||||
@@ -120,12 +120,12 @@ function getItems(module: IModule) {
|
||||
...config,
|
||||
modules: {
|
||||
...config.modules,
|
||||
[module.title]: {
|
||||
...config.modules[module.title],
|
||||
[module.id]: {
|
||||
...config.modules[module.id],
|
||||
options: {
|
||||
...config.modules[module.title].options,
|
||||
...config.modules[module.id].options,
|
||||
[keys[index]]: {
|
||||
...config.modules[module.title].options?.[keys[index]],
|
||||
...config.modules[module.id].options?.[keys[index]],
|
||||
value: e.currentTarget.checked,
|
||||
},
|
||||
},
|
||||
@@ -148,7 +148,7 @@ export function ModuleWrapper(props: any) {
|
||||
const { config, setConfig } = useConfig();
|
||||
const enabledModules = config.modules ?? {};
|
||||
// Remove 'Module' from enabled modules titles
|
||||
const isShown = enabledModules[module.title]?.enabled ?? false;
|
||||
const isShown = enabledModules[module.id]?.enabled ?? false;
|
||||
//TODO: fix the hover problem
|
||||
const [hovering, setHovering] = useState(false);
|
||||
const { t } = useTranslation('modules');
|
||||
@@ -160,7 +160,7 @@ export function ModuleWrapper(props: any) {
|
||||
return (
|
||||
<Card
|
||||
{...props}
|
||||
key={module.title}
|
||||
key={module.id}
|
||||
hidden={!isShown}
|
||||
withBorder
|
||||
radius="lg"
|
||||
@@ -195,7 +195,7 @@ export function ModuleMenu(props: any) {
|
||||
<>
|
||||
{module.options && (
|
||||
<Menu
|
||||
key={module.title}
|
||||
key={module.id}
|
||||
withinPortal
|
||||
width="lg"
|
||||
shadow="xl"
|
||||
|
||||
@@ -6,7 +6,7 @@ export const OverseerrModule: IModule = {
|
||||
title: 'Overseerr',
|
||||
icon: IconEyeglass,
|
||||
component: OverseerrMediaDisplay,
|
||||
translationNamespace: 'modules/overseerr-module',
|
||||
id: 'overseerr',
|
||||
};
|
||||
|
||||
export interface OverseerSearchProps {
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useColorTheme } from '../../tools/color';
|
||||
import { MovieResult } from './Movie.d';
|
||||
import { MediaType, Result } from './SearchResult.d';
|
||||
import { TvShowResult, TvShowResultSeason } from './TvShow.d';
|
||||
|
||||
interface RequestModalProps {
|
||||
base: Result;
|
||||
opened: boolean;
|
||||
@@ -57,7 +58,7 @@ export function MovieRequestModal({
|
||||
setOpened: (opened: boolean) => void;
|
||||
}) {
|
||||
const { secondaryColor } = useColorTheme();
|
||||
const { t } = useTranslation('modules/overseerr-module');
|
||||
const { t } = useTranslation('modules/overseerr');
|
||||
|
||||
return (
|
||||
<Modal
|
||||
@@ -114,7 +115,7 @@ export function TvRequestModal({
|
||||
}) {
|
||||
const [selection, setSelection] = useState<TvShowResultSeason[]>(result.seasons);
|
||||
const { classes, cx } = useStyles();
|
||||
const { t } = useTranslation('modules/overseerr-module');
|
||||
const { t } = useTranslation('modules/overseerr');
|
||||
|
||||
const toggleRow = (container: TvShowResultSeason) =>
|
||||
setSelection((current: TvShowResultSeason[]) =>
|
||||
|
||||
@@ -11,7 +11,7 @@ export const PingModule: IModule = {
|
||||
title: 'Ping Services',
|
||||
icon: Plug,
|
||||
component: PingComponent,
|
||||
translationNamespace: 'modules/ping-module',
|
||||
id: 'ping',
|
||||
};
|
||||
|
||||
export default function PingComponent(props: any) {
|
||||
@@ -21,9 +21,9 @@ export default function PingComponent(props: any) {
|
||||
const { url }: { url: string } = props;
|
||||
const [isOnline, setOnline] = useState<State>('loading');
|
||||
const [response, setResponse] = useState(500);
|
||||
const exists = config.modules?.[PingModule.title]?.enabled ?? false;
|
||||
const exists = config.modules?.[PingModule.id]?.enabled ?? false;
|
||||
|
||||
const { t } = useTranslation('modules/ping-module');
|
||||
const { t } = useTranslation('modules/ping');
|
||||
|
||||
function statusCheck(response: AxiosResponse) {
|
||||
const { status }: { status: string[] } = props;
|
||||
@@ -54,7 +54,7 @@ export default function PingComponent(props: any) {
|
||||
.catch((error) => {
|
||||
statusCheck(error.response);
|
||||
});
|
||||
}, [config.modules?.[PingModule.title]?.enabled]);
|
||||
}, [config.modules?.[PingModule.id]?.enabled]);
|
||||
if (!exists) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -30,15 +30,15 @@ export const SearchModule: IModule = {
|
||||
title: 'Search',
|
||||
icon: Search,
|
||||
component: SearchBar,
|
||||
translationNamespace: 'modules/search-module',
|
||||
id: 'search',
|
||||
};
|
||||
|
||||
export default function SearchBar(props: any) {
|
||||
const { classes, cx } = useStyles();
|
||||
// Config
|
||||
const { config } = useConfig();
|
||||
const isModuleEnabled = config.modules?.[SearchModule.title]?.enabled ?? false;
|
||||
const isOverseerrEnabled = config.modules?.[OverseerrModule.title]?.enabled ?? false;
|
||||
const isModuleEnabled = config.modules?.[SearchModule.id]?.enabled ?? false;
|
||||
const isOverseerrEnabled = config.modules?.[OverseerrModule.id]?.enabled ?? false;
|
||||
const OverseerrService = config.services.find(
|
||||
(service) => service.type === 'Overseerr' || service.type === 'Jellyseerr'
|
||||
);
|
||||
@@ -60,7 +60,7 @@ export default function SearchBar(props: any) {
|
||||
},
|
||||
});
|
||||
const [debounced, cancel] = useDebouncedValue(form.values.query, 250);
|
||||
const { t } = useTranslation('modules/search-module');
|
||||
const { t } = useTranslation('modules/search');
|
||||
|
||||
useEffect(() => {
|
||||
if (OverseerrService === undefined && isOverseerrEnabled) {
|
||||
|
||||
@@ -32,7 +32,7 @@ export const WeatherModule: IModule = {
|
||||
value: 'Paris',
|
||||
},
|
||||
},
|
||||
translationNamespace: 'modules/weather-module',
|
||||
id: 'weather',
|
||||
};
|
||||
|
||||
// 0 Clear sky
|
||||
@@ -49,7 +49,7 @@ export const WeatherModule: IModule = {
|
||||
// 95 *Thunderstorm: Slight or moderate
|
||||
// 96, 99 *Thunderstorm with slight and heavy hail
|
||||
export function WeatherIcon(props: any) {
|
||||
const { t } = useTranslation('modules/weather-module');
|
||||
const { t } = useTranslation('modules/weather');
|
||||
|
||||
const { code } = props;
|
||||
let data: { icon: any; name: string };
|
||||
@@ -146,9 +146,9 @@ export default function WeatherComponent(props: any) {
|
||||
const { config } = useConfig();
|
||||
const [weather, setWeather] = useState({} as WeatherResponse);
|
||||
const cityInput: string =
|
||||
(config?.modules?.[WeatherModule.title]?.options?.location?.value as string) ?? 'Paris';
|
||||
(config?.modules?.[WeatherModule.id]?.options?.location?.value as string) ?? 'Paris';
|
||||
const isFahrenheit: boolean =
|
||||
(config?.modules?.[WeatherModule.title]?.options?.freedomunit?.value as boolean) ?? false;
|
||||
(config?.modules?.[WeatherModule.id]?.options?.freedomunit?.value as boolean) ?? false;
|
||||
|
||||
useEffect(() => {
|
||||
axios
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
} from '@mantine/core';
|
||||
import { NextLink } from '@mantine/next';
|
||||
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
|
||||
const useStyles = createStyles((theme) => ({
|
||||
root: {
|
||||
paddingTop: 80,
|
||||
@@ -92,3 +94,12 @@ export default function Custom404() {
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
export async function getStaticProps({ locale }: { locale: string }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(locale, ['404'])),
|
||||
// Will be passed to the page component as props
|
||||
},
|
||||
};
|
||||
}
|
||||
+17
-16
@@ -17,18 +17,19 @@ export async function getServerSideProps({
|
||||
res,
|
||||
locale,
|
||||
}: GetServerSidePropsContext): Promise<{ props: { config: Config } }> {
|
||||
let cookie = getCookie('config-name', { req, res });
|
||||
if (!cookie) {
|
||||
let configName = getCookie('config-name', { req, res });
|
||||
const configLocale = getCookie('config-locale', { req, res });
|
||||
if (!configName) {
|
||||
setCookie('config-name', 'default', {
|
||||
req,
|
||||
res,
|
||||
maxAge: 60 * 60 * 24 * 30,
|
||||
sameSite: 'strict',
|
||||
});
|
||||
cookie = 'default';
|
||||
configName = 'default';
|
||||
}
|
||||
|
||||
const translations = await serverSideTranslations(locale as string, [
|
||||
const translations = await serverSideTranslations((configLocale ?? locale) as string, [
|
||||
'common',
|
||||
'layout/app-shelf',
|
||||
'layout/add-service-app-shelf',
|
||||
@@ -46,19 +47,19 @@ export async function getServerSideProps({
|
||||
'settings/customization/app-width',
|
||||
'settings/customization/opacity-selector',
|
||||
'modules/common',
|
||||
'modules/date-module',
|
||||
'modules/calendar-module',
|
||||
'modules/total-downloads-module',
|
||||
'modules/search-module',
|
||||
'modules/downloads-module',
|
||||
'modules/weather-module',
|
||||
'modules/ping-module',
|
||||
'modules/docker-module',
|
||||
'modules/dashdot-module',
|
||||
'modules/overseerr-module',
|
||||
'modules/common-media-cards-module',
|
||||
'modules/date',
|
||||
'modules/calendar',
|
||||
'modules/dlspeed',
|
||||
'modules/search',
|
||||
'modules/torrents-status',
|
||||
'modules/weather',
|
||||
'modules/ping',
|
||||
'modules/docker',
|
||||
'modules/dashdot',
|
||||
'modules/overseerr',
|
||||
'modules/common-media-cards',
|
||||
]);
|
||||
return getConfig(cookie as string, translations);
|
||||
return getConfig(configName as string, translations);
|
||||
}
|
||||
|
||||
export default function HomePage(props: any) {
|
||||
|
||||
Reference in new issue
Block a user