From 2eeea41a45aa638995c81b10c26c6b3df18ed363 Mon Sep 17 00:00:00 2001 From: Daniel <50052685+schroda@users.noreply.github.com> Date: Sun, 5 Feb 2023 16:15:20 +0100 Subject: [PATCH] force absolute import path (#223) * Add "no-relative-import-paths" eslint plugin * Add "no-relative-import-paths" eslint plugin - Fix imports --- .eslintrc.js | 10 +++++++++- package.json | 1 + src/components/MangaGrid.tsx | 4 ++-- src/components/atoms/SortRadioInput.tsx | 2 +- src/components/atoms/ThreeStateCheckboxInput.tsx | 2 +- src/components/context/AppContext.tsx | 2 +- src/components/library/LibraryToolbarMenu.tsx | 2 +- src/components/library/UpdateChecker.tsx | 2 +- src/components/manga/ChapterList.tsx | 4 ++-- src/components/manga/ChapterOptions.tsx | 2 +- src/components/manga/ChaptersToolbarMenu.tsx | 4 ++-- src/components/manga/SelectionFAB.tsx | 4 ++-- src/components/manga/SelectionFABActionItem.tsx | 4 ++-- src/components/molecules/OptionsTabs.tsx | 2 +- src/components/navbar/DefaultNavBar.tsx | 4 ++-- src/components/navbar/ReaderNavBar.tsx | 2 +- src/components/reader/pager/DoublePagedPager.tsx | 4 ++-- src/components/reader/pager/HorizontalPager.tsx | 2 +- src/components/reader/pager/PagedPager.tsx | 2 +- src/components/reader/pager/VerticalPager.tsx | 2 +- src/components/source/SourceOptions.tsx | 16 ++++++++-------- src/components/source/filters/GroupFilter.tsx | 2 +- src/index.tsx | 4 ++-- src/screens/Library.tsx | 2 +- src/screens/Reader.tsx | 2 +- src/screens/Settings.tsx | 8 ++++---- src/screens/settings/Backup.tsx | 4 ++-- src/util/client.tsx | 2 +- src/util/metadata.ts | 2 +- src/util/readerSettings.ts | 2 +- src/util/useLocalStorage.tsx | 2 +- yarn.lock | 5 +++++ 32 files changed, 63 insertions(+), 49 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index d2eace74..6d4d9bb4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,7 +3,7 @@ module.exports = { 'airbnb', 'airbnb-typescript' ], - plugins: ['@typescript-eslint'], + plugins: ['@typescript-eslint', 'no-relative-import-paths'], parserOptions: { project: './tsconfig.json', }, @@ -24,5 +24,13 @@ module.exports = { 'react/jsx-no-bind' : 'off', 'react/jsx-props-no-spreading': 'off', 'react/require-default-props': 'off', + + "no-relative-import-paths/no-relative-import-paths": [ + "error", + { + rootDir: "src", + prefix: false, + }, + ], }, }; diff --git a/package.json b/package.json index 24528e29..d51fae3f 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "eslint-config-airbnb-typescript": "^14.0.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-react": "^7.21.5", "eslint-plugin-react-hooks": "^1.7.0", "typescript": "^4.8.4" diff --git a/src/components/MangaGrid.tsx b/src/components/MangaGrid.tsx index 0864c576..4233afa0 100644 --- a/src/components/MangaGrid.tsx +++ b/src/components/MangaGrid.tsx @@ -13,8 +13,8 @@ import EmptyView from 'components/util/EmptyView'; import LoadingPlaceholder from 'components/util/LoadingPlaceholder'; import { Typography } from '@mui/material'; import { Box } from '@mui/system'; -import MangaCard from './MangaCard'; -import { GridLayout } from './context/LibraryOptionsContext'; +import MangaCard from 'components/MangaCard'; +import { GridLayout } from 'components/context/LibraryOptionsContext'; export interface IMangaGridProps{ mangas: IMangaCard[] diff --git a/src/components/atoms/SortRadioInput.tsx b/src/components/atoms/SortRadioInput.tsx index f11c03b1..81131bf7 100644 --- a/src/components/atoms/SortRadioInput.tsx +++ b/src/components/atoms/SortRadioInput.tsx @@ -9,7 +9,7 @@ import ArrowDownward from '@mui/icons-material/ArrowDownward'; import ArrowUpward from '@mui/icons-material/ArrowUpward'; import React from 'react'; -import RadioInput, { RadioInputProps } from './RadioInput'; +import RadioInput, { RadioInputProps } from 'components/atoms/RadioInput'; interface IProps extends RadioInputProps { sortDescending?: boolean | null | undefined diff --git a/src/components/atoms/ThreeStateCheckboxInput.tsx b/src/components/atoms/ThreeStateCheckboxInput.tsx index 6b59ba5c..6d38acb4 100644 --- a/src/components/atoms/ThreeStateCheckboxInput.tsx +++ b/src/components/atoms/ThreeStateCheckboxInput.tsx @@ -8,7 +8,7 @@ import { FormControlLabel } from '@mui/material'; import React from 'react'; -import ThreeStateCheckbox, { ThreeStateCheckboxProps } from './ThreeStateCheckbox'; +import ThreeStateCheckbox, { ThreeStateCheckboxProps } from 'components/atoms/ThreeStateCheckbox'; interface IProps extends ThreeStateCheckboxProps { label?: string diff --git a/src/components/context/AppContext.tsx b/src/components/context/AppContext.tsx index da9184c6..b590cc99 100644 --- a/src/components/context/AppContext.tsx +++ b/src/components/context/AppContext.tsx @@ -20,7 +20,7 @@ import createTheme from 'theme'; import { QueryParamProvider } from 'use-query-params'; import { fetcher } from 'util/client'; import useLocalStorage from 'util/useLocalStorage'; -import DarkTheme from './DarkTheme'; +import DarkTheme from 'components/context/DarkTheme'; interface Props { children: React.ReactNode diff --git a/src/components/library/LibraryToolbarMenu.tsx b/src/components/library/LibraryToolbarMenu.tsx index 080bc977..9cc4d227 100644 --- a/src/components/library/LibraryToolbarMenu.tsx +++ b/src/components/library/LibraryToolbarMenu.tsx @@ -9,7 +9,7 @@ import FilterList from '@mui/icons-material/FilterList'; import { IconButton } from '@mui/material'; import { useLibraryOptionsContext } from 'components/context/LibraryOptionsContext'; import React, { useState } from 'react'; -import LibraryOptionsPanel from './LibraryOptionsPanel'; +import LibraryOptionsPanel from 'components/library/LibraryOptionsPanel'; const LibraryToolbarMenu: React.FC = () => { const [open, setOpen] = useState(false); diff --git a/src/components/library/UpdateChecker.tsx b/src/components/library/UpdateChecker.tsx index f1ed0249..95913544 100644 --- a/src/components/library/UpdateChecker.tsx +++ b/src/components/library/UpdateChecker.tsx @@ -5,7 +5,7 @@ import CircularProgress from '@mui/material/CircularProgress'; import { Box } from '@mui/system'; import Typography from '@mui/material/Typography'; import client from 'util/client'; -import makeToast from '../util/Toast'; +import makeToast from 'components/util/Toast'; interface IProgressProps { progress: number diff --git a/src/components/manga/ChapterList.tsx b/src/components/manga/ChapterList.tsx index 100e1309..87245aed 100644 --- a/src/components/manga/ChapterList.tsx +++ b/src/components/manga/ChapterList.tsx @@ -23,8 +23,8 @@ import React, { } from 'react'; import { Virtuoso } from 'react-virtuoso'; import client, { useQuery } from 'util/client'; -import ChaptersToolbarMenu from './ChaptersToolbarMenu'; -import SelectionFAB from './SelectionFAB'; +import ChaptersToolbarMenu from 'components/manga/ChaptersToolbarMenu'; +import SelectionFAB from 'components/manga/SelectionFAB'; const StyledVirtuoso = styled(Virtuoso)(({ theme }) => ({ listStyle: 'none', diff --git a/src/components/manga/ChapterOptions.tsx b/src/components/manga/ChapterOptions.tsx index e76361ad..d9e47445 100644 --- a/src/components/manga/ChapterOptions.tsx +++ b/src/components/manga/ChapterOptions.tsx @@ -11,7 +11,7 @@ import SortRadioInput from 'components/atoms/SortRadioInput'; import ThreeStateCheckboxInput from 'components/atoms/ThreeStateCheckboxInput'; import OptionsTabs from 'components/molecules/OptionsTabs'; import React from 'react'; -import { SORT_OPTIONS } from './util'; +import { SORT_OPTIONS } from 'components/manga/util'; interface IProps { open: boolean diff --git a/src/components/manga/ChaptersToolbarMenu.tsx b/src/components/manga/ChaptersToolbarMenu.tsx index b0162aa7..13df5f1f 100644 --- a/src/components/manga/ChaptersToolbarMenu.tsx +++ b/src/components/manga/ChaptersToolbarMenu.tsx @@ -8,8 +8,8 @@ import FilterList from '@mui/icons-material/FilterList'; import { IconButton } from '@mui/material'; import * as React from 'react'; -import ChapterOptions from './ChapterOptions'; -import { isFilterActive } from './util'; +import ChapterOptions from 'components/manga/ChapterOptions'; +import { isFilterActive } from 'components/manga/util'; interface IProps { options: ChapterListOptions diff --git a/src/components/manga/SelectionFAB.tsx b/src/components/manga/SelectionFAB.tsx index ac1b533b..044e9f5f 100644 --- a/src/components/manga/SelectionFAB.tsx +++ b/src/components/manga/SelectionFAB.tsx @@ -12,8 +12,8 @@ import { import { Box } from '@mui/system'; import { pluralize } from 'components/util/helpers'; import React, { useRef, useState } from 'react'; -import type { IChapterWithMeta } from './ChapterList'; -import SelectionFABActionItem from './SelectionFABActionItem'; +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'; diff --git a/src/components/manga/SelectionFABActionItem.tsx b/src/components/manga/SelectionFABActionItem.tsx index 2b6abbc6..a1098fe6 100644 --- a/src/components/manga/SelectionFABActionItem.tsx +++ b/src/components/manga/SelectionFABActionItem.tsx @@ -13,8 +13,8 @@ import Download from '@mui/icons-material/Download'; import RemoveDone from '@mui/icons-material/RemoveDone'; import { ListItemIcon, ListItemText, MenuItem } from '@mui/material'; import React from 'react'; -import type { IChapterWithMeta } from './ChapterList'; -import type { SelectionAction } from './SelectionFAB'; +import type { IChapterWithMeta } from 'components/manga/ChapterList'; +import type { SelectionAction } from 'components/manga/SelectionFAB'; interface IProps { action: SelectionAction diff --git a/src/components/molecules/OptionsTabs.tsx b/src/components/molecules/OptionsTabs.tsx index c52a9377..c1bb3499 100644 --- a/src/components/molecules/OptionsTabs.tsx +++ b/src/components/molecules/OptionsTabs.tsx @@ -8,7 +8,7 @@ import { Stack, Tab, Tabs } from '@mui/material'; import TabPanel from 'components/util/TabPanel'; import React, { useState } from 'react'; -import OptionsPanel from './OptionsPanel'; +import OptionsPanel from 'components/molecules/OptionsPanel'; interface IProps{ open: boolean diff --git a/src/components/navbar/DefaultNavBar.tsx b/src/components/navbar/DefaultNavBar.tsx index 1e1f8f59..659b1d60 100644 --- a/src/components/navbar/DefaultNavBar.tsx +++ b/src/components/navbar/DefaultNavBar.tsx @@ -29,8 +29,8 @@ import ExtensionOutlinedIcon from 'components/util/CustomExtensionOutlinedIcon'; import { Box } from '@mui/system'; import { createPortal } from 'react-dom'; import useBackTo from 'util/useBackTo'; -import DesktopSideBar from './navigation/DesktopSideBar'; -import MobileBottomBar from './navigation/MobileBottomBar'; +import DesktopSideBar from 'components/navbar/navigation/DesktopSideBar'; +import MobileBottomBar from 'components/navbar/navigation/MobileBottomBar'; const navbarItems: Array = [ { diff --git a/src/components/navbar/ReaderNavBar.tsx b/src/components/navbar/ReaderNavBar.tsx index b07a98c9..e3ca79a0 100644 --- a/src/components/navbar/ReaderNavBar.tsx +++ b/src/components/navbar/ReaderNavBar.tsx @@ -25,7 +25,7 @@ import Collapse from '@mui/material/Collapse'; import Button from '@mui/material/Button'; import { styled } from '@mui/system'; import useBackTo from 'util/useBackTo'; -import ReaderSettingsOptions from '../reader/ReaderSettingsOptions'; +import ReaderSettingsOptions from 'components/reader/ReaderSettingsOptions'; const Root = styled('div')(({ theme }) => ({ top: 0, diff --git a/src/components/reader/pager/DoublePagedPager.tsx b/src/components/reader/pager/DoublePagedPager.tsx index ade3fd6a..3b720149 100644 --- a/src/components/reader/pager/DoublePagedPager.tsx +++ b/src/components/reader/pager/DoublePagedPager.tsx @@ -8,8 +8,8 @@ import React, { useEffect, useRef } from 'react'; import ReactDOM from 'react-dom'; import { Box } from '@mui/system'; -import Page from '../Page'; -import DoublePage from '../DoublePage'; +import Page from 'components/reader/Page'; +import DoublePage from 'components/reader/DoublePage'; const isSpreadPage = (image: HTMLImageElement): boolean => { const aspectRatio = image.height / image.width; diff --git a/src/components/reader/pager/HorizontalPager.tsx b/src/components/reader/pager/HorizontalPager.tsx index 8fa78004..0e48f557 100644 --- a/src/components/reader/pager/HorizontalPager.tsx +++ b/src/components/reader/pager/HorizontalPager.tsx @@ -7,7 +7,7 @@ import React, { useEffect, useRef } from 'react'; import { Box } from '@mui/system'; -import Page from '../Page'; +import Page from 'components/reader/Page'; const findCurrentPageIndex = (wrapper: HTMLDivElement): number => { for (let i = 0; i < wrapper.children.length; i++) { diff --git a/src/components/reader/pager/PagedPager.tsx b/src/components/reader/pager/PagedPager.tsx index 74401ab7..18069fa7 100644 --- a/src/components/reader/pager/PagedPager.tsx +++ b/src/components/reader/pager/PagedPager.tsx @@ -7,7 +7,7 @@ import React, { useEffect, useRef } from 'react'; import { Box } from '@mui/system'; -import Page from '../Page'; +import Page from 'components/reader/Page'; export default function PagedReader(props: IReaderProps) { const { diff --git a/src/components/reader/pager/VerticalPager.tsx b/src/components/reader/pager/VerticalPager.tsx index 7f2e01b9..93cc1e82 100644 --- a/src/components/reader/pager/VerticalPager.tsx +++ b/src/components/reader/pager/VerticalPager.tsx @@ -7,7 +7,7 @@ import React, { useCallback, useEffect, useRef } from 'react'; import { Box } from '@mui/system'; -import Page from '../Page'; +import Page from 'components/reader/Page'; const findCurrentPageIndex = (wrapper: HTMLDivElement): number => { for (let i = 0; i < wrapper.children.length; i++) { diff --git a/src/components/source/SourceOptions.tsx b/src/components/source/SourceOptions.tsx index 890663e8..517a71c4 100644 --- a/src/components/source/SourceOptions.tsx +++ b/src/components/source/SourceOptions.tsx @@ -11,16 +11,16 @@ import { Button, Fab, Stack } from '@mui/material'; import { Box } from '@mui/system'; import OptionsPanel from 'components/molecules/OptionsPanel'; import React from 'react'; -import CheckBoxFilter from './filters/CheckBoxFilter'; -import HeaderFilter from './filters/HeaderFilter'; -import SelectFilter from './filters/SelectFilter'; -import SortFilter from './filters/SortFilter'; -import TextFilter from './filters/TextFilter'; -import TriStateFilter from './filters/TriStateFilter'; +import CheckBoxFilter from 'components/source/filters/CheckBoxFilter'; +import HeaderFilter from 'components/source/filters/HeaderFilter'; +import SelectFilter from 'components/source/filters/SelectFilter'; +import SortFilter from 'components/source/filters/SortFilter'; +import TextFilter from 'components/source/filters/TextFilter'; +import TriStateFilter from 'components/source/filters/TriStateFilter'; // this can only cycle once, so should be fine // eslint-disable-next-line import/no-cycle -import GroupFilter from './filters/GroupFilter'; -import SeperatorFilter from './filters/SeparatorFilter'; +import GroupFilter from 'components/source/filters/GroupFilter'; +import SeperatorFilter from 'components/source/filters/SeparatorFilter'; interface IFilters { sourceFilter: ISourceFilters[] diff --git a/src/components/source/filters/GroupFilter.tsx b/src/components/source/filters/GroupFilter.tsx index a02de50a..20d26bc9 100644 --- a/src/components/source/filters/GroupFilter.tsx +++ b/src/components/source/filters/GroupFilter.tsx @@ -12,7 +12,7 @@ import { import { Box } from '@mui/system'; import React from 'react'; // eslint-disable-next-line import/no-cycle -import { Options } from '../SourceOptions'; +import { Options } from 'components/source/SourceOptions'; interface Props { state: ISourceFilters[] diff --git a/src/index.tsx b/src/index.tsx index b4100d19..8185b753 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -7,8 +7,8 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import App from './App'; -import './index.css'; +import App from 'App'; +import 'src/index.css'; // roboto font import '@fontsource/roboto'; diff --git a/src/screens/Library.tsx b/src/screens/Library.tsx index b8f4d690..b4975b58 100644 --- a/src/screens/Library.tsx +++ b/src/screens/Library.tsx @@ -18,7 +18,7 @@ import LibraryMangaGrid from 'components/library/LibraryMangaGrid'; import AppbarSearch from 'components/util/AppbarSearch'; import { useQueryParam, NumberParam } from 'use-query-params'; import { useQuery } from 'util/client'; -import UpdateChecker from '../components/library/UpdateChecker'; +import UpdateChecker from 'components/library/UpdateChecker'; export default function Library() { const [lastLibraryUpdate, setLastLibraryUpdate] = useState(Date.now()); diff --git a/src/screens/Reader.tsx b/src/screens/Reader.tsx index 73d72c9b..d04ed3cb 100644 --- a/src/screens/Reader.tsx +++ b/src/screens/Reader.tsx @@ -26,7 +26,7 @@ import { getReaderSettingsFor, useDefaultReaderSettings, } from 'util/readerSettings'; -import makeToast from '../components/util/Toast'; +import makeToast from 'components/util/Toast'; const getReaderComponent = (readerType: ReaderType) => { switch (readerType) { diff --git a/src/screens/Settings.tsx b/src/screens/Settings.tsx index 3f976e1f..d1a29b41 100644 --- a/src/screens/Settings.tsx +++ b/src/screens/Settings.tsx @@ -31,10 +31,10 @@ import FavoriteIcon from '@mui/icons-material/Favorite'; import Slider from '@mui/material/Slider'; import { DialogTitle, ListItemButton } from '@mui/material'; import ViewModuleIcon from '@mui/icons-material/ViewModule'; -import NavbarContext from '../components/context/NavbarContext'; -import DarkTheme from '../components/context/DarkTheme'; -import useLocalStorage from '../util/useLocalStorage'; -import ListItemLink from '../components/util/ListItemLink'; +import NavbarContext from 'components/context/NavbarContext'; +import DarkTheme from 'components/context/DarkTheme'; +import useLocalStorage from 'util/useLocalStorage'; +import ListItemLink from 'components/util/ListItemLink'; export default function Settings() { const { setTitle, setAction } = useContext(NavbarContext); diff --git a/src/screens/settings/Backup.tsx b/src/screens/settings/Backup.tsx index a6f75a1e..e02c4532 100644 --- a/src/screens/settings/Backup.tsx +++ b/src/screens/settings/Backup.tsx @@ -12,8 +12,8 @@ import ListItemText from '@mui/material/ListItemText'; import { fromEvent } from 'file-selector'; import client from 'util/client'; import makeToast from 'components/util/Toast'; -import ListItemLink from '../../components/util/ListItemLink'; -import NavbarContext from '../../components/context/NavbarContext'; +import ListItemLink from 'components/util/ListItemLink'; +import NavbarContext from 'components/context/NavbarContext'; export default function Backup() { const { setTitle, setAction } = useContext(NavbarContext); diff --git a/src/util/client.tsx b/src/util/client.tsx index b55e00db..f6a2394c 100644 --- a/src/util/client.tsx +++ b/src/util/client.tsx @@ -7,7 +7,7 @@ import axios from 'axios'; import useSWR, { SWRConfiguration, SWRResponse } from 'swr'; -import storage from './localStorage'; +import storage from 'util/localStorage'; const { hostname, port, protocol } = window.location; diff --git a/src/util/metadata.ts b/src/util/metadata.ts index b102c917..2039a5a3 100644 --- a/src/util/metadata.ts +++ b/src/util/metadata.ts @@ -7,7 +7,7 @@ */ import { mutate } from 'swr'; -import client from './client'; +import client from 'util/client'; const APP_METADATA_KEY_PREFIX = 'webUI_'; diff --git a/src/util/readerSettings.ts b/src/util/readerSettings.ts index db796498..ee82cf92 100644 --- a/src/util/readerSettings.ts +++ b/src/util/readerSettings.ts @@ -7,7 +7,7 @@ */ import { getMetadataFrom, requestUpdateMangaMetadata, requestUpdateServerMetadata } from 'util/metadata'; -import { useQuery } from './client'; +import { useQuery } from 'util/client'; export const getDefaultSettings = (forceUndefined: boolean = false) => ({ staticNav: forceUndefined ? undefined : false, diff --git a/src/util/useLocalStorage.tsx b/src/util/useLocalStorage.tsx index 83b97719..5eff05ae 100644 --- a/src/util/useLocalStorage.tsx +++ b/src/util/useLocalStorage.tsx @@ -13,7 +13,7 @@ import React, { Reducer, useCallback, } from 'react'; -import storage from './localStorage'; +import storage from 'util/localStorage'; // eslint-disable-next-line max-len export default function useLocalStorage( diff --git a/yarn.lock b/yarn.lock index d1096640..a94700b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4982,6 +4982,11 @@ eslint-plugin-jsx-a11y@^6.3.1, eslint-plugin-jsx-a11y@^6.4.1: jsx-ast-utils "^3.1.0" language-tags "^1.0.5" +eslint-plugin-no-relative-import-paths@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-no-relative-import-paths/-/eslint-plugin-no-relative-import-paths-1.5.2.tgz#c35f2fd0bf2a6a57b268193ed7df63ff7000134e" + integrity sha512-wMlL+TVuDhKk1plP+w3L4Hc7+u89vUkrOYq6/0ARjcYqwc9/YaS9uEXNzaqAk+WLoEgakzNL5JgJJw6m4qd5zw== + eslint-plugin-react-hooks@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04"