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:
schroda
2026-01-10 19:45:02 +01:00
parent c1ac58f4d6
commit 65a9a905be
287 changed files with 120766 additions and 37748 deletions

View File

@@ -10,8 +10,8 @@ import { useCallback, useMemo } from 'react';
import IconButton from '@mui/material/IconButton';
import TravelExploreIcon from '@mui/icons-material/TravelExplore';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
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 { DefaultLanguage } from '@/base/utils/Languages.ts';
@@ -32,7 +32,7 @@ import { StyledGroupItemWrapper } from '@/base/components/virtuoso/StyledGroupIt
import { SourceLanguageSelect } from '@/features/source/components/SourceLanguageSelect.tsx';
export function Sources({ tabsMenuHeight }: { tabsMenuHeight: number }) {
const { t } = useTranslation();
const { t } = useLingui();
const { languages: shownLangs, setLanguages: setShownLangs } = SourceService.useLanguages();
const {
@@ -97,7 +97,7 @@ export function Sources({ tabsMenuHeight }: { tabsMenuHeight: number }) {
useAppAction(
<>
<CustomTooltip title={t('search.title.global_search')}>
<CustomTooltip title={t`Global Search`}>
<IconButton onClick={() => navigate(AppRoutes.sources.childRoutes.searchAll.path())} color="inherit">
<TravelExploreIcon />
</IconButton>
@@ -117,7 +117,7 @@ export function Sources({ tabsMenuHeight }: { tabsMenuHeight: number }) {
if (error) {
return (
<EmptyViewAbsoluteCentered
message={t('global.error.label.failed_to_load_data')}
message={t`Unable to load data`}
messageExtra={getErrorMessage(error)}
retry={() => refetch().catch(defaultPromiseErrorHandler('Sources::refetch'))}
/>
@@ -125,7 +125,7 @@ export function Sources({ tabsMenuHeight }: { tabsMenuHeight: number }) {
}
if (sources?.length === 0) {
return <EmptyViewAbsoluteCentered message={t('source.error.label.no_sources_found')} />;
return <EmptyViewAbsoluteCentered message={t`No sources found. Install Some extensions first.`} />;
}
return (

View File

@@ -11,12 +11,12 @@ import Button from '@mui/material/Button';
import Card from '@mui/material/Card';
import Typography from '@mui/material/Typography';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import Stack from '@mui/material/Stack';
import PushPinIcon from '@mui/icons-material/PushPin';
import PushPinOutlinedIcon from '@mui/icons-material/PushPinOutlined';
import IconButton from '@mui/material/IconButton';
import { useLingui } from '@lingui/react/macro';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { SourceContentType } from '@/features/source/browse/screens/SourceMangas.tsx';
import { GetSourcesListQuery } from '@/lib/graphql/generated/graphql.ts';
@@ -38,7 +38,7 @@ interface IProps {
}
export const SourceCard: React.FC<IProps> = (props: IProps) => {
const { t } = useTranslation();
const { t } = useLingui();
const { source, showSourceRepo, showLanguage } = props;
const {
@@ -53,10 +53,10 @@ export const SourceCard: React.FC<IProps> = (props: IProps) => {
const { isPinned } = useGetSourceMetadata(source);
const sourceName = Sources.isLocalSource(source) ? t('source.local_source.title') : name;
const sourceName = Sources.isLocalSource(source) ? t`Local source` : name;
const updateSetting = createUpdateSourceMetadata(source, (e) =>
makeToast(t('global.error.label.failed_to_save_changes'), 'error', getErrorMessage(e)),
makeToast(t`Failed to save changes`, 'error', getErrorMessage(e)),
);
return (
@@ -105,10 +105,10 @@ export const SourceCard: React.FC<IProps> = (props: IProps) => {
to={AppRoutes.sources.childRoutes.browse.path(id)}
state={{ contentType: SourceContentType.LATEST, clearCache: true }}
>
{t('global.button.latest')}
{t`Latest`}
</Button>
)}
<CustomTooltip title={t(isPinned ? 'source.pin.remove' : 'source.pin.add')}>
<CustomTooltip title={isPinned ? t`Unpin source` : t`Pin source`}>
<IconButton
{...MUIUtil.preventRippleProp()}
onClick={(e) => {