From 4e0a860dfd7e47d463bc0b89c5fb1259c48368a1 Mon Sep 17 00:00:00 2001 From: Daniel <50052685+schroda@users.noreply.github.com> Date: Mon, 6 Feb 2023 10:06:33 +0100 Subject: [PATCH] add prettier for auto formatting (#231) * [Prettier] Add "prettier" Makes the formatting of the code consistent. By using the eslint-plugin-prettier formatting issues will be highlighted as a lint error. These errors will be auto fixed by running "lint --fix" (which can be done automatically on file save) * [Prettier] Add "prettier" - Fix formatting --- .eslintrc.js | 21 +- .prettierrc | 7 + package.json | 3 + src/App.tsx | 21 +- src/components/ExtensionCard.tsx | 82 ++-- src/components/MangaCard.tsx | 137 ++++--- src/components/MangaGrid.tsx | 78 ++-- src/components/SourceCard.tsx | 27 +- src/components/atoms/CheckboxInput.tsx | 14 +- src/components/atoms/LoadingIconButton.tsx | 10 +- src/components/atoms/RadioInput.tsx | 14 +- src/components/atoms/SortRadioInput.tsx | 10 +- src/components/atoms/ThreeStateCheckbox.tsx | 4 +- .../atoms/ThreeStateCheckboxInput.tsx | 14 +- src/components/context/AppContext.tsx | 33 +- src/components/context/DarkTheme.tsx | 6 +- src/components/context/NavbarContext.tsx | 24 +- src/components/library/LibraryMangaGrid.tsx | 60 ++- .../library/LibraryOptionsPanel.tsx | 56 ++- .../library/LibraryOptionsProvider.tsx | 9 +- src/components/library/LibraryToolbarMenu.tsx | 5 +- src/components/library/UpdateChecker.tsx | 19 +- src/components/library/useSubscription.ts | 5 +- src/components/manga/ChapterCard.tsx | 63 +-- src/components/manga/ChapterList.tsx | 113 +++--- src/components/manga/ChapterOptions.tsx | 61 ++- src/components/manga/ChaptersToolbarMenu.tsx | 4 +- src/components/manga/MangaDetails.tsx | 229 ++++++----- src/components/manga/MangaToolbarMenu.tsx | 46 ++- src/components/manga/ResumeFAB.tsx | 18 +- src/components/manga/SelectionFAB.tsx | 23 +- .../manga/SelectionFABActionItem.tsx | 17 +- src/components/manga/hooks.ts | 12 +- src/components/manga/util.tsx | 59 +-- .../molecules/DownloadStateIndicator.tsx | 7 +- src/components/molecules/OptionsPanel.tsx | 20 +- src/components/molecules/OptionsTabs.tsx | 31 +- src/components/navbar/DefaultNavBar.tsx | 31 +- .../navbar/NavBarContextProvider.tsx | 12 +- src/components/navbar/ReaderNavBar.tsx | 61 ++- .../navbar/action/CategorySelect.tsx | 33 +- src/components/navbar/action/LangSelect.tsx | 14 +- .../navbar/navigation/DesktopSideBar.tsx | 42 +- .../navbar/navigation/MobileBottomBar.tsx | 57 +-- src/components/reader/DoublePage.tsx | 22 +- src/components/reader/Page.tsx | 23 +- src/components/reader/PageNumber.tsx | 31 +- .../reader/ReaderSettingsOptions.tsx | 44 +-- .../reader/pager/DoublePagedPager.tsx | 46 +-- .../reader/pager/HorizontalPager.tsx | 38 +- src/components/reader/pager/PagedPager.tsx | 8 +- src/components/reader/pager/VerticalPager.tsx | 63 +-- src/components/source/GridLayouts.tsx | 30 +- src/components/source/SourceMangaGrid.tsx | 10 +- src/components/source/SourceOptions.tsx | 70 ++-- .../source/filters/CheckBoxFilter.tsx | 34 +- src/components/source/filters/GroupFilter.tsx | 22 +- .../source/filters/HeaderFilter.tsx | 8 +- .../source/filters/SelectFilter.tsx | 90 ++--- .../source/filters/SeparatorFilter.tsx | 8 +- src/components/source/filters/SortFilter.tsx | 35 +- src/components/source/filters/TextFilter.tsx | 46 +-- .../source/filters/TriStateFilter.tsx | 43 +- .../EditTextPreference.tsx | 22 +- .../sourceConfiguration/ListPreference.tsx | 31 +- .../MultiSelectListPreference.tsx | 50 ++- .../TwoStatePreference.tsx | 28 +- src/components/util/AppbarSearch.tsx | 46 +-- .../util/CustomExtensionOutlinedIcon.tsx | 3 +- src/components/util/EmptyView.tsx | 32 +- src/components/util/LoadingPlaceholder.tsx | 29 +- src/components/util/SpinnerImage.tsx | 25 +- src/components/util/TabPanel.tsx | 10 +- src/components/util/Toast.tsx | 33 +- src/components/util/helpers.ts | 4 +- src/screens/DownloadQueue.tsx | 44 ++- src/screens/Extensions.tsx | 62 +-- src/screens/Library.tsx | 23 +- src/screens/Manga.tsx | 47 +-- src/screens/Reader.tsx | 90 +++-- src/screens/SearchAll.tsx | 134 ++++--- src/screens/Settings.tsx | 13 +- src/screens/SourceConfigure.tsx | 47 ++- src/screens/SourceMangas.tsx | 103 +++-- src/screens/Sources.tsx | 57 +-- src/screens/Updates.tsx | 53 ++- src/screens/settings/About.tsx | 5 +- src/screens/settings/Backup.tsx | 18 +- src/screens/settings/Categories.tsx | 60 ++- .../settings/DefaultReaderSettings.tsx | 21 +- src/theme.ts | 24 +- src/typings.d.ts | 372 +++++++++--------- src/util/client.tsx | 11 +- src/util/date.ts | 11 +- src/util/language.tsx | 21 +- src/util/localStorage.tsx | 8 +- src/util/metadata.ts | 44 ++- src/util/readerSettings.ts | 38 +- src/util/useBackTo.ts | 2 +- src/util/useLocalStorage.tsx | 18 +- yarn.lock | 29 ++ 101 files changed, 2065 insertions(+), 1886 deletions(-) create mode 100644 .prettierrc diff --git a/.eslintrc.js b/.eslintrc.js index 6d4d9bb4..d1c49126 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,27 +1,16 @@ module.exports = { - extends: [ - 'airbnb', - 'airbnb-typescript' - ], - plugins: ['@typescript-eslint', 'no-relative-import-paths'], + extends: ['airbnb', 'airbnb-typescript', 'prettier'], + plugins: ['@typescript-eslint', 'no-relative-import-paths', 'prettier'], parserOptions: { project: './tsconfig.json', }, rules: { - // Indent with 4 spaces - '@typescript-eslint/indent': ['error', 4], - - // Indent JSX with 4 spaces - 'react/jsx-indent': ['error', 4], - - // Indent props with 4 spaces - 'react/jsx-indent-props': ['error', 4], - - 'no-plusplus': ['error', { 'allowForLoopAfterthoughts': true }], + 'prettier/prettier': 'error', + 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], // just why - 'react/jsx-no-bind' : 'off', + 'react/jsx-no-bind': 'off', 'react/jsx-props-no-spreading': 'off', 'react/require-default-props': 'off', diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..97d11eb6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "tabWidth": 4, + "singleQuote": true, + "printWidth": 100, + "semi": true, + "trailingComma": "all" +} diff --git a/package.json b/package.json index d51fae3f..4ea5907a 100644 --- a/package.json +++ b/package.json @@ -58,11 +58,14 @@ "eslint": "^7.2.0", "eslint-config-airbnb": "18.2.1", "eslint-config-airbnb-typescript": "^14.0.0", + "eslint-config-prettier": "^8.6.0", "eslint-plugin-import": "^2.22.1", "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-no-relative-import-paths": "^1.5.2", + "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.21.5", "eslint-plugin-react-hooks": "^1.7.0", + "prettier": "^2.8.2", "typescript": "^4.8.4" } } diff --git a/src/App.tsx b/src/App.tsx index 3ee40643..91a2b076 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,9 +10,7 @@ import CssBaseline from '@mui/material/CssBaseline'; import AppContext from 'components/context/AppContext'; import DefaultNavBar from 'components/navbar/DefaultNavBar'; import React from 'react'; -import { - Redirect, Route, Switch, -} from 'react-router-dom'; +import { Redirect, Route, Switch } from 'react-router-dom'; import Browse from 'screens/Browse'; import DownloadQueue from 'screens/DownloadQueue'; import Extensions from 'screens/Extensions'; @@ -48,13 +46,7 @@ const App: React.FC = () => ( > {/* General Routes */} - ( - - )} - /> + } /> @@ -116,14 +108,7 @@ const App: React.FC = () => ( path="/manga/:mangaId/chapter/:chapterIndex" // passing a key re-mounts the reader // when changing chapters - render={(props: any) => ( - - )} + render={(props: any) => } /> diff --git a/src/components/ExtensionCard.tsx b/src/components/ExtensionCard.tsx index 2c7160cb..bfb92bab 100644 --- a/src/components/ExtensionCard.tsx +++ b/src/components/ExtensionCard.tsx @@ -16,24 +16,34 @@ import useLocalStorage from 'util/useLocalStorage'; import { Box } from '@mui/system'; interface IProps { - extension: IExtension - notifyInstall: () => void + extension: IExtension; + notifyInstall: () => void; } export default function ExtensionCard(props: IProps) { const { extension: { - name, lang, versionName, installed, hasUpdate, obsolete, pkgName, iconUrl, isNsfw, + name, + lang, + versionName, + installed, + hasUpdate, + obsolete, + pkgName, + iconUrl, + isNsfw, }, notifyInstall, } = props; - const [installedState, setInstalledState] = useState( - () => { - if (obsolete) { return 'obsolete'; } - if (hasUpdate) { return 'update'; } - return (installed ? 'uninstall' : 'install'); - }, - ); + const [installedState, setInstalledState] = useState(() => { + if (obsolete) { + return 'obsolete'; + } + if (hasUpdate) { + return 'update'; + } + return installed ? 'uninstall' : 'install'; + }); const [serverAddress] = useLocalStorage('serverBaseURL', ''); const [useCache] = useLocalStorage('useCache', true); @@ -42,29 +52,26 @@ export default function ExtensionCard(props: IProps) { function install() { setInstalledState('installing'); - client.get(`/api/v1/extension/install/${pkgName}`) - .then(() => { - setInstalledState('uninstall'); - notifyInstall(); - }); + client.get(`/api/v1/extension/install/${pkgName}`).then(() => { + setInstalledState('uninstall'); + notifyInstall(); + }); } function update() { setInstalledState('updating'); - client.get(`/api/v1/extension/update/${pkgName}`) - .then(() => { - setInstalledState('uninstall'); - notifyInstall(); - }); + client.get(`/api/v1/extension/update/${pkgName}`).then(() => { + setInstalledState('uninstall'); + notifyInstall(); + }); } function uninstall() { setInstalledState('uninstalling'); - client.get(`/api/v1/extension/uninstall/${pkgName}`) - .then(() => { - // setInstalledState('install'); - notifyInstall(); - }); + client.get(`/api/v1/extension/uninstall/${pkgName}`).then(() => { + // setInstalledState('install'); + notifyInstall(); + }); } function handleButtonClick() { @@ -89,12 +96,13 @@ export default function ExtensionCard(props: IProps) { return ( - - {langPress} - {' '} - {versionName} + {langPress} {versionName} {isNsfw && ( - + {' 18+'} )} @@ -131,7 +142,6 @@ export default function ExtensionCard(props: IProps) { onClick={() => handleButtonClick()} > {installedState} - diff --git a/src/components/MangaCard.tsx b/src/components/MangaCard.tsx index 42bb16c3..bd415e06 100644 --- a/src/components/MangaCard.tsx +++ b/src/components/MangaCard.tsx @@ -65,22 +65,30 @@ const truncateText = (str: string, maxLength: number) => { }; interface IProps { - manga: IMangaCard - gridLayout?: GridLayout - dimensions: number - inLibraryIndicator?: boolean + manga: IMangaCard; + gridLayout?: GridLayout; + dimensions: number; + inLibraryIndicator?: boolean; } + const MangaCard = React.forwardRef((props: IProps, ref) => { const { manga: { // eslint-disable-next-line @typescript-eslint/no-unused-vars - id, title, thumbnailUrl, downloadCount, unreadCount: unread, inLibrary, + id, + title, + thumbnailUrl, + downloadCount, + unreadCount: unread, + inLibrary, }, gridLayout, dimensions, inLibraryIndicator, } = props; - const { options: { showUnreadBadge, showDownloadBadge } } = useLibraryOptionsContext(); + const { + options: { showUnreadBadge, showDownloadBadge }, + } = useLibraryOptionsContext(); const [serverAddress] = useLocalStorage('serverBaseURL', ''); const [useCache] = useLocalStorage('useCache', true); @@ -92,7 +100,10 @@ const MangaCard = React.forwardRef((props: IProps, ref) const cols = Math.ceil(dimensions / ItemWidth); return ( - + ((props: IProps, ref) height: '100%', }} > - ((props: IProps, ref) In library )} - { showUnreadBadge && unread! > 0 && ( - + {showUnreadBadge && unread! > 0 && ( + {unread} )} - { showDownloadBadge && downloadCount! > 0 && ( - 0 && ( + {downloadCount} @@ -147,30 +156,34 @@ const MangaCard = React.forwardRef((props: IProps, ref) - {(gridLayout === GridLayout.Comfortable) ? (<>) : ( + {gridLayout === GridLayout.Comfortable ? ( + <> + ) : ( <> )} - {(gridLayout === GridLayout.Comfortable) ? ( + {gridLayout === GridLayout.Comfortable ? ( <> ) : ( ((props: IProps, ref) )} - {(gridLayout === GridLayout.Comfortable) ? ( + {gridLayout === GridLayout.Comfortable ? ( ((props: IProps, ref) > {truncateText(title, 61)} - ) : (<>)} + ) : ( + <> + )} @@ -205,10 +220,7 @@ const MangaCard = React.forwardRef((props: IProps, ref) return ( - + ((props: IProps, ref) > ((props: IProps, ref) {inLibraryIndicator && inLibrary && ( - + In library )} - { showUnreadBadge && unread! > 0 && ( - + {showUnreadBadge && unread! > 0 && ( + {unread} )} - { showDownloadBadge && downloadCount! > 0 && ( - 0 && ( + {downloadCount} diff --git a/src/components/MangaGrid.tsx b/src/components/MangaGrid.tsx index 4233afa0..149ca5c5 100644 --- a/src/components/MangaGrid.tsx +++ b/src/components/MangaGrid.tsx @@ -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 React, { - useEffect, useLayoutEffect, useRef, useState, -} from 'react'; +import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; import Grid from '@mui/material/Grid'; import EmptyView from 'components/util/EmptyView'; import LoadingPlaceholder from 'components/util/LoadingPlaceholder'; @@ -16,24 +14,32 @@ import { Box } from '@mui/system'; import MangaCard from 'components/MangaCard'; import { GridLayout } from 'components/context/LibraryOptionsContext'; -export interface IMangaGridProps{ - mangas: IMangaCard[] - isLoading: boolean - message?: string - messageExtra?: JSX.Element - hasNextPage: boolean - lastPageNum: number - setLastPageNum: (lastPageNum: number) => void - gridLayout?: GridLayout - horisontal?: boolean | undefined - noFaces?: boolean | undefined - inLibraryIndicator?: boolean +export interface IMangaGridProps { + mangas: IMangaCard[]; + isLoading: boolean; + message?: string; + messageExtra?: JSX.Element; + hasNextPage: boolean; + lastPageNum: number; + setLastPageNum: (lastPageNum: number) => void; + gridLayout?: GridLayout; + horisontal?: boolean | undefined; + noFaces?: boolean | undefined; + inLibraryIndicator?: boolean; } const MangaGrid: React.FC = (props) => { const { - mangas, isLoading, message, messageExtra, - hasNextPage, lastPageNum, setLastPageNum, gridLayout, horisontal, noFaces, + mangas, + isLoading, + message, + messageExtra, + hasNextPage, + lastPageNum, + setLastPageNum, + gridLayout, + horisontal, + noFaces, inLibraryIndicator, } = props; let mapped; @@ -42,7 +48,7 @@ const MangaGrid: React.FC = (props) => { const scrollHandler = () => { if (lastManga.current) { const rect = lastManga.current.getBoundingClientRect(); - if (((rect.y + rect.height) / window.innerHeight < 2) && hasNextPage) { + if ((rect.y + rect.height) / window.innerHeight < 2 && hasNextPage) { setLastPageNum(lastPageNum + 1); } } @@ -73,9 +79,7 @@ const MangaGrid: React.FC = (props) => { if (mangas.length === 0) { if (isLoading) { - mapped = ( - - ); + mapped = ; } else { mapped = noFaces ? ( = (props) => { margin: 'auto', }} > - - {message} - + {message} {messageExtra} ) : ( @@ -110,18 +112,22 @@ const MangaGrid: React.FC = (props) => { {mapped} diff --git a/src/components/SourceCard.tsx b/src/components/SourceCard.tsx index 45de4928..47a9f16c 100644 --- a/src/components/SourceCard.tsx +++ b/src/components/SourceCard.tsx @@ -36,14 +36,12 @@ const WiderWidthButtons = styled('div')(({ theme }) => ({ })); interface IProps { - source: ISource + source: ISource; } const SourceCard: React.FC = (props: IProps) => { const { - source: { - id, name, lang, iconUrl, supportsLatest, isNsfw, - }, + source: { id, name, lang, iconUrl, supportsLatest, isNsfw }, } = props; const history = useHistory(); @@ -64,10 +62,7 @@ const SourceCard: React.FC = (props: IProps) => { margin: '10px', }} > - + = (props: IProps) => { padding: 2, }} > - = (props: IProps) => { }} src={`${serverAddress}${iconUrl}?useCache=${useCache}`} /> - + {name} @@ -97,7 +97,12 @@ const SourceCard: React.FC = (props: IProps) => { {langCodeToName(lang)} {isNsfw && ( - + {' 18+'} )} diff --git a/src/components/atoms/CheckboxInput.tsx b/src/components/atoms/CheckboxInput.tsx index 2bf2684a..1d9c34df 100644 --- a/src/components/atoms/CheckboxInput.tsx +++ b/src/components/atoms/CheckboxInput.tsx @@ -10,19 +10,11 @@ import { Checkbox, CheckboxProps, FormControlLabel } from '@mui/material'; import React from 'react'; interface IProps extends CheckboxProps { - label?: string + label?: string; } -const CheckboxInput: React.FC = ({ - label, sx, ...rest -}) => ( - - )} - label={label} - sx={sx} - /> +const CheckboxInput: React.FC = ({ label, sx, ...rest }) => ( + } label={label} sx={sx} /> ); export default CheckboxInput; diff --git a/src/components/atoms/LoadingIconButton.tsx b/src/components/atoms/LoadingIconButton.tsx index 9fa439b7..719b7475 100644 --- a/src/components/atoms/LoadingIconButton.tsx +++ b/src/components/atoms/LoadingIconButton.tsx @@ -2,13 +2,11 @@ import { CircularProgress, IconButton, IconButtonProps } from '@mui/material'; import React, { useState } from 'react'; interface IProps extends Omit { - loading?: boolean - onClick: (e: React.MouseEvent) => Promise + loading?: boolean; + onClick: (e: React.MouseEvent) => Promise; } -const LoadingIconButton = ({ - onClick, children, loading: iLoading, ...rest -}: IProps) => { +const LoadingIconButton = ({ onClick, children, loading: iLoading, ...rest }: IProps) => { const [sLoading, setLoading] = useState(false); const loading = sLoading || iLoading; @@ -19,7 +17,7 @@ const LoadingIconButton = ({ return ( - {loading ? () : children} + {loading ? : children} ); }; diff --git a/src/components/atoms/RadioInput.tsx b/src/components/atoms/RadioInput.tsx index ee772f5e..d7a107fb 100644 --- a/src/components/atoms/RadioInput.tsx +++ b/src/components/atoms/RadioInput.tsx @@ -10,19 +10,11 @@ import { FormControlLabel, Radio, RadioProps } from '@mui/material'; import React from 'react'; export interface RadioInputProps extends RadioProps { - label?: string + label?: string; } -const RadioInput: React.FC = ({ - label, sx, ...rest -}) => ( - - )} - label={label} - sx={sx} - /> +const RadioInput: React.FC = ({ label, sx, ...rest }) => ( + } label={label} sx={sx} /> ); export default RadioInput; diff --git a/src/components/atoms/SortRadioInput.tsx b/src/components/atoms/SortRadioInput.tsx index 81131bf7..3ae5ba0d 100644 --- a/src/components/atoms/SortRadioInput.tsx +++ b/src/components/atoms/SortRadioInput.tsx @@ -12,14 +12,14 @@ import React from 'react'; import RadioInput, { RadioInputProps } from 'components/atoms/RadioInput'; interface IProps extends RadioInputProps { - sortDescending?: boolean | null | undefined + sortDescending?: boolean | null | undefined; } -const SortRadioInput: React.FC = ({ - sortDescending, ...rest -}) => ( +const SortRadioInput: React.FC = ({ sortDescending, ...rest }) => ( : } + checkedIcon={ + sortDescending ? : + } {...rest} /> ); diff --git a/src/components/atoms/ThreeStateCheckbox.tsx b/src/components/atoms/ThreeStateCheckbox.tsx index b8abf119..9e8baefc 100644 --- a/src/components/atoms/ThreeStateCheckbox.tsx +++ b/src/components/atoms/ThreeStateCheckbox.tsx @@ -19,8 +19,8 @@ function nextState(state: CheckState): CheckState { } export interface ThreeStateCheckboxProps extends Omit { - checked?: boolean | undefined | null - onChange?: (checked: boolean | undefined | null) => void + checked?: boolean | undefined | null; + onChange?: (checked: boolean | undefined | null) => void; } /** diff --git a/src/components/atoms/ThreeStateCheckboxInput.tsx b/src/components/atoms/ThreeStateCheckboxInput.tsx index 6d38acb4..b4077d7f 100644 --- a/src/components/atoms/ThreeStateCheckboxInput.tsx +++ b/src/components/atoms/ThreeStateCheckboxInput.tsx @@ -11,19 +11,11 @@ import React from 'react'; import ThreeStateCheckbox, { ThreeStateCheckboxProps } from 'components/atoms/ThreeStateCheckbox'; interface IProps extends ThreeStateCheckboxProps { - label?: string + label?: string; } -const ThreeStateCheckboxInput: React.FC = ({ - label, sx, ...rest -}) => ( - - )} - label={label} - sx={sx} - /> +const ThreeStateCheckboxInput: React.FC = ({ label, sx, ...rest }) => ( + } label={label} sx={sx} /> ); export default ThreeStateCheckboxInput; diff --git a/src/components/context/AppContext.tsx b/src/components/context/AppContext.tsx index b590cc99..4355d1ce 100644 --- a/src/components/context/AppContext.tsx +++ b/src/components/context/AppContext.tsx @@ -6,15 +6,11 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { - StyledEngineProvider, ThemeProvider, -} from '@mui/material/styles'; +import { StyledEngineProvider, ThemeProvider } from '@mui/material/styles'; import LibraryOptionsContextProvider from 'components/library/LibraryOptionsProvider'; import NavBarContextProvider from 'components/navbar/NavBarContextProvider'; import React, { useMemo } from 'react'; -import { - BrowserRouter as Router, Route, -} from 'react-router-dom'; +import { BrowserRouter as Router, Route } from 'react-router-dom'; import { SWRConfig } from 'swr'; import createTheme from 'theme'; import { QueryParamProvider } from 'use-query-params'; @@ -23,25 +19,22 @@ import useLocalStorage from 'util/useLocalStorage'; import DarkTheme from 'components/context/DarkTheme'; interface Props { - children: React.ReactNode + children: React.ReactNode; } const AppContext: React.FC = ({ children }) => { - const [darkTheme, setDarkTheme] = useLocalStorage( - 'darkTheme', - true, - ); + const [darkTheme, setDarkTheme] = useLocalStorage('darkTheme', true); - const darkThemeContext = useMemo(() => ({ - darkTheme, - setDarkTheme, - }), [darkTheme]); - - const theme = useMemo( - () => createTheme(darkTheme), + const darkThemeContext = useMemo( + () => ({ + darkTheme, + setDarkTheme, + }), [darkTheme], ); + const theme = useMemo(() => createTheme(darkTheme), [darkTheme]); + return ( @@ -50,9 +43,7 @@ const AppContext: React.FC = ({ children }) => { - - {children} - + {children} diff --git a/src/components/context/DarkTheme.tsx b/src/components/context/DarkTheme.tsx index 011762c1..f05ee4cd 100644 --- a/src/components/context/DarkTheme.tsx +++ b/src/components/context/DarkTheme.tsx @@ -8,13 +8,13 @@ import React from 'react'; type ContextType = { - darkTheme: boolean - setDarkTheme: React.Dispatch> + darkTheme: boolean; + setDarkTheme: React.Dispatch>; }; const DarkTheme = React.createContext({ darkTheme: true, - setDarkTheme: ():void => {}, + setDarkTheme: (): void => {}, }); export default DarkTheme; diff --git a/src/components/context/NavbarContext.tsx b/src/components/context/NavbarContext.tsx index c3bd8842..6bc3f2c9 100644 --- a/src/components/context/NavbarContext.tsx +++ b/src/components/context/NavbarContext.tsx @@ -9,31 +9,31 @@ import React, { useContext, useEffect } from 'react'; type ContextType = { // Default back button url - defaultBackTo: string | undefined - setDefaultBackTo: React.Dispatch> + defaultBackTo: string | undefined; + setDefaultBackTo: React.Dispatch>; // AppBar title - title: string - setTitle: (title: string) => void + title: string; + setTitle: (title: string) => void; // AppBar action buttons - action: any - setAction: React.Dispatch> + action: any; + setAction: React.Dispatch>; // Allow default navbar to be overrided - override: INavbarOverride - setOverride: React.Dispatch> + override: INavbarOverride; + setOverride: React.Dispatch>; }; const NavBarContext = React.createContext({ defaultBackTo: undefined, - setDefaultBackTo: ():void => {}, + setDefaultBackTo: (): void => {}, title: 'Tachidesk', - setTitle: ():void => {}, + setTitle: (): void => {}, action:
, - setAction: ():void => {}, + setAction: (): void => {}, override: { status: false, value:
}, - setOverride: ():void => {}, + setOverride: (): void => {}, }); export default NavBarContext; diff --git a/src/components/library/LibraryMangaGrid.tsx b/src/components/library/LibraryMangaGrid.tsx index 564af443..53c98200 100644 --- a/src/components/library/LibraryMangaGrid.tsx +++ b/src/components/library/LibraryMangaGrid.tsx @@ -24,8 +24,10 @@ const unreadFilter = (unread: NullAndUndefined, { unreadCount }: IManga } }; -const downloadedFilter = (downloaded: NullAndUndefined, - { downloadCount }: IMangaCard): boolean => { +const downloadedFilter = ( + downloaded: NullAndUndefined, + { downloadCount }: IMangaCard, +): boolean => { switch (downloaded) { case true: return !!downloadCount && downloadCount >= 1; @@ -46,13 +48,14 @@ const filterManga = ( query: NullAndUndefined, unread: NullAndUndefined, downloaded: NullAndUndefined, -): IMangaCard[] => manga.filter((m) => { - if (query) { - return queryFilter(query, m); - } +): IMangaCard[] => + manga.filter((m) => { + if (query) { + return queryFilter(query, m); + } - return downloadedFilter(downloaded, m) && unreadFilter(unread, m); -}); + return downloadedFilter(downloaded, m) && unreadFilter(unread, m); + }); const sortByUnread = (a: IMangaCard, b: IMangaCard): number => // eslint-disable-next-line implicit-arrow-linebreak @@ -70,10 +73,17 @@ const sortManga = ( const result = [...manga]; switch (sort) { - case 'sortAlph': result.sort(sortByTitle); break; - case 'sortID': result.sort(sortById); break; - case 'sortToRead': result.sort(sortByUnread); break; - default: break; + case 'sortAlph': + result.sort(sortByTitle); + break; + case 'sortID': + result.sort(sortById); + break; + case 'sortToRead': + result.sort(sortByUnread); + break; + default: + break; } if (desc === true) { @@ -84,20 +94,32 @@ const sortManga = ( }; const LibraryMangaGrid: React.FC = ({ - mangas, isLoading, hasNextPage, lastPageNum, setLastPageNum, message, lastLibraryUpdate, + mangas, + isLoading, + hasNextPage, + lastPageNum, + setLastPageNum, + message, + lastLibraryUpdate, }) => { const [query] = useQueryParam('query', StringParam); const { options } = useLibraryOptionsContext(); const { unread, downloaded } = options; - const sortedManga = useMemo(() => sortManga(mangas, options.sorts, options.sortDesc), - [mangas, lastLibraryUpdate, options.sorts, options.sortDesc]); + const sortedManga = useMemo( + () => sortManga(mangas, options.sorts, options.sortDesc), + [mangas, lastLibraryUpdate, options.sorts, options.sortDesc], + ); - const filteredManga = useMemo(() => filterManga(sortedManga, query, unread, downloaded), - [sortedManga, lastLibraryUpdate, query, unread, downloaded]); + const filteredManga = useMemo( + () => filterManga(sortedManga, query, unread, downloaded), + [sortedManga, lastLibraryUpdate, query, unread, downloaded], + ); - const showFilteredOutMessage = (unread != null || downloaded != null || query) - && filteredManga.length === 0 && mangas.length > 0; + const showFilteredOutMessage = + (unread != null || downloaded != null || query) && + filteredManga.length === 0 && + mangas.length > 0; return ( void, + open: boolean; + onClose: () => void; } const LibraryOptionsPanel: React.FC = ({ open, onClose }) => { @@ -51,8 +51,16 @@ const LibraryOptionsPanel: React.FC = ({ open, onClose }) => { if (key === 'filter') { return ( <> - handleFilterChange('unread', c)} /> - handleFilterChange('downloaded', c)} /> + handleFilterChange('unread', c)} + /> + handleFilterChange('downloaded', c)} + /> ); } @@ -63,9 +71,11 @@ const LibraryOptionsPanel: React.FC = ({ open, onClose }) => { label={label} checked={options.sorts === mode} sortDescending={options.sortDesc} - onClick={() => (mode !== options.sorts - ? handleFilterChange('sorts', mode) - : handleFilterChange('sortDesc', !options.sortDesc))} + onClick={() => + mode !== options.sorts + ? handleFilterChange('sorts', mode) + : handleFilterChange('sortDesc', !options.sortDesc) + } /> )); } @@ -75,24 +85,44 @@ const LibraryOptionsPanel: React.FC = ({ open, onClose }) => { <> Display mode handleFilterChange('gridLayout', Number(e.target.value))} + onChange={(e) => + handleFilterChange('gridLayout', Number(e.target.value)) + } value={gridLayout} > - - - + + + Badges handleFilterChange('showUnreadBadge', !showUnreadBadge)} + onChange={() => + handleFilterChange('showUnreadBadge', !showUnreadBadge) + } /> handleFilterChange('showDownloadBadge', !showDownloadBadge)} + onChange={() => + handleFilterChange('showDownloadBadge', !showDownloadBadge) + } /> ); diff --git a/src/components/library/LibraryOptionsProvider.tsx b/src/components/library/LibraryOptionsProvider.tsx index df2c815b..8cd00af9 100644 --- a/src/components/library/LibraryOptionsProvider.tsx +++ b/src/components/library/LibraryOptionsProvider.tsx @@ -5,7 +5,9 @@ * 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'; @@ -14,7 +16,10 @@ interface IProps { } const LibraryOptionsContextProvider: React.FC = ({ children }) => { - const [options, setOptions] = useLocalStorage('libraryOptions', DefaultLibraryOptions); + const [options, setOptions] = useLocalStorage( + 'libraryOptions', + DefaultLibraryOptions, + ); return ( diff --git a/src/components/library/LibraryToolbarMenu.tsx b/src/components/library/LibraryToolbarMenu.tsx index 9cc4d227..83b32299 100644 --- a/src/components/library/LibraryToolbarMenu.tsx +++ b/src/components/library/LibraryToolbarMenu.tsx @@ -18,10 +18,7 @@ const LibraryToolbarMenu: React.FC = () => { return ( <> - setOpen(!open)} - color={active ? 'warning' : 'default'} - > + setOpen(!open)} color={active ? 'warning' : 'default'}> setOpen(false)} /> diff --git a/src/components/library/UpdateChecker.tsx b/src/components/library/UpdateChecker.tsx index 95913544..813a8ed3 100644 --- a/src/components/library/UpdateChecker.tsx +++ b/src/components/library/UpdateChecker.tsx @@ -8,7 +8,7 @@ import client from 'util/client'; import makeToast from 'components/util/Toast'; interface IProgressProps { - progress: number + progress: number; } function Progress({ progress }: IProgressProps) { @@ -16,19 +16,19 @@ function Progress({ progress }: IProgressProps) { - - {`${Math.round(progress)}%`} - + {`${Math.round(progress)}%`} - ); } -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 + handleFinishedUpdate: (time: number) => void; } function UpdateChecker({ handleFinishedUpdate }: IUpdateCheckerProps) { @@ -58,9 +58,8 @@ 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; diff --git a/src/components/library/useSubscription.ts b/src/components/library/useSubscription.ts index 87452594..46e6e252 100644 --- a/src/components/library/useSubscription.ts +++ b/src/components/library/useSubscription.ts @@ -1,6 +1,9 @@ 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 = (path: string, callback?: (newValue: T) => boolean | void) => { const [state, setState] = useState(); diff --git a/src/components/manga/ChapterCard.tsx b/src/components/manga/ChapterCard.tsx index 8f7db020..d0d714c1 100644 --- a/src/components/manga/ChapterCard.tsx +++ b/src/components/manga/ChapterCard.tsx @@ -15,9 +15,7 @@ import DoneAll from '@mui/icons-material/DoneAll'; import Download from '@mui/icons-material/Download'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import RemoveDone from '@mui/icons-material/RemoveDone'; -import { - CardActionArea, Checkbox, ListItemIcon, ListItemText, Stack, -} from '@mui/material'; +import { CardActionArea, Checkbox, ListItemIcon, ListItemText, Stack } from '@mui/material'; import Card from '@mui/material/Card'; import CardContent from '@mui/material/CardContent'; import IconButton from '@mui/material/IconButton'; @@ -33,19 +31,24 @@ import { BACK } from 'util/useBackTo'; import { getUploadDateString } from 'util/date'; interface IProps { - chapter: IChapter - triggerChaptersUpdate: () => void - downloadChapter: IDownloadChapter | undefined - showChapterNumber: boolean - onSelect: (selected: boolean) => void - selected: boolean | null + chapter: IChapter; + triggerChaptersUpdate: () => void; + downloadChapter: IDownloadChapter | undefined; + showChapterNumber: boolean; + onSelect: (selected: boolean) => void; + selected: boolean | null; } const ChapterCard: React.FC = (props: IProps) => { const theme = useTheme(); const { - chapter, triggerChaptersUpdate, downloadChapter: dc, showChapterNumber, onSelect, selected, + chapter, + triggerChaptersUpdate, + downloadChapter: dc, + showChapterNumber, + onSelect, + selected, } = props; const isSelecting = selected !== null; @@ -71,7 +74,8 @@ const ChapterCard: React.FC = (props: IProps) => { if (key === 'read') { formData.append('lastPageRead', '1'); } - client.patch(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`, formData) + client + .patch(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`, formData) .then(() => triggerChaptersUpdate()); }; @@ -81,7 +85,8 @@ const ChapterCard: React.FC = (props: IProps) => { }; const deleteChapter = () => { - client.delete(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`) + client + .delete(`/api/v1/manga/${chapter.mangaId}/chapter/${chapter.index}`) .then(() => triggerChaptersUpdate()); handleClose(); }; @@ -112,7 +117,10 @@ const ChapterCard: React.FC = (props: IProps) => { > = (props: IProps) => { {chapter.bookmarked && ( - + )} - {showChapterNumber ? `Chapter ${chapter.chapterNumber}` : chapter.name} - - - {chapter.scanlator} + {showChapterNumber + ? `Chapter ${chapter.chapterNumber}` + : chapter.name} + {chapter.scanlator} {getUploadDateString(chapter.uploadDate)} {isDownloaded && ' • Downloaded'} @@ -164,18 +175,14 @@ const ChapterCard: React.FC = (props: IProps) => { - - Select - + Select {isDownloaded && ( - - Delete - + Delete )} {canBeDownloaded && ( @@ -183,9 +190,7 @@ const ChapterCard: React.FC = (props: IProps) => { - - Download - + Download )} sendChange('bookmarked', !chapter.bookmarked)}> @@ -212,9 +217,7 @@ const ChapterCard: React.FC = (props: IProps) => { - - Mark previous as Read - + Mark previous as Read diff --git a/src/components/manga/ChapterList.tsx b/src/components/manga/ChapterList.tsx index 87245aed..279a5368 100644 --- a/src/components/manga/ChapterList.tsx +++ b/src/components/manga/ChapterList.tsx @@ -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 { - Button, CircularProgress, Stack, -} from '@mui/material'; +import { Button, CircularProgress, Stack } from '@mui/material'; import Typography from '@mui/material/Typography'; import { styled } from '@mui/system'; import useSubscription from 'components/library/useSubscription'; @@ -17,10 +15,7 @@ import { filterAndSortChapters, useChapterOptions } from 'components/manga/util' import EmptyView from 'components/util/EmptyView'; import { interpolate } from 'components/util/helpers'; import makeToast from 'components/util/Toast'; -import React, { - ComponentProps, - useEffect, useMemo, useRef, useState, -} from 'react'; +import React, { ComponentProps, useEffect, useMemo, useRef, useState } from 'react'; import { Virtuoso } from 'react-virtuoso'; import client, { useQuery } from 'util/client'; import ChaptersToolbarMenu from 'components/manga/ChaptersToolbarMenu'; @@ -66,13 +61,13 @@ const actionsStrings = { }; export interface IChapterWithMeta { - chapter: IChapter - downloadChapter: IDownloadChapter | undefined - selected: boolean | null + chapter: IChapter; + downloadChapter: IDownloadChapter | undefined; + selected: boolean | null; } interface IProps { - mangaId: string + mangaId: string; } const ChapterList: React.FC = ({ mangaId }) => { @@ -92,9 +87,9 @@ const ChapterList: React.FC = ({ mangaId }) => { if (prevQueueRef.current && queue) { const prevQueue = prevQueueRef.current; const changedDownloads = queue.filter((cd) => { - const prevChapterDownload = prevQueue - .find((pcd) => cd.chapterIndex === pcd.chapterIndex - && cd.mangaId === pcd.mangaId); + const prevChapterDownload = prevQueue.find( + (pcd) => cd.chapterIndex === pcd.chapterIndex && cd.mangaId === pcd.mangaId, + ); if (!prevChapterDownload) return true; return cd.state !== prevChapterDownload.state; }); @@ -107,13 +102,19 @@ const ChapterList: React.FC = ({ mangaId }) => { prevQueueRef.current = queue; }, [queue]); - const visibleChapters = useMemo(() => filterAndSortChapters(chapters, options), // - [chapters, options]); + const visibleChapters = useMemo( + () => filterAndSortChapters(chapters, options), // + [chapters, options], + ); - const firstUnreadChapter = useMemo(() => visibleChapters.slice() - .reverse() - .find((c) => c.read === false), - [visibleChapters]); + const firstUnreadChapter = useMemo( + () => + visibleChapters + .slice() + .reverse() + .find((c) => c.read === false), + [visibleChapters], + ); const handleSelection = (index: number) => { const chapter = visibleChapters[index]; @@ -139,7 +140,10 @@ const ChapterList: React.FC = ({ mangaId }) => { setSelection(null); }; - const handleFabAction: ComponentProps['onAction'] = (action, actionChapters) => { + const handleFabAction: ComponentProps['onAction'] = ( + action, + actionChapters, + ) => { if (actionChapters.length === 0) return; const chapterIds = actionChapters.map(({ chapter }) => chapter.id); @@ -160,18 +164,26 @@ const ChapterList: React.FC = ({ 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) { return ( -
@@ -183,8 +195,7 @@ const ChapterList: React.FC = ({ mangaId }) => { const chaptersWithMeta: IChapterWithMeta[] = visibleChapters.map((chapter) => { const downloadChapter = queue?.find( - (cd) => cd.chapterIndex === chapter.index - && cd.mangaId === chapter.mangaId, + (cd) => cd.chapterIndex === chapter.index && cd.mangaId === chapter.mangaId, ); const selected = selection?.includes(chapter.id) ?? null; return { @@ -194,9 +205,10 @@ const ChapterList: React.FC = ({ mangaId }) => { }; }); - const selectedChapters = (selection === null) - ? null - : chaptersWithMeta.filter(({ chapter }) => selection.includes(chapter.id)); + const selectedChapters = + selection === null + ? null + : chaptersWithMeta.filter(({ chapter }) => selection.includes(chapter.id)); return ( <> @@ -206,38 +218,44 @@ const ChapterList: React.FC = ({ mangaId }) => { alignItems="center" justifyContent="space-between" sx={{ - m: 1, mb: 0, mr: 2, minHeight: 40, + m: 1, + mb: 0, + mr: 2, + minHeight: 40, }} > - {`${visibleChapters.length} Chapter${visibleChapters.length === 1 ? '' : 's'}`} + {`${visibleChapters.length} Chapter${ + visibleChapters.length === 1 ? '' : 's' + }`} {selection === null ? ( ) : ( - - + + )}
- {noChaptersFound && ( - - )} - {noChaptersMatchingFilter && ( - - )} + {noChaptersFound && } + {noChaptersMatchingFilter && } ( + itemContent={(index: number) => ( = ({ mangaId }) => { /> {selectedChapters !== null ? ( - + ) : ( firstUnreadChapter && )} diff --git a/src/components/manga/ChapterOptions.tsx b/src/components/manga/ChapterOptions.tsx index d9e47445..bb6166d9 100644 --- a/src/components/manga/ChapterOptions.tsx +++ b/src/components/manga/ChapterOptions.tsx @@ -14,10 +14,10 @@ import React from 'react'; import { SORT_OPTIONS } from 'components/manga/util'; interface IProps { - open: boolean - onClose: () => void - options: ChapterListOptions - optionsDispatch: React.Dispatch + open: boolean; + onClose: () => void; + options: ChapterListOptions; + optionsDispatch: React.Dispatch; } const TITLES = { @@ -26,9 +26,7 @@ const TITLES = { display: 'Display', }; -const ChapterOptions: React.FC = ({ - open, onClose, options, optionsDispatch, -}) => ( +const ChapterOptions: React.FC = ({ open, onClose, options, optionsDispatch }) => ( open={open} onClose={onClose} @@ -39,9 +37,39 @@ const ChapterOptions: React.FC = ({ if (key === 'filter') { return ( <> - optionsDispatch({ type: 'filter', filterType: 'unread', filterValue: c })} /> - optionsDispatch({ type: 'filter', filterType: 'downloaded', filterValue: c })} /> - optionsDispatch({ type: 'filter', filterType: 'bookmarked', filterValue: c })} /> + + optionsDispatch({ + type: 'filter', + filterType: 'unread', + filterValue: c, + }) + } + /> + + optionsDispatch({ + type: 'filter', + filterType: 'downloaded', + filterValue: c, + }) + } + /> + + optionsDispatch({ + type: 'filter', + filterType: 'bookmarked', + filterValue: c, + }) + } + /> ); } @@ -52,15 +80,20 @@ const ChapterOptions: React.FC = ({ label={label} checked={options.sortBy === mode} sortDescending={options.reverse} - onClick={() => (mode !== options.sortBy - ? optionsDispatch({ type: 'sortBy', sortBy: mode }) - : optionsDispatch({ type: 'sortReverse' }))} + onClick={() => + mode !== options.sortBy + ? optionsDispatch({ type: 'sortBy', sortBy: mode }) + : optionsDispatch({ type: 'sortReverse' }) + } /> )); } if (key === 'display') { return ( - optionsDispatch({ type: 'showChapterNumber' })} value={options.showChapterNumber}> + optionsDispatch({ type: 'showChapterNumber' })} + value={options.showChapterNumber} + > diff --git a/src/components/manga/ChaptersToolbarMenu.tsx b/src/components/manga/ChaptersToolbarMenu.tsx index 13df5f1f..6798ba3e 100644 --- a/src/components/manga/ChaptersToolbarMenu.tsx +++ b/src/components/manga/ChaptersToolbarMenu.tsx @@ -12,8 +12,8 @@ import ChapterOptions from 'components/manga/ChapterOptions'; import { isFilterActive } from 'components/manga/util'; interface IProps { - options: ChapterListOptions - optionsDispatch: React.Dispatch + options: ChapterListOptions; + optionsDispatch: React.Dispatch; } const ChaptersToolbarMenu = ({ options, optionsDispatch }: IProps) => { diff --git a/src/components/manga/MangaDetails.tsx b/src/components/manga/MangaDetails.tsx index 7d652de1..dd8ced14 100644 --- a/src/components/manga/MangaDetails.tsx +++ b/src/components/manga/MangaDetails.tsx @@ -17,102 +17,103 @@ import { mutate } from 'swr'; import client from 'util/client'; import useLocalStorage from 'util/useLocalStorage'; -const useStyles = (inLibrary: boolean) => makeStyles((theme: Theme) => ({ - root: { - width: '100%', - [theme.breakpoints.up('md')]: { - position: 'sticky', - top: '64px', - left: '0px', - width: '50vw', - height: 'calc(100vh - 64px)', - alignSelf: 'flex-start', - overflowY: 'auto', - }, - }, - top: { - padding: '10px', - // [theme.breakpoints.up('md')]: { - // minWidth: '50%', - // }, - }, - leftRight: { - display: 'flex', - }, - leftSide: { - '& img': { - borderRadius: 4, - maxWidth: '100%', - minWidth: '100%', - height: 'auto', - }, - maxWidth: '50%', - // [theme.breakpoints.up('md')]: { - // minWidth: '100px', - // }, - }, - rightSide: { - marginLeft: 15, - maxWidth: '100%', - '& span': { - fontWeight: '400', - }, - [theme.breakpoints.up('lg')]: { - fontSize: '1.3em', - }, - }, - buttons: { - display: 'flex', - justifyContent: 'space-around', - '& button': { - color: inLibrary ? '#2196f3' : 'inherit', - }, - '& a': { - textDecoration: 'none', - color: '#858585', - '& button': { - color: 'inherit', +const useStyles = (inLibrary: boolean) => + makeStyles((theme: Theme) => ({ + root: { + width: '100%', + [theme.breakpoints.up('md')]: { + position: 'sticky', + top: '64px', + left: '0px', + width: '50vw', + height: 'calc(100vh - 64px)', + alignSelf: 'flex-start', + overflowY: 'auto', }, }, - }, - bottom: { - paddingLeft: '10px', - paddingRight: '10px', - [theme.breakpoints.up('md')]: { - fontSize: '1.2em', - // maxWidth: '50%', + top: { + padding: '10px', + // [theme.breakpoints.up('md')]: { + // minWidth: '50%', + // }, }, - [theme.breakpoints.up('lg')]: { - fontSize: '1.3em', + leftRight: { + display: 'flex', }, - }, - description: { - '& h4': { - marginTop: '1em', - marginBottom: 0, + leftSide: { + '& img': { + borderRadius: 4, + maxWidth: '100%', + minWidth: '100%', + height: 'auto', + }, + maxWidth: '50%', + // [theme.breakpoints.up('md')]: { + // minWidth: '100px', + // }, }, - '& p': { - textAlign: 'justify', - textJustify: 'inter-word', + rightSide: { + marginLeft: 15, + maxWidth: '100%', + '& span': { + fontWeight: '400', + }, + [theme.breakpoints.up('lg')]: { + fontSize: '1.3em', + }, }, - }, - genre: { - display: 'flex', - flexWrap: 'wrap', - '& h5': { - border: '2px solid #2196f3', - borderRadius: '1.13em', - marginRight: '1em', - marginTop: 0, - marginBottom: '10px', - padding: '0.3em', - color: '#2196f3', + buttons: { + display: 'flex', + justifyContent: 'space-around', + '& button': { + color: inLibrary ? '#2196f3' : 'inherit', + }, + '& a': { + textDecoration: 'none', + color: '#858585', + '& button': { + color: 'inherit', + }, + }, }, - }, -})); + bottom: { + paddingLeft: '10px', + paddingRight: '10px', + [theme.breakpoints.up('md')]: { + fontSize: '1.2em', + // maxWidth: '50%', + }, + [theme.breakpoints.up('lg')]: { + fontSize: '1.3em', + }, + }, + description: { + '& h4': { + marginTop: '1em', + marginBottom: 0, + }, + '& p': { + textAlign: 'justify', + textJustify: 'inter-word', + }, + }, + genre: { + display: 'flex', + flexWrap: 'wrap', + '& h5': { + border: '2px solid #2196f3', + borderRadius: '1.13em', + marginRight: '1em', + marginTop: 0, + marginBottom: '10px', + padding: '0.3em', + color: '#2196f3', + }, + }, + })); -interface IProps{ - manga: IManga +interface IProps { + manga: IManga; } function getSourceName(source: ISource) { @@ -133,14 +134,24 @@ const MangaDetails: React.FC = ({ manga }) => { const classes = useStyles(manga.inLibrary)(); const addToLibrary = () => { - mutate(`/api/v1/manga/${manga.id}/?onlineFetch=false`, { ...manga, inLibrary: true }, { revalidate: false }); - client.get(`/api/v1/manga/${manga.id}/library/`) + 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 }); - client.delete(`/api/v1/manga/${manga.id}/library/`) + 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`)); }; @@ -149,12 +160,13 @@ const MangaDetails: React.FC = ({ manga }) => {
- Manga Thumbnail + Manga Thumbnail
-

- {manga.title} -

+

{manga.title}

{'Author: '} {getValueOrUnknown(manga.author)} @@ -163,20 +175,21 @@ const MangaDetails: React.FC = ({ manga }) => { {'Artist: '} {getValueOrUnknown(manga.artist)}

-

- {`Status: ${manga.status}`} -

-

- {`Source: ${getSourceName(manga.source)}`} -

+

{`Status: ${manga.status}`}

+

{`Source: ${getSourceName(manga.source)}`}

- - {manga.inLibrary - ? - : } + + {manga.inLibrary ? ( + + ) : ( + + )} {manga.inLibrary ? 'In Library' : 'Add To Library'} @@ -198,7 +211,9 @@ const MangaDetails: React.FC = ({ manga }) => {

{manga.description}

- {manga.genre.map((g) =>
{g}
)} + {manga.genre.map((g) => ( +
{g}
+ ))}
diff --git a/src/components/manga/MangaToolbarMenu.tsx b/src/components/manga/MangaToolbarMenu.tsx index 07a11994..55a71512 100644 --- a/src/components/manga/MangaToolbarMenu.tsx +++ b/src/components/manga/MangaToolbarMenu.tsx @@ -9,7 +9,14 @@ import Label from '@mui/icons-material/Label'; import MoreHoriz from '@mui/icons-material/MoreHoriz'; import Refresh from '@mui/icons-material/Refresh'; import { - IconButton, ListItemIcon, ListItemText, Menu, MenuItem, Tooltip, useMediaQuery, useTheme, + IconButton, + ListItemIcon, + ListItemText, + Menu, + MenuItem, + Tooltip, + useMediaQuery, + useTheme, } from '@mui/material'; import CategorySelect from 'components/navbar/action/CategorySelect'; import React, { useState } from 'react'; @@ -37,13 +44,22 @@ const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => { {isLargeScreen && ( <> - { onRefresh(); }} disabled={refreshing}> + { + onRefresh(); + }} + disabled={refreshing} + > {manga.inLibrary && ( - { setEditCategories(true); }}> + { + setEditCategories(true); + }} + > @@ -71,37 +87,35 @@ const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => { }} > { onRefresh(); handleClose(); }} + onClick={() => { + onRefresh(); + handleClose(); + }} disabled={refreshing} > - - Reload data from source - + Reload data from source {manga.inLibrary && ( { setEditCategories(true); handleClose(); }} + onClick={() => { + setEditCategories(true); + handleClose(); + }} > - - Edit manga categories - + Edit manga categories )} )} - + ); }; diff --git a/src/components/manga/ResumeFAB.tsx b/src/components/manga/ResumeFAB.tsx index 325e2276..72016a06 100644 --- a/src/components/manga/ResumeFAB.tsx +++ b/src/components/manga/ResumeFAB.tsx @@ -11,23 +11,29 @@ import { Link } from 'react-router-dom'; import { PlayArrow } from '@mui/icons-material'; import { BACK } from 'util/useBackTo'; -interface ResumeFABProps{ - chapter: IChapter - mangaId: string +interface ResumeFABProps { + chapter: IChapter; + mangaId: string; } export default function ResumeFab(props: ResumeFABProps) { - const { chapter: { index, lastPageRead }, mangaId } = props; + const { + chapter: { index, lastPageRead }, + mangaId, + } = props; return ( - {index === 1 ? 'Start' : 'Resume' } + {index === 1 ? 'Start' : 'Resume'} ); } diff --git a/src/components/manga/SelectionFAB.tsx b/src/components/manga/SelectionFAB.tsx index 044e9f5f..a43eafd4 100644 --- a/src/components/manga/SelectionFAB.tsx +++ b/src/components/manga/SelectionFAB.tsx @@ -6,20 +6,24 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import MoreHoriz from '@mui/icons-material/MoreHoriz'; -import { - Fab, Menu, -} from '@mui/material'; +import { Fab, Menu } from '@mui/material'; import { Box } from '@mui/system'; import { pluralize } from 'components/util/helpers'; 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[] - onAction: (action: SelectionAction, chapters: IChapterWithMeta[]) => void +interface SelectionFABProps { + selectedChapters: IChapterWithMeta[]; + onAction: (action: SelectionAction, chapters: IChapterWithMeta[]) => void; } const SelectionFAB: React.FC = (props) => { @@ -38,7 +42,10 @@ const SelectionFAB: React.FC = (props) => { return ( diff --git a/src/components/manga/SelectionFABActionItem.tsx b/src/components/manga/SelectionFABActionItem.tsx index a1098fe6..4d1e65ad 100644 --- a/src/components/manga/SelectionFABActionItem.tsx +++ b/src/components/manga/SelectionFABActionItem.tsx @@ -17,10 +17,10 @@ import type { IChapterWithMeta } from 'components/manga/ChapterList'; import type { SelectionAction } from 'components/manga/SelectionFAB'; interface IProps { - action: SelectionAction - matchingChapters: IChapterWithMeta[] - title: string - onClick: (action: SelectionAction, chapters: IChapterWithMeta[]) => void + action: SelectionAction; + matchingChapters: IChapterWithMeta[]; + title: string; + onClick: (action: SelectionAction, chapters: IChapterWithMeta[]) => void; } const ICONS = { @@ -32,16 +32,11 @@ const ICONS = { mark_as_unread: RemoveDone, }; -const SelectionFABActionItem: React.FC = ({ - action, matchingChapters, onClick, title, -}) => { +const SelectionFABActionItem: React.FC = ({ action, matchingChapters, onClick, title }) => { const count = matchingChapters.length; const Icon = ICONS[action]; return ( - onClick(action, matchingChapters)} - disabled={count === 0} - > + onClick(action, matchingChapters)} disabled={count === 0}> diff --git a/src/components/manga/hooks.ts b/src/components/manga/hooks.ts index 03567413..260a2937 100644 --- a/src/components/manga/hooks.ts +++ b/src/components/manga/hooks.ts @@ -16,10 +16,14 @@ export const useRefreshManga = (mangaId: string) => { const handleRefresh = useCallback(async () => { setFetchingOnline(true); await Promise.all([ - fetcher(`/api/v1/manga/${mangaId}/?onlineFetch=true`) - .then((res) => mutate(`/api/v1/manga/${mangaId}/?onlineFetch=false`, res, { revalidate: false })), - fetcher(`/api/v1/manga/${mangaId}/chapters?onlineFetch=true`) - .then((res) => mutate(`/api/v1/manga/${mangaId}/chapters?onlineFetch=false`, res, { revalidate: false })), + fetcher(`/api/v1/manga/${mangaId}/?onlineFetch=true`).then((res) => + mutate(`/api/v1/manga/${mangaId}/?onlineFetch=false`, res, { revalidate: false }), + ), + fetcher(`/api/v1/manga/${mangaId}/chapters?onlineFetch=true`).then((res) => + mutate(`/api/v1/manga/${mangaId}/chapters?onlineFetch=false`, res, { + revalidate: false, + }), + ), ]).finally(() => setFetchingOnline(false)); }, [mangaId]); diff --git a/src/components/manga/util.tsx b/src/components/manga/util.tsx index 244629c7..08f9779b 100644 --- a/src/components/manga/util.tsx +++ b/src/components/manga/util.tsx @@ -17,15 +17,15 @@ 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,8 +53,10 @@ export function unreadFilter(unread: NullAndUndefined, { read: isChapte } } -function downloadFilter(downloaded: NullAndUndefined, - { downloaded: chapterDownload }: IChapter) { +function downloadFilter( + downloaded: NullAndUndefined, + { downloaded: chapterDownload }: IChapter, +) { switch (downloaded) { case true: return chapterDownload; @@ -65,8 +67,10 @@ function downloadFilter(downloaded: NullAndUndefined, } } -function bookmarkedFilter(bookmarked: NullAndUndefined, - { bookmarked: chapterBookmarked }: IChapter) { +function bookmarkedFilter( + bookmarked: NullAndUndefined, + { bookmarked: chapterBookmarked }: IChapter, +) { switch (bookmarked) { case true: return chapterBookmarked; @@ -77,29 +81,34 @@ function bookmarkedFilter(bookmarked: NullAndUndefined, } } -export function filterAndSortChapters(chapters: IChapter[], options: ChapterListOptions) - : IChapter[] { +export function filterAndSortChapters( + chapters: IChapter[], + options: ChapterListOptions, +): IChapter[] { const filtered = options.active - ? chapters.filter((chp) => unreadFilter(options.unread, chp) - && downloadFilter(options.downloaded, chp) - && bookmarkedFilter(options.bookmarked, chp)) + ? chapters.filter( + (chp) => + unreadFilter(options.unread, chp) && + downloadFilter(options.downloaded, chp) && + 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(); } return Sorted; } -export const useChapterOptions = (mangaId: string) => useReducerLocalStorage< -ChapterListOptions, -ChapterOptionsReducerAction ->( - chapterOptionsReducer, - `${mangaId}filterOptions`, defaultChapterOptions, -); +export const useChapterOptions = (mangaId: string) => + useReducerLocalStorage( + chapterOptionsReducer, + `${mangaId}filterOptions`, + defaultChapterOptions, + ); export const SORT_OPTIONS: [ChapterSortMode, string][] = [ ['source', 'By Source'], diff --git a/src/components/molecules/DownloadStateIndicator.tsx b/src/components/molecules/DownloadStateIndicator.tsx index cb892817..a5bb0eb5 100644 --- a/src/components/molecules/DownloadStateIndicator.tsx +++ b/src/components/molecules/DownloadStateIndicator.tsx @@ -12,7 +12,7 @@ import { Box } from '@mui/system'; import React from 'react'; interface DownloadStateIndicatorProps { - download: IDownloadChapter + download: IDownloadChapter; } const DownloadStateIndicator: React.FC = ({ download }) => ( @@ -25,10 +25,7 @@ const DownloadStateIndicator: React.FC = ({ downloa }} > {download.progress !== 0 && ( - + )} void - children: React.ReactNode - minHeight?: number + open: boolean; + onClose: () => void; + children: React.ReactNode; + minHeight?: number; } -const OptionsPanel: React.FC = ({ - open, onClose, children, minHeight, -}) => ( +const OptionsPanel: React.FC = ({ open, onClose, children, minHeight }) => ( = ({ }, }} > - - {children} - + {children} ); diff --git a/src/components/molecules/OptionsTabs.tsx b/src/components/molecules/OptionsTabs.tsx index c1bb3499..17fbfb4c 100644 --- a/src/components/molecules/OptionsTabs.tsx +++ b/src/components/molecules/OptionsTabs.tsx @@ -10,26 +10,27 @@ import TabPanel from 'components/util/TabPanel'; import React, { useState } from 'react'; import OptionsPanel from 'components/molecules/OptionsPanel'; -interface IProps{ - open: boolean - onClose: () => void - tabs: T[] - tabTitle: (key: T) => React.ReactNode - tabContent: (key: T) => React.ReactNode - minHeight?: number +interface IProps { + open: boolean; + onClose: () => void; + tabs: T[]; + tabTitle: (key: T) => React.ReactNode; + tabContent: (key: T) => React.ReactNode; + minHeight?: number; } const OptionsTabs = ({ - open, onClose, tabs, tabTitle, tabContent, minHeight, + open, + onClose, + tabs, + tabTitle, + tabContent, + minHeight, }: IProps) => { const [tabNum, setTabNum] = useState(0); return ( - + ({ {tabs.map((tab, tabIndex) => ( - - {tabContent(tab)} - + {tabContent(tab)} ))} diff --git a/src/components/navbar/DefaultNavBar.tsx b/src/components/navbar/DefaultNavBar.tsx index 659b1d60..d2f3a97b 100644 --- a/src/components/navbar/DefaultNavBar.tsx +++ b/src/components/navbar/DefaultNavBar.tsx @@ -39,37 +39,43 @@ const navbarItems: Array = [ SelectedIconComponent: CollectionsBookmarkIcon, IconComponent: CollectionsOutlinedBookmarkIcon, show: 'both', - }, { + }, + { path: '/updates', title: 'Updates', SelectedIconComponent: NewReleasesIcon, IconComponent: NewReleasesOutlinedIcon, show: 'both', - }, { + }, + { path: '/extensions', title: 'Extensions', SelectedIconComponent: ExtensionIcon, IconComponent: ExtensionOutlinedIcon, show: 'desktop', - }, { + }, + { path: '/sources', title: 'Sources', SelectedIconComponent: ExploreIcon, IconComponent: ExploreOutlinedIcon, show: 'desktop', - }, { + }, + { path: '/browse', title: 'Browse', SelectedIconComponent: ExploreIcon, IconComponent: ExploreOutlinedIcon, show: 'mobile', - }, { + }, + { path: '/downloads', title: 'Downloads', SelectedIconComponent: GetAppIcon, IconComponent: GetAppOutlinedIcon, show: 'both', - }, { + }, + { path: '/settings', title: 'Settings', SelectedIconComponent: SettingsIcon, @@ -94,7 +100,9 @@ export default function DefaultNavBar() { let navbar = <>; if (isMobileWidth) { if (isMainRoute) { - navbar = it.show !== 'desktop')} />; + navbar = ( + it.show !== 'desktop')} /> + ); } } else { navbar = it.show !== 'mobile')} />; @@ -124,7 +132,12 @@ export default function DefaultNavBar() {
)} - + {title} {action} @@ -137,7 +150,7 @@ export default function DefaultNavBar() { } interface INavbarToolbarProps { - children?: React.ReactNode + children?: React.ReactNode; } export const NavbarToolbar: React.FC = ({ children }) => { diff --git a/src/components/navbar/NavBarContextProvider.tsx b/src/components/navbar/NavBarContextProvider.tsx index aca7d00d..7443a85e 100644 --- a/src/components/navbar/NavBarContextProvider.tsx +++ b/src/components/navbar/NavBarContextProvider.tsx @@ -8,11 +8,11 @@ import React, { useState } from 'react'; import NavBarContext from 'components/context/NavbarContext'; -interface IProps{ - children: React.ReactNode +interface IProps { + children: React.ReactNode; } -export default function NavBarProvider({ children }:IProps) { +export default function NavBarProvider({ children }: IProps) { const [defaultBackTo, setDefaultBackTo] = useState(); const [title, setTitle] = useState('Tachidesk'); const [action, setAction] = useState(
); @@ -36,9 +36,5 @@ export default function NavBarProvider({ children }:IProps) { override, setOverride, }; - return ( - - {children} - - ); + return {children}; } diff --git a/src/components/navbar/ReaderNavBar.tsx b/src/components/navbar/ReaderNavBar.tsx index e3ca79a0..ed021f33 100644 --- a/src/components/navbar/ReaderNavBar.tsx +++ b/src/components/navbar/ReaderNavBar.tsx @@ -104,28 +104,23 @@ const OpenDrawerButton = styled(IconButton)(({ theme }) => ({ })); interface IProps { - settings: IReaderSettings - setSettingValue: (key: keyof IReaderSettings, value: string | boolean) => void - manga: IManga | IMangaCard - chapter: IChapter - curPage: number + settings: IReaderSettings; + setSettingValue: (key: keyof IReaderSettings, value: string | boolean) => void; + manga: IManga | IMangaCard; + chapter: IChapter; + curPage: number; } export default function ReaderNavBar(props: IProps) { const history = useHistory(); const backTo = useBackTo(); const location = useLocation<{ - prevDrawerOpen?: boolean, - prevSettingsCollapseOpen?: boolean + prevDrawerOpen?: boolean; + prevSettingsCollapseOpen?: boolean; }>(); - const { - prevDrawerOpen, - prevSettingsCollapseOpen, - } = location.state ?? {}; + const { prevDrawerOpen, prevSettingsCollapseOpen } = location.state ?? {}; - const { - settings, setSettingValue, manga, chapter, curPage, - } = props; + const { settings, setSettingValue, manga, chapter, curPage } = props; const [drawerOpen, setDrawerOpen] = useState(settings.staticNav || prevDrawerOpen); const [updateDrawerOnRender, setUpdateDrawerOnRender] = useState(true); @@ -164,8 +159,8 @@ export default function ReaderNavBar(props: IProps) { useEffect(() => { window.addEventListener('scroll', handleScroll); - const rootEl:HTMLDivElement = document.querySelector('#root')!; - const mainContainer:HTMLDivElement = document.querySelector('#appMainContainer')!; + const rootEl: HTMLDivElement = document.querySelector('#root')!; + const mainContainer: HTMLDivElement = document.querySelector('#appMainContainer')!; // main container and root div need to change styles... rootEl.style.display = 'flex'; @@ -176,7 +171,7 @@ export default function ReaderNavBar(props: IProps) { mainContainer.style.display = 'block'; window.removeEventListener('scroll', handleScroll); }; - }, [handleScroll]);// handleScroll changes on every render + }, [handleScroll]); // handleScroll changes on every render const handleClose = () => { if (backTo.back) history.goBack(); @@ -194,13 +189,13 @@ export default function ReaderNavBar(props: IProps) { mountOnEnter unmountOnExit > -
- {!settings.staticNav - && ( + {!settings.staticNav && ( )} - + {chapter.name} - - {`Currently on page ${curPage + 1} of ${chapter.pageCount}`} - + {`Currently on page ${curPage + 1} of ${chapter.pageCount}`} - {chapter.index > 1 - && ( + {chapter.index > 1 && ( )} - {chapter.index < chapter.chapterCount - && ( + {chapter.index < chapter.chapterCount && ( - diff --git a/src/components/navbar/action/CategorySelect.tsx b/src/components/navbar/action/CategorySelect.tsx index 0c9e38a7..211bdbac 100644 --- a/src/components/navbar/action/CategorySelect.tsx +++ b/src/components/navbar/action/CategorySelect.tsx @@ -17,15 +17,17 @@ import FormGroup from '@mui/material/FormGroup'; import client, { useQuery } from 'util/client'; interface IProps { - open: boolean - setOpen: (value: boolean) => void - mangaId: number + open: boolean; + setOpen: (value: boolean) => void; + mangaId: number; } export default function CategorySelect(props: IProps) { const { open, setOpen, mangaId } = props; - const { data: mangaCategoriesData, mutate } = useQuery(`/api/v1/manga/${mangaId}/category`); + const { data: mangaCategoriesData, mutate } = useQuery( + `/api/v1/manga/${mangaId}/category`, + ); const { data: categoriesData } = useQuery('/api/v1/category'); const allCategories = useMemo(() => { @@ -50,8 +52,7 @@ export default function CategorySelect(props: IProps) { const { checked } = event.target as HTMLInputElement; const method = checked ? client.get : client.delete; - method(`/api/v1/manga/${mangaId}/category/${categoryId}`) - .then(() => mutate()); + method(`/api/v1/manga/${mangaId}/category/${categoryId}`).then(() => mutate()); }; return ( @@ -68,29 +69,27 @@ export default function CategorySelect(props: IProps) { Set categories - {allCategories.length === 0 - && ( - - No categories found! -
- You should make some from settings. -
- )} + {allCategories.length === 0 && ( + + No categories found! +
+ You should make some from settings. +
+ )} {allCategories.map((category) => ( handleChange(e, category.id)} color="default" /> - )} + } label={category.name} key={category.id} /> ))}
-
- + diff --git a/src/components/source/filters/CheckBoxFilter.tsx b/src/components/source/filters/CheckBoxFilter.tsx index 933c3d31..a304546d 100644 --- a/src/components/source/filters/CheckBoxFilter.tsx +++ b/src/components/source/filters/CheckBoxFilter.tsx @@ -9,37 +9,29 @@ import CheckboxInput from 'components/atoms/CheckboxInput'; import React from 'react'; interface Props { - state: boolean - name: string - position: number - group: number | undefined - updateFilterValue: Function - update: any + state: boolean; + name: string; + position: number; + group: number | undefined; + updateFilterValue: Function; + update: any; } const CheckBoxFilter: React.FC = (props: Props) => { - const { - state, - name, - position, - group, - updateFilterValue, - update, - } = props; + const { state, name, position, group, updateFilterValue, update } = props; const [val, setval] = React.useState(state); - const handleChange = (event: { target: { name: any; checked: any; }; }) => { + 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)); + const upd = update.filter( + (e: { position: number; group: number | undefined }) => + !(position === e.position && group === e.group), + ); updateFilterValue([...upd, { position, state: event.target.checked.toString(), group }]); }; if (state !== undefined) { - return ( - - ); + return ; } return null; }; diff --git a/src/components/source/filters/GroupFilter.tsx b/src/components/source/filters/GroupFilter.tsx index 20d26bc9..69f2389e 100644 --- a/src/components/source/filters/GroupFilter.tsx +++ b/src/components/source/filters/GroupFilter.tsx @@ -6,30 +6,22 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { ExpandLess, ExpandMore } from '@mui/icons-material'; -import { - Collapse, ListItemButton, ListItemText, Stack, -} from '@mui/material'; +import { Collapse, ListItemButton, ListItemText, Stack } from '@mui/material'; import { Box } from '@mui/system'; import React from 'react'; // eslint-disable-next-line import/no-cycle import { Options } from 'components/source/SourceOptions'; interface Props { - state: ISourceFilters[] - name: string - position: number - updateFilterValue: Function - update: any + state: ISourceFilters[]; + name: string; + position: number; + updateFilterValue: Function; + update: any; } const GroupFilter: React.FC = (props: Props) => { - const { - state, - name, - position, - updateFilterValue, - update, - } = props; + const { state, name, position, updateFilterValue, update } = props; const [open, setOpen] = React.useState(false); diff --git a/src/components/source/filters/HeaderFilter.tsx b/src/components/source/filters/HeaderFilter.tsx index 71ed004d..d5bac788 100644 --- a/src/components/source/filters/HeaderFilter.tsx +++ b/src/components/source/filters/HeaderFilter.tsx @@ -10,9 +10,13 @@ import { Typography } from '@mui/material'; import React from 'react'; interface Props { - name: string + name: string; } -const HeaderFilter: React.FC = ({ name }) => ({name}); +const HeaderFilter: React.FC = ({ name }) => ( + + {name} + +); export default HeaderFilter; diff --git a/src/components/source/filters/SelectFilter.tsx b/src/components/source/filters/SelectFilter.tsx index ad34067b..3042c713 100644 --- a/src/components/source/filters/SelectFilter.tsx +++ b/src/components/source/filters/SelectFilter.tsx @@ -13,20 +13,20 @@ import MenuItem from '@mui/material/MenuItem'; import Select from '@mui/material/Select'; interface Props { - values: any - name: string - state: number - selected: Selected | undefined - position: number - updateFilterValue: Function - group: number | undefined - update: any + values: any; + name: string; + state: number; + selected: Selected | undefined; + position: number; + updateFilterValue: Function; + group: number | undefined; + update: any; } interface Selected { - displayname: string - value: string - _value: string + displayname: string; + value: string; + _value: string; } function hasSelect( @@ -40,30 +40,24 @@ function hasSelect( ) { const [val, setval] = React.useState(state); if (values) { - const handleChange = (event: { target: { name: any; value: any; }; }) => { + const handleChange = (event: { target: { name: any; value: any } }) => { 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)); + const upd = update.filter( + (e: { position: number; group: number | undefined }) => + !(position === e.position && group === e.group), + ); updateFilterValue([...upd, { position, state: vall.toString(), group }]); }; const rett = values.map((e: Selected) => ( - - { - e.displayname - } + + {e.displayname} )); return ( - - {name} - + {name} + {name} + @@ -130,26 +122,10 @@ const SelectFilter: React.FC = ({ group, }) => { if (selected === undefined) { - return noSelect( - values, - name, - state, - position, - updateFilterValue, - update, - group, - ); + return noSelect(values, name, state, position, updateFilterValue, update, group); } - return hasSelect( - values, - name, - state, - position, - updateFilterValue, - update, - group, - ); + return hasSelect(values, name, state, position, updateFilterValue, update, group); }; export default SelectFilter; diff --git a/src/components/source/filters/SeparatorFilter.tsx b/src/components/source/filters/SeparatorFilter.tsx index 5e3075d4..a2389739 100644 --- a/src/components/source/filters/SeparatorFilter.tsx +++ b/src/components/source/filters/SeparatorFilter.tsx @@ -9,9 +9,13 @@ import { Divider } from '@mui/material'; import React from 'react'; interface Props { - name: string + name: string; } -const SeparatorFilter: React.FC = ({ name }) => ({name}); +const SeparatorFilter: React.FC = ({ name }) => ( + + {name} + +); export default SeparatorFilter; diff --git a/src/components/source/filters/SortFilter.tsx b/src/components/source/filters/SortFilter.tsx index c4027403..c0847be8 100644 --- a/src/components/source/filters/SortFilter.tsx +++ b/src/components/source/filters/SortFilter.tsx @@ -6,33 +6,23 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { ExpandLess, ExpandMore } from '@mui/icons-material'; -import { - Collapse, ListItemButton, ListItemText, Stack, -} from '@mui/material'; +import { Collapse, ListItemButton, ListItemText, Stack } from '@mui/material'; import { Box } from '@mui/system'; import SortRadioInput from 'components/atoms/SortRadioInput'; import React from 'react'; interface Props { - values: any - name: string - state: IState - position: number - group: number | undefined - updateFilterValue: Function - update: any + values: any; + name: string; + state: IState; + position: number; + group: number | undefined; + updateFilterValue: Function; + update: any; } const SortFilter: React.FC = (props: Props) => { - const { - values, - name, - state, - position, - group, - updateFilterValue, - update, - } = props; + const { values, name, state, position, group, updateFilterValue, update } = props; const [val, setval] = React.useState(state); const [open, setOpen] = React.useState(false); @@ -51,9 +41,10 @@ const SortFilter: React.FC = (props: Props) => { } tmp.index = index; setval(tmp); - const upd = update.filter((e: { - position: number; group: number | undefined; - }) => !(position === e.position && group === e.group)); + const upd = update.filter( + (e: { position: number; group: number | undefined }) => + !(position === e.position && group === e.group), + ); updateFilterValue([...upd, { position, state: JSON.stringify(tmp), group }]); }; diff --git a/src/components/source/filters/TextFilter.tsx b/src/components/source/filters/TextFilter.tsx index a7e90b75..74207c3f 100644 --- a/src/components/source/filters/TextFilter.tsx +++ b/src/components/source/filters/TextFilter.tsx @@ -6,36 +6,28 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import SearchIcon from '@mui/icons-material/Search'; -import { - FormControl, Input, InputAdornment, InputLabel, -} from '@mui/material'; +import { FormControl, Input, InputAdornment, InputLabel } from '@mui/material'; import React from 'react'; interface Props { - state: string - name: string - position: number - group: number | undefined - updateFilterValue: Function - update: any + state: string; + name: string; + position: number; + group: number | undefined; + updateFilterValue: Function; + update: any; } const TextFilter: React.FC = (props) => { - const { - state, - name, - position, - group, - updateFilterValue, - update, - } = props; + const { state, name, position, group, updateFilterValue, update } = props; const [Search, setsearch] = React.useState(state || ''); let typingTimer: NodeJS.Timeout; function doneTyping(e: React.ChangeEvent) { - const upd = update.filter((el: { - position: number; group: number | undefined; - }) => !(position === el.position && group === el.group)); + const upd = update.filter( + (el: { position: number; group: number | undefined }) => + !(position === el.position && group === el.group), + ); updateFilterValue([...upd, { position, state: e.target.value, group }]); } @@ -43,29 +35,29 @@ const TextFilter: React.FC = (props) => { setsearch(e.target.value); clearTimeout(typingTimer); - typingTimer = setTimeout(() => { doneTyping(e); }, 2500); + typingTimer = setTimeout(() => { + doneTyping(e); + }, 2500); } if (state !== undefined) { return ( - - {name} - + {name} - )} + } /> ); } - return (<>); + return <>; }; export default TextFilter; diff --git a/src/components/source/filters/TriStateFilter.tsx b/src/components/source/filters/TriStateFilter.tsx index 7034e71a..30dff72e 100644 --- a/src/components/source/filters/TriStateFilter.tsx +++ b/src/components/source/filters/TriStateFilter.tsx @@ -9,37 +9,34 @@ import ThreeStateCheckboxInput from 'components/atoms/ThreeStateCheckboxInput'; import React from 'react'; interface Props { - state: number - name: string - position: number - group: number | undefined - updateFilterValue: Function - update: any + state: number; + name: string; + position: number; + group: number | undefined; + updateFilterValue: Function; + update: any; } const TriStateFilter: React.FC = (props) => { - const { - state, - name, - position, - group, - updateFilterValue, - update, - } = props; + const { state, name, position, group, updateFilterValue, update } = props; const [val, setval] = React.useState(Number(state)); const handleChange = (checked: boolean | null | undefined) => { // eslint-disable-next-line no-nested-ternary 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)); - updateFilterValue([...upd, { - position, - state: newState.toString(), - group, - }]); + const upd = update.filter( + (e: { position: number; group: number | undefined }) => + !(position === e.position && group === e.group), + ); + updateFilterValue([ + ...upd, + { + position, + state: newState.toString(), + group, + }, + ]); }; if (state !== undefined) { @@ -51,7 +48,7 @@ const TriStateFilter: React.FC = (props) => { /> ); } - return (<>); + return <>; }; export default TriStateFilter; diff --git a/src/components/sourceConfiguration/EditTextPreference.tsx b/src/components/sourceConfiguration/EditTextPreference.tsx index 38a6f053..900efe61 100644 --- a/src/components/sourceConfiguration/EditTextPreference.tsx +++ b/src/components/sourceConfiguration/EditTextPreference.tsx @@ -17,9 +17,7 @@ import TextField from '@mui/material/TextField'; import Button from '@mui/material/Button'; export default function EditTextPreference(props: EditTextPreferenceProps) { - const { - title, summary, dialogTitle, dialogMessage, currentValue, updateValue, - } = props; + const { title, summary, dialogTitle, dialogMessage, currentValue, updateValue } = props; const [internalCurrentValue, setInternalCurrentValue] = useState(currentValue); const [dialogOpen, setDialogOpen] = useState(false); @@ -39,23 +37,13 @@ export default function EditTextPreference(props: EditTextPreferenceProps) { return ( <> - setDialogOpen(true)} - > - + setDialogOpen(true)}> + - - {dialogTitle} - + {dialogTitle} - - {dialogMessage} - + {dialogMessage} void - options: string[] - title: string +interface IListDialogProps { + value: string; + open: boolean; + onClose: (arg0: string | null) => void; + options: string[]; + title: string; } function ListDialog(props: IListDialogProps) { - const { - value: valueProp, open, onClose, options, title, - } = props; + const { value: valueProp, open, onClose, options, title } = props; const [value, setValue] = React.useState(valueProp); const radioGroupRef = React.useRef(null); @@ -65,11 +63,7 @@ function ListDialog(props: IListDialogProps) { > {title} - + {options.map((option) => ( (currentValue); const [dialogOpen, setDialogOpen] = useState(false); @@ -131,10 +123,7 @@ export default function ListPreference(props: ListPreferenceProps) { return ( <> - setDialogOpen(true)} - > + setDialogOpen(true)}> void - values: string[] - title: string +interface IListDialogProps { + selectedValues: string[]; + open: boolean; + onClose: (arg0: string[] | null) => void; + values: string[]; + title: string; } function ListDialog(props: IListDialogProps) { - const { - selectedValues: selectedValuesProp, open, onClose, values, title, - } = props; + const { selectedValues: selectedValuesProp, open, onClose, values, title } = props; const [selectedValues, setSelectedValues] = React.useState(selectedValuesProp); React.useEffect(() => { @@ -56,7 +54,8 @@ function ListDialog(props: IListDialogProps) { selectedValuesClone.push(value); setSelectedValues(selectedValuesClone); } - } else if (hasEntry) { // not checked and has entry + } else if (hasEntry) { + // not checked and has entry const selectedValuesClone = cloneObject(selectedValues) as string[]; const index = selectedValuesClone.indexOf(value); selectedValuesClone.splice(index, 1); @@ -75,7 +74,7 @@ function ListDialog(props: IListDialogProps) { {values.map((value) => ( value === selectedValue, @@ -83,7 +82,7 @@ function ListDialog(props: IListDialogProps) { onChange={(e) => handleChange(e, value)} color="default" /> - )} + } label={value} key={value} /> @@ -101,9 +100,7 @@ function ListDialog(props: IListDialogProps) { } export default function MultiSelectListPreference(props: MultiSelectListPreferenceProps) { - const { - title, summary, currentValue, updateValue, entryValues, entries, - } = props; + const { title, summary, currentValue, updateValue, entryValues, entries } = props; const [internalCurrentValue, setInternalCurrentValue] = useState(currentValue); const [dialogOpen, setDialogOpen] = useState(false); @@ -111,15 +108,17 @@ export default function MultiSelectListPreference(props: MultiSelectListPreferen setInternalCurrentValue(currentValue); }, [currentValue]); - const findEntriesOf = (values: string[]) => values.map((value) => { - const idx = entryValues.indexOf(value); - return entries[idx]; - }); + const findEntriesOf = (values: string[]) => + values.map((value) => { + const idx = entryValues.indexOf(value); + return entries[idx]; + }); - const findEntryValuesOf = (values: string[]) => values.map((value) => { - const idx = entries.indexOf(value); - return entryValues[idx]; - }); + const findEntryValuesOf = (values: string[]) => + values.map((value) => { + const idx = entries.indexOf(value); + return entryValues[idx]; + }); const getSummary = () => summary; @@ -137,10 +136,7 @@ export default function MultiSelectListPreference(props: MultiSelectListPreferen return ( <> - setDialogOpen(true)} - > + setDialogOpen(true)}> (currentValue); useEffect(() => { @@ -31,17 +31,16 @@ function TwoSatePreference(props: TwoStatePreferenceProps) { - {React.createElement(getTwoStateType(type), - { - edge: 'end', - checked: internalCurrentValue, - onChange: () => { - updateValue(!currentValue); + {React.createElement(getTwoStateType(type), { + edge: 'end', + checked: internalCurrentValue, + onChange: () => { + updateValue(!currentValue); - // appear smooth - setInternalCurrentValue(!currentValue); - }, - })} + // appear smooth + setInternalCurrentValue(!currentValue); + }, + })} ); @@ -50,6 +49,7 @@ function TwoSatePreference(props: TwoStatePreferenceProps) { export function CheckBoxPreference(props: CheckBoxPreferenceProps) { return ; } + export function SwitchPreferenceCompat(props: SwitchPreferenceCompatProps) { return ; } diff --git a/src/components/util/AppbarSearch.tsx b/src/components/util/AppbarSearch.tsx index 8d240710..392378af 100644 --- a/src/components/util/AppbarSearch.tsx +++ b/src/components/util/AppbarSearch.tsx @@ -13,7 +13,7 @@ import CancelIcon from '@mui/icons-material/Cancel'; import { useQueryParam, StringParam } from 'use-query-params'; interface IProps { - autoOpen?: boolean + autoOpen?: boolean; } const defaultProps = { @@ -29,11 +29,14 @@ const AppbarSearch: React.FunctionComponent = (props) => { function handleChange(e: React.ChangeEvent) { setQuery(e.target.value === '' ? undefined : e.target.value); } + const cancelSearch = () => { setQuery(null); setSearchOpen(false); }; - const handleBlur = () => { if (!query) setSearchOpen(false); }; + const handleBlur = () => { + if (!query) setSearchOpen(false); + }; const openSearch = () => { setSearchOpen(true); // Put Focus Action at the end of the Callstack so Input actually exists on the dom @@ -43,7 +46,7 @@ const AppbarSearch: React.FunctionComponent = (props) => { }; const handleSearchShortcut = (e: KeyboardEvent) => { - if ((e.code === 'F3') || (e.ctrlKey && e.code === 'KeyF')) { + if (e.code === 'F3' || (e.ctrlKey && e.code === 'KeyF')) { e.preventDefault(); openSearch(); } @@ -65,26 +68,23 @@ const AppbarSearch: React.FunctionComponent = (props) => { return ( <> - {searchOpen - ? ( - - -
- )} - /> - ) : ( - - - - )} + {searchOpen ? ( + + + + } + /> + ) : ( + + + + )} ); }; diff --git a/src/components/util/CustomExtensionOutlinedIcon.tsx b/src/components/util/CustomExtensionOutlinedIcon.tsx index 7a0a13f6..38213db7 100644 --- a/src/components/util/CustomExtensionOutlinedIcon.tsx +++ b/src/components/util/CustomExtensionOutlinedIcon.tsx @@ -1,7 +1,8 @@ import React from 'react'; import createSvgIcon from '@mui/material/utils/createSvgIcon'; -const d = 'M 11 1 C 9.3550302 1 8 2.3550302 8 4 L 4 4 C 2.9069372 4 2 4.9069372 2 6 L 2 12 L 4 12 C 4.5650302 12 5 12.43497 5 13 C 5 13.56503 4.5650302 14 4 14 L 2 14 L 2 20 C 2 21.093063 2.9069372 22 4 22 L 10 22 L 10 20 C 10 19.43497 10.43497 19 11 19 C 11.56503 19 12 19.43497 12 20 L 12 22 L 18 22 C 19.093063 22 20 21.093063 20 20 L 20 16 C 21.64497 16 23 14.64497 23 13 C 23 11.35503 21.64497 10 20 10 L 20 6 C 20 4.9069372 19.093063 4 18 4 L 14 4 C 14 2.3550302 12.64497 1 11 1 z M 11 3 C 11.56503 3 12 3.4349698 12 4 L 12 6 L 18 6 L 18 12 L 20 12 C 20.56503 12 21 12.43497 21 13 C 21 13.56503 20.56503 14 20 14 L 18 14 L 18 20 L 14 20 C 14 18.35503 12.64497 17 11 17 C 9.3550302 17 8 18.35503 8 20 L 4 20 L 4 16 C 5.6449698 16 7 14.64497 7 13 C 7 11.35503 5.6449698 10 4 10 L 4 6 L 10 6 L 10 4 C 10 3.4349698 10.43497 3 11 3 z'; +const d = + 'M 11 1 C 9.3550302 1 8 2.3550302 8 4 L 4 4 C 2.9069372 4 2 4.9069372 2 6 L 2 12 L 4 12 C 4.5650302 12 5 12.43497 5 13 C 5 13.56503 4.5650302 14 4 14 L 2 14 L 2 20 C 2 21.093063 2.9069372 22 4 22 L 10 22 L 10 20 C 10 19.43497 10.43497 19 11 19 C 11.56503 19 12 19.43497 12 20 L 12 22 L 18 22 C 19.093063 22 20 21.093063 20 20 L 20 16 C 21.64497 16 23 14.64497 23 13 C 23 11.35503 21.64497 10 20 10 L 20 6 C 20 4.9069372 19.093063 4 18 4 L 14 4 C 14 2.3550302 12.64497 1 11 1 z M 11 3 C 11.56503 3 12 3.4349698 12 4 L 12 6 L 18 6 L 18 12 L 20 12 C 20.56503 12 21 12.43497 21 13 C 21 13.56503 20.56503 14 20 14 L 18 14 L 18 20 L 14 20 C 14 18.35503 12.64497 17 11 17 C 9.3550302 17 8 18.35503 8 20 L 4 20 L 4 16 C 5.6449698 16 7 14.64497 7 13 C 7 11.35503 5.6449698 10 4 10 L 4 6 L 10 6 L 10 4 C 10 3.4349698 10.43497 3 11 3 z'; const icon = createSvgIcon(, 'CustomExtensionOutlined'); diff --git a/src/components/util/EmptyView.tsx b/src/components/util/EmptyView.tsx index 17730098..610708d6 100644 --- a/src/components/util/EmptyView.tsx +++ b/src/components/util/EmptyView.tsx @@ -12,14 +12,7 @@ import { useTheme } from '@mui/material/styles'; import { useMediaQuery } from '@mui/material'; import { Box } from '@mui/system'; -const ERROR_FACES = [ - '(・o・;)', - 'Σ(ಠ_ಠ)', - 'ಥ_ಥ', - '(˘・_・˘)', - '(; ̄Д ̄)', - '(・Д・。', -]; +const ERROR_FACES = ['(・o・;)', 'Σ(ಠ_ಠ)', 'ಥ_ಥ', '(˘・_・˘)', '(; ̄Д ̄)', '(・Д・。']; function getRandomErrorFace() { const randIndex = Math.floor(Math.random() * ERROR_FACES.length); @@ -27,8 +20,8 @@ function getRandomErrorFace() { } interface IProps { - message: string - messageExtra?: JSX.Element + message: string; + messageExtra?: JSX.Element; } export default function EmptyView({ message, messageExtra }: IProps) { @@ -38,20 +31,19 @@ export default function EmptyView({ message, messageExtra }: IProps) { const errorFace = useMemo(() => getRandomErrorFace(), []); return ( - {errorFace} - - {message} - + {message} {messageExtra} ); diff --git a/src/components/util/LoadingPlaceholder.tsx b/src/components/util/LoadingPlaceholder.tsx index e34ae833..e0e40596 100644 --- a/src/components/util/LoadingPlaceholder.tsx +++ b/src/components/util/LoadingPlaceholder.tsx @@ -10,16 +10,14 @@ import CircularProgress from '@mui/material/CircularProgress'; import { Box } from '@mui/system'; interface IProps { - shouldRender?: boolean | (() => boolean) - children?: React.ReactNode - component?: string | React.FunctionComponent | React.ComponentClass - componentProps?: any + shouldRender?: boolean | (() => boolean); + children?: React.ReactNode; + component?: string | React.FunctionComponent | React.ComponentClass; + componentProps?: any; } export default function LoadingPlaceholder(props: IProps) { - const { - children, shouldRender, component, componentProps, - } = props; + const { children, shouldRender, component, componentProps } = props; let condition = true; if (shouldRender !== undefined) { @@ -32,20 +30,17 @@ export default function LoadingPlaceholder(props: IProps) { } if (children) { - return ( - <> - {children} - - ); + return <>{children}; } } return ( - diff --git a/src/components/util/SpinnerImage.tsx b/src/components/util/SpinnerImage.tsx index 620a823c..4b2fa706 100644 --- a/src/components/util/SpinnerImage.tsx +++ b/src/components/util/SpinnerImage.tsx @@ -12,21 +12,19 @@ import { Theme } from '@mui/system/createTheme'; import { SxProps } from '@mui/system/styleFunctionSx'; interface IProps { - src: string - alt: string + src: string; + alt: string; - imgRef?: React.RefObject + imgRef?: React.RefObject; - spinnerStyle?: SxProps - imgStyle?: CSSProperties + spinnerStyle?: SxProps; + imgStyle?: CSSProperties; - onImageLoad?: () => void + onImageLoad?: () => void; } export default function SpinnerImage(props: IProps) { - const { - src, alt, onImageLoad, imgRef, spinnerStyle, imgStyle, - } = props; + const { src, alt, onImageLoad, imgRef, spinnerStyle, imgStyle } = props; const [imageSrc, setImagsrc] = useState(''); useEffect(() => { @@ -61,14 +59,7 @@ export default function SpinnerImage(props: IProps) { return ; } - return ( - {alt} - ); + return {alt}; } SpinnerImage.defaultProps = { diff --git a/src/components/util/TabPanel.tsx b/src/components/util/TabPanel.tsx index 0b7c2d02..a320633f 100644 --- a/src/components/util/TabPanel.tsx +++ b/src/components/util/TabPanel.tsx @@ -14,16 +14,10 @@ interface IProps { } export default function TabPanel(props: IProps) { - const { - children, index, currentIndex, - } = props; + const { children, index, currentIndex } = props; return ( -