import {
Accordion,
ActionIcon,
Anchor,
Badge,
Button,
createStyles,
Grid,
Group,
HoverCard,
Kbd,
Modal,
Table,
Text,
Title,
Tooltip,
} from '@mantine/core';
import {
IconAnchor,
IconBrandDiscord,
IconBrandGithub,
IconFile,
IconKey,
IconLanguage,
IconSchema,
IconVersions,
IconVocabulary,
IconWorldWww,
} from '@tabler/icons-react';
import { motion } from 'framer-motion';
import { InitOptions } from 'i18next';
import { i18n, Trans, useTranslation } from 'next-i18next';
import Image from 'next/image';
import { ReactNode } from 'react';
import { useConfigContext } from '../../../../config/provider';
import { useConfigStore } from '../../../../config/store';
import { useEditModeInformationStore } from '../../../../hooks/useEditModeInformation';
import { usePackageAttributesStore } from '../../../../tools/client/zustands/usePackageAttributesStore';
import { useColorTheme } from '../../../../tools/color';
import Tip from '../../../layout/Tip';
import { usePrimaryGradient } from '../../../layout/useGradient';
import Credits from '../../../Settings/Common/Credits';
interface AboutModalProps {
opened: boolean;
closeModal: () => void;
newVersionAvailable?: string;
}
export const AboutModal = ({ opened, closeModal, newVersionAvailable }: AboutModalProps) => {
const { classes } = useStyles();
const colorGradiant = usePrimaryGradient();
const informations = useInformationTableItems(newVersionAvailable);
const { t } = useTranslation(['common', 'layout/modals/about']);
const keybinds = [
{ key: 'Mod + J', shortcut: 'Toggle light/dark mode' },
{ key: 'Mod + K', shortcut: 'Focus on search bar' },
{ key: 'Mod + B', shortcut: 'Open docker widget' },
{ key: 'Mod + E', shortcut: 'Toggle Edit mode' },
];
const rows = keybinds.map((element) => (
|
{element.key}
|
{element.shortcut}
|
));
return (
closeModal()}
opened={opened}
title={
{t('about')} Homarr
}
size="xl"
>
{informations.map((item, index) => (
|
{item.icon}
}}
/>
|
{item.content}
|
))}
}>
{t('layout/modals/about:keybinds')}
| {t('layout/modals/about:key')} |
{t('layout/modals/about:action')} |
{rows}
{t('layout/modals/about:tip')}
{t('layout/modals/about:contact')}
}
variant="default"
fullWidth
>
GitHub
}
variant="default"
fullWidth
>
Documentation
}
variant="default"
fullWidth
>
Discord
);
};
interface InformationTableItem {
icon: ReactNode;
label: string;
content: ReactNode;
}
interface ExtendedInitOptions extends InitOptions {
locales: string[];
}
const useInformationTableItems = (newVersionAvailable?: string): InformationTableItem[] => {
const { attributes } = usePackageAttributesStore();
const { editModeEnabled } = useEditModeInformationStore();
const { primaryColor } = useColorTheme();
const { configVersion } = useConfigContext();
const { configs } = useConfigStore();
let items: InformationTableItem[] = [];
if (editModeEnabled) {
items = [
...items,
{
icon: ,
label: 'experimental_disableEditMode',
content: (
WARNING
),
},
];
}
if (i18n !== null) {
const usedI18nNamespaces = i18n.reportNamespaces.getUsedNamespaces();
const initOptions = i18n.options as ExtendedInitOptions;
items = [
...items,
{
icon: ,
label: 'i18n',
content: (
{usedI18nNamespaces.length}
),
},
{
icon: ,
label: 'locales',
content: (
{initOptions.locales.length}
),
},
];
}
items = [
{
icon: ,
label: 'configurationSchemaVersion',
content: (
{configVersion}
),
},
{
icon: ,
label: 'configurationsCount',
content: (
{configs.length}
),
},
{
icon: ,
label: 'version',
content: (
{attributes.packageVersion ?? 'Unknown'}
{newVersionAvailable && (
new: {newVersionAvailable}
Version{' '}
{newVersionAvailable}
{' '}
is available ! Current version: {attributes.packageVersion}
)}
),
},
{
icon: ,
label: 'nodeEnvironment',
content: (
{attributes.environment}
),
},
...items,
];
return items;
};
const useStyles = createStyles(() => ({
informationTableColumn: {
textAlign: 'right',
},
informationIcon: {
cursor: 'default',
},
}));