From 158b467fff07981b43af81f6520d3dba06baeffa Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Mon, 10 Jul 2023 16:34:09 +0800
Subject: Run react-codemod update-react-imports

---
 FrontEnd/src/views/settings/index.tsx | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'FrontEnd/src/views/settings/index.tsx')

diff --git a/FrontEnd/src/views/settings/index.tsx b/FrontEnd/src/views/settings/index.tsx
index 31726dc2..79c816a0 100644
--- a/FrontEnd/src/views/settings/index.tsx
+++ b/FrontEnd/src/views/settings/index.tsx
@@ -1,4 +1,5 @@
-import React, { useState } from "react";
+import { useState } from "react";
+import * as React from "react";
 import { useNavigate } from "react-router-dom";
 import { useTranslation } from "react-i18next";
 import classNames from "classnames";
-- 
cgit v1.2.3


From d46b1aed549938c9f5e3e658b4098e71b5e2acf7 Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Tue, 11 Jul 2023 01:01:48 +0800
Subject: Lint error, get away!

---
 FrontEnd/.eslintignore                             |  1 -
 FrontEnd/.eslintrc.cjs                             | 24 ++++++++++++
 FrontEnd/.eslintrc.mjs                             | 39 --------------------
 FrontEnd/package.json                              | 18 +++++----
 FrontEnd/pnpm-lock.yaml                            |  2 +-
 FrontEnd/src/i18n.ts                               | 43 ++++++++++++----------
 FrontEnd/src/services/TimelinePostBuilder.ts       |  4 +-
 FrontEnd/src/services/alert.ts                     |  1 -
 FrontEnd/src/services/timeline.ts                  |  4 +-
 FrontEnd/src/views/about/index.tsx                 |  7 +---
 FrontEnd/src/views/admin/Admin.tsx                 |  1 -
 FrontEnd/src/views/admin/AdminNav.tsx              |  5 +--
 FrontEnd/src/views/common/AppBar.tsx               |  2 +-
 FrontEnd/src/views/common/button/IconButton.tsx    |  6 +--
 FrontEnd/src/views/common/button/LoadingButton.tsx | 16 ++++----
 FrontEnd/src/views/login/index.tsx                 |  2 +-
 FrontEnd/src/views/settings/index.tsx              |  6 +--
 FrontEnd/src/views/timeline/TimelinePostEdit.tsx   |  6 +--
 18 files changed, 86 insertions(+), 101 deletions(-)
 create mode 100644 FrontEnd/.eslintrc.cjs
 delete mode 100644 FrontEnd/.eslintrc.mjs

(limited to 'FrontEnd/src/views/settings/index.tsx')

diff --git a/FrontEnd/.eslintignore b/FrontEnd/.eslintignore
index 7b8399d8..6fc7bee6 100644
--- a/FrontEnd/.eslintignore
+++ b/FrontEnd/.eslintignore
@@ -1,2 +1 @@
 dist
