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:
Daniel
2023-02-08 18:19:26 +01:00
committed by GitHub
parent b958d74b92
commit 2c11708c92
54 changed files with 156 additions and 542 deletions

View File

@@ -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>
)}

View File

@@ -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

View File

@@ -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>

View File

@@ -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}
/>
);

View File

@@ -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

View File

@@ -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)}
/>
</>
);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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>();

View File

@@ -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" />

View File

@@ -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 ? (

View File

@@ -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>

View File

@@ -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>

View File

@@ -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();
}

View File

@@ -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,

View File

@@ -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')} />;

View File

@@ -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

View File

@@ -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(() => {

View File

@@ -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 = () => {

View File

@@ -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>
);

View File

@@ -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>
);
}

View File

@@ -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',

View File

@@ -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>
);
}

View File

@@ -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,
});
},

View File

@@ -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}
/>
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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 }]);
};

View File

@@ -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 }]);
};

View File

@@ -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 }]);
};

View File

@@ -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 }]);
}

View File

@@ -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,

View File

@@ -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>

View File

@@ -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"
/>

View File

@@ -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} />]);
},
];
}

View File

@@ -97,9 +97,7 @@ const DownloadQueue: React.FC = () => {
>
<Card
sx={{
backgroundColor: snapshot.isDragging
? 'custom.light'
: undefined,
backgroundColor: snapshot.isDragging ? 'custom.light' : undefined,
}}
>
<CardActionArea
@@ -117,18 +115,9 @@ const DownloadQueue: React.FC = () => {
<IconButton sx={{ pointerEvents: 'none' }}>
<DragHandle />
</IconButton>
<Stack
sx={{ flex: 1, ml: 1 }}
direction="column"
>
<Typography variant="h6">
{item.manga.title}
</Typography>
<Typography
variant="caption"
display="block"
gutterBottom
>
<Stack sx={{ flex: 1, ml: 1 }} direction="column">
<Typography variant="h6">{item.manga.title}</Typography>
<Typography variant="caption" display="block" gutterBottom>
{item.chapter.name}
</Typography>
</Stack>

View File

@@ -67,10 +67,7 @@ function groupExtensions(extensions: IExtension[]) {
export default function MangaExtensions() {
const inputRef = useRef<HTMLInputElement>(null);
const { setTitle, setAction } = useContext(NavbarContext);
const [shownLangs, setShownLangs] = useLocalStorage<string[]>(
'shownExtensionLangs',
extensionDefaultLangs(),
);
const [shownLangs, setShownLangs] = useLocalStorage<string[]>('shownExtensionLangs', extensionDefaultLangs());
const [showNsfw] = useLocalStorage<boolean>('showNsfw', true);
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
@@ -84,20 +81,12 @@ export default function MangaExtensions() {
<IconButton onClick={() => inputRef.current?.click()} size="large">
<AddIcon />
</IconButton>
<LangSelect
shownLangs={shownLangs}
setShownLangs={setShownLangs}
allLangs={allLangs}
/>
<LangSelect shownLangs={shownLangs} setShownLangs={setShownLangs} allLangs={allLangs} />
</>,
);
}, [shownLangs]);
const {
data: allExtensions,
mutate,
loading,
} = useQuery<IExtension[]>('/api/v1/extension/list');
const { data: allExtensions, mutate, loading } = useQuery<IExtension[]>('/api/v1/extension/list');
const filteredExtensions = useMemo(
() =>
@@ -113,11 +102,7 @@ export default function MangaExtensions() {
() =>
groupExtensions(filteredExtensions)
.filter((group) => group[EXTENSIONS].length > 0)
.filter((group) =>
['installed', 'updates pending', 'all', ...shownLangs].includes(
group[LANGUAGE],
),
),
.filter((group) => ['installed', 'updates pending', 'all', ...shownLangs].includes(group[LANGUAGE])),
[shownLangs, filteredExtensions],
);

View File

@@ -60,12 +60,7 @@ export default function Library() {
};
if (tabsError != null) {
return (
<EmptyView
message="Could not load categories"
messageExtra={tabsError?.message ?? tabsError}
/>
);
return <EmptyView message="Could not load categories" messageExtra={tabsError?.message ?? tabsError} />;
}
if (loading) {

View File

@@ -38,9 +38,7 @@ const Manga: React.FC = () => {
const [refresh, { loading: refreshing }] = useRefreshManga(id);
useSetDefaultBackTo(
manga?.inLibrary === false && manga.sourceId != null
? `/sources/${manga.sourceId}/popular`
: '/library',
manga?.inLibrary === false && manga.sourceId != null ? `/sources/${manga.sourceId}/popular` : '/library',
);
useEffect(() => {
@@ -89,13 +87,7 @@ const Manga: React.FC = () => {
<CircularProgress size={16} />
</IconButton>
)}
{manga && (
<MangaToolbarMenu
manga={manga}
onRefresh={refresh}
refreshing={refreshing}
/>
)}
{manga && <MangaToolbarMenu manga={manga} onRefresh={refresh} refreshing={refreshing} />}
</Stack>
</NavbarToolbar>

View File

@@ -75,8 +75,7 @@ export default function Reader() {
const [curPage, setCurPage] = useState<number>(0);
const { setOverride, setTitle } = useContext(NavbarContext);
const { settings: defaultSettings, loading: areDefaultSettingsLoading } =
useDefaultReaderSettings();
const { settings: defaultSettings, loading: areDefaultSettingsLoading } = useDefaultReaderSettings();
const [settings, setSettings] = useState(getReaderSettingsFor(manga, defaultSettings));
const [isMangaLoading, setIsMangaLoading] = useState(true);
@@ -97,9 +96,7 @@ export default function Reader() {
useEffect(() => {
if (!areDefaultSettingsLoading && !isMangaLoading) {
checkAndHandleMissingStoredReaderSettings(manga, 'manga', defaultSettings).catch(
() => {},
);
checkAndHandleMissingStoredReaderSettings(manga, 'manga', defaultSettings).catch(() => {});
setSettings(getReaderSettingsFor(manga, defaultSettings));
}
}, [areDefaultSettingsLoading, isMangaLoading]);

View File

@@ -16,12 +16,7 @@ import React, { useContext, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { StringParam, useQueryParam } from 'use-query-params';
import client from 'util/client';
import {
langCodeToName,
langSortCmp,
sourceDefualtLangs,
sourceForcedDefaultLangs,
} from 'util/language';
import { langCodeToName, langSortCmp, sourceDefualtLangs, sourceForcedDefaultLangs } from 'util/language';
import useLocalStorage from 'util/useLocalStorage';
function sourceToLangList(sources: ISource[]) {
@@ -43,10 +38,7 @@ const SearchAll: React.FC = () => {
const [triggerUpdate, setTriggerUpdate] = useState<number>(2);
const [mangas, setMangas] = useState<any>({});
const [shownLangs, setShownLangs] = useLocalStorage<string[]>(
'shownSourceLangs',
sourceDefualtLangs(),
);
const [shownLangs, setShownLangs] = useLocalStorage<string[]>('shownSourceLangs', sourceDefualtLangs());
const [showNsfw] = useLocalStorage<boolean>('showNsfw', true);
const [sources, setSources] = useState<ISource[]>([]);
@@ -210,9 +202,7 @@ const SearchAll: React.FC = () => {
sx={{ p: 3 }}
>
<Typography variant="h5">{displayName}</Typography>
<Typography variant="caption">
{langCodeToName(lang)}
</Typography>
<Typography variant="caption">{langCodeToName(lang)}</Typography>
</CardActionArea>
</Card>
<MangaGrid

View File

@@ -118,11 +118,7 @@ export default function Settings() {
</ListItemIcon>
<ListItemText primary="Dark Theme" />
<ListItemSecondaryAction>
<Switch
edge="end"
checked={darkTheme}
onChange={() => setDarkTheme(!darkTheme)}
/>
<Switch edge="end" checked={darkTheme} onChange={() => setDarkTheme(!darkTheme)} />
</ListItemSecondaryAction>
</ListItem>
<ListItemButton>
@@ -141,16 +137,9 @@ export default function Settings() {
<ListItemIcon>
<FavoriteIcon />
</ListItemIcon>
<ListItemText
primary="Show NSFW"
secondary="Hide NSFW extensions and sources"
/>
<ListItemText primary="Show NSFW" secondary="Hide NSFW extensions and sources" />
<ListItemSecondaryAction>
<Switch
edge="end"
checked={showNsfw}
onChange={() => setShowNsfw(!showNsfw)}
/>
<Switch edge="end" checked={showNsfw} onChange={() => setShowNsfw(!showNsfw)} />
</ListItemSecondaryAction>
</ListItem>
<ListItem>
@@ -163,11 +152,7 @@ export default function Settings() {
but uses it much more internet traffic in turn"
/>
<ListItemSecondaryAction>
<Switch
edge="end"
checked={useCache}
onChange={() => setUseCache(!useCache)}
/>
<Switch edge="end" checked={useCache} onChange={() => setUseCache(!useCache)} />
</ListItemSecondaryAction>
</ListItem>
<ListItem>

View File

@@ -9,10 +9,7 @@ import React, { useContext, useEffect } from 'react';
import NavbarContext from 'components/context/NavbarContext';
import { useParams } from 'react-router-dom';
import client, { useQuery } from 'util/client';
import {
SwitchPreferenceCompat,
CheckBoxPreference,
} from 'components/sourceConfiguration/TwoStatePreference';
import { SwitchPreferenceCompat, CheckBoxPreference } from 'components/sourceConfiguration/TwoStatePreference';
import ListPreference from 'components/sourceConfiguration/ListPreference';
import EditTextPreference from 'components/sourceConfiguration/EditTextPreference';
import MultiSelectListPreference from 'components/sourceConfiguration/MultiSelectListPreference';

View File

@@ -221,9 +221,7 @@ export default function SourceMangas(props: { popular: boolean }) {
messageExtra = (
<>
<span>Check out </span>
<a href="https://github.com/Suwayomi/Tachidesk-Server/wiki/Local-Source">
Local source guide
</a>
<a href="https://github.com/Suwayomi/Tachidesk-Server/wiki/Local-Source">Local source guide</a>
</>
);
}

View File

@@ -9,12 +9,7 @@ import React, { useContext, useEffect } from 'react';
import LangSelect from 'components/navbar/action/LangSelect';
import SourceCard from 'components/SourceCard';
import NavbarContext from 'components/context/NavbarContext';
import {
sourceDefualtLangs,
sourceForcedDefaultLangs,
langCodeToName,
langSortCmp,
} from 'util/language';
import { sourceDefualtLangs, sourceForcedDefaultLangs, langCodeToName, langSortCmp } from 'util/language';
import useLocalStorage from 'util/useLocalStorage';
import LoadingPlaceholder from 'components/util/LoadingPlaceholder';
import { IconButton } from '@mui/material';
@@ -50,10 +45,7 @@ function groupByLang(sources: ISource[]) {
export default function Sources() {
const { setTitle, setAction } = useContext(NavbarContext);
const [shownLangs, setShownLangs] = useLocalStorage<string[]>(
'shownSourceLangs',
sourceDefualtLangs(),
);
const [shownLangs, setShownLangs] = useLocalStorage<string[]>('shownSourceLangs', sourceDefualtLangs());
const [showNsfw] = useLocalStorage<boolean>('showNsfw', true);
const { data: sources, loading } = useQuery<ISource[]>('/api/v1/source/list');

View File

@@ -46,9 +46,7 @@ function getDateString(date: Date) {
return date.toLocaleDateString();
}
function groupByDate(
updates: IMangaChapter[],
): [string, { item: IMangaChapter; globalIdx: number }[]][] {
function groupByDate(updates: IMangaChapter[]): [string, { item: IMangaChapter; globalIdx: number }[]][] {
if (updates.length === 0) return [];
const groups = {};
@@ -64,10 +62,7 @@ function groupByDate(
return Object.keys(groups).map((key) => [key, groups[key]]);
}
const baseWebsocketUrl = JSON.parse(window.localStorage.getItem('serverBaseURL')!).replace(
'http',
'ws',
);
const baseWebsocketUrl = JSON.parse(window.localStorage.getItem('serverBaseURL')!).replace('http', 'ws');
const initialQueue = {
status: 'Stopped',
queue: [],
@@ -205,11 +200,7 @@ const Updates: React.FC = () => {
<Typography variant="h5" component="h2">
{manga.title}
</Typography>
<Typography
variant="caption"
display="block"
gutterBottom
>
<Typography variant="caption" display="block" gutterBottom>
{chapter.name}
</Typography>
</Box>

View File

@@ -74,10 +74,7 @@ export default function Backup() {
<>
<List sx={{ padding: 0 }}>
<ListItemLink to={`${baseURL}/api/v1/backup/export/file`} directLink>
<ListItemText
primary="Create Backup"
secondary="Backup library as a Tachiyomi backup"
/>
<ListItemText primary="Create Backup" secondary="Backup library as a Tachiyomi backup" />
</ListItemLink>
<ListItem button onClick={() => document.getElementById('backup-file')?.click()}>
<ListItemText

View File

@@ -139,11 +139,7 @@ export default function Categories() {
{(provided) => (
<List ref={provided.innerRef}>
{categories.map((item, index) => (
<Draggable
key={item.id}
draggableId={item.id.toString()}
index={index}
>
<Draggable key={item.id} draggableId={item.id.toString()} index={index}>
{(provided, snapshot) => (
<ListItem
ContainerProps={{ ref: provided.innerRef } as any}

View File

@@ -51,11 +51,7 @@ export default function DefaultReaderSettings() {
);
}
checkAndHandleMissingStoredReaderSettings(
{ meta: metadata },
'server',
getDefaultSettings(),
).catch(() => {});
checkAndHandleMissingStoredReaderSettings({ meta: metadata }, 'server', getDefaultSettings()).catch(() => {});
return (
<ReaderSettingsOptions

View File

@@ -83,10 +83,7 @@ export function langCodeToName(code: string): string {
let result = `language with code: ${code}`;
for (let i = 0; i < ISOLanguages.length; i++) {
if (
ISOLanguages[i].code === proccessedCode ||
ISOLanguages[i].code === code.toLocaleLowerCase()
) {
if (ISOLanguages[i].code === proccessedCode || ISOLanguages[i].code === code.toLocaleLowerCase()) {
result = ISOLanguages[i].nativeName;
}
}

View File

@@ -17,14 +17,10 @@ const migrations: IMetadataMigration[] = [
},
];
const getMetadataKey = (key: string, appPrefix: string = APP_METADATA_KEY_PREFIX) =>
`${appPrefix}${key}`;
const getMetadataKey = (key: string, appPrefix: string = APP_METADATA_KEY_PREFIX) => `${appPrefix}${key}`;
const doesMetadataKeyExistIn = (
meta: IMetadata | undefined,
key: string,
appPrefix?: string,
): boolean => Object.prototype.hasOwnProperty.call(meta ?? {}, getMetadataKey(key, appPrefix));
const doesMetadataKeyExistIn = (meta: IMetadata | undefined, key: string, appPrefix?: string): boolean =>
Object.prototype.hasOwnProperty.call(meta ?? {}, getMetadataKey(key, appPrefix));
const convertValueFromMetadata = <T extends AllowedMetadataValueTypes = AllowedMetadataValueTypes>(
value: string,
@@ -44,10 +40,7 @@ const convertValueFromMetadata = <T extends AllowedMetadataValueTypes = AllowedM
return value as T;
};
const getAppMetadataFrom = (
meta: IMetadata,
appPrefix: string = APP_METADATA_KEY_PREFIX,
): IMetadata => {
const getAppMetadataFrom = (meta: IMetadata, appPrefix: string = APP_METADATA_KEY_PREFIX): IMetadata => {
const appMetadata: IMetadata = {};
Object.entries(meta).forEach(([key, value]) => {
@@ -71,9 +64,7 @@ const applyAppKeyPrefixMigration = (meta: IMetadata, migration: IMetadataMigrati
const oldAppMetadata = getAppMetadataFrom(meta, oldPrefix);
const newAppMetadata = getAppMetadataFrom(meta, newPrefix);
const missingMetadataKeys = Object.keys(oldAppMetadata).filter(
(key) => !Object.keys(newAppMetadata).includes(key),
);
const missingMetadataKeys = Object.keys(oldAppMetadata).filter((key) => !Object.keys(newAppMetadata).includes(key));
const isMissingOldMetadata = missingMetadataKeys.length;
if (isMissingOldMetadata) {
@@ -134,9 +125,7 @@ const applyMetadataMigrations = (meta?: IMetadata): IMetadata | undefined => {
return migrationToMetadata.pop()![1];
};
export const getMetadataValueFrom = <
T extends AllowedMetadataValueTypes = AllowedMetadataValueTypes,
>(
export const getMetadataValueFrom = <T extends AllowedMetadataValueTypes = AllowedMetadataValueTypes>(
{ meta }: IMetadataHolder,
key: AppMetadataKeys,
defaultValue?: T,
@@ -220,22 +209,14 @@ export const requestUpdateMetadata = async (
): Promise<void[]> =>
Promise.all(
keysToValues.map(([key, value]) =>
requestUpdateMetadataValue(
endpoint,
metadataHolder,
key,
value,
endpointToMutate,
wrapWithMetaKey,
),
requestUpdateMetadataValue(endpoint, metadataHolder, key, value, endpointToMutate, wrapWithMetaKey),
),
);
export const requestUpdateServerMetadata = async (
serverMetadata: IMetadata,
keysToValues: MetadataKeyValuePair[],
): Promise<void[]> =>
requestUpdateMetadata('', { meta: serverMetadata }, keysToValues, '/meta', false);
): Promise<void[]> => requestUpdateMetadata('', { meta: serverMetadata }, keysToValues, '/meta', false);
export const requestUpdateMangaMetadata = async (
manga: IMangaCard | IManga,

View File

@@ -6,11 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import {
getMetadataFrom,
requestUpdateMangaMetadata,
requestUpdateServerMetadata,
} from 'util/metadata';
import { getMetadataFrom, requestUpdateMangaMetadata, requestUpdateServerMetadata } from 'util/metadata';
import { useQuery } from 'util/client';
export const getDefaultSettings = (forceUndefined: boolean = false) =>
@@ -75,9 +71,7 @@ export const checkAndHandleMissingStoredReaderSettings = async (
const settingsToCheck = getReaderSettingsFor({ meta }, getDefaultSettings(true), false);
const newSettings = getReaderSettingsFor({ meta }, defaultSettings);
const undefinedSettings = Object.entries(settingsToCheck).filter(
(setting) => setting[1] === undefined,
);
const undefinedSettings = Object.entries(settingsToCheck).filter((setting) => setting[1] === undefined);
const settingsToUpdate: MetadataKeyValuePair[] = [];
undefinedSettings.forEach((setting) => {

View File

@@ -9,10 +9,7 @@ import React, { useState, Dispatch, SetStateAction, useReducer, Reducer, useCall
import storage from 'util/localStorage';
// eslint-disable-next-line max-len
export default function useLocalStorage<T>(
key: string,
defaultValue: T | (() => T),
): [T, Dispatch<SetStateAction<T>>] {
export default function useLocalStorage<T>(key: string, defaultValue: T | (() => T)): [T, Dispatch<SetStateAction<T>>] {
const initialState = defaultValue instanceof Function ? defaultValue() : defaultValue;
const [storedValue, setStoredValue] = useState<T>(storage.getItem(key, initialState));
@@ -31,11 +28,7 @@ export default function useLocalStorage<T>(
return [storedValue, setValue];
}
export function useReducerLocalStorage<S, A>(
reducer: Reducer<S, A>,
key: string,
defaultState: S | (() => S),
) {
export function useReducerLocalStorage<S, A>(reducer: Reducer<S, A>, key: string, defaultState: S | (() => S)) {
const [storedValue, setValue] = useLocalStorage(key, defaultState);
return useReducer((state: S, action: A): S => {
const newState = reducer(state, action);