Fix styling of SearchAll error messages
This commit is contained in:
57
src/components/util/EmptyView.tsx
Normal file
57
src/components/util/EmptyView.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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 = {
|
||||||
|
|||||||
@@ -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}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user