increase prettier line length to 120 (#233)
* [Prettier] Increase max line length to 120 100 is quite low, especially on modern monitors. The length is also reached quite quickly with 4 spaces per tab depending on the indentation depth * [Prettier] Increase max line length to 120 - Fix formatting
This commit is contained in:
@@ -22,17 +22,7 @@ interface IProps {
|
||||
|
||||
export default function ExtensionCard(props: IProps) {
|
||||
const {
|
||||
extension: {
|
||||
name,
|
||||
lang,
|
||||
versionName,
|
||||
installed,
|
||||
hasUpdate,
|
||||
obsolete,
|
||||
pkgName,
|
||||
iconUrl,
|
||||
isNsfw,
|
||||
},
|
||||
extension: { name, lang, versionName, installed, hasUpdate, obsolete, pkgName, iconUrl, isNsfw },
|
||||
notifyInstall,
|
||||
} = props;
|
||||
const [installedState, setInstalledState] = useState<string>(() => {
|
||||
@@ -123,12 +113,7 @@ export default function ExtensionCard(props: IProps) {
|
||||
<Typography variant="caption" display="block" gutterBottom>
|
||||
{langPress} {versionName}
|
||||
{isNsfw && (
|
||||
<Typography
|
||||
variant="caption"
|
||||
display="inline"
|
||||
gutterBottom
|
||||
color="red"
|
||||
>
|
||||
<Typography variant="caption" display="inline" gutterBottom color="red">
|
||||
{' 18+'}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
@@ -100,10 +100,7 @@ const MangaCard = React.forwardRef<HTMLDivElement, IProps>((props: IProps, ref)
|
||||
const cols = Math.ceil(dimensions / ItemWidth);
|
||||
return (
|
||||
<Grid item columns={cols} xs={1}>
|
||||
<Link
|
||||
to={mangaLinkTo}
|
||||
style={gridLayout === GridLayout.Comfortable ? { textDecoration: 'none' } : {}}
|
||||
>
|
||||
<Link to={mangaLinkTo} style={gridLayout === GridLayout.Comfortable ? { textDecoration: 'none' } : {}}>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
@@ -132,16 +129,12 @@ const MangaCard = React.forwardRef<HTMLDivElement, IProps>((props: IProps, ref)
|
||||
}}
|
||||
>
|
||||
{inLibraryIndicator && inLibrary && (
|
||||
<Typography
|
||||
sx={{ backgroundColor: 'primary.dark', zIndex: '1' }}
|
||||
>
|
||||
<Typography sx={{ backgroundColor: 'primary.dark', zIndex: '1' }}>
|
||||
In library
|
||||
</Typography>
|
||||
)}
|
||||
{showUnreadBadge && unread! > 0 && (
|
||||
<Typography sx={{ backgroundColor: 'primary.dark' }}>
|
||||
{unread}
|
||||
</Typography>
|
||||
<Typography sx={{ backgroundColor: 'primary.dark' }}>{unread}</Typography>
|
||||
)}
|
||||
{showDownloadBadge && downloadCount! > 0 && (
|
||||
<Typography
|
||||
@@ -266,14 +259,10 @@ const MangaCard = React.forwardRef<HTMLDivElement, IProps>((props: IProps, ref)
|
||||
</Box>
|
||||
<BadgeContainer>
|
||||
{inLibraryIndicator && inLibrary && (
|
||||
<Typography sx={{ backgroundColor: 'primary.dark' }}>
|
||||
In library
|
||||
</Typography>
|
||||
<Typography sx={{ backgroundColor: 'primary.dark' }}>In library</Typography>
|
||||
)}
|
||||
{showUnreadBadge && unread! > 0 && (
|
||||
<Typography sx={{ backgroundColor: 'primary.dark' }}>
|
||||
{unread}
|
||||
</Typography>
|
||||
<Typography sx={{ backgroundColor: 'primary.dark' }}>{unread}</Typography>
|
||||
)}
|
||||
{showDownloadBadge && downloadCount! > 0 && (
|
||||
<Typography
|
||||
|
||||
@@ -97,12 +97,7 @@ const SourceCard: React.FC<IProps> = (props: IProps) => {
|
||||
<Typography variant="caption" display="block" gutterBottom>
|
||||
{langCodeToName(lang)}
|
||||
{isNsfw && (
|
||||
<Typography
|
||||
variant="caption"
|
||||
display="inline"
|
||||
gutterBottom
|
||||
color="red"
|
||||
>
|
||||
<Typography variant="caption" display="inline" gutterBottom color="red">
|
||||
{' 18+'}
|
||||
</Typography>
|
||||
)}
|
||||
@@ -113,29 +108,18 @@ const SourceCard: React.FC<IProps> = (props: IProps) => {
|
||||
<>
|
||||
<MobileWidthButtons>
|
||||
{supportsLatest && (
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={(e) => redirectTo(e, `/sources/${id}/latest/`)}
|
||||
>
|
||||
<Button variant="outlined" onClick={(e) => redirectTo(e, `/sources/${id}/latest/`)}>
|
||||
Latest
|
||||
</Button>
|
||||
)}
|
||||
</MobileWidthButtons>
|
||||
<WiderWidthButtons>
|
||||
{supportsLatest && (
|
||||
<Button
|
||||
component={Link}
|
||||
to={`/sources/${id}/latest/`}
|
||||
variant="outlined"
|
||||
>
|
||||
<Button component={Link} to={`/sources/${id}/latest/`} variant="outlined">
|
||||
Latest
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
component={Link}
|
||||
to={`/sources/${id}/popular/`}
|
||||
variant="outlined"
|
||||
>
|
||||
<Button component={Link} to={`/sources/${id}/popular/`} variant="outlined">
|
||||
Browse
|
||||
</Button>
|
||||
</WiderWidthButtons>
|
||||
|
||||
@@ -17,9 +17,7 @@ interface IProps extends RadioInputProps {
|
||||
|
||||
const SortRadioInput: React.FC<IProps> = ({ sortDescending, ...rest }) => (
|
||||
<RadioInput
|
||||
checkedIcon={
|
||||
sortDescending ? <ArrowDownward color="primary" /> : <ArrowUpward color="primary" />
|
||||
}
|
||||
checkedIcon={sortDescending ? <ArrowDownward color="primary" /> : <ArrowUpward color="primary" />}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -24,10 +24,7 @@ const unreadFilter = (unread: NullAndUndefined<boolean>, { unreadCount }: IManga
|
||||
}
|
||||
};
|
||||
|
||||
const downloadedFilter = (
|
||||
downloaded: NullAndUndefined<boolean>,
|
||||
{ downloadCount }: IMangaCard,
|
||||
): boolean => {
|
||||
const downloadedFilter = (downloaded: NullAndUndefined<boolean>, { downloadCount }: IMangaCard): boolean => {
|
||||
switch (downloaded) {
|
||||
case true:
|
||||
return !!downloadCount && downloadCount >= 1;
|
||||
@@ -117,9 +114,7 @@ const LibraryMangaGrid: React.FC<IMangaGridProps & { lastLibraryUpdate: number }
|
||||
);
|
||||
|
||||
const showFilteredOutMessage =
|
||||
(unread != null || downloaded != null || query) &&
|
||||
filteredManga.length === 0 &&
|
||||
mangas.length > 0;
|
||||
(unread != null || downloaded != null || query) && filteredManga.length === 0 && mangas.length > 0;
|
||||
|
||||
return (
|
||||
<MangaGrid
|
||||
|
||||
@@ -34,10 +34,7 @@ interface IProps {
|
||||
const LibraryOptionsPanel: React.FC<IProps> = ({ open, onClose }) => {
|
||||
const { options, setOptions } = useLibraryOptionsContext();
|
||||
|
||||
const handleFilterChange = <T extends keyof LibraryOptions>(
|
||||
key: T,
|
||||
value: LibraryOptions[T],
|
||||
) => {
|
||||
const handleFilterChange = <T extends keyof LibraryOptions>(key: T, value: LibraryOptions[T]) => {
|
||||
setOptions((v) => ({ ...v, [key]: value }));
|
||||
};
|
||||
|
||||
@@ -85,17 +82,13 @@ const LibraryOptionsPanel: React.FC<IProps> = ({ open, onClose }) => {
|
||||
<>
|
||||
<FormLabel>Display mode</FormLabel>
|
||||
<RadioGroup
|
||||
onChange={(e) =>
|
||||
handleFilterChange('gridLayout', Number(e.target.value))
|
||||
}
|
||||
onChange={(e) => handleFilterChange('gridLayout', Number(e.target.value))}
|
||||
value={gridLayout}
|
||||
>
|
||||
<RadioInput
|
||||
label="Compact grid"
|
||||
value={GridLayout.Compact}
|
||||
checked={
|
||||
gridLayout == null || gridLayout === GridLayout.Compact
|
||||
}
|
||||
checked={gridLayout == null || gridLayout === GridLayout.Compact}
|
||||
/>
|
||||
<RadioInput
|
||||
label="Comfortable grid"
|
||||
@@ -113,16 +106,12 @@ const LibraryOptionsPanel: React.FC<IProps> = ({ open, onClose }) => {
|
||||
<CheckboxInput
|
||||
label="Unread Badges"
|
||||
checked={showUnreadBadge === true}
|
||||
onChange={() =>
|
||||
handleFilterChange('showUnreadBadge', !showUnreadBadge)
|
||||
}
|
||||
onChange={() => handleFilterChange('showUnreadBadge', !showUnreadBadge)}
|
||||
/>
|
||||
<CheckboxInput
|
||||
label="Download Badges"
|
||||
checked={showDownloadBadge === true}
|
||||
onChange={() =>
|
||||
handleFilterChange('showDownloadBadge', !showDownloadBadge)
|
||||
}
|
||||
onChange={() => handleFilterChange('showDownloadBadge', !showDownloadBadge)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
* 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/. */
|
||||
|
||||
import LibraryOptionsContext, {
|
||||
DefaultLibraryOptions,
|
||||
} from 'components/context/LibraryOptionsContext';
|
||||
import LibraryOptionsContext, { DefaultLibraryOptions } from 'components/context/LibraryOptionsContext';
|
||||
import React from 'react';
|
||||
import useLocalStorage from 'util/useLocalStorage';
|
||||
|
||||
@@ -16,16 +14,9 @@ interface IProps {
|
||||
}
|
||||
|
||||
const LibraryOptionsContextProvider: React.FC<IProps> = ({ children }) => {
|
||||
const [options, setOptions] = useLocalStorage<LibraryOptions>(
|
||||
'libraryOptions',
|
||||
DefaultLibraryOptions,
|
||||
);
|
||||
const [options, setOptions] = useLocalStorage<LibraryOptions>('libraryOptions', DefaultLibraryOptions);
|
||||
|
||||
return (
|
||||
<LibraryOptionsContext.Provider value={{ options, setOptions }}>
|
||||
{children}
|
||||
</LibraryOptionsContext.Provider>
|
||||
);
|
||||
return <LibraryOptionsContext.Provider value={{ options, setOptions }}>{children}</LibraryOptionsContext.Provider>;
|
||||
};
|
||||
|
||||
export default LibraryOptionsContextProvider;
|
||||
|
||||
@@ -22,10 +22,7 @@ function Progress({ progress }: IProgressProps) {
|
||||
);
|
||||
}
|
||||
|
||||
const baseWebsocketUrl = JSON.parse(window.localStorage.getItem('serverBaseURL')!).replace(
|
||||
'http',
|
||||
'ws',
|
||||
);
|
||||
const baseWebsocketUrl = JSON.parse(window.localStorage.getItem('serverBaseURL')!).replace('http', 'ws');
|
||||
|
||||
interface IUpdateCheckerProps {
|
||||
handleFinishedUpdate: (time: number) => void;
|
||||
@@ -58,8 +55,7 @@ function UpdateChecker({ handleFinishedUpdate }: IUpdateCheckerProps) {
|
||||
const { running, statusMap } = JSON.parse(e.data) as IUpdateStatus;
|
||||
const { COMPLETE = [], RUNNING = [], PENDING = [] } = statusMap;
|
||||
|
||||
const currentProgress =
|
||||
100 * (COMPLETE.length / (COMPLETE.length + RUNNING.length + PENDING.length));
|
||||
const currentProgress = 100 * (COMPLETE.length / (COMPLETE.length + RUNNING.length + PENDING.length));
|
||||
|
||||
const isUpdateFinished = currentProgress === 100;
|
||||
const ignoreFaultyMessage = !updateStarted && !running && isUpdateFinished;
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const baseWebsocketUrl = JSON.parse(window.localStorage.getItem('serverBaseURL')!).replace(
|
||||
'http',
|
||||
'ws',
|
||||
);
|
||||
const baseWebsocketUrl = JSON.parse(window.localStorage.getItem('serverBaseURL')!).replace('http', 'ws');
|
||||
|
||||
const useSubscription = <T>(path: string, callback?: (newValue: T) => boolean | void) => {
|
||||
const [state, setState] = useState<T | undefined>();
|
||||
|
||||
@@ -42,14 +42,7 @@ interface IProps {
|
||||
const ChapterCard: React.FC<IProps> = (props: IProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const {
|
||||
chapter,
|
||||
triggerChaptersUpdate,
|
||||
downloadChapter: dc,
|
||||
showChapterNumber,
|
||||
onSelect,
|
||||
selected,
|
||||
} = props;
|
||||
const { chapter, triggerChaptersUpdate, downloadChapter: dc, showChapterNumber, onSelect, selected } = props;
|
||||
const isSelecting = selected !== null;
|
||||
|
||||
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||
@@ -85,9 +78,7 @@ const ChapterCard: React.FC<IProps> = (props: IProps) => {
|
||||
};
|
||||
|
||||
const deleteChapter = () => {
|
||||
client
|
||||
.delete(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`)
|
||||
.then(() => triggerChaptersUpdate());
|
||||
client.delete(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`).then(() => triggerChaptersUpdate());
|
||||
handleClose();
|
||||
};
|
||||
|
||||
@@ -143,9 +134,7 @@ const ChapterCard: React.FC<IProps> = (props: IProps) => {
|
||||
sx={{ mr: 0.5, position: 'relative', top: '0.15em' }}
|
||||
/>
|
||||
)}
|
||||
{showChapterNumber
|
||||
? `Chapter ${chapter.chapterNumber}`
|
||||
: chapter.name}
|
||||
{showChapterNumber ? `Chapter ${chapter.chapterNumber}` : chapter.name}
|
||||
</Typography>
|
||||
<Typography variant="caption">{chapter.scanlator}</Typography>
|
||||
<Typography variant="caption">
|
||||
@@ -165,12 +154,7 @@ const ChapterCard: React.FC<IProps> = (props: IProps) => {
|
||||
)}
|
||||
</CardContent>
|
||||
</CardActionArea>
|
||||
<Menu
|
||||
anchorEl={anchorEl}
|
||||
keepMounted
|
||||
open={Boolean(anchorEl)}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<Menu anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}>
|
||||
<MenuItem onClick={handleSelect}>
|
||||
<ListItemIcon>
|
||||
<CheckBoxOutlineBlank fontSize="small" />
|
||||
|
||||
@@ -140,10 +140,7 @@ const ChapterList: React.FC<IProps> = ({ mangaId }) => {
|
||||
setSelection(null);
|
||||
};
|
||||
|
||||
const handleFabAction: ComponentProps<typeof SelectionFAB>['onAction'] = (
|
||||
action,
|
||||
actionChapters,
|
||||
) => {
|
||||
const handleFabAction: ComponentProps<typeof SelectionFAB>['onAction'] = (action, actionChapters) => {
|
||||
if (actionChapters.length === 0) return;
|
||||
const chapterIds = actionChapters.map(({ chapter }) => chapter.id);
|
||||
|
||||
@@ -164,16 +161,9 @@ const ChapterList: React.FC<IProps> = ({ mangaId }) => {
|
||||
}
|
||||
|
||||
actionPromise
|
||||
.then(() =>
|
||||
makeToast(
|
||||
interpolate(chapterIds.length, actionsStrings[action].success),
|
||||
'success',
|
||||
),
|
||||
)
|
||||
.then(() => makeToast(interpolate(chapterIds.length, actionsStrings[action].success), 'success'))
|
||||
.then(() => mutate())
|
||||
.catch(() =>
|
||||
makeToast(interpolate(chapterIds.length, actionsStrings[action].error), 'error'),
|
||||
);
|
||||
.catch(() => makeToast(interpolate(chapterIds.length, actionsStrings[action].error), 'error'));
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
@@ -206,9 +196,7 @@ const ChapterList: React.FC<IProps> = ({ mangaId }) => {
|
||||
});
|
||||
|
||||
const selectedChapters =
|
||||
selection === null
|
||||
? null
|
||||
: chaptersWithMeta.filter(({ chapter }) => selection.includes(chapter.id));
|
||||
selection === null ? null : chaptersWithMeta.filter(({ chapter }) => selection.includes(chapter.id));
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -225,9 +213,7 @@ const ChapterList: React.FC<IProps> = ({ mangaId }) => {
|
||||
}}
|
||||
>
|
||||
<Typography variant="h5">
|
||||
{`${visibleChapters.length} Chapter${
|
||||
visibleChapters.length === 1 ? '' : 's'
|
||||
}`}
|
||||
{`${visibleChapters.length} Chapter${visibleChapters.length === 1 ? '' : 's'}`}
|
||||
</Typography>
|
||||
|
||||
{selection === null ? (
|
||||
|
||||
@@ -134,22 +134,14 @@ const MangaDetails: React.FC<IProps> = ({ manga }) => {
|
||||
const classes = useStyles(manga.inLibrary)();
|
||||
|
||||
const addToLibrary = () => {
|
||||
mutate(
|
||||
`/api/v1/manga/${manga.id}/?onlineFetch=false`,
|
||||
{ ...manga, inLibrary: true },
|
||||
{ revalidate: false },
|
||||
);
|
||||
mutate(`/api/v1/manga/${manga.id}/?onlineFetch=false`, { ...manga, inLibrary: true }, { revalidate: false });
|
||||
client
|
||||
.get(`/api/v1/manga/${manga.id}/library/`)
|
||||
.then(() => mutate(`/api/v1/manga/${manga.id}/?onlineFetch=false`));
|
||||
};
|
||||
|
||||
const removeFromLibrary = () => {
|
||||
mutate(
|
||||
`/api/v1/manga/${manga.id}/?onlineFetch=false`,
|
||||
{ ...manga, inLibrary: false },
|
||||
{ revalidate: false },
|
||||
);
|
||||
mutate(`/api/v1/manga/${manga.id}/?onlineFetch=false`, { ...manga, inLibrary: false }, { revalidate: false });
|
||||
client
|
||||
.delete(`/api/v1/manga/${manga.id}/library/`)
|
||||
.then(() => mutate(`/api/v1/manga/${manga.id}/?onlineFetch=false`));
|
||||
@@ -160,10 +152,7 @@ const MangaDetails: React.FC<IProps> = ({ manga }) => {
|
||||
<div className={classes.top}>
|
||||
<div className={classes.leftRight}>
|
||||
<div className={classes.leftSide}>
|
||||
<img
|
||||
src={`${serverAddress}${manga.thumbnailUrl}?useCache=${useCache}`}
|
||||
alt="Manga Thumbnail"
|
||||
/>
|
||||
<img src={`${serverAddress}${manga.thumbnailUrl}?useCache=${useCache}`} alt="Manga Thumbnail" />
|
||||
</div>
|
||||
<div className={classes.rightSide}>
|
||||
<h1>{manga.title}</h1>
|
||||
@@ -181,15 +170,8 @@ const MangaDetails: React.FC<IProps> = ({ manga }) => {
|
||||
</div>
|
||||
<div className={classes.buttons}>
|
||||
<div>
|
||||
<IconButton
|
||||
onClick={manga.inLibrary ? removeFromLibrary : addToLibrary}
|
||||
size="large"
|
||||
>
|
||||
{manga.inLibrary ? (
|
||||
<FavoriteIcon sx={{ mr: 1 }} />
|
||||
) : (
|
||||
<FavoriteBorderIcon sx={{ mr: 1 }} />
|
||||
)}
|
||||
<IconButton onClick={manga.inLibrary ? removeFromLibrary : addToLibrary} size="large">
|
||||
{manga.inLibrary ? <FavoriteIcon sx={{ mr: 1 }} /> : <FavoriteBorderIcon sx={{ mr: 1 }} />}
|
||||
<Typography sx={{ fontSize: { xs: '0.75em', sm: '0.85em' } }}>
|
||||
{manga.inLibrary ? 'In Library' : 'Add To Library'}
|
||||
</Typography>
|
||||
@@ -198,9 +180,7 @@ const MangaDetails: React.FC<IProps> = ({ manga }) => {
|
||||
<a href={manga.realUrl} target="_blank" rel="noreferrer">
|
||||
<IconButton size="large">
|
||||
<PublicIcon sx={{ mr: 1 }} />
|
||||
<Typography sx={{ fontSize: { xs: '0.75em', sm: '0.85em' } }}>
|
||||
Open Site
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: { xs: '0.75em', sm: '0.85em' } }}>Open Site</Typography>
|
||||
</IconButton>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -13,13 +13,7 @@ import React, { useRef, useState } from 'react';
|
||||
import type { IChapterWithMeta } from 'components/manga/ChapterList';
|
||||
import SelectionFABActionItem from 'components/manga/SelectionFABActionItem';
|
||||
|
||||
export type SelectionAction =
|
||||
| 'download'
|
||||
| 'delete'
|
||||
| 'bookmark'
|
||||
| 'unbookmark'
|
||||
| 'mark_as_read'
|
||||
| 'mark_as_unread';
|
||||
export type SelectionAction = 'download' | 'delete' | 'bookmark' | 'unbookmark' | 'mark_as_read' | 'mark_as_unread';
|
||||
|
||||
interface SelectionFABProps {
|
||||
selectedChapters: IChapterWithMeta[];
|
||||
@@ -49,12 +43,7 @@ const SelectionFAB: React.FC<SelectionFABProps> = (props) => {
|
||||
}}
|
||||
ref={anchorEl}
|
||||
>
|
||||
<Fab
|
||||
variant="extended"
|
||||
color="primary"
|
||||
id="selectionMenuButton"
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
<Fab variant="extended" color="primary" id="selectionMenuButton" onClick={() => setOpen(true)}>
|
||||
{`${count} ${pluralize(count, 'chapter')}`}
|
||||
<MoreHoriz sx={{ ml: 1 }} />
|
||||
</Fab>
|
||||
|
||||
@@ -17,15 +17,11 @@ const defaultChapterOptions: ChapterListOptions = {
|
||||
showChapterNumber: false,
|
||||
};
|
||||
|
||||
function chapterOptionsReducer(
|
||||
state: ChapterListOptions,
|
||||
actions: ChapterOptionsReducerAction,
|
||||
): ChapterListOptions {
|
||||
function chapterOptionsReducer(state: ChapterListOptions, actions: ChapterOptionsReducerAction): ChapterListOptions {
|
||||
switch (actions.type) {
|
||||
case 'filter':
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const active =
|
||||
state.unread !== false && state.downloaded !== false && state.bookmarked !== false;
|
||||
const active = state.unread !== false && state.downloaded !== false && state.bookmarked !== false;
|
||||
return {
|
||||
...state,
|
||||
active,
|
||||
@@ -53,10 +49,7 @@ export function unreadFilter(unread: NullAndUndefined<boolean>, { read: isChapte
|
||||
}
|
||||
}
|
||||
|
||||
function downloadFilter(
|
||||
downloaded: NullAndUndefined<boolean>,
|
||||
{ downloaded: chapterDownload }: IChapter,
|
||||
) {
|
||||
function downloadFilter(downloaded: NullAndUndefined<boolean>, { downloaded: chapterDownload }: IChapter) {
|
||||
switch (downloaded) {
|
||||
case true:
|
||||
return chapterDownload;
|
||||
@@ -67,10 +60,7 @@ function downloadFilter(
|
||||
}
|
||||
}
|
||||
|
||||
function bookmarkedFilter(
|
||||
bookmarked: NullAndUndefined<boolean>,
|
||||
{ bookmarked: chapterBookmarked }: IChapter,
|
||||
) {
|
||||
function bookmarkedFilter(bookmarked: NullAndUndefined<boolean>, { bookmarked: chapterBookmarked }: IChapter) {
|
||||
switch (bookmarked) {
|
||||
case true:
|
||||
return chapterBookmarked;
|
||||
@@ -81,10 +71,7 @@ function bookmarkedFilter(
|
||||
}
|
||||
}
|
||||
|
||||
export function filterAndSortChapters(
|
||||
chapters: IChapter[],
|
||||
options: ChapterListOptions,
|
||||
): IChapter[] {
|
||||
export function filterAndSortChapters(chapters: IChapter[], options: ChapterListOptions): IChapter[] {
|
||||
const filtered = options.active
|
||||
? chapters.filter(
|
||||
(chp) =>
|
||||
@@ -93,10 +80,7 @@ export function filterAndSortChapters(
|
||||
bookmarkedFilter(options.bookmarked, chp),
|
||||
)
|
||||
: [...chapters];
|
||||
const Sorted =
|
||||
options.sortBy === 'fetchedAt'
|
||||
? filtered.sort((a, b) => a.fetchedAt - b.fetchedAt)
|
||||
: filtered;
|
||||
const Sorted = options.sortBy === 'fetchedAt' ? filtered.sort((a, b) => a.fetchedAt - b.fetchedAt) : filtered;
|
||||
if (options.reverse) {
|
||||
Sorted.reverse();
|
||||
}
|
||||
|
||||
@@ -24,9 +24,7 @@ const DownloadStateIndicator: React.FC<DownloadStateIndicatorProps> = ({ downloa
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
{download.progress !== 0 && (
|
||||
<CircularProgress variant="determinate" value={download.progress * 100} />
|
||||
)}
|
||||
{download.progress !== 0 && <CircularProgress variant="determinate" value={download.progress * 100} />}
|
||||
<Box
|
||||
sx={{
|
||||
top: 0,
|
||||
|
||||
@@ -100,9 +100,7 @@ export default function DefaultNavBar() {
|
||||
let navbar = <></>;
|
||||
if (isMobileWidth) {
|
||||
if (isMainRoute) {
|
||||
navbar = (
|
||||
<MobileBottomBar navBarItems={navbarItems.filter((it) => it.show !== 'desktop')} />
|
||||
);
|
||||
navbar = <MobileBottomBar navBarItems={navbarItems.filter((it) => it.show !== 'desktop')} />;
|
||||
}
|
||||
} else {
|
||||
navbar = <DesktopSideBar navBarItems={navbarItems.filter((it) => it.show !== 'mobile')} />;
|
||||
|
||||
@@ -126,9 +126,7 @@ export default function ReaderNavBar(props: IProps) {
|
||||
const [updateDrawerOnRender, setUpdateDrawerOnRender] = useState(true);
|
||||
const [hideOpenButton, setHideOpenButton] = useState(settings.staticNav || prevDrawerOpen);
|
||||
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
||||
const [settingsCollapseOpen, setSettingsCollapseOpen] = useState(
|
||||
prevSettingsCollapseOpen ?? true,
|
||||
);
|
||||
const [settingsCollapseOpen, setSettingsCollapseOpen] = useState(prevSettingsCollapseOpen ?? true);
|
||||
|
||||
const updateSettingValue = (key: keyof IReaderSettings, value: string | boolean) => {
|
||||
// prevent closing the navBar when updating the "staticNav" setting
|
||||
@@ -181,14 +179,7 @@ export default function ReaderNavBar(props: IProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Slide
|
||||
direction="right"
|
||||
in={drawerOpen}
|
||||
timeout={200}
|
||||
appear={false}
|
||||
mountOnEnter
|
||||
unmountOnExit
|
||||
>
|
||||
<Slide direction="right" in={drawerOpen} timeout={200} appear={false} mountOnEnter unmountOnExit>
|
||||
<Root
|
||||
sx={{
|
||||
position: settings.staticNav ? 'sticky' : 'fixed',
|
||||
@@ -207,12 +198,7 @@ export default function ReaderNavBar(props: IProps) {
|
||||
<KeyboardArrowLeftIcon />
|
||||
</IconButton>
|
||||
)}
|
||||
<Typography
|
||||
variant="h1"
|
||||
textOverflow="ellipsis"
|
||||
overflow="hidden"
|
||||
sx={{ py: 1 }}
|
||||
>
|
||||
<Typography variant="h1" textOverflow="ellipsis" overflow="hidden" sx={{ py: 1 }}>
|
||||
{chapter.name}
|
||||
</Typography>
|
||||
<IconButton
|
||||
|
||||
@@ -25,9 +25,7 @@ interface IProps {
|
||||
export default function CategorySelect(props: IProps) {
|
||||
const { open, setOpen, mangaId } = props;
|
||||
|
||||
const { data: mangaCategoriesData, mutate } = useQuery<ICategory[]>(
|
||||
`/api/v1/manga/${mangaId}/category`,
|
||||
);
|
||||
const { data: mangaCategoriesData, mutate } = useQuery<ICategory[]>(`/api/v1/manga/${mangaId}/category`);
|
||||
const { data: categoriesData } = useQuery<ICategory[]>('/api/v1/category');
|
||||
|
||||
const allCategories = useMemo(() => {
|
||||
|
||||
@@ -40,9 +40,7 @@ interface IProps {
|
||||
export default function LangSelect(props: IProps) {
|
||||
const { shownLangs, setShownLangs, allLangs, forcedLangs } = props;
|
||||
// hold a copy and only sate state on parent when OK pressed, improves performance
|
||||
const [mShownLangs, setMShownLangs] = useState(
|
||||
removeAll(cloneObject(shownLangs), forcedLangs!),
|
||||
);
|
||||
const [mShownLangs, setMShownLangs] = useState(removeAll(cloneObject(shownLangs), forcedLangs!));
|
||||
const [open, setOpen] = useState<boolean>(false);
|
||||
|
||||
const handleCancel = () => {
|
||||
|
||||
@@ -35,10 +35,7 @@ export default function DesktopSideBar({ navBarItems }: IProps) {
|
||||
if (location.pathname === path)
|
||||
return <SelectedIconComponent sx={{ color: 'primary.main' }} fontSize="large" />;
|
||||
return (
|
||||
<IconComponent
|
||||
sx={{ color: theme.palette.mode === 'dark' ? 'grey.A400' : 'grey.600' }}
|
||||
fontSize="large"
|
||||
/>
|
||||
<IconComponent sx={{ color: theme.palette.mode === 'dark' ? 'grey.A400' : 'grey.600' }} fontSize="large" />
|
||||
);
|
||||
};
|
||||
|
||||
@@ -46,23 +43,17 @@ export default function DesktopSideBar({ navBarItems }: IProps) {
|
||||
<SideNavBarContainer>
|
||||
{
|
||||
// eslint-disable-next-line react/destructuring-assignment
|
||||
navBarItems.map(
|
||||
({ path, title, IconComponent, SelectedIconComponent }: NavbarItem) => (
|
||||
<Link
|
||||
to={path}
|
||||
style={{ color: 'inherit', textDecoration: 'none' }}
|
||||
key={path}
|
||||
>
|
||||
<ListItem disableRipple button key={title}>
|
||||
<ListItemIcon sx={{ minWidth: '0' }}>
|
||||
<Tooltip placement="right" title={title}>
|
||||
{iconFor(path, IconComponent, SelectedIconComponent)}
|
||||
</Tooltip>
|
||||
</ListItemIcon>
|
||||
</ListItem>
|
||||
</Link>
|
||||
),
|
||||
)
|
||||
navBarItems.map(({ path, title, IconComponent, SelectedIconComponent }: NavbarItem) => (
|
||||
<Link to={path} style={{ color: 'inherit', textDecoration: 'none' }} key={path}>
|
||||
<ListItem disableRipple button key={title}>
|
||||
<ListItemIcon sx={{ minWidth: '0' }}>
|
||||
<Tooltip placement="right" title={title}>
|
||||
{iconFor(path, IconComponent, SelectedIconComponent)}
|
||||
</Tooltip>
|
||||
</ListItemIcon>
|
||||
</ListItem>
|
||||
</Link>
|
||||
))
|
||||
}
|
||||
</SideNavBarContainer>
|
||||
);
|
||||
|
||||
@@ -44,45 +44,35 @@ export default function MobileBottomBar({ navBarItems }: IProps) {
|
||||
if (location.pathname === path)
|
||||
return <SelectedIconComponent sx={{ color: 'primary.main' }} fontSize="medium" />;
|
||||
return (
|
||||
<IconComponent
|
||||
sx={{ color: theme.palette.mode === 'dark' ? 'grey.A400' : 'grey.600' }}
|
||||
fontSize="medium"
|
||||
/>
|
||||
<IconComponent sx={{ color: theme.palette.mode === 'dark' ? 'grey.A400' : 'grey.600' }} fontSize="medium" />
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<BottomNavContainer>
|
||||
{navBarItems.map(
|
||||
({ path, title, IconComponent, SelectedIconComponent }: NavbarItem) => (
|
||||
<Link to={path} key={path}>
|
||||
<ListItem
|
||||
disableRipple
|
||||
button
|
||||
sx={{ justifyContent: 'center', padding: '8px' }}
|
||||
key={title}
|
||||
>
|
||||
<Box display="flex" flexDirection="column" alignItems="center">
|
||||
{iconFor(path, IconComponent, SelectedIconComponent)}
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: '0.65rem',
|
||||
color:
|
||||
// eslint-disable-next-line no-nested-ternary
|
||||
location.pathname === path
|
||||
? 'primary.main'
|
||||
: theme.palette.mode === 'dark'
|
||||
? 'grey.A400'
|
||||
: 'grey.600',
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Box>
|
||||
{navBarItems.map(({ path, title, IconComponent, SelectedIconComponent }: NavbarItem) => (
|
||||
<Link to={path} key={path}>
|
||||
<ListItem disableRipple button sx={{ justifyContent: 'center', padding: '8px' }} key={title}>
|
||||
<Box display="flex" flexDirection="column" alignItems="center">
|
||||
{iconFor(path, IconComponent, SelectedIconComponent)}
|
||||
<Box
|
||||
sx={{
|
||||
fontSize: '0.65rem',
|
||||
color:
|
||||
// eslint-disable-next-line no-nested-ternary
|
||||
location.pathname === path
|
||||
? 'primary.main'
|
||||
: theme.palette.mode === 'dark'
|
||||
? 'grey.A400'
|
||||
: 'grey.600',
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</Box>
|
||||
</ListItem>
|
||||
</Link>
|
||||
),
|
||||
)}
|
||||
</Box>
|
||||
</ListItem>
|
||||
</Link>
|
||||
))}
|
||||
</BottomNavContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -164,10 +164,8 @@ export default function HorizontalPager(props: IReaderProps) {
|
||||
ref={selfRef}
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection:
|
||||
settings.readerType === 'ContinuesHorizontalLTR' ? 'row' : 'row-reverse',
|
||||
justifyContent:
|
||||
settings.readerType === 'ContinuesHorizontalLTR' ? 'flex-start' : 'flex-end',
|
||||
flexDirection: settings.readerType === 'ContinuesHorizontalLTR' ? 'row' : 'row-reverse',
|
||||
justifyContent: settings.readerType === 'ContinuesHorizontalLTR' ? 'flex-start' : 'flex-end',
|
||||
margin: '0 auto',
|
||||
width: 'auto',
|
||||
height: 'auto',
|
||||
|
||||
@@ -98,13 +98,7 @@ export default function PagedReader(props: IReaderProps) {
|
||||
height: '100vh',
|
||||
}}
|
||||
>
|
||||
<Page
|
||||
key={curPage}
|
||||
index={curPage}
|
||||
onImageLoad={() => {}}
|
||||
src={pages[curPage].src}
|
||||
settings={settings}
|
||||
/>
|
||||
<Page key={curPage} index={curPage} onImageLoad={() => {}} src={pages[curPage].src} settings={settings} />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -85,9 +85,7 @@ export default function VerticalPager(props: IReaderProps) {
|
||||
}
|
||||
|
||||
window.scroll({
|
||||
top:
|
||||
window.scrollY +
|
||||
window.innerHeight * SCROLL_OFFSET * (direction === 'up' ? -1 : 1),
|
||||
top: window.scrollY + window.innerHeight * SCROLL_OFFSET * (direction === 'up' ? -1 : 1),
|
||||
behavior: SCROLL_BEHAVIOR,
|
||||
});
|
||||
},
|
||||
|
||||
@@ -58,10 +58,7 @@ export default function SourceGridLayout() {
|
||||
control={
|
||||
<Radio
|
||||
name={GridLayout.Compact.toString()}
|
||||
checked={
|
||||
SourcegridLayout === GridLayout.Compact ||
|
||||
SourcegridLayout === undefined
|
||||
}
|
||||
checked={SourcegridLayout === GridLayout.Compact || SourcegridLayout === undefined}
|
||||
onChange={setGridContextOptions}
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -16,16 +16,7 @@ function filterManga(mangas: IMangaCard[]): IMangaCard[] {
|
||||
}
|
||||
|
||||
export default function SourceMangaGrid(props: IMangaGridProps) {
|
||||
const {
|
||||
mangas,
|
||||
isLoading,
|
||||
hasNextPage,
|
||||
lastPageNum,
|
||||
setLastPageNum,
|
||||
message,
|
||||
messageExtra,
|
||||
gridLayout,
|
||||
} = props;
|
||||
const { mangas, isLoading, hasNextPage, lastPageNum, setLastPageNum, message, messageExtra, gridLayout } = props;
|
||||
|
||||
const filteredManga = filterManga(mangas);
|
||||
const showFilteredOutMessage = filteredManga.length === 0 && mangas.length > 0;
|
||||
|
||||
@@ -72,9 +72,7 @@ export function Options({ sourceFilter, group, updateFilterValue, update }: IFil
|
||||
/>
|
||||
);
|
||||
case 'Header':
|
||||
return (
|
||||
<HeaderFilter key={`filters ${e.filter.name}`} name={e.filter.name} />
|
||||
);
|
||||
return <HeaderFilter key={`filters ${e.filter.name}`} name={e.filter.name} />;
|
||||
case 'Select':
|
||||
return (
|
||||
<SelectFilter
|
||||
@@ -90,12 +88,7 @@ export function Options({ sourceFilter, group, updateFilterValue, update }: IFil
|
||||
/>
|
||||
);
|
||||
case 'Separator':
|
||||
return (
|
||||
<SeperatorFilter
|
||||
key={`filters ${e.filter.name}`}
|
||||
name={e.filter.name}
|
||||
/>
|
||||
);
|
||||
return <SeperatorFilter key={`filters ${e.filter.name}`} name={e.filter.name} />;
|
||||
case 'Sort':
|
||||
return (
|
||||
<SortFilter
|
||||
|
||||
@@ -24,8 +24,7 @@ const CheckBoxFilter: React.FC<Props> = (props: Props) => {
|
||||
const handleChange = (event: { target: { name: any; checked: any } }) => {
|
||||
setval(event.target.checked);
|
||||
const upd = update.filter(
|
||||
(e: { position: number; group: number | undefined }) =>
|
||||
!(position === e.position && group === e.group),
|
||||
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
||||
);
|
||||
updateFilterValue([...upd, { position, state: event.target.checked.toString(), group }]);
|
||||
};
|
||||
|
||||
@@ -44,8 +44,7 @@ function hasSelect(
|
||||
const vall = values.map((e) => e.displayname).indexOf(`${event.target.value}`);
|
||||
setval(vall);
|
||||
const upd = update.filter(
|
||||
(e: { position: number; group: number | undefined }) =>
|
||||
!(position === e.position && group === e.group),
|
||||
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
||||
);
|
||||
updateFilterValue([...upd, { position, state: vall.toString(), group }]);
|
||||
};
|
||||
@@ -58,12 +57,7 @@ function hasSelect(
|
||||
return (
|
||||
<FormControl sx={{ my: 1 }} variant="standard">
|
||||
<InputLabel>{name}</InputLabel>
|
||||
<Select
|
||||
name={name}
|
||||
value={values[val].displayname}
|
||||
label={name}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<Select name={name} value={values[val].displayname} label={name} onChange={handleChange}>
|
||||
{rett}
|
||||
</Select>
|
||||
</FormControl>
|
||||
@@ -88,8 +82,7 @@ function noSelect(
|
||||
const vall = values.indexOf(`${event.target.value}`);
|
||||
setval(vall);
|
||||
const upd = update.filter(
|
||||
(e: { position: number; group: number | undefined }) =>
|
||||
!(position === e.position && group === e.group),
|
||||
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
||||
);
|
||||
updateFilterValue([...upd, { position, state: vall.toString(), group }]);
|
||||
};
|
||||
|
||||
@@ -42,8 +42,7 @@ const SortFilter: React.FC<Props> = (props: Props) => {
|
||||
tmp.index = index;
|
||||
setval(tmp);
|
||||
const upd = update.filter(
|
||||
(e: { position: number; group: number | undefined }) =>
|
||||
!(position === e.position && group === e.group),
|
||||
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
||||
);
|
||||
updateFilterValue([...upd, { position, state: JSON.stringify(tmp), group }]);
|
||||
};
|
||||
|
||||
@@ -25,8 +25,7 @@ const TextFilter: React.FC<Props> = (props) => {
|
||||
|
||||
function doneTyping(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
const upd = update.filter(
|
||||
(el: { position: number; group: number | undefined }) =>
|
||||
!(position === el.position && group === el.group),
|
||||
(el: { position: number; group: number | undefined }) => !(position === el.position && group === el.group),
|
||||
);
|
||||
updateFilterValue([...upd, { position, state: e.target.value, group }]);
|
||||
}
|
||||
|
||||
@@ -26,8 +26,7 @@ const TriStateFilter: React.FC<Props> = (props) => {
|
||||
const newState = checked === undefined ? 0 : checked ? 1 : 2;
|
||||
setval(newState);
|
||||
const upd = update.filter(
|
||||
(e: { position: number; group: number | undefined }) =>
|
||||
!(position === e.position && group === e.group),
|
||||
(e: { position: number; group: number | undefined }) => !(position === e.position && group === e.group),
|
||||
);
|
||||
updateFilterValue([
|
||||
...upd,
|
||||
|
||||
@@ -65,12 +65,7 @@ function ListDialog(props: IListDialogProps) {
|
||||
<DialogContent dividers>
|
||||
<RadioGroup ref={radioGroupRef} value={value} onChange={handleChange}>
|
||||
{options.map((option) => (
|
||||
<FormControlLabel
|
||||
value={option}
|
||||
key={option}
|
||||
control={<Radio />}
|
||||
label={option}
|
||||
/>
|
||||
<FormControlLabel value={option} key={option} control={<Radio />} label={option} />
|
||||
))}
|
||||
</RadioGroup>
|
||||
</DialogContent>
|
||||
|
||||
@@ -64,11 +64,7 @@ function ListDialog(props: IListDialogProps) {
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
sx={{ '& .MuiDialog-paper': { width: '80%', maxHeight: 435 } }}
|
||||
maxWidth="xs"
|
||||
open={open}
|
||||
>
|
||||
<Dialog sx={{ '& .MuiDialog-paper': { width: '80%', maxHeight: 435 } }} maxWidth="xs" open={open}>
|
||||
<DialogTitle>{title}</DialogTitle>
|
||||
<DialogContent dividers>
|
||||
<FormGroup>
|
||||
@@ -76,9 +72,7 @@ function ListDialog(props: IListDialogProps) {
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={selectedValues.some(
|
||||
(selectedValue) => value === selectedValue,
|
||||
)}
|
||||
checked={selectedValues.some((selectedValue) => value === selectedValue)}
|
||||
onChange={(e) => handleChange(e, value)}
|
||||
color="default"
|
||||
/>
|
||||
|
||||
@@ -61,20 +61,14 @@ export default function makeToast(message: string, severity: Severity) {
|
||||
setTimeout(() => removeToast(container.id), 3500);
|
||||
}
|
||||
|
||||
export function makeToaster([toasts, setToasts]: [
|
||||
export function makeToaster([toasts, setToasts]: [React.ReactElement[], (arg0: React.ReactElement[]) => void]): [
|
||||
React.ReactElement[],
|
||||
(arg0: React.ReactElement[]) => void,
|
||||
]): [React.ReactElement[], (message: string, severity: Severity) => void] {
|
||||
(message: string, severity: Severity) => void,
|
||||
] {
|
||||
return [
|
||||
toasts,
|
||||
(message: string, severity: Severity) => {
|
||||
setToasts([
|
||||
<Toast
|
||||
key={Math.floor(Math.random() * 1000) + 1}
|
||||
message={message}
|
||||
severity={severity}
|
||||
/>,
|
||||
]);
|
||||
setToasts([<Toast key={Math.floor(Math.random() * 1000) + 1} message={message} severity={severity} />]);
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user