-vite.config.js
diff --git a/FrontEnd/.eslintrc.cjs b/FrontEnd/.eslintrc.cjs
new file mode 100644
index 00000000..a9cd8e03
--- /dev/null
+++ b/FrontEnd/.eslintrc.cjs
@@ -0,0 +1,24 @@
+module.exports = {
+  root: true,
+  extends: [
+    "eslint:recommended",
+    "plugin:react/recommended",
+    "plugin:react-hooks/recommended",
+    "plugin:react/jsx-runtime",
+    "plugin:@typescript-eslint/eslint-recommended",
+    "plugin:@typescript-eslint/recommended",
+    "plugin:@typescript-eslint/recommended-requiring-type-checking",
+    "prettier",
+  ],
+  plugins: ["@typescript-eslint", "prettier", "react", "react-hooks"],
+  parser: "@typescript-eslint/parser",
+  parserOptions: {
+    project: true,
+    tsconfigRootDir: __dirname
+  },
+  settings: {
+    react: {
+      version: "detect",
+    },
+  },
+};
diff --git a/FrontEnd/.eslintrc.mjs b/FrontEnd/.eslintrc.mjs
deleted file mode 100644
index 61db0dd4..00000000
--- a/FrontEnd/.eslintrc.mjs
+++ /dev/null
@@ -1,39 +0,0 @@
-export default {
-  root: true,
-  env: {
-    browser: true,
-    es2022: true,
-  },
-  extends: [
-    "eslint:recommended",
-    "plugin:react/recommended",
-    "plugin:@typescript-eslint/eslint-recommended",
-    "plugin:@typescript-eslint/recommended",
-    "plugin:@typescript-eslint/recommended-requiring-type-checking",
-    "plugin:prettier/recommended",
-    "plugin:react-hooks/recommended",
-  ],
-  parser: "@typescript-eslint/parser",
-  parserOptions: {
-    tsconfigRootDir: __dirname,
-    project: ["./tsconfig.json"],
-  },
-  plugins: ["react", "@typescript-eslint", "react-hooks"],
-  settings: {
-    react: {
-      version: "detect",
-    },
-  },
-  rules: {
-    "react/prop-types": "off",
-    "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
-    "@typescript-eslint/explicit-function-return-type": [
-      "warn",
-      {
-        allowExpressions: true,
-        allowTypedFunctionExpressions: true,
-        allowHigherOrderFunctions: true,
-      },
-    ],
-  },
-};
diff --git a/FrontEnd/package.json b/FrontEnd/package.json
index bcbc36d4..7f438f0e 100644
--- a/FrontEnd/package.json
+++ b/FrontEnd/package.json
@@ -4,6 +4,15 @@
   "private": true,
   "type": "module",
   "source": "index.html",
+  "scripts": {
+    "start": "parcel --port 5678",
+    "build": "tsc && parcel build",
+    "type-check": "tsc",
+    "lint": "eslint src/ --ext .js --ext .jsx --ext .ts --ext .tsx",
+    "lint:fix": "eslint src/ --ext .js --ext .jsx --ext .ts --ext .tsx --fix",
+    "check": "pnpm run type-check && pnpm run lint",
+    "check:fix": "pnpm run type-check && pnpm run lint:fix"
+  },
   "dependencies": {
     "@microsoft/signalr": "^7.0.7",
     "@popperjs/core": "^2.11.8",
@@ -31,13 +40,6 @@
     "rxjs": "^7.8.1",
     "xregexp": "^5.1.1"
   },
