Fix styling of SearchAll error messages

This commit is contained in:
schroda
2024-04-29 15:34:12 +02:00
parent 054585f488
commit c19df43e4a
3 changed files with 76 additions and 62 deletions

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
// adopted from: https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/main/java/eu/kanade/tachiyomi/widget/EmptyView.kt
import { useMemo } from 'react';
import Typography from '@mui/material/Typography';
import { SxProps, Theme } from '@mui/material/styles';
import { useTranslation } from 'react-i18next';
import Button from '@mui/material/Button';
import Stack from '@mui/material/Stack';
const ERROR_FACES = ['(・o・;)', 'Σ(ಠ_ಠ)', 'ಥ_ಥ', '(˘・_・˘)', '(; ̄Д ̄)', '(・Д・。'];
function getRandomErrorFace() {
const randIndex = Math.floor(Math.random() * ERROR_FACES.length);
return ERROR_FACES[randIndex];
}
export interface EmptyViewProps {
message: string;
messageExtra?: JSX.Element | string;
retry?: () => void;
noFaces?: boolean;
sx?: SxProps<Theme>;
}
export function EmptyView({ message, messageExtra, retry, noFaces, sx }: EmptyViewProps) {
const { t } = useTranslation();
const errorFace = useMemo(() => getRandomErrorFace(), []);
return (
<Stack
sx={{
textAlign: 'center',
alignItems: 'center',
height: '100%',
...sx,
}}
>
{!noFaces && (
<Typography variant="h3" gutterBottom>
{errorFace}
</Typography>
)}
{retry && <Button onClick={retry}>{t('global.button.retry')}</Button>}
<Typography variant="h5">{message}</Typography>
{messageExtra}
</Stack>
);
}

View File

@@ -6,58 +6,10 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/ */
// adopted from: https://github.com/tachiyomiorg/tachiyomi/blob/master/app/src/main/java/eu/kanade/tachiyomi/widget/EmptyView.kt import { EmptyView, EmptyViewProps } from '@/components/util/EmptyView.tsx';
import { useMemo } from 'react'; export function EmptyViewAbsoluteCentered({ sx, ...emptyViewProps }: EmptyViewProps) {
import Typography from '@mui/material/Typography'; return <EmptyView {...emptyViewProps} sx={{ position: 'absolute', width: '100%', height: '100%', ...sx }} />;
import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
import { useTranslation } from 'react-i18next';
import Button from '@mui/material/Button';
import Stack from '@mui/material/Stack';
const ERROR_FACES = ['(・o・;)', 'Σ(ಠ_ಠ)', 'ಥ_ಥ', '(˘・_・˘)', '(; ̄Д ̄)', '(・Д・。'];
function getRandomErrorFace() {
const randIndex = Math.floor(Math.random() * ERROR_FACES.length);
return ERROR_FACES[randIndex];
}
interface IProps {
message: string;
messageExtra?: JSX.Element | string;
retry?: () => void;
noFaces?: boolean;
}
export function EmptyViewAbsoluteCentered({ message, messageExtra, retry, noFaces }: IProps) {
const { t } = useTranslation();
const theme = useTheme();
const isMobileWidth = useMediaQuery(theme.breakpoints.down('sm'));
const errorFace = useMemo(() => getRandomErrorFace(), []);
return (
<Stack
sx={{
position: 'absolute',
left: `calc(50% + ${isMobileWidth ? '0px' : theme.spacing(8 / 2)})`,
top: '50%',
transform: 'translate(-50%, -50%)',
textAlign: 'center',
alignItems: 'center',
}}
>
{!noFaces && (
<Typography variant="h3" gutterBottom>
{errorFace}
</Typography>
)}
{retry && <Button onClick={retry}>{t('global.button.retry')}</Button>}
<Typography variant="h5">{message}</Typography>
{messageExtra}
</Stack>
);
} }
EmptyViewAbsoluteCentered.defaultProps = { EmptyViewAbsoluteCentered.defaultProps = {

View File

@@ -24,6 +24,7 @@ import { MangaGrid } from '@/components/MangaGrid';
import { useDebounce } from '@/util/useDebounce.ts'; import { useDebounce } from '@/util/useDebounce.ts';
import { NavBarContext, useSetDefaultBackTo } from '@/components/context/NavbarContext.tsx'; import { NavBarContext, useSetDefaultBackTo } from '@/components/context/NavbarContext.tsx';
import { MangaCardProps } from '@/components/manga/MangaCard.types.tsx'; import { MangaCardProps } from '@/components/manga/MangaCard.types.tsx';
import { EmptyView } from '@/components/util/EmptyView';
type SourceLoadingState = { isLoading: boolean; hasResults: boolean; emptySearch: boolean }; type SourceLoadingState = { isLoading: boolean; hasResults: boolean; emptySearch: boolean };
type SourceToLoadingStateMap = Map<string, SourceLoadingState>; type SourceToLoadingStateMap = Map<string, SourceLoadingState>;
@@ -145,17 +146,21 @@ const SourceSearchPreview = React.memo(
<Typography variant="caption">{translateExtensionLanguage(lang)}</Typography> <Typography variant="caption">{translateExtensionLanguage(lang)}</Typography>
</CardActionArea> </CardActionArea>
</Card> </Card>
<MangaGrid {errorMessage ? (
mangas={mangas} <EmptyView sx={{ alignItems: 'start' }} noFaces message={errorMessage} />
isLoading={isLoading} ) : (
hasNextPage={false} <MangaGrid
loadMore={() => undefined} mangas={mangas}
horizontal isLoading={isLoading}
noFaces hasNextPage={false}
message={errorMessage} loadMore={() => undefined}
inLibraryIndicator horizontal
mode={mode} noFaces
/> message={errorMessage}
inLibraryIndicator
mode={mode}
/>
)}
</> </>
); );
}, },