aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FrontEnd/.eslintignore1
-rw-r--r--FrontEnd/.eslintrc.cjs24
-rw-r--r--FrontEnd/.eslintrc.mjs39
-rw-r--r--FrontEnd/package.json18
-rw-r--r--FrontEnd/pnpm-lock.yaml2
-rw-r--r--FrontEnd/src/i18n.ts43
-rw-r--r--FrontEnd/src/services/TimelinePostBuilder.ts4
-rw-r--r--FrontEnd/src/services/alert.ts1
-rw-r--r--FrontEnd/src/services/timeline.ts4
-rw-r--r--FrontEnd/src/views/about/index.tsx7
-rw-r--r--FrontEnd/src/views/admin/Admin.tsx1
-rw-r--r--FrontEnd/src/views/admin/AdminNav.tsx5
-rw-r--r--FrontEnd/src/views/common/AppBar.tsx2
-rw-r--r--FrontEnd/src/views/common/button/IconButton.tsx6
-rw-r--r--FrontEnd/src/views/common/button/LoadingButton.tsx16
-rw-r--r--FrontEnd/src/views/login/index.tsx2
-rw-r--r--FrontEnd/src/views/settings/index.tsx6
-rw-r--r--FrontEnd/src/views/timeline/TimelinePostEdit.tsx6
18 files changed, 86 insertions, 101 deletions
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();
- }
+ },
);
};