add translation keys (#246)
* Fix i18n tsc issue "t" can return null by default. This was already disabled in the config, but it had no effect on tsc. * Fix translation in "DefaultNavBar" key was missing and since this is a constant the translation wouldn't update in case the language got changed after first load. * Enable typing for i18n translation keys * Add translation keys
This commit is contained in:
@@ -7,12 +7,14 @@ import NavbarContext from 'components/context/NavbarContext';
|
||||
import LoadingPlaceholder from 'components/util/LoadingPlaceholder';
|
||||
import { useQuery } from 'util/client';
|
||||
import { IAbout } from 'typings';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function About() {
|
||||
const { t } = useTranslation();
|
||||
const { setTitle, setAction } = useContext(NavbarContext);
|
||||
|
||||
useEffect(() => {
|
||||
setTitle('About');
|
||||
setTitle(t('settings.about.title'));
|
||||
setAction(null);
|
||||
}, []);
|
||||
|
||||
@@ -32,19 +34,22 @@ export default function About() {
|
||||
return (
|
||||
<List>
|
||||
<ListItem>
|
||||
<ListItemText primary="Server" secondary={`${about.name} ${about.buildType}`} />
|
||||
<ListItemText
|
||||
primary={t('settings.about.label.server')}
|
||||
secondary={`${about.name} ${about.buildType}`}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText primary="Server version" secondary={version()} />
|
||||
<ListItemText primary={t('settings.about.label.server_version')} secondary={version()} />
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<ListItemText primary="Build time" secondary={buildTime()} />
|
||||
<ListItemText primary={t('settings.about.label.build_time')} secondary={buildTime()} />
|
||||
</ListItem>
|
||||
<ListItemLink to={about.github}>
|
||||
<ListItemText primary="Github" secondary={about.github} />
|
||||
<ListItemText primary={t('settings.about.label.github')} secondary={about.github} />
|
||||
</ListItemLink>
|
||||
<ListItemLink to={about.discord}>
|
||||
<ListItemText primary="Discord" secondary={about.discord} />
|
||||
<ListItemText primary={t('settings.about.label.discord')} secondary={about.discord} />
|
||||
</ListItemLink>
|
||||
</List>
|
||||
);
|
||||
|
||||
@@ -14,11 +14,13 @@ import client from 'util/client';
|
||||
import makeToast from 'components/util/Toast';
|
||||
import ListItemLink from 'components/util/ListItemLink';
|
||||
import NavbarContext from 'components/context/NavbarContext';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function Backup() {
|
||||
const { t } = useTranslation();
|
||||
const { setTitle, setAction } = useContext(NavbarContext);
|
||||
useEffect(() => {
|
||||
setTitle('Backup');
|
||||
setTitle(t('settings.backup.title'));
|
||||
setAction(null);
|
||||
}, []);
|
||||
|
||||
@@ -29,17 +31,17 @@ export default function Backup() {
|
||||
const formData = new FormData();
|
||||
formData.append('backup.proto.gz', file);
|
||||
|
||||
makeToast('Restoring backup....', 'info');
|
||||
makeToast(t('settings.backup.label.restoring_backup'), 'info');
|
||||
client
|
||||
.post('/api/v1/backup/import/file', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
})
|
||||
.then(() => makeToast('Backup restore finished!', 'success'))
|
||||
.catch(() => makeToast('Backup restore failed!', 'error'));
|
||||
.then(() => makeToast(t('settings.backup.label.restored_backup'), 'success'))
|
||||
.catch(() => makeToast(t('settings.backup.label.backup_restore_failed'), 'error'));
|
||||
} else if (file.name.toLowerCase().endsWith('json')) {
|
||||
makeToast('legacy backups are not supported!', 'error');
|
||||
makeToast(t('settings.backup.label.legacy_backup_unsupported'), 'error');
|
||||
} else {
|
||||
makeToast('invalid file type!', 'error');
|
||||
makeToast(t('global.error.label.invalid_file_type'), 'error');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -74,12 +76,15 @@ export default function Backup() {
|
||||
<>
|
||||
<List sx={{ padding: 0 }}>
|
||||
<ListItemLink to={`${baseURL}/api/v1/backup/export/file`} directLink>
|
||||
<ListItemText primary="Create Backup" secondary="Backup library as a Tachiyomi backup" />
|
||||
<ListItemText
|
||||
primary={t('settings.backup.label.create_backup')}
|
||||
secondary={t('settings.backup.label.create_backup_info')}
|
||||
/>
|
||||
</ListItemLink>
|
||||
<ListItem button onClick={() => document.getElementById('backup-file')?.click()}>
|
||||
<ListItemText
|
||||
primary="Restore Backup"
|
||||
secondary="You can also drag and drop the backup file here to restore"
|
||||
primary={t('settings.backup.label.restore_backup')}
|
||||
secondary={t('settings.backup.label.restore_backup_info')}
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
|
||||
@@ -34,6 +34,7 @@ import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import NavbarContext from 'components/context/NavbarContext';
|
||||
import client, { useQuery } from 'util/client';
|
||||
import { ICategory } from 'typings';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const getItemStyle = (
|
||||
isDragging: boolean,
|
||||
@@ -49,9 +50,11 @@ const getItemStyle = (
|
||||
});
|
||||
|
||||
export default function Categories() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { setTitle, setAction } = useContext(NavbarContext);
|
||||
useEffect(() => {
|
||||
setTitle('Categories');
|
||||
setTitle(t('category.title.categories'));
|
||||
setAction(null);
|
||||
}, []);
|
||||
|
||||
@@ -196,14 +199,16 @@ export default function Categories() {
|
||||
</Fab>
|
||||
<Dialog open={dialogOpen} onClose={handleDialogCancel}>
|
||||
<DialogTitle id="form-dialog-title">
|
||||
{categoryToEdit === -1 ? 'New Catalog' : 'Edit Catalog'}
|
||||
{categoryToEdit === -1
|
||||
? t('category.dialog.title.new_category')
|
||||
: t('category.dialog.title.edit_category')}
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<TextField
|
||||
autoFocus
|
||||
margin="dense"
|
||||
id="name"
|
||||
label="Category Name"
|
||||
label={t('category.label.category_name')}
|
||||
type="text"
|
||||
fullWidth
|
||||
value={dialogName}
|
||||
@@ -217,15 +222,15 @@ export default function Categories() {
|
||||
color="default"
|
||||
/>
|
||||
}
|
||||
label="Default category when adding new manga to library"
|
||||
label={t('category.label.use_as_default_category')}
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={handleDialogCancel} color="primary">
|
||||
Cancel
|
||||
{t('global.button.cancel')}
|
||||
</Button>
|
||||
<Button onClick={handleDialogSubmit} color="primary">
|
||||
Submit
|
||||
{t('global.button.submit')}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
@@ -21,11 +21,13 @@ import {
|
||||
} from 'util/readerSettings';
|
||||
import ReaderSettingsOptions from 'components/reader/ReaderSettingsOptions';
|
||||
import { IReaderSettings } from 'typings';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function DefaultReaderSettings() {
|
||||
const { t } = useTranslation();
|
||||
const { setTitle, setAction } = useContext(NavbarContext);
|
||||
useEffect(() => {
|
||||
setTitle('Default Reader Settings');
|
||||
setTitle(t('reader.settings.title.default_reader_settings'));
|
||||
setAction(null);
|
||||
}, []);
|
||||
|
||||
@@ -33,7 +35,7 @@ export default function DefaultReaderSettings() {
|
||||
|
||||
const setSettingValue = (key: keyof IReaderSettings, value: string | boolean) => {
|
||||
requestUpdateServerMetadata(metadata ?? {}, [[key, value]]).catch(() =>
|
||||
makeToast('Failed to save the default reader settings to the server', 'warning'),
|
||||
makeToast(t('reader.settings.error.label.failed_to_save_settings'), 'warning'),
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,13 +7,15 @@ import makeToast from 'components/util/Toast';
|
||||
import ListItemIcon from '@mui/material/ListItemIcon';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import { SearchMetadataKeys } from 'typings';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export default function SearchSettings() {
|
||||
const { t } = useTranslation();
|
||||
const { metadata, settings } = useSearchSettings();
|
||||
|
||||
const setSettingValue = (key: SearchMetadataKeys, value: boolean) => {
|
||||
requestUpdateServerMetadata(metadata ?? {}, [[key, value]]).catch(() =>
|
||||
makeToast('Failed to save the default search settings to the server', 'warning'),
|
||||
makeToast(t('search.error.label.failed_to_save_settings'), 'warning'),
|
||||
);
|
||||
};
|
||||
return (
|
||||
@@ -21,7 +23,7 @@ export default function SearchSettings() {
|
||||
<ListItemIcon>
|
||||
<SearchIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary="Ignore Filters when Searching" />
|
||||
<ListItemText primary={t('search.label.ignore_filters')} />
|
||||
<ListItemSecondaryAction>
|
||||
<Switch
|
||||
edge="end"
|
||||
|
||||
Reference in New Issue
Block a user