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,6 +6,8 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { MessageDescriptor } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import {
|
||||
ExtensionAction,
|
||||
ExtensionGroupState,
|
||||
@@ -14,7 +16,6 @@ import {
|
||||
InstalledStates,
|
||||
} from '@/features/extension/Extensions.types.ts';
|
||||
import { DefaultLanguage } from '@/base/utils/Languages.ts';
|
||||
import { TranslationKey } from '@/base/Base.types.ts';
|
||||
|
||||
export const EXTENSION_ACTION_TO_STATE_MAP: { [action in ExtensionAction]: ExtensionState } = {
|
||||
[ExtensionAction.UPDATE]: ExtensionState.UPDATING,
|
||||
@@ -28,31 +29,33 @@ export const EXTENSION_ACTION_TO_NEXT_ACTION_MAP: { [action in ExtensionAction]:
|
||||
[ExtensionAction.INSTALL]: ExtensionAction.UNINSTALL,
|
||||
} as const;
|
||||
|
||||
export const INSTALLED_STATE_TO_TRANSLATION_KEY_MAP: { [installedState in InstalledStates]: TranslationKey } = {
|
||||
[InstalledState.UNINSTALL]: 'extension.action.label.uninstall',
|
||||
[InstalledState.INSTALL]: 'extension.action.label.install',
|
||||
[InstalledState.UPDATE]: 'extension.action.label.update',
|
||||
[InstalledState.OBSOLETE]: 'extension.state.label.obsolete',
|
||||
[InstalledState.UPDATING]: 'extension.state.label.updating',
|
||||
[InstalledState.UNINSTALLING]: 'extension.state.label.uninstalling',
|
||||
[InstalledState.INSTALLING]: 'extension.state.label.installing',
|
||||
export const INSTALLED_STATE_TO_TRANSLATION_MAP: { [installedState in InstalledStates]: MessageDescriptor } = {
|
||||
[InstalledState.UNINSTALL]: msg`Uninstall`,
|
||||
[InstalledState.INSTALL]: msg`Install`,
|
||||
[InstalledState.UPDATE]: msg`Update`,
|
||||
[InstalledState.OBSOLETE]: msg`Obsolete`,
|
||||
[InstalledState.UPDATING]: msg`Updating`,
|
||||
[InstalledState.UNINSTALLING]: msg`Uninstalling`,
|
||||
[InstalledState.INSTALLING]: msg`Installing`,
|
||||
} as const;
|
||||
|
||||
export const EXTENSION_ACTION_TO_FAILURE_TRANSLATION_KEY_MAP: {
|
||||
[action in ExtensionAction]: TranslationKey;
|
||||
export const EXTENSION_ACTION_TO_FAILURE_TRANSLATION_MAP: {
|
||||
[action in ExtensionAction]: MessageDescriptor;
|
||||
} = {
|
||||
[ExtensionAction.UPDATE]: 'extension.label.update_failed',
|
||||
[ExtensionAction.INSTALL]: 'extension.label.installation_failed',
|
||||
[ExtensionAction.UNINSTALL]: 'extension.label.uninstallation_failed',
|
||||
[ExtensionAction.UPDATE]: msg`{count, plural, one {Could not update the extension} other {Could not update the extensions}}`,
|
||||
[ExtensionAction.INSTALL]: msg`{count, plural, one {Could not install the extension} other {Could not install the extensions}}`,
|
||||
[ExtensionAction.UNINSTALL]: msg`{count, plural, one {Could not uninstall the extension} other {Could not uninstall the extensions}}`,
|
||||
};
|
||||
|
||||
export const extensionLanguageToTranslationKey: { [state in ExtensionGroupState | DefaultLanguage]: TranslationKey } = {
|
||||
[ExtensionGroupState.INSTALLED]: 'extension.state.label.installed',
|
||||
[ExtensionGroupState.UPDATE_PENDING]: 'extension.state.label.update_pending',
|
||||
[ExtensionGroupState.OBSOLETE]: 'extension.state.label.obsolete',
|
||||
[DefaultLanguage.ALL]: 'extension.language.all',
|
||||
[DefaultLanguage.OTHER]: 'extension.language.other',
|
||||
[DefaultLanguage.LOCAL_SOURCE]: 'extension.language.other',
|
||||
[DefaultLanguage.PINNED]: 'global.label.pinned',
|
||||
[DefaultLanguage.LAST_USED_SOURCE]: 'global.label.last_used',
|
||||
export const extensionLanguageToTranslation: {
|
||||
[state in ExtensionGroupState | DefaultLanguage]: MessageDescriptor;
|
||||
} = {
|
||||
[ExtensionGroupState.INSTALLED]: msg`Installed`,
|
||||
[ExtensionGroupState.UPDATE_PENDING]: msg`Update pending`,
|
||||
[ExtensionGroupState.OBSOLETE]: msg`Obsolete`,
|
||||
[DefaultLanguage.ALL]: msg`All`,
|
||||
[DefaultLanguage.OTHER]: msg`Other`,
|
||||
[DefaultLanguage.LOCAL_SOURCE]: msg`Other`,
|
||||
[DefaultLanguage.PINNED]: msg`Pinned`,
|
||||
[DefaultLanguage.LAST_USED_SOURCE]: msg`Last used`,
|
||||
};
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { t } from 'i18next';
|
||||
import {
|
||||
ExtensionAction,
|
||||
ExtensionGroupState,
|
||||
@@ -23,14 +22,15 @@ import {
|
||||
toComparableLanguages,
|
||||
} from '@/base/utils/Languages.ts';
|
||||
import {
|
||||
EXTENSION_ACTION_TO_FAILURE_TRANSLATION_KEY_MAP,
|
||||
extensionLanguageToTranslationKey,
|
||||
EXTENSION_ACTION_TO_FAILURE_TRANSLATION_MAP,
|
||||
extensionLanguageToTranslation,
|
||||
} from '@/features/extension/Extensions.constants.ts';
|
||||
import { enhancedCleanup } from '@/base/utils/Strings.ts';
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { makeToast } from '@/base/utils/Toast.ts';
|
||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||
import { toUniqueISOLanguageCodes } from '@/lib/ISOLanguageUtil.ts';
|
||||
import { i18n } from '@/i18n';
|
||||
|
||||
export const getInstalledState = (
|
||||
isInstalled: boolean,
|
||||
@@ -65,7 +65,7 @@ export const isExtensionStateOrLanguage = (languageCode: string): boolean =>
|
||||
|
||||
export const translateExtensionLanguage = (languageCode: string): string =>
|
||||
isExtensionStateOrLanguage(languageCode)
|
||||
? t(extensionLanguageToTranslationKey[languageCode as ExtensionGroupState | DefaultLanguage])
|
||||
? i18n._(extensionLanguageToTranslation[languageCode as ExtensionGroupState | DefaultLanguage])
|
||||
: languageCodeToName(languageCode);
|
||||
|
||||
export function groupExtensionsByLanguage(extensions: TExtension[]): GroupedExtensionsResult {
|
||||
@@ -165,7 +165,8 @@ export const updateExtension = async (
|
||||
}
|
||||
} catch (e) {
|
||||
makeToast(
|
||||
t(EXTENSION_ACTION_TO_FAILURE_TRANSLATION_KEY_MAP[action], { count: 1 }),
|
||||
/* lingui-extract-ignore */
|
||||
i18n.t({ ...EXTENSION_ACTION_TO_FAILURE_TRANSLATION_MAP[action], values: { count: 1 } }),
|
||||
'error',
|
||||
getErrorMessage(e),
|
||||
);
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
import Box from '@mui/material/Box';
|
||||
import Button from '@mui/material/Button';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { INSTALLED_STATE_TO_TRANSLATION_KEY_MAP } from '@/features/extension/Extensions.constants.ts';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { INSTALLED_STATE_TO_TRANSLATION_MAP } from '@/features/extension/Extensions.constants.ts';
|
||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||
import { getInstalledState, updateExtension } from '@/features/extension/Extensions.utils.ts';
|
||||
import { useBackButton } from '@/base/hooks/useBackButton.ts';
|
||||
@@ -17,7 +17,7 @@ import { ExtensionAction, InstalledState, TExtension } from '@/features/extensio
|
||||
|
||||
export const ActionButton = ({ pkgName, isInstalled, isObsolete, hasUpdate }: TExtension) => {
|
||||
const handleBack = useBackButton();
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const installedState = getInstalledState(isInstalled, isObsolete, hasUpdate);
|
||||
|
||||
@@ -44,7 +44,7 @@ export const ActionButton = ({ pkgName, isInstalled, isObsolete, hasUpdate }: TE
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t(INSTALLED_STATE_TO_TRANSLATION_KEY_MAP[installedState])}
|
||||
{t(INSTALLED_STATE_TO_TRANSLATION_MAP[installedState])}
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -7,25 +7,19 @@
|
||||
*/
|
||||
|
||||
import Stack from '@mui/material/Stack';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { TExtension } from '@/features/extension/Extensions.types.ts';
|
||||
import { ExtensionMetadata } from '@/features/extension/info/components/ExtensionMetadata.tsx';
|
||||
import { languageCodeToName } from '@/base/utils/Languages.ts';
|
||||
|
||||
export const Meta = ({ versionName, lang, isNsfw }: TExtension) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
return (
|
||||
<Stack sx={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<ExtensionMetadata title={t('global.label.version')} value={versionName} />
|
||||
<ExtensionMetadata title={t('global.language.label.language')} value={languageCodeToName(lang)} />
|
||||
{isNsfw && (
|
||||
<ExtensionMetadata
|
||||
title={t('extension.label.age_rating')}
|
||||
value="18+"
|
||||
valueProps={{ color: 'error' }}
|
||||
/>
|
||||
)}
|
||||
<ExtensionMetadata title={t`Version`} value={versionName} />
|
||||
<ExtensionMetadata title={t`Language`} value={languageCodeToName(lang)} />
|
||||
{isNsfw && <ExtensionMetadata title={t`Age rating`} value="18+" valueProps={{ color: 'error' }} />}
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,13 +7,13 @@
|
||||
*/
|
||||
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Card from '@mui/material/Card';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import SettingsIcon from '@mui/icons-material/Settings';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import CardActionArea from '@mui/material/CardActionArea';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { MUIUtil } from '@/lib/mui/MUI.util.ts';
|
||||
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
||||
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
|
||||
@@ -29,11 +29,11 @@ import { SourceConfigurableInfo, SourceIdInfo, SourceLanguageInfo } from '@/feat
|
||||
export const SourceCard = (source: SourceIdInfo & SourceLanguageInfo & SourceConfigurableInfo) => {
|
||||
const { id, isConfigurable } = source;
|
||||
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
const { isEnabled } = useGetSourceMetadata(source);
|
||||
|
||||
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 (
|
||||
@@ -45,7 +45,7 @@ export const SourceCard = (source: SourceIdInfo & SourceLanguageInfo & SourceCon
|
||||
{translateExtensionLanguage(Sources.getLanguage(source))}
|
||||
</Typography>
|
||||
{isConfigurable && (
|
||||
<CustomTooltip title={t('settings.title')}>
|
||||
<CustomTooltip title={t`Settings`}>
|
||||
<IconButton
|
||||
component={Link}
|
||||
to={AppRoutes.sources.childRoutes.configure.path(id)}
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
|
||||
import Box from '@mui/material/Box';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useMemo } from 'react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useAppTitle } from '@/features/navigation-bar/hooks/useAppTitle.ts';
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { EmptyViewAbsoluteCentered } from '@/base/components/feedback/EmptyViewAbsoluteCentered.tsx';
|
||||
@@ -26,10 +26,10 @@ import { ActionButton } from '@/features/extension/info/components/ActionButton.
|
||||
import { SourceCard } from '@/features/extension/info/components/SourceCard.tsx';
|
||||
|
||||
export const ExtensionInfo = () => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
const { pkgName } = useParams<{ pkgName: string }>();
|
||||
|
||||
useAppTitle(t('source.extension_info.title'));
|
||||
useAppTitle(t`Extension info`);
|
||||
|
||||
const extensionResponse = requestManager.useGetExtension(pkgName);
|
||||
const sourcesResponse = requestManager.useGetSourceList();
|
||||
@@ -55,7 +55,7 @@ export const ExtensionInfo = () => {
|
||||
if (error) {
|
||||
return (
|
||||
<EmptyViewAbsoluteCentered
|
||||
message={t('global.error.label.failed_to_load_data')}
|
||||
message={t`Unable to load data`}
|
||||
messageExtra={getErrorMessage(extensionResponse.error)}
|
||||
retry={() => {
|
||||
if (extensionResponse.error) {
|
||||
|
||||
Reference in New Issue
Block a user