-  "scripts": {
-    "start": "parcel --port 5678",
-    "build": "tsc && parcel build",
-    "type-check": "tsc",
-    "lint": "eslint src/ --ext .js --ext .jsx --ext .ts --ext .tsx",
-    "lint:fix": "eslint src/ --ext .js --ext .jsx --ext .ts --ext .tsx --fix"
-  },
   "devDependencies": {
     "@parcel/packager-raw-url": "2.9.3",
     "@parcel/transformer-webmanifest": "2.9.3",
@@ -54,7 +56,7 @@
     "@types/react-transition-group": "^4.4.6",
     "@typescript-eslint/eslint-plugin": "^5.61.0",
     "@typescript-eslint/parser": "^5.61.0",
-    "buffer": "^5.5.0||^6.0.0",
+    "buffer": "^6.0.0",
     "eslint": "^8.44.0",
     "eslint-config-prettier": "^8.8.0",
     "eslint-plugin-prettier": "^4.2.1",
diff --git a/FrontEnd/pnpm-lock.yaml b/FrontEnd/pnpm-lock.yaml
index 05d1f05f..d4a2962c 100644
--- a/FrontEnd/pnpm-lock.yaml
+++ b/FrontEnd/pnpm-lock.yaml
@@ -128,7 +128,7 @@ devDependencies:
     specifier: ^5.61.0
     version: 5.61.0(eslint@8.44.0)(typescript@5.1.6)
   buffer:
-    specifier: ^5.5.0||^6.0.0
+    specifier: ^6.0.0
     version: 6.0.3
   eslint:
     specifier: ^8.44.0
diff --git a/FrontEnd/src/i18n.ts b/FrontEnd/src/i18n.ts
index ad261c6e..9bf8721f 100644
--- a/FrontEnd/src/i18n.ts
+++ b/FrontEnd/src/i18n.ts
@@ -1,29 +1,34 @@
-import i18n, { BackendModule, ResourceKey } from "i18next";
+import i18n, { BackendModule } from "i18next";
 import LanguageDetector from "i18next-browser-languagedetector";
 import { initReactI18next } from "react-i18next";
 
 const backend: BackendModule = {
   type: "backend",
-  async read(language, namespace) {
-    if (namespace === "translation") {
-      if (language === "en") {
-        return await import("./locales/en/translation.json");
-      } else if (language === "zh") {
-        return await import("./locales/zh/translation.json");
+  read(language, namespace, callback) {
+    (async () => {
+      if (namespace === "translation") {
+        if (language === "en") {
+          return await import("./locales/en/translation.json");
+        } else if (language === "zh") {
+          return await import("./locales/zh/translation.json");
+        } else {
+          throw Error(`Language ${language} is not supported.`);
+        }
+      } else if (namespace === "admin") {
+        if (language === "en") {
+          return await import("./locales/en/admin.json");
+        } else if (language === "zh") {
+          return await import("./locales/zh/admin.json");
+        } else {
+          throw Error(`Language ${language} is not supported.`);
+        }
       } else {
-        throw Error(`Language ${language} is not supported.`);
+        throw Error(`Namespace ${namespace} is not supported.`);
       }
-    } else if (namespace === "admin") {
-      if (language === "en") {
-        return await import("./locales/en/admin.json");
-      } else if (language === "zh") {
-        return await import("./locales/zh/admin.json");
-      } else {
-        throw Error(`Language ${language} is not supported.`);
-      }
-    } else {
-      throw Error(`Namespace ${namespace} is not supported.`);
-    }
+    })().then(
+      (resources) => callback(null, resources.default),
+      (error: Error) => callback(error, null),
+    );
   },
   init() {}, // eslint-disable-line @typescript-eslint/no-empty-function
   create() {}, // eslint-disable-line @typescript-eslint/no-empty-function
diff --git a/FrontEnd/src/services/TimelinePostBuilder.ts b/FrontEnd/src/services/TimelinePostBuilder.ts
index 0e49bdc5..83d63abe 100644
--- a/FrontEnd/src/services/TimelinePostBuilder.ts
+++ b/FrontEnd/src/services/TimelinePostBuilder.ts
@@ -117,8 +117,8 @@ export default class TimelinePostBuilder {
           base64(image.file).then((data) => ({
             contentType: image.file.type,
             data,
-          }))
-        )
+          })),
+        ),
       )),
     ];
   }
diff --git a/FrontEnd/src/services/alert.ts b/FrontEnd/src/services/alert.ts
index 1aa5423c..42b14451 100644
--- a/FrontEnd/src/services/alert.ts
+++ b/FrontEnd/src/services/alert.ts
@@ -1,4 +1,3 @@
-import * as React from "react";
 import pull from "lodash/pull";
 
 import { I18nText } from "@/common";
