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

@@ -7,20 +7,20 @@
*/
import Stack from '@mui/material/Stack';
import { useTranslation } from 'react-i18next';
import Typography from '@mui/material/Typography';
import { useLingui } from '@lingui/react/macro';
import { ReaderSettingsTypeProps } from '@/features/reader/Reader.types.ts';
import { ReaderSettingHotkey } from '@/features/reader/hotkeys/settings/components/ReaderSettingHotkey.tsx';
import { READER_HOTKEYS } from '@/features/reader/settings/ReaderSettings.constants.tsx';
import { ResetButton } from '@/base/components/buttons/ResetButton.tsx';
export const ReaderHotkeysSettings = ({ settings, updateSetting, onDefault }: ReaderSettingsTypeProps) => {
const { t } = useTranslation();
const { t } = useLingui();
return (
<Stack sx={{ gap: 2 }}>
<Stack sx={{ alignItems: 'end' }}>
<Typography variant="caption">{t('hotkeys.info.delete')}</Typography>
<Typography variant="caption">{t`Click key to remove binding`}</Typography>
</Stack>
{READER_HOTKEYS.map((hotkey) => (
<ReaderSettingHotkey

View File

@@ -8,18 +8,18 @@
import { Fragment } from 'react';
import Stack from '@mui/material/Stack';
import { useTranslation } from 'react-i18next';
import { useLingui } from '@lingui/react/macro';
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
import { Kbd } from '@/base/components/texts/Kbd.tsx';
export const Hotkey = ({ keys, removeKey }: { keys: string[]; removeKey?: (key: string) => void }) => {
const { t } = useTranslation();
const { t } = useLingui();
return (
<Stack sx={{ flexDirection: 'row', flexWrap: 'wrap', gap: 1 }}>
{keys.map((key, index) => (
<Fragment key={key}>
<CustomTooltip title={t('global.button.delete')} hidden={!removeKey}>
<CustomTooltip title={t`Delete`} hidden={!removeKey}>
<Stack
sx={{
flexDirection: 'row',

View File

@@ -6,37 +6,38 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { MessageDescriptor } from '@lingui/core';
import Stack from '@mui/material/Stack';
import { useTranslation } from 'react-i18next';
import AddIcon from '@mui/icons-material/Add';
import Typography from '@mui/material/Typography';
import { bindTrigger, usePopupState } from 'material-ui-popup-state/hooks';
import IconButton from '@mui/material/IconButton';
import { useLingui } from '@lingui/react/macro';
import { msg } from '@lingui/core/macro';
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
import { ReaderHotkey } from '@/features/reader/Reader.types.ts';
import { DEFAULT_READER_SETTINGS } from '@/features/reader/settings/ReaderSettings.constants.tsx';
import { RecordHotkey } from '@/features/reader/hotkeys/settings/components/RecordHotkey.tsx';
import { Hotkey } from '@/features/reader/hotkeys/settings/components/Hotkey.tsx';
import { ResetButton } from '@/base/components/buttons/ResetButton.tsx';
import { TranslationKey } from '@/base/Base.types.ts';
const READER_HOTKEY_TO_TITLE: Record<ReaderHotkey, TranslationKey> = {
[ReaderHotkey.PREVIOUS_PAGE]: 'reader.settings.hotkey.previous_page',
[ReaderHotkey.NEXT_PAGE]: 'reader.settings.hotkey.next_page',
[ReaderHotkey.SCROLL_BACKWARD]: 'reader.settings.hotkey.scroll_backward',
[ReaderHotkey.SCROLL_FORWARD]: 'reader.settings.hotkey.scroll_forward',
[ReaderHotkey.PREVIOUS_CHAPTER]: 'reader.settings.hotkey.previous_chapter',
[ReaderHotkey.NEXT_CHAPTER]: 'reader.settings.hotkey.next_chapter',
[ReaderHotkey.TOGGLE_MENU]: 'reader.settings.hotkey.menu',
[ReaderHotkey.CYCLE_SCALE_TYPE]: 'reader.settings.hotkey.scale_type',
[ReaderHotkey.STRETCH_IMAGE]: 'reader.settings.hotkey.stretch_image',
[ReaderHotkey.OFFSET_SPREAD_PAGES]: 'reader.settings.hotkey.offset_spread_pages',
[ReaderHotkey.CYCLE_READING_MODE]: 'reader.settings.hotkey.reading_mode',
[ReaderHotkey.CYCLE_READING_DIRECTION]: 'reader.settings.hotkey.reading_direction',
[ReaderHotkey.TOGGLE_AUTO_SCROLL]: 'reader.settings.hotkey.auto_scroll',
[ReaderHotkey.AUTO_SCROLL_SPEED_INCREASE]: 'reader.settings.hotkey.auto_scroll_speed_increase',
[ReaderHotkey.AUTO_SCROLL_SPEED_DECREASE]: 'reader.settings.hotkey.auto_scroll_speed_decrease',
[ReaderHotkey.EXIT_READER]: 'reader.button.exit',
const READER_HOTKEY_TO_TITLE: Record<ReaderHotkey, MessageDescriptor> = {
[ReaderHotkey.PREVIOUS_PAGE]: msg`Previous page`,
[ReaderHotkey.NEXT_PAGE]: msg`Next page`,
[ReaderHotkey.SCROLL_BACKWARD]: msg`Scroll backward`,
[ReaderHotkey.SCROLL_FORWARD]: msg`Scroll forward`,
[ReaderHotkey.PREVIOUS_CHAPTER]: msg`Previous chapter`,
[ReaderHotkey.NEXT_CHAPTER]: msg`Next chapter`,
[ReaderHotkey.TOGGLE_MENU]: msg`Toggle menu`,
[ReaderHotkey.CYCLE_SCALE_TYPE]: msg`Cycle image scale type`,
[ReaderHotkey.STRETCH_IMAGE]: msg`Toggle stretch image`,
[ReaderHotkey.OFFSET_SPREAD_PAGES]: msg`Toggle offset spread pages`,
[ReaderHotkey.CYCLE_READING_MODE]: msg`Cycle reading mode`,
[ReaderHotkey.CYCLE_READING_DIRECTION]: msg`Cycle reading direction`,
[ReaderHotkey.TOGGLE_AUTO_SCROLL]: msg`Toggle auto scroll`,
[ReaderHotkey.AUTO_SCROLL_SPEED_INCREASE]: msg`Increase auto scroll speed`,
[ReaderHotkey.AUTO_SCROLL_SPEED_DECREASE]: msg`Decrease auto scroll speed`,
[ReaderHotkey.EXIT_READER]: msg`Exit reader`,
};
export const ReaderSettingHotkey = ({
@@ -50,7 +51,7 @@ export const ReaderSettingHotkey = ({
existingKeys: string[];
updateSetting: (keys: string[]) => void;
}) => {
const { t } = useTranslation();
const { t } = useLingui();
const popupState = usePopupState({ popupId: 'reader-setting-record-hotkey', variant: 'dialog' });
return (
@@ -61,7 +62,7 @@ export const ReaderSettingHotkey = ({
keys={keys}
removeKey={(keyToRemove) => updateSetting(keys.filter((key) => key !== keyToRemove))}
/>
<CustomTooltip title={t('global.button.add')}>
<CustomTooltip title={t`Add`}>
<IconButton {...bindTrigger(popupState)} color="inherit">
<AddIcon />
</IconButton>

View File

@@ -8,7 +8,6 @@
import { useEffect } from 'react';
import Stack from '@mui/material/Stack';
import { Trans, useTranslation } from 'react-i18next';
import { useRecordHotkeys } from 'react-hotkeys-hook';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
@@ -16,6 +15,7 @@ import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
import { Trans, useLingui } from '@lingui/react/macro';
import { Hotkey } from '@/features/reader/hotkeys/settings/components/Hotkey.tsx';
export const RecordHotkey = ({
@@ -27,7 +27,7 @@ export const RecordHotkey = ({
onCreate: (keys: string[]) => void;
existingKeys: string[];
}) => {
const { t } = useTranslation();
const { t } = useLingui();
const [recordedKeys, { start, stop, resetKeys }] = useRecordHotkeys();
const keys = [[...recordedKeys].join('+')];
@@ -45,23 +45,15 @@ export const RecordHotkey = ({
return (
<Dialog open onClose={onClose} fullWidth>
<DialogTitle>{t('hotkeys.create.dialog.title')}</DialogTitle>
<DialogTitle>{t`Record keybind`}</DialogTitle>
<DialogContent>
<Stack sx={{ flexDirection: 'row', gap: 1 }}>
<Trans
i18nKey="hotkeys.create.dialog.label"
components={{
Keys: recordedKeys.size ? (
<Hotkey keys={keys} />
) : (
<Typography>{t('hotkeys.create.dialog.placeholder')}</Typography>
),
}}
>
Recorded keys:
<Trans>
Recorded hotkeys:{' '}
{recordedKeys.size ? <Hotkey keys={keys} /> : <Typography>{t`Press keys`}</Typography>}
</Trans>
</Stack>
{isExistingKey && <Typography color="error">{t('hotkeys.create.error.exists')}</Typography>}
{isExistingKey && <Typography color="error">{t`Hotkey already exists`}</Typography>}
</DialogContent>
<DialogActions>
<Stack
@@ -71,9 +63,9 @@ export const RecordHotkey = ({
width: '100%',
}}
>
<Button onClick={resetKeys}>{t('global.button.reset')}</Button>
<Button onClick={resetKeys}>{t`Reset`}</Button>
<Stack direction="row">
<Button onClick={onClose}>{t('global.button.cancel')}</Button>
<Button onClick={onClose}>{t`Cancel`}</Button>
<Button
disabled={isExistingKey}
onClick={() => {
@@ -81,7 +73,7 @@ export const RecordHotkey = ({
onCreate(keys);
}}
>
{t('global.button.create')}
{t`Create`}
</Button>
</Stack>
</Stack>