chore: update eslint rules

This commit is contained in:
Steven 2022-09-04 06:48:19 +08:00
parent 4743818fe7
commit b884327a53
25 changed files with 69 additions and 93 deletions

View File

@ -21,7 +21,6 @@
"endOfLine": "auto" "endOfLine": "auto"
} }
], ],
"@typescript-eslint/no-empty-interface": ["off"],
"@typescript-eslint/no-explicit-any": ["off"], "@typescript-eslint/no-explicit-any": ["off"],
"react/react-in-jsx-scope": "off" "react/react-in-jsx-scope": "off"
}, },

View File

@ -7,7 +7,7 @@ import { generateDialog } from "./Dialog";
import GitHubBadge from "./GitHubBadge"; import GitHubBadge from "./GitHubBadge";
import "../less/about-site-dialog.less"; import "../less/about-site-dialog.less";
interface Props extends DialogProps {} type Props = DialogProps;
const AboutSiteDialog: React.FC<Props> = ({ destroy }: Props) => { const AboutSiteDialog: React.FC<Props> = ({ destroy }: Props) => {
const { t } = useI18n(); const { t } = useI18n();

View File

@ -8,7 +8,7 @@ import toastHelper from "./Toast";
import ArchivedMemo from "./ArchivedMemo"; import ArchivedMemo from "./ArchivedMemo";
import "../less/archived-memo-dialog.less"; import "../less/archived-memo-dialog.less";
interface Props extends DialogProps {} type Props = DialogProps;
const ArchivedMemoDialog: React.FC<Props> = (props: Props) => { const ArchivedMemoDialog: React.FC<Props> = (props: Props) => {
const { destroy } = props; const { destroy } = props;

View File

@ -14,7 +14,7 @@ const validateConfig: ValidatorConfig = {
noChinese: true, noChinese: true,
}; };
interface Props extends DialogProps {} type Props = DialogProps;
const ChangePasswordDialog: React.FC<Props> = ({ destroy }: Props) => { const ChangePasswordDialog: React.FC<Props> = ({ destroy }: Props) => {
const { t } = useI18n(); const { t } = useI18n();

View File

@ -3,9 +3,7 @@ import * as api from "../helpers/api";
import Icon from "./Icon"; import Icon from "./Icon";
import "../less/github-badge.less"; import "../less/github-badge.less";
interface Props {} const GitHubBadge = () => {
const GitHubBadge: React.FC<Props> = () => {
const [starCount, setStarCount] = useState(0); const [starCount, setStarCount] = useState(0);
useEffect(() => { useEffect(() => {

View File

@ -9,14 +9,12 @@ import toastHelper from "./Toast";
import Editor, { EditorRefActions } from "./Editor/Editor"; import Editor, { EditorRefActions } from "./Editor/Editor";
import "../less/memo-editor.less"; import "../less/memo-editor.less";
interface Props {}
interface State { interface State {
isUploadingResource: boolean; isUploadingResource: boolean;
fullscreen: boolean; fullscreen: boolean;
} }
const MemoEditor: React.FC<Props> = () => { const MemoEditor = () => {
const { t, locale } = useI18n(); const { t, locale } = useI18n();
const user = useAppSelector((state) => state.user.user); const user = useAppSelector((state) => state.user.user);
const editorState = useAppSelector((state) => state.editor); const editorState = useAppSelector((state) => state.editor);

View File

@ -4,9 +4,7 @@ import * as utils from "../helpers/utils";
import { getTextWithMemoType } from "../helpers/filter"; import { getTextWithMemoType } from "../helpers/filter";
import "../less/memo-filter.less"; import "../less/memo-filter.less";
interface FilterProps {} const MemoFilter = () => {
const MemoFilter: React.FC<FilterProps> = () => {
const query = useAppSelector((state) => state.location.query); const query = useAppSelector((state) => state.location.query);
useAppSelector((state) => state.shortcut.shortcuts); useAppSelector((state) => state.shortcut.shortcuts);
const { tag: tagQuery, duration, type: memoType, text: textQuery, shortcutId } = query; const { tag: tagQuery, duration, type: memoType, text: textQuery, shortcutId } = query;

View File

@ -10,9 +10,7 @@ import Only from "./common/OnlyWhen";
import Memo from "./Memo"; import Memo from "./Memo";
import "../less/memo-list.less"; import "../less/memo-list.less";
interface Props {} const MemoList = () => {
const MemoList: React.FC<Props> = () => {
const { t } = useI18n(); const { t } = useI18n();
const query = useAppSelector((state) => state.location.query); const query = useAppSelector((state) => state.location.query);
const { memos, isFetching } = useAppSelector((state) => state.memo); const { memos, isFetching } = useAppSelector((state) => state.memo);

View File

@ -8,9 +8,7 @@ import "../less/memos-header.less";
let prevRequestTimestamp = Date.now(); let prevRequestTimestamp = Date.now();
interface Props {} const MemosHeader = () => {
const MemosHeader: React.FC<Props> = () => {
const query = useAppSelector((state) => state.location.query); const query = useAppSelector((state) => state.location.query);
const shortcuts = useAppSelector((state) => state.shortcut.shortcuts); const shortcuts = useAppSelector((state) => state.shortcut.shortcuts);
const [titleText, setTitleText] = useState("MEMOS"); const [titleText, setTitleText] = useState("MEMOS");

View File

@ -11,7 +11,7 @@ import Icon from "./Icon";
import toastHelper from "./Toast"; import toastHelper from "./Toast";
import "../less/resources-dialog.less"; import "../less/resources-dialog.less";
interface Props extends DialogProps {} type Props = DialogProps;
interface State { interface State {
resources: Resource[]; resources: Resource[];

View File

@ -4,9 +4,7 @@ import { memoSpecialTypes } from "../helpers/filter";
import Icon from "./Icon"; import Icon from "./Icon";
import "../less/search-bar.less"; import "../less/search-bar.less";
interface Props {} const SearchBar = () => {
const SearchBar: React.FC<Props> = () => {
const memoType = useAppSelector((state) => state.location.query?.type); const memoType = useAppSelector((state) => state.location.query?.type);
const handleMemoTypeItemClick = (type: MemoSpecType | undefined) => { const handleMemoTypeItemClick = (type: MemoSpecType | undefined) => {

View File

@ -8,7 +8,7 @@ import PreferencesSection from "./Settings/PreferencesSection";
import MemberSection from "./Settings/MemberSection"; import MemberSection from "./Settings/MemberSection";
import "../less/setting-dialog.less"; import "../less/setting-dialog.less";
interface Props extends DialogProps {} type Props = DialogProps;
type SettingSection = "my-account" | "preferences" | "member"; type SettingSection = "my-account" | "preferences" | "member";

View File

@ -9,14 +9,12 @@ import Dropdown from "../common/Dropdown";
import { showCommonDialog } from "../Dialog/CommonDialog"; import { showCommonDialog } from "../Dialog/CommonDialog";
import "../../less/settings/member-section.less"; import "../../less/settings/member-section.less";
interface Props {}
interface State { interface State {
createUserEmail: string; createUserEmail: string;
createUserPassword: string; createUserPassword: string;
} }
const PreferencesSection: React.FC<Props> = () => { const PreferencesSection = () => {
const { t } = useI18n(); const { t } = useI18n();
const currentUser = useAppSelector((state) => state.user.user); const currentUser = useAppSelector((state) => state.user.user);
const [state, setState] = useState<State>({ const [state, setState] = useState<State>({

View File

@ -15,9 +15,7 @@ const validateConfig: ValidatorConfig = {
noChinese: true, noChinese: true,
}; };
interface Props {} const MyAccountSection = () => {
const MyAccountSection: React.FC<Props> = () => {
const { t } = useI18n(); const { t } = useI18n();
const user = useAppSelector((state) => state.user.user as User); const user = useAppSelector((state) => state.user.user as User);
const [username, setUsername] = useState<string>(user.name); const [username, setUsername] = useState<string>(user.name);

View File

@ -6,8 +6,6 @@ import Selector from "../common/Selector";
import BetaBadge from "../BetaBadge"; import BetaBadge from "../BetaBadge";
import "../../less/settings/preferences-section.less"; import "../../less/settings/preferences-section.less";
interface Props {}
const localeSelectorItems = [ const localeSelectorItems = [
{ {
text: "English", text: "English",
@ -30,7 +28,7 @@ const editorFontStyleSelectorItems = [
}, },
]; ];
const PreferencesSection: React.FC<Props> = () => { const PreferencesSection = () => {
const { t } = useI18n(); const { t } = useI18n();
const { setting } = useAppSelector((state) => state.user.user as User); const { setting } = useAppSelector((state) => state.user.user as User);

View File

@ -10,9 +10,7 @@ import toastHelper from "./Toast";
import showCreateShortcutDialog from "./CreateShortcutDialog"; import showCreateShortcutDialog from "./CreateShortcutDialog";
import "../less/shortcut-list.less"; import "../less/shortcut-list.less";
interface Props {} const ShortcutList = () => {
const ShortcutList: React.FC<Props> = () => {
const query = useAppSelector((state) => state.location.query); const query = useAppSelector((state) => state.location.query);
const shortcuts = useAppSelector((state) => state.shortcut.shortcuts); const shortcuts = useAppSelector((state) => state.shortcut.shortcuts);
const loadingState = useLoading(); const loadingState = useLoading();

View File

@ -12,9 +12,7 @@ import ShortcutList from "./ShortcutList";
import TagList from "./TagList"; import TagList from "./TagList";
import "../less/siderbar.less"; import "../less/siderbar.less";
interface Props {} const Sidebar = () => {
const Sidebar: React.FC<Props> = () => {
const { t } = useI18n(); const { t } = useI18n();
const handleMyAccountBtnClick = () => { const handleMyAccountBtnClick = () => {

View File

@ -14,9 +14,7 @@ interface Tag {
subTags: Tag[]; subTags: Tag[];
} }
interface Props {} const TagList = () => {
const TagList: React.FC<Props> = () => {
const { t } = useI18n(); const { t } = useI18n();
const { memos, tags: tagsText } = useAppSelector((state) => state.memo); const { memos, tags: tagsText } = useAppSelector((state) => state.memo);
const query = useAppSelector((state) => state.location.query); const query = useAppSelector((state) => state.location.query);

View File

@ -1,6 +1,5 @@
import { useEffect } from "react"; import { useEffect } from "react";
import { createRoot, Root } from "react-dom/client"; import { createRoot, Root } from "react-dom/client";
import { TOAST_ANIMATION_DURATION } from "../helpers/consts";
import "../less/toast.less"; import "../less/toast.less";
type ToastType = "normal" | "success" | "info" | "error"; type ToastType = "normal" | "success" | "info" | "error";
@ -36,42 +35,26 @@ const Toast: React.FC<ToastItemProps> = (props: ToastItemProps) => {
); );
}; };
class ToastHelper { // toast animation duration.
private shownToastAmount = 0; const TOAST_ANIMATION_DURATION = 400;
private toastWrapper: HTMLDivElement;
private shownToastContainers: [Root, HTMLDivElement][] = [];
constructor() { const initialToastHelper = () => {
const wrapperClassName = "toast-list-container"; const shownToastContainers: [Root, HTMLDivElement][] = [];
const tempDiv = document.createElement("div"); let shownToastAmount = 0;
tempDiv.className = wrapperClassName;
document.body.appendChild(tempDiv);
this.toastWrapper = tempDiv;
}
public info = (content: string, duration = 3000) => { const wrapperClassName = "toast-list-container";
return this.showToast({ type: "normal", content, duration }); const tempDiv = document.createElement("div");
}; tempDiv.className = wrapperClassName;
document.body.appendChild(tempDiv);
const toastWrapper = tempDiv;
public success = (content: string, duration = 3000) => { const showToast = (config: ToastConfig) => {
return this.showToast({ type: "success", content, duration });
};
public error = (content: string, duration = 3000) => {
return this.showToast({ type: "error", content, duration });
};
private showToast = (config: ToastConfig) => {
const tempDiv = document.createElement("div"); const tempDiv = document.createElement("div");
const toast = createRoot(tempDiv); const toast = createRoot(tempDiv);
tempDiv.className = `toast-wrapper ${config.type}`; tempDiv.className = `toast-wrapper ${config.type}`;
this.toastWrapper.appendChild(tempDiv); toastWrapper.appendChild(tempDiv);
this.shownToastAmount++; shownToastAmount++;
this.shownToastContainers.push([toast, tempDiv]); shownToastContainers.push([toast, tempDiv]);
setTimeout(() => {
tempDiv.classList.add("showup");
}, 0);
const cbs = { const cbs = {
destory: () => { destory: () => {
@ -82,13 +65,13 @@ class ToastHelper {
return; return;
} }
this.shownToastAmount--; shownToastAmount--;
if (this.shownToastAmount === 0) { if (shownToastAmount === 0) {
for (const [root, tempDiv] of this.shownToastContainers) { for (const [root, tempDiv] of shownToastContainers) {
root.unmount(); root.unmount();
tempDiv.remove(); tempDiv.remove();
} }
this.shownToastContainers.splice(0, this.shownToastContainers.length); shownToastContainers.splice(0, shownToastContainers.length);
} }
}, TOAST_ANIMATION_DURATION); }, TOAST_ANIMATION_DURATION);
}, },
@ -96,10 +79,32 @@ class ToastHelper {
toast.render(<Toast {...config} destory={cbs.destory} />); toast.render(<Toast {...config} destory={cbs.destory} />);
setTimeout(() => {
tempDiv.classList.add("showup");
}, 10);
return cbs; return cbs;
}; };
}
const toastHelper = new ToastHelper(); const info = (content: string, duration = 3000) => {
return showToast({ type: "normal", content, duration });
};
const success = (content: string, duration = 3000) => {
return showToast({ type: "success", content, duration });
};
const error = (content: string, duration = 3000) => {
return showToast({ type: "error", content, duration });
};
return {
info,
success,
error,
};
};
const toastHelper = initialToastHelper();
export default toastHelper; export default toastHelper;

View File

@ -26,9 +26,7 @@ interface DailyUsageStat {
count: number; count: number;
} }
interface Props {} const UsageHeatMap = () => {
const UsageHeatMap: React.FC<Props> = () => {
const todayTimeStamp = utils.getDateStampByDate(Date.now()); const todayTimeStamp = utils.getDateStampByDate(Date.now());
const todayDay = new Date(todayTimeStamp).getDay() + 1; const todayDay = new Date(todayTimeStamp).getDay() + 1;
const nullCell = new Array(7 - todayDay).fill(0); const nullCell = new Array(7 - todayDay).fill(0);

View File

@ -7,9 +7,7 @@ import Icon from "./Icon";
import MenuBtnsPopup from "./MenuBtnsPopup"; import MenuBtnsPopup from "./MenuBtnsPopup";
import "../less/user-banner.less"; import "../less/user-banner.less";
interface Props {} const UserBanner = () => {
const UserBanner: React.FC<Props> = () => {
const { user, owner } = useAppSelector((state) => state.user); const { user, owner } = useAppSelector((state) => state.user);
const { memos, tags } = useAppSelector((state) => state.memo); const { memos, tags } = useAppSelector((state) => state.memo);
const [shouldShowPopupBtns, setShouldShowPopupBtns] = useState(false); const [shouldShowPopupBtns, setShouldShowPopupBtns] = useState(false);

View File

@ -4,9 +4,6 @@ export const UNKNOWN_ID = -1;
// default animation duration // default animation duration
export const ANIMATION_DURATION = 200; export const ANIMATION_DURATION = 200;
// toast animation duration
export const TOAST_ANIMATION_DURATION = 400;
// millisecond in a day // millisecond in a day
export const DAILY_TIMESTAMP = 3600 * 24 * 1000; export const DAILY_TIMESTAMP = 3600 * 24 * 1000;

View File

@ -54,10 +54,14 @@
@apply flex-row justify-end items-center hidden shrink-0; @apply flex-row justify-end items-center hidden shrink-0;
> .action-btn { > .action-btn {
@apply flex flex-row justify-center items-center w-6 h-6 shrink-0; @apply flex flex-row justify-center items-center;
&.toggle-btn { &.toggle-btn {
@apply w-4 h-auto text-gray-600; @apply text-gray-600;
> .icon-img {
@apply w-4 h-auto;
}
&:hover { &:hover {
& + .action-btns-wrapper { & + .action-btns-wrapper {

View File

@ -6,6 +6,7 @@
> .toast-wrapper { > .toast-wrapper {
@apply flex flex-col justify-start items-start relative left-full invisible text-base cursor-pointer shadow-lg rounded bg-white mt-6 py-2 px-4; @apply flex flex-col justify-start items-start relative left-full invisible text-base cursor-pointer shadow-lg rounded bg-white mt-6 py-2 px-4;
min-width: 6em; min-width: 6em;
left: calc(100% + 32px);
transition: all 0.4s ease; transition: all 0.4s ease;
&.showup { &.showup {

View File

@ -9,8 +9,6 @@ import Only from "../components/common/OnlyWhen";
import toastHelper from "../components/Toast"; import toastHelper from "../components/Toast";
import "../less/auth.less"; import "../less/auth.less";
interface Props {}
const validateConfig: ValidatorConfig = { const validateConfig: ValidatorConfig = {
minLength: 4, minLength: 4,
maxLength: 24, maxLength: 24,
@ -18,7 +16,7 @@ const validateConfig: ValidatorConfig = {
noChinese: true, noChinese: true,
}; };
const Auth: React.FC<Props> = () => { const Auth = () => {
const { t, locale } = useI18n(); const { t, locale } = useI18n();
const pageLoadingState = useLoading(true); const pageLoadingState = useLoading(true);
const [siteHost, setSiteHost] = useState<User>(); const [siteHost, setSiteHost] = useState<User>();