diff --git a/FrontEnd/src/services/timeline.ts b/FrontEnd/src/services/timeline.ts
index 58dc9be6..707c956f 100644
--- a/FrontEnd/src/services/timeline.ts
+++ b/FrontEnd/src/services/timeline.ts
@@ -22,7 +22,7 @@ export const timelineVisibilityTooltipTranslationMap: Record<
 
 export function getTimelinePostUpdate$(
   owner: string,
-  timeline: string
+  timeline: string,
 ): Observable<{ update: boolean; state: HubConnectionState }> {
   return new Observable((subscriber) => {
     subscriber.next({
@@ -76,7 +76,7 @@ export function getTimelinePostUpdate$(
       return connection.invoke(
         "SubscribeTimelinePostChangeV2",
         owner,
-        timeline
+        timeline,
       );
     });
 
diff --git a/FrontEnd/src/views/about/index.tsx b/FrontEnd/src/views/about/index.tsx
index 513b5003..093da894 100644
--- a/FrontEnd/src/views/about/index.tsx
+++ b/FrontEnd/src/views/about/index.tsx
@@ -1,4 +1,3 @@
-import * as React from "react";
 import { useTranslation, Trans } from "react-i18next";
 
 import authorAvatarUrl from "./author-avatar.png";
@@ -57,7 +56,7 @@ const backendCredits: {
   },
 ];
 
-const AboutPage: React.FC = () => {
+export default function AboutPage() {
   const { t } = useTranslation();
 
   return (
@@ -141,6 +140,4 @@ const AboutPage: React.FC = () => {
       </Card>
     </div>
   );
-};
-
-export default AboutPage;
+}
diff --git a/FrontEnd/src/views/admin/Admin.tsx b/FrontEnd/src/views/admin/Admin.tsx
index dc8b0aa6..986c36b4 100644
--- a/FrontEnd/src/views/admin/Admin.tsx
+++ b/FrontEnd/src/views/admin/Admin.tsx
@@ -1,4 +1,3 @@
-import * as React from "react";
 import { Route, Routes } from "react-router-dom";
 import { useTranslation } from "react-i18next";
 
diff --git a/FrontEnd/src/views/admin/AdminNav.tsx b/FrontEnd/src/views/admin/AdminNav.tsx
index 4081cf96..b7385e5c 100644
--- a/FrontEnd/src/views/admin/AdminNav.tsx
+++ b/FrontEnd/src/views/admin/AdminNav.tsx
@@ -1,9 +1,8 @@
-import * as React from "react";
 import { useLocation } from "react-router-dom";
 
 import Tabs from "../common/tab/Tabs";
 
-const AdminNav: React.FC<{ className?: string }> = ({ className }) => {
+export function AdminNav({ className }: { className?: string }) {
   const location = useLocation();
   const name = location.pathname.split("/")[2] ?? "user";
 
@@ -25,6 +24,6 @@ const AdminNav: React.FC<{ className?: string }> = ({ className }) => {
       ]}
     />
   );
-};
+}
 
 export default AdminNav;
diff --git a/FrontEnd/src/views/common/AppBar.tsx b/FrontEnd/src/views/common/AppBar.tsx
index 43d727c9..278c70fd 100644
--- a/FrontEnd/src/views/common/AppBar.tsx
+++ b/FrontEnd/src/views/common/AppBar.tsx
@@ -11,7 +11,7 @@ import UserAvatar from "./user/UserAvatar";
 
 import "./AppBar.css";
 
-const AppBar: React.FC = (_) => {
+const AppBar: React.FC = () => {
   const { t } = useTranslation();
 
   const user = useUser();
diff --git a/FrontEnd/src/views/common/button/IconButton.tsx b/FrontEnd/src/views/common/button/IconButton.tsx
index d9d828e7..3ba56277 100644
--- a/FrontEnd/src/views/common/button/IconButton.tsx
+++ b/FrontEnd/src/views/common/button/IconButton.tsx
@@ -5,11 +5,11 @@ import { PaletteColorType } from "@/palette";
 
 import "./IconButton.css";
 
-export type IconButtonProps = {
+export interface IconButtonProps extends React.ComponentPropsWithRef<"i"> {
   icon: string;
   color?: PaletteColorType;
   large?: boolean;
-} & React.ComponentPropsWithRef<"i">;
+}
 
 export default function IconButton(props: IconButtonProps): JSX.Element {
   const { icon, color, className, large, ...otherProps } = props;
@@ -21,7 +21,7 @@ export default function IconButton(props: IconButtonProps): JSX.Element {
         large && "large",
         "bi-" + icon,
         color ? "cru-" + color : "cru-primary",
-        className
+        className,
       )}
       {...otherProps}
     />
diff --git a/FrontEnd/src/views/common/button/LoadingButton.tsx b/FrontEnd/src/views/common/button/LoadingButton.tsx
index 0804e40d..fceaec27 100644
--- a/FrontEnd/src/views/common/button/LoadingButton.tsx
+++ b/FrontEnd/src/views/common/button/LoadingButton.tsx
@@ -7,13 +7,13 @@ import { PaletteColorType } from "@/palette";
 
 import Spinner from "../Spinner";
 
-function LoadingButton(
-  props: {
-    color?: PaletteColorType;
-    text?: I18nText;
-    loading?: boolean;
-  } & React.ComponentPropsWithoutRef<"button">
-): JSX.Element {
+interface LoadingButtonProps extends React.ComponentPropsWithoutRef<"button"> {
+  color?: PaletteColorType;
+  text?: I18nText;
+  loading?: boolean;
+}
+
+function LoadingButton(props: LoadingButtonProps): JSX.Element {
   const { t } = useTranslation();
 
   const { color, text, loading, className, children, ...otherProps } = props;
@@ -27,7 +27,7 @@ function LoadingButton(
       className={classNames(
         "cru-" + (color ?? "primary"),
         "cru-button outline",
-        className
+        className,
       )}
       {...otherProps}
     >
diff --git a/FrontEnd/src/views/login/index.tsx b/FrontEnd/src/views/login/index.tsx
index c083edeb..cc1d9865 100644
--- a/FrontEnd/src/views/login/index.tsx
+++ b/FrontEnd/src/views/login/index.tsx
@@ -9,7 +9,7 @@ import LoadingButton from "../common/button/LoadingButton";
 
 import "./index.css";
 
-const LoginPage: React.FC = (_) => {
+const LoginPage: React.FC = () => {
   const { t } = useTranslation();
 
   const navigate = useNavigate();
diff --git a/FrontEnd/src/views/settings/index.tsx b/FrontEnd/src/views/settings/index.tsx
index 79c816a0..ccaf86d2 100644
--- a/FrontEnd/src/views/settings/index.tsx
+++ b/FrontEnd/src/views/settings/index.tsx
@@ -71,7 +71,7 @@ function SettingItemContainer({
         "row settings-item mx-0",
         first && "first",
         onClick && "clickable",
-        className
+        className,
       )}
       onClick={onClick}
     >
@@ -134,7 +134,7 @@ const SelectSettingsItem: React.FC<SelectSettingItemProps> = ({
   );
 };
 
-const SettingsPage: React.FC = (_) => {
+const SettingsPage: React.FC = () => {
   const { i18n } = useTranslation();
   const user = useUser();
   const navigate = useNavigate();
@@ -149,7 +149,7 @@ const SettingsPage: React.FC = (_) => {
   >(null);
 
   const [registerCode, setRegisterCode] = useState<undefined | null | string>(
-    undefined
+    undefined,
   );
 
   const [bookmarkVisibility, setBookmarkVisibility] =
diff --git a/FrontEnd/src/views/timeline/TimelinePostEdit.tsx b/FrontEnd/src/views/timeline/TimelinePostEdit.tsx
index 88fa11a0..38e72264 100644
--- a/FrontEnd/src/views/timeline/TimelinePostEdit.tsx
+++ b/FrontEnd/src/views/timeline/TimelinePostEdit.tsx
@@ -161,7 +161,7 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => {
       case "image":
         if (image == null) {
           throw new UiLogicError(
-            "Content type is image but image blob is null."
+            "Content type is image but image blob is null.",
           );
         }
         requestData = {
@@ -187,10 +187,10 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => {
           setKind("text");
           onPosted(data);
         },
-        (_) => {
+        () => {
           setProcess(false);
           onPostError();
-        }
+        },
       );
   };
 
-- 
cgit v1.2.3

