Migrate to lingui
Switch to "lingui" for better DX. Tried to persist existing languages as much as possible. Removed "vite-plugin-node-polyfills" because it's incompatible with "lingui"
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useEffect, useState } from 'react';
|
||||
import ListItemButton from '@mui/material/ListItemButton';
|
||||
import ListItemText from '@mui/material/ListItemText';
|
||||
@@ -16,7 +15,8 @@ import DialogTitle from '@mui/material/DialogTitle';
|
||||
import DialogContentText from '@mui/material/DialogContentText';
|
||||
import DialogActions from '@mui/material/DialogActions';
|
||||
import Button from '@mui/material/Button';
|
||||
import { t as translate } from 'i18next';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { t as translate } from '@lingui/core/macro';
|
||||
import { ThreeStateCheckboxInput } from '@/base/components/inputs/ThreeStateCheckboxInput.tsx';
|
||||
import { makeToast } from '@/base/utils/Toast.ts';
|
||||
import { IncludeOrExclude } from '@/lib/graphql/generated/graphql.ts';
|
||||
@@ -68,11 +68,11 @@ const getCategoryUpdateInfo = (
|
||||
const noSpecificallyIncludedCategories = areIncluded && !categories.length && unsetCategories;
|
||||
const includesAllCategories = categories.length === allCategories;
|
||||
if (noSpecificallyIncludedCategories || includesAllCategories) {
|
||||
return translate('extension.language.all');
|
||||
return translate`All`;
|
||||
}
|
||||
|
||||
if (!categories.length) {
|
||||
return translate('global.label.none');
|
||||
return translate`None`;
|
||||
}
|
||||
|
||||
return categories.map((category) => category.name).join(', ');
|
||||
@@ -91,7 +91,7 @@ export const CategoriesInclusionSetting = ({
|
||||
includeField,
|
||||
dialogText,
|
||||
}: CategoriesInclusionSettingProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const [dialogCategories, setDialogCategories] = useState(categories);
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
@@ -141,7 +141,7 @@ export const CategoriesInclusionSetting = ({
|
||||
// TODO - update cache immediately
|
||||
// mutate(categoriesEndpoint, [...dialogCategories], { revalidate: false });
|
||||
} catch (e) {
|
||||
makeToast(t('global.error.label.failed_to_save_changes'), 'error', getErrorMessage(e));
|
||||
makeToast(t`Failed to save changes`, 'error', getErrorMessage(e));
|
||||
// mutate(categoriesEndpoint, [...categories]);
|
||||
}
|
||||
};
|
||||
@@ -155,27 +155,18 @@ export const CategoriesInclusionSetting = ({
|
||||
<>
|
||||
<ListItemButton onClick={() => setIsDialogOpen(true)}>
|
||||
<ListItemText
|
||||
primary={t('category.title.category_other')}
|
||||
primary={t`Category`}
|
||||
secondary={
|
||||
<>
|
||||
<span>
|
||||
{t('category.settings.inclusion.label.include', {
|
||||
includedCategoriesText,
|
||||
})}
|
||||
</span>
|
||||
<span>
|
||||
{t('category.settings.inclusion.label.exclude', {
|
||||
excludedCategoriesText,
|
||||
})}
|
||||
</span>
|
||||
<span>{t`Include: ${includedCategoriesText}`}</span>
|
||||
<span>{t`Exclude: ${excludedCategoriesText}`}</span>
|
||||
</>
|
||||
}
|
||||
secondaryTypographyProps={{ style: { display: 'flex', flexDirection: 'column' } }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
|
||||
<Dialog open={isDialogOpen} onClose={closeDialog}>
|
||||
<DialogTitle>{t('category.title.category_other')}</DialogTitle>
|
||||
<DialogTitle>{t`Category`}</DialogTitle>
|
||||
<DialogContent>
|
||||
{dialogText && <DialogContentText sx={{ paddingBottom: '10px' }}>{dialogText}</DialogContentText>}
|
||||
<CheckboxContainer>
|
||||
@@ -207,10 +198,10 @@ export const CategoriesInclusionSetting = ({
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={closeDialog} color="primary">
|
||||
{t('global.button.cancel')}
|
||||
{t`Cancel`}
|
||||
</Button>
|
||||
<Button onClick={updateCategories} color="primary">
|
||||
{t('global.button.ok')}
|
||||
{t`Ok`}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
@@ -13,10 +13,10 @@ import DialogContent from '@mui/material/DialogContent';
|
||||
import DialogActions from '@mui/material/DialogActions';
|
||||
import Dialog from '@mui/material/Dialog';
|
||||
import FormGroup from '@mui/material/FormGroup';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import { AwaitableComponentProps } from 'awaitable-component';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { Mangas } from '@/features/manga/services/Mangas.ts';
|
||||
import { useSelectableCollection } from '@/base/collection/hooks/useSelectableCollection.ts';
|
||||
@@ -90,7 +90,7 @@ const getCategoryCheckedState = (
|
||||
};
|
||||
|
||||
export function CategorySelect(props: CategorySelectProps) {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const {
|
||||
onDismiss,
|
||||
@@ -161,7 +161,7 @@ export function CategorySelect(props: CategorySelectProps) {
|
||||
|
||||
if (doNotShowAddToLibraryDialogAgain) {
|
||||
updateMetadataServerSettings('showAddToLibraryCategorySelectDialog', false).catch((e) =>
|
||||
makeToast(t('search.error.label.failed_to_save_settings'), 'error', getErrorMessage(e)),
|
||||
makeToast(t`Could not save the default search settings to the server`, 'error', getErrorMessage(e)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -196,10 +196,10 @@ export function CategorySelect(props: CategorySelectProps) {
|
||||
onTransitionExited={onExitComplete}
|
||||
onClose={handleCancel}
|
||||
>
|
||||
<DialogTitle>{t('category.title.set_categories')}</DialogTitle>
|
||||
<DialogTitle>{t`Set categories`}</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<FormGroup>
|
||||
{allCategories.length === 0 && <span>{t('category.error.no_categories_found.label.info')}</span>}
|
||||
{allCategories.length === 0 && <span>{t`You don't have any categories yet.`}</span>}
|
||||
{allCategories.map((category) => (
|
||||
<ThreeStateCheckboxInput
|
||||
checked={getCategoryCheckedState(
|
||||
@@ -232,7 +232,7 @@ export function CategorySelect(props: CategorySelectProps) {
|
||||
<CheckboxInput
|
||||
sx={{ margin: 0 }}
|
||||
size="small"
|
||||
label={t('global.button.dont_show_dialog_again')}
|
||||
label={t`Don't show this dialog again`}
|
||||
onChange={(e) => setDoNotShowAddToLibraryDialogAgain(e.target.checked)}
|
||||
/>
|
||||
)}
|
||||
@@ -249,15 +249,15 @@ export function CategorySelect(props: CategorySelectProps) {
|
||||
to={AppRoutes.settings.childRoutes.categories.path}
|
||||
onClick={onDismiss}
|
||||
>
|
||||
{t(allCategories.length ? 'global.button.edit' : 'global.button.create')}
|
||||
{allCategories.length ? t`Edit` : t`Create`}
|
||||
</Button>
|
||||
<Stack direction="row">
|
||||
<Button autoFocus onClick={handleCancel} color="primary">
|
||||
{t('global.button.cancel')}
|
||||
{t`Cancel`}
|
||||
</Button>
|
||||
{!!allCategories.length && (
|
||||
<Button onClick={handleOk} color="primary">
|
||||
{t('global.button.ok')}
|
||||
{t`Ok`}
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
@@ -10,11 +10,11 @@ import IconButton from '@mui/material/IconButton';
|
||||
import DragHandleIcon from '@mui/icons-material/DragHandle';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Box from '@mui/material/Box';
|
||||
import Card from '@mui/material/Card';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { CategoryType } from '@/lib/graphql/generated/graphql.ts';
|
||||
@@ -27,7 +27,7 @@ export const CategorySettingsCard = ({
|
||||
category: Pick<CategoryType, 'id' | 'name'>;
|
||||
onEdit: () => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const deleteCategory = () => {
|
||||
requestManager.deleteCategory(category.id);
|
||||
@@ -42,12 +42,12 @@ export const CategorySettingsCard = ({
|
||||
{category.name}
|
||||
</Typography>
|
||||
<Stack sx={{ flexDirection: 'row' }}>
|
||||
<CustomTooltip title={t('global.button.edit')}>
|
||||
<CustomTooltip title={t`Edit`}>
|
||||
<IconButton component={Box} onClick={onEdit}>
|
||||
<EditIcon />
|
||||
</IconButton>
|
||||
</CustomTooltip>
|
||||
<CustomTooltip title={t('chapter.action.download.delete.label.action')}>
|
||||
<CustomTooltip title={t`Delete`}>
|
||||
<IconButton component={Box} onClick={deleteCategory}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
|
||||
@@ -15,7 +15,7 @@ import DialogContent from '@mui/material/DialogContent';
|
||||
import DialogTitle from '@mui/material/DialogTitle';
|
||||
import Checkbox from '@mui/material/Checkbox';
|
||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { CategoryDefaultInfo, CategoryIdInfo, CategoryNameInfo } from '@/features/category/Category.types.ts';
|
||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||
@@ -31,7 +31,7 @@ export const CreateOrEditCategoryDialog = ({
|
||||
}) => {
|
||||
const isEditMode = !!category;
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const [dialogName, setDialogName] = useState(category?.name);
|
||||
const [dialogDefault, setDialogDefault] = useState(!!category?.default);
|
||||
@@ -47,47 +47,43 @@ export const CreateOrEditCategoryDialog = ({
|
||||
if (isEditMode) {
|
||||
requestManager
|
||||
.updateCategory(category.id, { name: dialogName, default: dialogDefault })
|
||||
.response.catch((e) =>
|
||||
makeToast(t('global.error.label.failed_to_save_changes'), 'error', getErrorMessage(e)),
|
||||
);
|
||||
.response.catch((e) => makeToast(t`Failed to save changes`, 'error', getErrorMessage(e)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
requestManager
|
||||
.createCategory({ name: dialogName, default: dialogDefault })
|
||||
.response.catch((e) => makeToast(t('category.error.label.create_failure'), 'error', getErrorMessage(e)));
|
||||
.response.catch((e) => makeToast(t`Could not create category`, 'error', getErrorMessage(e)));
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open onClose={onClose}>
|
||||
<DialogTitle id="form-dialog-title">
|
||||
{isEditMode ? t('category.dialog.title.edit_category_one') : t('category.dialog.title.new_category')}
|
||||
</DialogTitle>
|
||||
<DialogTitle id="form-dialog-title">{isEditMode ? t`Edit category` : t`New category`}</DialogTitle>
|
||||
<DialogContent>
|
||||
<TextField
|
||||
autoFocus
|
||||
margin="dense"
|
||||
id="name"
|
||||
label={t('category.label.category_name')}
|
||||
label={t`Category Name`}
|
||||
type="text"
|
||||
fullWidth
|
||||
value={dialogName}
|
||||
onChange={(e) => setDialogName(e.target.value.trim())}
|
||||
error={isInvalidName}
|
||||
helperText={isInvalidName ? t`global.error.label.invalid_input` : undefined}
|
||||
helperText={isInvalidName ? t`Invalid input` : undefined}
|
||||
/>
|
||||
<FormControlLabel
|
||||
control={<Checkbox checked={dialogDefault} onChange={(e) => setDialogDefault(e.target.checked)} />}
|
||||
label={t('category.label.use_as_default_category')}
|
||||
label={t`Default category when adding new manga to the library`}
|
||||
/>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} color="primary">
|
||||
{t('global.button.cancel')}
|
||||
{t`Cancel`}
|
||||
</Button>
|
||||
<Button onClick={handleDialogSubmit} color="primary" disabled={!canSubmit}>
|
||||
{t('global.button.submit')}
|
||||
{t`Submit`}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
import { ComponentProps, useMemo, useState } from 'react';
|
||||
import Fab from '@mui/material/Fab';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Box from '@mui/material/Box';
|
||||
import { closestCenter, DndContext, DragEndEvent } from '@dnd-kit/core';
|
||||
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { DEFAULT_FULL_FAB_HEIGHT } from '@/base/components/buttons/StyledFab.tsx';
|
||||
import { LoadingPlaceholder } from '@/base/components/feedback/LoadingPlaceholder.tsx';
|
||||
@@ -31,10 +31,10 @@ import { CREATE_NEW_CATEGORY_ID } from '@/features/category/Category.constants.t
|
||||
import { CreateOrEditCategoryDialog } from '@/features/category/components/CreateOrEditCategoryDialog.tsx';
|
||||
|
||||
export function CategorySettings() {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
const dndSensors = DndKitUtil.useSensorsForDevice();
|
||||
|
||||
useAppTitle(t('category.dialog.title.edit_category_other'));
|
||||
useAppTitle(t`Edit categories`);
|
||||
|
||||
const { data, loading, error, refetch } = requestManager.useGetCategories<
|
||||
GetCategoriesSettingsQuery,
|
||||
@@ -96,7 +96,7 @@ export function CategorySettings() {
|
||||
if (error) {
|
||||
return (
|
||||
<EmptyViewAbsoluteCentered
|
||||
message={t('category.error.label.request_failure')}
|
||||
message={t`Could not load categories`}
|
||||
messageExtra={getErrorMessage(error)}
|
||||
retry={() => refetch().catch(defaultPromiseErrorHandler('CategorySettings::refetch'))}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user