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:
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import { ReactElement } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { CustomTooltip } from '@/base/components/CustomTooltip';
|
||||
import {
|
||||
ChapterNameInfo,
|
||||
@@ -28,7 +28,7 @@ export const ContinueReadingTooltip = ({
|
||||
ChapterScanlatorInfo & {
|
||||
children: ReactElement;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const isFirstChapter = sourceOrder === 1;
|
||||
|
||||
@@ -41,11 +41,11 @@ export const ContinueReadingTooltip = ({
|
||||
},
|
||||
},
|
||||
}}
|
||||
title={t(isFirstChapter ? 'chapter.action.read.start' : 'chapter.action.read.resume', {
|
||||
chapterNumber,
|
||||
title: name,
|
||||
scanlator,
|
||||
})}
|
||||
title={
|
||||
isFirstChapter
|
||||
? t`Start reading\n#${chapterNumber} — ${name}\n${scanlator}`
|
||||
: t`Continue reading\n#${chapterNumber} — ${name}\n${scanlator}`
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</CustomTooltip>
|
||||
|
||||
@@ -11,7 +11,6 @@ import Delete from '@mui/icons-material/Delete';
|
||||
import Download from '@mui/icons-material/Download';
|
||||
import RemoveDone from '@mui/icons-material/RemoveDone';
|
||||
import Done from '@mui/icons-material/Done';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder';
|
||||
import Label from '@mui/icons-material/Label';
|
||||
import { useMemo, useState } from 'react';
|
||||
@@ -20,6 +19,7 @@ import { Link } from 'react-router-dom';
|
||||
import SyncIcon from '@mui/icons-material/Sync';
|
||||
import Dialog from '@mui/material/Dialog';
|
||||
import { AwaitableComponent } from 'awaitable-component';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { Mangas } from '@/features/manga/services/Mangas.ts';
|
||||
import { SelectableCollectionReturnType } from '@/base/collection/hooks/useSelectableCollection.ts';
|
||||
import { MenuItem } from '@/base/components/menu/MenuItem.tsx';
|
||||
@@ -60,7 +60,7 @@ export const MangaActionMenuItems = ({
|
||||
onClose,
|
||||
setHideMenu,
|
||||
}: Props) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const [isTrackDialogOpen, setIsTrackDialogOpen] = useState(false);
|
||||
|
||||
@@ -108,7 +108,7 @@ export const MangaActionMenuItems = ({
|
||||
return (
|
||||
<>
|
||||
{!!handleSelection && isSingleMode && (
|
||||
<MenuItem onClick={handleSelect} Icon={CheckBoxOutlineBlank} title={t('chapter.action.label.select')} />
|
||||
<MenuItem onClick={handleSelect} Icon={CheckBoxOutlineBlank} title={t`Select`} />
|
||||
)}
|
||||
{shouldShowMenuItem(!isFullyDownloaded) && (
|
||||
<NestedMenuItem
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
*/
|
||||
|
||||
import { styled } from '@mui/material/styles';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Button from '@mui/material/Button';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { MangaCardMode } from '@/features/manga/Manga.types.ts';
|
||||
import { MediaQuery } from '@/base/utils/MediaQuery.tsx';
|
||||
import { useMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts';
|
||||
@@ -42,7 +42,7 @@ export const MangaBadges = ({
|
||||
downloadCount?: number;
|
||||
mode: MangaCardMode;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const isTouchDevice = MediaQuery.useIsTouchDevice();
|
||||
|
||||
@@ -69,7 +69,7 @@ export const MangaBadges = ({
|
||||
}}
|
||||
color={isInLibrary ? 'error' : 'primary'}
|
||||
>
|
||||
{t(isInLibrary ? 'manga.action.library.remove.label.action' : 'manga.button.add_to_library')}
|
||||
{isInLibrary ? t`Remove from the library` : t`Add To Library`}
|
||||
</Button>
|
||||
)}
|
||||
{inLibraryIndicator && isInLibrary && (
|
||||
@@ -77,7 +77,7 @@ export const MangaBadges = ({
|
||||
className="source-manga-library-state-indicator"
|
||||
sx={{ backgroundColor: 'primary.dark', color: 'primary.contrastText', p: 0.3 }}
|
||||
>
|
||||
{t('manga.button.in_library')}
|
||||
{t`In Library`}
|
||||
</Typography>
|
||||
)}
|
||||
{((showUnreadBadge && mode === 'default') || mode === 'duplicate') && (unread ?? 0) > 0 && (
|
||||
|
||||
@@ -10,7 +10,7 @@ import React, { ForwardedRef, Ref, useCallback, useLayoutEffect, useMemo, useRef
|
||||
import Grid, { GridTypeMap } from '@mui/material/Grid';
|
||||
import Box, { BoxProps } from '@mui/material/Box';
|
||||
import { GridItemProps } from 'react-virtuoso';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { EmptyViewAbsoluteCentered } from '@/base/components/feedback/EmptyViewAbsoluteCentered.tsx';
|
||||
import { LoadingPlaceholder } from '@/base/components/feedback/LoadingPlaceholder.tsx';
|
||||
import { MangaCard } from '@/features/manga/components/cards/MangaCard.tsx';
|
||||
@@ -209,7 +209,7 @@ export const MangaGrid: React.FC<IMangaGridProps> = ({
|
||||
retry,
|
||||
gridWrapperProps,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const { navBarWidth } = useNavBarContext();
|
||||
const {
|
||||
@@ -313,7 +313,7 @@ export const MangaGrid: React.FC<IMangaGridProps> = ({
|
||||
return (
|
||||
<EmptyViewAbsoluteCentered
|
||||
noFaces={noFaces}
|
||||
message={message ?? t('manga.error.label.no_mangas_found')}
|
||||
message={message ?? t`No manga found`}
|
||||
messageExtra={messageExtra}
|
||||
retry={retry}
|
||||
/>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { BaseSyntheticEvent, ChangeEvent, useMemo, ForwardedRef } from 'react';
|
||||
import Button from '@mui/material/Button';
|
||||
import Checkbox from '@mui/material/Checkbox';
|
||||
@@ -14,6 +13,7 @@ import IconButton from '@mui/material/IconButton';
|
||||
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
||||
import { PopupState } from 'material-ui-popup-state/hooks';
|
||||
import { bindTrigger } from 'material-ui-popup-state';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
|
||||
import { SelectableCollectionReturnType } from '@/base/collection/hooks/useSelectableCollection.ts';
|
||||
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
|
||||
@@ -34,7 +34,7 @@ export const MangaOptionButton = ({
|
||||
popupState: PopupState;
|
||||
ref?: ForwardedRef<HTMLButtonElement | null>;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const bindTriggerProps = useMemo(() => bindTrigger(popupState), [popupState]);
|
||||
|
||||
@@ -59,7 +59,7 @@ export const MangaOptionButton = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<CustomTooltip title={t(selected ? 'global.button.deselect' : 'global.button.select')}>
|
||||
<CustomTooltip title={selected ? t`Deselect` : t`Select`}>
|
||||
<Checkbox {...MUIUtil.preventRippleProp()} checked={selected} onChange={handleSelectionChange} />
|
||||
</CustomTooltip>
|
||||
);
|
||||
@@ -67,7 +67,7 @@ export const MangaOptionButton = ({
|
||||
|
||||
if (asCheckbox) {
|
||||
return (
|
||||
<CustomTooltip title={t('global.button.options')}>
|
||||
<CustomTooltip title={t`Options`}>
|
||||
<IconButton
|
||||
ref={ref}
|
||||
{...MUIUtil.preventRippleProp(bindTriggerProps, { onClick: preventDefaultAction })}
|
||||
@@ -80,7 +80,7 @@ export const MangaOptionButton = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<CustomTooltip title={t('global.button.options')}>
|
||||
<CustomTooltip title={t`Options`}>
|
||||
<Button
|
||||
ref={ref}
|
||||
{...MUIUtil.preventRippleProp(bindTriggerProps, { onClick: preventDefaultAction })}
|
||||
|
||||
@@ -15,13 +15,13 @@ import ListItemText from '@mui/material/ListItemText';
|
||||
import Menu from '@mui/material/Menu';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Link } from 'react-router-dom';
|
||||
import SyncAltIcon from '@mui/icons-material/SyncAlt';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import useMediaQuery from '@mui/material/useMediaQuery';
|
||||
import { AwaitableComponent } from 'awaitable-component';
|
||||
import ColorLensIcon from '@mui/icons-material/ColorLens';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
|
||||
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
|
||||
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
||||
@@ -40,7 +40,7 @@ interface IProps {
|
||||
}
|
||||
|
||||
export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const theme = useTheme();
|
||||
const isLargeScreen = useMediaQuery(theme.breakpoints.up('sm'));
|
||||
@@ -78,7 +78,7 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
||||
<>
|
||||
{isLargeScreen && (
|
||||
<>
|
||||
<CustomTooltip title={t('manga.label.reload_from_source')} disabled={refreshing}>
|
||||
<CustomTooltip title={t`Reload data from source`} disabled={refreshing}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
onRefresh();
|
||||
@@ -90,7 +90,7 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
||||
</IconButton>
|
||||
</CustomTooltip>
|
||||
{settings.mangaDynamicColorSchemes && (
|
||||
<CustomTooltip title={t('settings.appearance.manga_dynamic_color_schemes.save')}>
|
||||
<CustomTooltip title={t`Save dynamic color theme`}>
|
||||
<IconButton onClick={saveDynamicColorTheme} color="inherit">
|
||||
<ColorLensIcon />
|
||||
</IconButton>
|
||||
@@ -98,7 +98,7 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
||||
)}
|
||||
{manga.inLibrary && (
|
||||
<>
|
||||
<CustomTooltip title={t('global.button.migrate')}>
|
||||
<CustomTooltip title={t`Migrate`}>
|
||||
<Link
|
||||
to={AppRoutes.migrate.childRoutes.search.path(
|
||||
manga.sourceId,
|
||||
@@ -113,7 +113,7 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
||||
</IconButton>
|
||||
</Link>
|
||||
</CustomTooltip>
|
||||
<CustomTooltip title={t('manga.label.edit_categories')}>
|
||||
<CustomTooltip title={t`Edit manga categories`}>
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
openCategorySelection();
|
||||
@@ -158,14 +158,14 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
||||
<ListItemIcon>
|
||||
<Refresh fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t('manga.label.reload_from_source')}</ListItemText>
|
||||
<ListItemText>{t`Reload data from source`}</ListItemText>
|
||||
</MenuItem>
|
||||
{settings.mangaDynamicColorSchemes && (
|
||||
<MenuItem onClick={saveDynamicColorTheme}>
|
||||
<ListItemIcon>
|
||||
<ColorLensIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t('settings.appearance.manga_dynamic_color_schemes.save')}</ListItemText>
|
||||
<ListItemText>{t`Save dynamic color theme`}</ListItemText>
|
||||
</MenuItem>
|
||||
)}
|
||||
{manga.inLibrary && [
|
||||
@@ -179,7 +179,7 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
||||
<ListItemIcon>
|
||||
<SyncAltIcon fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t('migrate.title')}</ListItemText>
|
||||
<ListItemText>{t`Migrate`}</ListItemText>
|
||||
</MenuItem>,
|
||||
<MenuItem
|
||||
key="categories"
|
||||
@@ -191,7 +191,7 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
||||
<ListItemIcon>
|
||||
<Label fontSize="small" />
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t('manga.label.edit_categories')}</ListItemText>
|
||||
<ListItemText>{t`Edit manga categories`}</ListItemText>
|
||||
</MenuItem>,
|
||||
]}
|
||||
</Menu>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import PlayArrow from '@mui/icons-material/PlayArrow';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { StyledFab } from '@/base/components/buttons/StyledFab.tsx';
|
||||
import { Chapters } from '@/features/chapter/services/Chapters.ts';
|
||||
import {
|
||||
@@ -31,7 +31,7 @@ export function ResumeFab({
|
||||
ChapterNameInfo &
|
||||
ChapterScanlatorInfo;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const { sourceOrder, name, chapterNumber, scanlator } = chapter;
|
||||
const isFirstChapter = sourceOrder === 1;
|
||||
@@ -51,7 +51,7 @@ export function ResumeFab({
|
||||
state={Chapters.getReaderOpenChapterLocationState(chapter)}
|
||||
>
|
||||
<PlayArrow />
|
||||
{isFirstChapter ? t('global.button.start') : t('global.button.resume')}
|
||||
{isFirstChapter ? t`Start` : t`Resume`}
|
||||
</StyledFab>
|
||||
</ContinueReadingTooltip>
|
||||
);
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import SyncIcon from '@mui/icons-material/Sync';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import PopupState, { bindDialog, bindTrigger } from 'material-ui-popup-state';
|
||||
import Dialog from '@mui/material/Dialog';
|
||||
import CheckIcon from '@mui/icons-material/Check';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { plural } from '@lingui/core/macro';
|
||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||
import { makeToast } from '@/base/utils/Toast.ts';
|
||||
import { TrackManga } from '@/features/tracker/components/TrackManga.tsx';
|
||||
@@ -23,7 +24,7 @@ import { MangaTrackRecordInfo } from '@/features/manga/Manga.types.ts';
|
||||
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
||||
|
||||
export const TrackMangaButton = ({ manga }: { manga: MangaTrackRecordInfo & Pick<MangaType, 'title'> }) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const trackerList = requestManager.useGetTrackerList<GetTrackersSettingsQuery>(GET_TRACKERS_SETTINGS);
|
||||
@@ -35,7 +36,7 @@ export const TrackMangaButton = ({ manga }: { manga: MangaTrackRecordInfo & Pick
|
||||
|
||||
const handleClick = (openPopup: () => void) => {
|
||||
if (trackerList.error) {
|
||||
makeToast(t('tracking.error.label.could_not_load_track_info'), 'error', trackerList.error?.toString());
|
||||
makeToast(t`Could not load track info`, 'error', trackerList.error?.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -60,8 +61,11 @@ export const TrackMangaButton = ({ manga }: { manga: MangaTrackRecordInfo & Pick
|
||||
>
|
||||
{trackersInUse.length ? <CheckIcon /> : <SyncIcon />}
|
||||
{trackersInUse.length
|
||||
? t('manga.button.track.active', { count: trackersInUse.length })
|
||||
: t('manga.button.track.start')}
|
||||
? plural(trackersInUse.length, {
|
||||
one: '# Tracker',
|
||||
other: '# Tracker',
|
||||
})
|
||||
: t`Tracking`}
|
||||
</CustomButton>
|
||||
{popupState.isOpen && (
|
||||
<Dialog {...bindDialog(popupState)} maxWidth="md" fullWidth scroll="paper">
|
||||
|
||||
@@ -10,14 +10,14 @@ import FavoriteIcon from '@mui/icons-material/Favorite';
|
||||
import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder';
|
||||
import { styled } from '@mui/material/styles';
|
||||
import { ComponentProps, ReactNode, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { t as translate } from 'i18next';
|
||||
import Link from '@mui/material/Link';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||
import ButtonGroup from '@mui/material/ButtonGroup';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { t as translate } from '@lingui/core/macro';
|
||||
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
|
||||
import { makeToast } from '@/base/utils/Toast.ts';
|
||||
import { Mangas } from '@/features/manga/services/Mangas.ts';
|
||||
@@ -136,11 +136,11 @@ const MangaButtonsContainer = styled('div')(({ theme }) => ({
|
||||
}));
|
||||
|
||||
const OpenSourceButton = ({ url }: { url?: string | null }) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
return (
|
||||
<ButtonGroup>
|
||||
<CustomTooltip title={t('global.button.open_browser')} disabled={!url}>
|
||||
<CustomTooltip title={t`Open in browser`} disabled={!url}>
|
||||
<CustomButtonIcon
|
||||
size="medium"
|
||||
disabled={!url}
|
||||
@@ -153,7 +153,7 @@ const OpenSourceButton = ({ url }: { url?: string | null }) => {
|
||||
<IconBrowser />
|
||||
</CustomButtonIcon>
|
||||
</CustomTooltip>
|
||||
<CustomTooltip title={t('global.button.open_webview')} disabled={!url}>
|
||||
<CustomTooltip title={t`Open in WebView`} disabled={!url}>
|
||||
<CustomButtonIcon
|
||||
size="medium"
|
||||
disabled={!url}
|
||||
@@ -172,11 +172,11 @@ const OpenSourceButton = ({ url }: { url?: string | null }) => {
|
||||
|
||||
function getSourceName(source?: Pick<SourceType, 'id' | 'displayName'> | null): string {
|
||||
if (!source) {
|
||||
return translate('global.label.unknown');
|
||||
return translate`Unknown`;
|
||||
}
|
||||
|
||||
if (Sources.isLocalSource(source)) {
|
||||
return translate('source.local_source.title');
|
||||
return translate`Local source`;
|
||||
}
|
||||
|
||||
return source.displayName ?? source.id;
|
||||
@@ -215,7 +215,7 @@ export const MangaDetails = ({
|
||||
};
|
||||
mode: MangaLocationState['mode'];
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useLingui();
|
||||
|
||||
const {
|
||||
settings: { mangaThumbnailBackdrop, mangaDynamicColorSchemes },
|
||||
@@ -223,16 +223,16 @@ export const MangaDetails = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (!manga.source) {
|
||||
makeToast(translate('source.error.label.source_not_found'), 'error');
|
||||
makeToast(t`Could not find source. Check your installed extensions.`, 'error');
|
||||
}
|
||||
}, [manga.source]);
|
||||
}, [manga.source, t]);
|
||||
|
||||
const { updateLibraryState } = useManageMangaLibraryState(manga);
|
||||
|
||||
const copyTitle = async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(manga.title);
|
||||
makeToast(t('global.label.copied_clipboard'), 'info');
|
||||
makeToast(t`Copied to clipboard`, 'info');
|
||||
} catch (e) {
|
||||
defaultPromiseErrorHandler('MangaDetails::copyTitleLongPress')(e);
|
||||
}
|
||||
@@ -250,7 +250,7 @@ export const MangaDetails = ({
|
||||
{manga.title}
|
||||
</Typography>
|
||||
</SearchLink>
|
||||
<CustomTooltip title={t('global.button.copy')}>
|
||||
<CustomTooltip title={t`Copy`}>
|
||||
<IconButton onClick={copyTitle} color="inherit">
|
||||
<ContentCopyIcon fontSize="small" />
|
||||
</IconButton>
|
||||
@@ -258,21 +258,18 @@ export const MangaDetails = ({
|
||||
</Stack>
|
||||
{manga.author && (
|
||||
<Metadata
|
||||
title={t('manga.label.author')}
|
||||
title={t`Author`}
|
||||
value={valuesToJoinedSearchLinks(Mangas.getAuthors(manga), manga.source?.id, mode)}
|
||||
/>
|
||||
)}
|
||||
{manga.artist && (
|
||||
<Metadata
|
||||
title={t('manga.label.artist')}
|
||||
title={t`Artist`}
|
||||
value={valuesToJoinedSearchLinks(Mangas.getArtists(manga), manga.source?.id, mode)}
|
||||
/>
|
||||
)}
|
||||
<Metadata
|
||||
title={t('manga.label.status')}
|
||||
value={t(MANGA_STATUS_TO_TRANSLATION[manga.status])}
|
||||
/>
|
||||
<Metadata title={t('source.title_one')} value={getSourceName(manga.source)} />
|
||||
<Metadata title={t`Status`} value={t(MANGA_STATUS_TO_TRANSLATION[manga.status])} />
|
||||
<Metadata title={t`Source`} value={getSourceName(manga.source)} />
|
||||
</MetadataContainer>
|
||||
</ThumbnailMetadataWrapper>
|
||||
<MangaButtonsContainer>
|
||||
@@ -282,7 +279,7 @@ export const MangaDetails = ({
|
||||
variant={manga.inLibrary ? 'contained' : 'outlined'}
|
||||
>
|
||||
{manga.inLibrary ? <FavoriteIcon /> : <FavoriteBorderIcon />}
|
||||
{manga.inLibrary ? t('manga.button.in_library') : t('manga.button.add_to_library')}
|
||||
{manga.inLibrary ? t`In Library` : t`Add To Library`}
|
||||
</CustomButton>
|
||||
<TrackMangaButton manga={manga} />
|
||||
<OpenSourceButton url={manga.realUrl} />
|
||||
|
||||
Reference in New Issue
Block a user