refactor: eslint v9

This commit is contained in:
Tristan Yang
2025-02-10 15:06:50 +08:00
parent 45e9530de4
commit 82761ee73e
41 changed files with 3902 additions and 4690 deletions
-6
View File
@@ -1,6 +0,0 @@
/scripts
/node_modules
/build
/.idea
/.vscode
/public
-25
View File
@@ -1,25 +0,0 @@
{
"printWidth": 100,
"singleQuote": false,
"bracketSpacing": true,
"tabWidth": 2,
"semi": true,
"trailingComma": "none",
"importOrder": [
"^react",
"<THIRD_PARTY_MODULES>",
"",
"^@/app/(.*)$",
"^@/types/(.*)$",
"^@/libs/(.*)$",
"^@/components/(.*)$",
"^@/hooks/(.*)$",
"^@/utils(.*)$",
"^@/assets/(.*)$",
"^[./]"
],
"importOrderParserPlugins": ["typescript", "jsx", "decorators-legacy"],
"importOrderCaseInsensitive": true,
"importOrderMergeDuplicateImports": true,
"importOrderSeparation": true
}
+2 -2
View File
@@ -7,7 +7,6 @@
"strings": true "strings": true
}, },
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"prettier.prettierPath": "./node_modules/prettier/index.cjs",
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit" "source.fixAll.eslint": "explicit"
@@ -69,5 +68,6 @@
}, },
"[svg]": { "[svg]": {
"editor.defaultFormatter": "jock.svg" "editor.defaultFormatter": "jock.svg"
} },
"i18n-ally.localesPaths": ["public/locales"]
} }
+8
View File
@@ -0,0 +1,8 @@
{
"printWidth": 100,
"singleQuote": false,
"bracketSpacing": true,
"tabWidth": 2,
"semi": true,
"trailingComma": "none"
}
+43
View File
@@ -0,0 +1,43 @@
// @ts-check
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
// import prettierConfig from "eslint-config-prettier";
export default tseslint.config(
eslint.configs.recommended,
tseslint.configs.recommended,
{
rules: {
"@typescript-eslint/no-unused-vars": ["error", { ignoreRestSiblings: true }],
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-empty-object-type": "off",
"react/jsx-uses-react": "off",
"react/react-in-jsx-scope": "off",
semi: 2,
"no-console": "off",
"no-empty-pattern": "off",
"no-control-regex": "off",
"prefer-const": "off",
"react/prop-types": 0,
"react/no-unescaped-entities": "off",
"no-unused-vars": "off",
"max-lines": ["warn", { max: 500 }],
"react/display-name": 0,
"@typescript-eslint/ban-ts-comment": "off"
}
},
{
ignores: [
"src/libs/polyfills.js",
"tailwind.config.js",
"**/*.d.ts",
"scripts/**/*",
"node_modules/**/*",
"config/**/*",
"build/**/*",
"public/**/*"
]
},
// prettierConfig
);
+41 -49
View File
@@ -1,13 +1,13 @@
{ {
"name": "vocechat-web", "name": "vocechat-web",
"version": "0.8.11", "version": "0.9.0",
"homepage": "https://voce.chat", "homepage": "https://voce.chat",
"dependencies": { "dependencies": {
"@metamask/onboarding": "^1.0.1", "@metamask/onboarding": "^1.0.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
"@radix-ui/react-popover": "^1.1.2", "@radix-ui/react-popover": "^1.1.6",
"@react-oauth/google": "^0.12.1", "@react-oauth/google": "^0.12.1",
"@reduxjs/toolkit": "^2.3.0", "@reduxjs/toolkit": "^2.5.1",
"@svgr/webpack": "^8.1.0", "@svgr/webpack": "^8.1.0",
"@tippyjs/react": "^4.2.6", "@tippyjs/react": "^4.2.6",
"@toast-ui/editor": "^3.2.2", "@toast-ui/editor": "^3.2.2",
@@ -24,63 +24,60 @@
"@udecode/plate-paragraph": "^33.0.0", "@udecode/plate-paragraph": "^33.0.0",
"@udecode/plate-trailing-block": "^33.0.0", "@udecode/plate-trailing-block": "^33.0.0",
"@uiball/loaders": "^1.3.1", "@uiball/loaders": "^1.3.1",
"agora-rtc-sdk-ng": "^4.22.2", "agora-rtc-sdk-ng": "^4.23.1",
"broadcast-channel": "^7.0.0", "broadcast-channel": "^7.0.0",
"browserslist": "^4.24.2", "browserslist": "^4.24.4",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"copy-image-clipboard": "^2.1.2", "copy-image-clipboard": "^2.1.2",
"css-loader": "^7.1.2", "css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.0", "css-minimizer-webpack-plugin": "^7.0.0",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"eslint": "^8.57.0", "firebase": "^11.3.0",
"firebase": "^11.0.1", "framer-motion": "12.4.1",
"framer-motion": "11.11.11", "fs-extra": "^11.3.0",
"fs-extra": "^11.2.0",
"heic2any": "^0.0.4", "heic2any": "^0.0.4",
"html-webpack-plugin": "^5.6.3", "html-webpack-plugin": "^5.6.3",
"i18next": "^23.16.4", "i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.0", "i18next-browser-languagedetector": "^8.0.2",
"i18next-http-backend": "^2.6.2", "i18next-http-backend": "^3.0.2",
"linkify-plugin-mention": "^4.1.3", "linkify-plugin-mention": "^4.2.0",
"linkify-react": "^4.1.3", "linkify-react": "^4.2.0",
"linkifyjs": "^4.1.3", "linkifyjs": "^4.2.0",
"localforage": "^1.10.0", "localforage": "^1.10.0",
"localforage-setitems": "^1.4.0", "localforage-setitems": "^1.4.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"masonry-layout": "^4.2.2", "masonry-layout": "^4.2.2",
"mini-css-extract-plugin": "^2.9.2", "mini-css-extract-plugin": "^2.9.2",
"prismjs": "^1.29.0", "prismjs": "^1.29.0",
"qrcode.react": "^4.1.0", "qrcode.react": "^4.2.0",
"react": "^18.3.1", "react": "^19.0.0",
"react-dev-utils": "^12.0.1", "react-dev-utils": "^12.0.1",
"react-dnd": "16.0.1", "react-dnd": "16.0.1",
"react-dnd-html5-backend": "16.0.1", "react-dnd-html5-backend": "16.0.1",
"react-dom": "^18.3.1", "react-dom": "^19.0.0",
"react-error-boundary": "^4.1.2", "react-error-boundary": "^5.0.0",
"react-helmet": "^6.1.0", "react-hot-toast": "^2.5.1",
"react-hot-toast": "^2.4.1", "react-i18next": "^15.4.0",
"react-i18next": "^15.1.0", "react-redux": "^9.2.0",
"react-redux": "^9.1.2", "react-refresh": "0.16.0",
"react-refresh": "0.14.2", "react-router-dom": "^7.1.5",
"react-router-dom": "^6.28.0",
"react-syntax-highlighter": "^15.6.1", "react-syntax-highlighter": "^15.6.1",
"react-textarea-autosize": "^8.5.4", "react-textarea-autosize": "^8.5.7",
"react-use-wizard": "^2.3.0", "react-use-wizard": "^2.3.0",
"react-viewport-list": "^7.1.2", "react-viewport-list": "^7.1.2",
"react-virtuoso": "^4.12.0", "react-virtuoso": "^4.12.5",
"rooks": "^7.14.1", "rooks": "^7.14.1",
"slate": "^0.110.2", "slate": "^0.112.0",
"slate-history": "^0.110.3", "slate-history": "^0.110.3",
"slate-hyperscript": "^0.100.0", "slate-hyperscript": "^0.100.0",
"slate-react": "0.111.0", "slate-react": "0.112.1",
"source-map-loader": "^5.0.0", "source-map-loader": "^5.0.0",
"style-loader": "^4.0.0", "style-loader": "^4.0.0",
"tailwind-merge": "2.5.4", "tailwind-merge": "2.5.4",
"terser-webpack-plugin": "^5.3.10", "terser-webpack-plugin": "^5.3.11",
"tippy.js": "^6.3.7", "tippy.js": "^6.3.7",
"typescript": "^5.6.3", "wavesurfer.js": "^7.9.0",
"wavesurfer.js": "^7.8.8", "webpack": "^5.97.1",
"webpack": "^5.96.1",
"webpack-dev-server": "^4.15.1", "webpack-dev-server": "^4.15.1",
"webpack-manifest-plugin": "^5.0.0", "webpack-manifest-plugin": "^5.0.0",
"workbox-core": "^7.3.0", "workbox-core": "^7.3.0",
@@ -115,34 +112,29 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.26.0", "@babel/core": "^7.26.8",
"@ianvs/prettier-plugin-sort-imports": "^4.4.0", "@eslint/js": "^9.20.0",
"@types/lodash": "^4.17.13", "@types/lodash": "^4.17.15",
"@types/masonry-layout": "^4.2.8", "@types/masonry-layout": "^4.2.8",
"@types/node": "^22.9.0", "@types/node": "^22.13.1",
"@types/react": "18.3.12", "@types/react": "18.3.18",
"@types/react-dom": "^18.3.1", "@types/react-dom": "^18.3.5",
"@types/react-helmet": "^6.1.11", "@types/react-helmet": "^6.1.11",
"@types/react-syntax-highlighter": "^15.5.13", "@types/react-syntax-highlighter": "^15.5.13",
"@typescript-eslint/eslint-plugin": "^7.15.0",
"@typescript-eslint/parser": "^7.15.0",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"babel-loader": "^9.2.1", "babel-loader": "^9.2.1",
"babel-plugin-named-asset-import": "^0.3.8", "babel-plugin-named-asset-import": "^0.3.8",
"babel-preset-react-app": "^10.0.1", "babel-preset-react-app": "^10.0.1",
"eslint-config-prettier": "^9.1.0", "eslint": "^9.20.0",
"eslint-plugin-import": "^2.31.0", "gh-pages": "^6.3.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^4.6.2",
"gh-pages": "^6.2.0",
"md5-file": "^5.0.0", "md5-file": "^5.0.0",
"patch-package": "^8.0.0", "patch-package": "^8.0.0",
"postcss": "^8.4.47", "postcss": "^8.5.1",
"postcss-loader": "^8.1.1", "postcss-loader": "^8.1.1",
"postinstall-postinstall": "^2.1.0", "postinstall-postinstall": "^2.1.0",
"prettier": "^3.3.3",
"tailwindcss": "^3.4.14", "tailwindcss": "^3.4.14",
"typescript": "^5.7.3",
"typescript-eslint": "^8.23.0",
"webpack-bundle-analyzer": "^4.10.2" "webpack-bundle-analyzer": "^4.10.2"
} }
} }
+3734 -4500
View File
File diff suppressed because it is too large Load Diff
+33 -33
View File
@@ -5,15 +5,15 @@ const prices: Price[] = [
{ {
type: "payment", type: "payment",
limit: 999999, limit: 999999,
pid: "price_1MbF30GGoUDRyc3jwOg30dVQ" pid: "price_1MbF30GGoUDRyc3jwOg30dVQ",
}, },
{ {
type: "booking" type: "booking",
} },
]; ];
const official_dev = `https://dev.voce.chat`; const official_dev = `https://dev.voce.chat`;
const local_dev = `https://dev.voce.chat`; const local_dev = `https://dev.voce.chat`;
// const local_dev = `http://localhost:3881`; // const local_dev = `http://localhost:3412`;
const dev_origin = process.env.REACT_APP_OFFICIAL_DEMO ? official_dev : local_dev; const dev_origin = process.env.REACT_APP_OFFICIAL_DEMO ? official_dev : local_dev;
// const local_dev = `https://im.ttt.td`; // const local_dev = `https://im.ttt.td`;
@@ -56,7 +56,7 @@ export const getLicensePriceList = () => {
title: "Test VoceChat Enterprise", title: "Test VoceChat Enterprise",
limit: 99999, limit: 99999,
pid: "price_1LkQGpGGoUDRyc3jGTh3GYHw", pid: "price_1LkQGpGGoUDRyc3jGTh3GYHw",
desc: "test price" desc: "test price",
}, },
{ {
title: "VoceChat Pro", title: "VoceChat Pro",
@@ -65,8 +65,8 @@ export const getLicensePriceList = () => {
pid: "price_1MMNNCGGoUDRyc3jSIGIsb3C", pid: "price_1MMNNCGGoUDRyc3jSIGIsb3C",
desc: "test subscription price", desc: "test subscription price",
type: "subscription", type: "subscription",
sub_dur: "year" //day month year sub_dur: "year", //day month year
} },
] ]
: ps; : ps;
}; };
@@ -84,14 +84,14 @@ export const ContentTypes = {
audio: "vocechat/audio", audio: "vocechat/audio",
archive: "vocechat/archive", archive: "vocechat/archive",
formData: "multipart/form-data", formData: "multipart/form-data",
json: "application/json" json: "application/json",
}; };
export const MessageTypes = { export const MessageTypes = {
text: "text/plain", text: "text/plain",
markdown: "text/markdown", markdown: "text/markdown",
audio: "vocechat/audio", audio: "vocechat/audio",
file: "vocechat/file", file: "vocechat/file",
archive: "vocechat/archive" archive: "vocechat/archive",
}; };
export const firebaseConfig = { export const firebaseConfig = {
apiKey: "AIzaSyCc3VuCJZgzQLIH2wrYdQzsUOc1DuZiIOA", apiKey: "AIzaSyCc3VuCJZgzQLIH2wrYdQzsUOc1DuZiIOA",
@@ -100,11 +100,11 @@ export const firebaseConfig = {
storageBucket: "vocechatdev.appspot.com", storageBucket: "vocechatdev.appspot.com",
messagingSenderId: "526613312184", messagingSenderId: "526613312184",
appId: "1:526613312184:web:d13c92582baf470d487a4d", appId: "1:526613312184:web:d13c92582baf470d487a4d",
measurementId: "G-82RQ3YSCP7" measurementId: "G-82RQ3YSCP7",
}; };
export const ChatPrefixes = { export const ChatPrefixes = {
channel: "#", channel: "#",
dm: "@" dm: "@",
}; };
export const vapidKey = `BOmzyZhw-DcIGYQ77mzQUVqLlcvn0bm_76P_kc7rpwRxzXNbui-JP8iPyEQYfyoxyJeq43Ud4IiIsJSMNHNujn0`; export const vapidKey = `BOmzyZhw-DcIGYQ77mzQUVqLlcvn0bm_76P_kc7rpwRxzXNbui-JP8iPyEQYfyoxyJeq43Ud4IiIsJSMNHNujn0`;
export const tokenHeader = "X-API-Key"; export const tokenHeader = "X-API-Key";
@@ -129,84 +129,84 @@ export const Emojis = ["👍", "❤️", "😄", "👀", "👎", "🎉", "🙁",
export const getInviteLinkExpireList = () => [ export const getInviteLinkExpireList = () => [
{ {
label: i18n.t("auth:invite_expire.min30"), label: i18n.t("auth:invite_expire.min30"),
value: 30 * 60 value: 30 * 60,
}, },
{ {
label: i18n.t("auth:invite_expire.h1"), label: i18n.t("auth:invite_expire.h1"),
value: 60 * 60 value: 60 * 60,
}, },
{ {
label: i18n.t("auth:invite_expire.h6"), label: i18n.t("auth:invite_expire.h6"),
value: 6 * 60 * 60 value: 6 * 60 * 60,
}, },
{ {
label: i18n.t("auth:invite_expire.h12"), label: i18n.t("auth:invite_expire.h12"),
value: 12 * 60 * 60 value: 12 * 60 * 60,
}, },
{ {
label: i18n.t("auth:invite_expire.d1"), label: i18n.t("auth:invite_expire.d1"),
value: 24 * 60 * 60 value: 24 * 60 * 60,
}, },
{ {
label: i18n.t("auth:invite_expire.d7"), label: i18n.t("auth:invite_expire.d7"),
value: 7 * 24 * 60 * 60 value: 7 * 24 * 60 * 60,
}, },
{ {
label: i18n.t("auth:invite_expire.d30"), label: i18n.t("auth:invite_expire.d30"),
value: 30 * 24 * 60 * 60 value: 30 * 24 * 60 * 60,
} },
]; ];
export const getInviteLinkTimesList = () => [ export const getInviteLinkTimesList = () => [
{ {
label: i18n.t("auth:invite_times.no_limit"), label: i18n.t("auth:invite_times.no_limit"),
value: 10000000 value: 10000000,
}, },
{ {
label: i18n.t("auth:invite_times.time1"), label: i18n.t("auth:invite_times.time1"),
value: 1 value: 1,
}, },
{ {
label: i18n.t("auth:invite_times.times5"), label: i18n.t("auth:invite_times.times5"),
value: 5 value: 5,
}, },
{ {
label: i18n.t("auth:invite_times.times10"), label: i18n.t("auth:invite_times.times10"),
value: 10 value: 10,
}, },
{ {
label: i18n.t("auth:invite_times.times25"), label: i18n.t("auth:invite_times.times25"),
value: 25 value: 25,
}, },
{ {
label: i18n.t("auth:invite_times.times50"), label: i18n.t("auth:invite_times.times50"),
value: 50 value: 50,
}, },
{ {
label: i18n.t("auth:invite_times.times100"), label: i18n.t("auth:invite_times.times100"),
value: 100 value: 100,
} },
]; ];
export const getEmailNotifyDelayList = () => [ export const getEmailNotifyDelayList = () => [
{ {
label: i18n.t("setting:overview.server_msg_notify.delay_5_min"), label: i18n.t("setting:overview.server_msg_notify.delay_5_min"),
value: 5 * 60 value: 5 * 60,
}, },
{ {
label: i18n.t("setting:overview.server_msg_notify.delay_15_min"), label: i18n.t("setting:overview.server_msg_notify.delay_15_min"),
value: 15 * 60 value: 15 * 60,
}, },
{ {
label: i18n.t("setting:overview.server_msg_notify.delay_1_hour"), label: i18n.t("setting:overview.server_msg_notify.delay_1_hour"),
value: 60 * 60 value: 60 * 60,
}, },
{ {
label: i18n.t("setting:overview.server_msg_notify.delay_3_hour"), label: i18n.t("setting:overview.server_msg_notify.delay_3_hour"),
value: 3 * 60 * 60 value: 3 * 60 * 60,
}, },
{ {
label: i18n.t("setting:overview.server_msg_notify.delay_12_hour"), label: i18n.t("setting:overview.server_msg_notify.delay_12_hour"),
value: 12 * 60 * 60 value: 12 * 60 * 60,
} },
]; ];
export const KEY_ADMIN_SEE_CHANNEL_MEMBERS = `only_admin_can_see_channel_members`; export const KEY_ADMIN_SEE_CHANNEL_MEMBERS = `only_admin_can_see_channel_members`;
export const KEY_MSG_URL_PREVIEW = `enable_msg_url_preview`; export const KEY_MSG_URL_PREVIEW = `enable_msg_url_preview`;
-1
View File
@@ -33,7 +33,6 @@ import { updateCallInfo, upsertVoiceList } from "../slices/voice";
import { RootState } from "../store"; import { RootState } from "../store";
import baseQuery from "./base.query"; import baseQuery from "./base.query";
import { GetFilesDTO, VoceChatFile } from "@/types/resource"; import { GetFilesDTO, VoceChatFile } from "@/types/resource";
import { IPData } from "@/types/common";
export const serverApi = createApi({ export const serverApi = createApi({
reducerPath: "serverApi", reducerPath: "serverApi",
+1 -1
View File
@@ -59,7 +59,7 @@ const uiSlice = createSlice({
...rest ...rest
} = action.payload; } = action.payload;
window.MSG_SOUND = msgSound; window.MSG_SOUND = msgSound;
return { ...state, msgSound, ...rest }; return { ...state, msgSound,fileListView, ...rest };
}, },
setReady(state, action: PayloadAction<boolean>) { setReady(state, action: PayloadAction<boolean>) {
state.ready = action.payload; state.ready = action.payload;
+2 -1
View File
@@ -4,7 +4,6 @@ import clsx from "clsx";
import { useAppSelector } from "@/app/store"; import { useAppSelector } from "@/app/store";
import useExpiredResMap from "@/hooks/useExpiredResMap"; import useExpiredResMap from "@/hooks/useExpiredResMap";
import { formatBytes, fromNowTime, getFileIcon } from "@/utils"; import { formatBytes, fromNowTime, getFileIcon } from "@/utils";
import IconDownload from "@/assets/icons/download.svg";
import { import {
AudioPreview, AudioPreview,
CodePreview, CodePreview,
@@ -95,6 +94,8 @@ const FileBox: FC<Props> = ({
setFetchError(true); setFetchError(true);
} }
} catch (e) { } catch (e) {
console.warn(e);
setFetchError(true); setFetchError(true);
} }
}; };
@@ -1,7 +1,6 @@
import { useState } from "react"; import { useState } from "react";
import clsx from "clsx"; import clsx from "clsx";
import IconDownload from "@/assets/icons/download.svg";
import IconAudio from "@/assets/icons/file.audio.svg"; import IconAudio from "@/assets/icons/file.audio.svg";
import { formatBytes } from "../../utils"; import { formatBytes } from "../../utils";
import ExpiredMessage from "./ExpiredMessage"; import ExpiredMessage from "./ExpiredMessage";
@@ -2,7 +2,6 @@ import { SyntheticEvent, useState } from "react";
import { Orbit } from "@uiball/loaders"; import { Orbit } from "@uiball/loaders";
import clsx from "clsx"; import clsx from "clsx";
import IconDownload from "@/assets/icons/download.svg";
import IconVideo from "@/assets/icons/file.video.svg"; import IconVideo from "@/assets/icons/file.video.svg";
import { formatBytes } from "../../utils"; import { formatBytes } from "../../utils";
import ExpiredMessage from "./ExpiredMessage"; import ExpiredMessage from "./ExpiredMessage";
@@ -10,7 +10,7 @@ type Props = {
}; };
const ViewPassword = ({ uid, onClose }: Props) => { const ViewPassword = ({ uid, onClose }: Props) => {
const { isLoading, data } = useGetUserByAdminQuery(uid ?? 0, { skip: !uid }); const { data } = useGetUserByAdminQuery(uid ?? 0, { skip: !uid });
console.log({ data }); console.log({ data });
if (!uid) return null; if (!uid) return null;
@@ -26,7 +26,6 @@ const PinMessageModal: FC<Props> = ({ closeModal, mid = 0, gid = 0 }) => {
closeModal(); closeModal();
toast.success(t("tip.pin")); toast.success(t("tip.pin"));
} }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isSuccess]); }, [isSuccess]);
if (!mid) return null; if (!mid) return null;
@@ -27,7 +27,7 @@ export function ComboboxItem<TData extends Data = NoData>({
item, item,
onRenderItem onRenderItem
}: ComboboxContentItemProps<TData>) { }: ComboboxContentItemProps<TData>) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { props } = useComboboxItem({ item, index, combobox, onRenderItem }); const { props } = useComboboxItem({ item, index, combobox, onRenderItem });
return ( return (
@@ -51,7 +51,7 @@ export function ComboboxContent<TData extends Data = NoData>(props: ComboboxCont
const activeComboboxStore = useActiveComboboxStore()!; const activeComboboxStore = useActiveComboboxStore()!;
const state = useComboboxContentState({ items, combobox }); const state = useComboboxContentState({ items, combobox });
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { menuProps, targetRange } = useComboboxContent(state); const { menuProps, targetRange } = useComboboxContent(state);
return ( return (
+2 -3
View File
@@ -1,5 +1,4 @@
import { FC } from "react"; import { FC } from "react";
import { Helmet } from "react-helmet";
import { useAppSelector } from "@/app/store"; import { useAppSelector } from "@/app/store";
import { useGetServerQuery } from "@/app/services/server"; import { useGetServerQuery } from "@/app/services/server";
import { shallowEqual } from "react-redux"; import { shallowEqual } from "react-redux";
@@ -9,10 +8,10 @@ const Meta: FC<Props> = () => {
useGetServerQuery(); useGetServerQuery();
const { name, logo } = useAppSelector((store) => store.server, shallowEqual); const { name, logo } = useAppSelector((store) => store.server, shallowEqual);
return ( return (
<Helmet> <>
{name && <title>{name} Web App</title>} {name && <title>{name} Web App</title>}
{logo && <link rel="icon" href={`${logo}?ts=${new Date().getTime()}`} />} {logo && <link rel="icon" href={`${logo}?ts=${new Date().getTime()}`} />}
</Helmet> </>
); );
}; };
export default Meta; export default Meta;
+3 -1
View File
@@ -14,7 +14,7 @@ export type VoiceMessageProps = {
url: string; url: string;
secure_url: string; secure_url: string;
}; };
// 全局存储Voice信息 // 全局存储 Voice 信息
const VoiceMap: { [key: string]: WaveSurfer | null } = {}; const VoiceMap: { [key: string]: WaveSurfer | null } = {};
const VoiceMessage = ({ file_path }: { file_path: string }) => { const VoiceMessage = ({ file_path }: { file_path: string }) => {
const containerRef = useRef(null); const containerRef = useRef(null);
@@ -56,6 +56,8 @@ const VoiceMessage = ({ file_path }: { file_path: string }) => {
}); });
VoiceMap[file_path] = wave; VoiceMap[file_path] = wave;
} catch (error) { } catch (error) {
console.error(error);
setStatus("error"); setStatus("error");
} }
}; };
-1
View File
@@ -22,7 +22,6 @@ const Radio: FC<Props> = ({
onChange = undefined onChange = undefined
}) => { }) => {
const id = useId(); const id = useId();
const [fallbackValue, setFallbackValue] = useState(defaultValue); const [fallbackValue, setFallbackValue] = useState(defaultValue);
const _value = value !== VALUE_NOT_SET ? value : fallbackValue; const _value = value !== VALUE_NOT_SET ? value : fallbackValue;
return ( return (
+3 -1
View File
@@ -18,7 +18,9 @@ const useServerExtSetting = (config?: { successTip?: boolean; key?: string }) =>
let setting = {}; let setting = {};
try { try {
setting = JSON.parse(jsonSetting); setting = JSON.parse(jsonSetting);
} catch (error) {} } catch (error) {
console.warn(error);
}
const defaultValueMap = { const defaultValueMap = {
string: "", string: "",
boolean: false boolean: false
+1 -1
View File
@@ -98,7 +98,7 @@ const handler = (
// } // }
}); });
// 推给 PC 端 // 推给 PC 端
console.info("{{NEW_MSG}}") console.info("{{NEW_MSG}}");
break; break;
} }
case "reply": case "reply":
-1
View File
@@ -19,7 +19,6 @@ import VoiceChat from "../VoiceChat";
import Dashboard from "../VoiceChat/Dashboard"; import Dashboard from "../VoiceChat/Dashboard";
import Members from "./Members"; import Members from "./Members";
import PinList from "./PinList"; import PinList from "./PinList";
import { getJSONField } from "@/utils";
import { KEY_ADMIN_SEE_CHANNEL_MEMBERS } from "@/app/config"; import { KEY_ADMIN_SEE_CHANNEL_MEMBERS } from "@/app/config";
import useServerExtSetting from "@/hooks/useServerExtSetting"; import useServerExtSetting from "@/hooks/useServerExtSetting";
+1 -1
View File
@@ -1,4 +1,4 @@
import { FC, ReactElement, useEffect, useRef } from "react"; import { FC, ReactElement, useEffect } from "react";
import { useDrop } from "react-dnd"; import { useDrop } from "react-dnd";
import { NativeTypes } from "react-dnd-html5-backend"; import { NativeTypes } from "react-dnd-html5-backend";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
-21
View File
@@ -11,27 +11,6 @@ import View from "./View";
import { useLazyGetFilesQuery } from "@/app/services/server"; import { useLazyGetFilesQuery } from "@/app/services/server";
import { shallowEqual } from "react-redux"; import { shallowEqual } from "react-redux";
const checkFilter = (data, filter, channelMessage) => {
let selected = true;
const { mid, from_uid, properties } = data;
const { name: nameFilter, from: fromFilter, channel: channelFilter } = filter;
const name = properties ? properties.name : "";
if (fromFilter && fromFilter != from_uid) {
selected = false;
}
if (channelFilter && channelMessage[channelFilter].findIndex((id) => id == mid) == -1) {
selected = false;
}
if (nameFilter) {
let str = ["", ...nameFilter.toLowerCase(), ""].join(".*");
let reg = new RegExp(str);
if (!reg.test(name)) {
selected = false;
}
}
return selected;
};
function Files() { function Files() {
const [getFiles, { data }] = useLazyGetFilesQuery(); const [getFiles, { data }] = useLazyGetFilesQuery();
const listContainerRef = useRef<HTMLDivElement>(); const listContainerRef = useRef<HTMLDivElement>();
-1
View File
@@ -16,7 +16,6 @@ import InvitePrivate from "./invitePrivate";
import LazyIt from "./lazy"; import LazyIt from "./lazy";
import InviteInMobile from "./reg/InviteInMobile"; import InviteInMobile from "./reg/InviteInMobile";
import usePrefetchData from "@/hooks/usePrefetchData"; import usePrefetchData from "@/hooks/usePrefetchData";
import ServerVersionChecker from "@/components/ServerVersionChecker";
const RegBasePage = lazy(() => import("./reg")); const RegBasePage = lazy(() => import("./reg"));
const RegWithUsernamePage = lazy(() => import("./reg/RegWithUsername")); const RegWithUsernamePage = lazy(() => import("./reg/RegWithUsername"));
+3 -1
View File
@@ -1,4 +1,4 @@
/* eslint-disable no-undef */
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import MetaMaskOnboarding from "@metamask/onboarding"; import MetaMaskOnboarding from "@metamask/onboarding";
@@ -82,6 +82,8 @@ export default function MetamaskLoginButton({
}); });
setAccounts(tmps); setAccounts(tmps);
} catch (error) { } catch (error) {
console.error(error);
// toast.error(error.message); // toast.error(error.message);
window.ethereum.request({ window.ethereum.request({
method: "wallet_requestPermissions", method: "wallet_requestPermissions",
+1 -1
View File
@@ -1,4 +1,4 @@
/* eslint-disable no-undef */
import { FC, useState } from "react"; import { FC, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
+1 -1
View File
@@ -1,4 +1,4 @@
/* eslint-disable no-undef */
import { ChangeEvent, FormEvent, useEffect, useState } from "react"; import { ChangeEvent, FormEvent, useEffect, useState } from "react";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
-3
View File
@@ -1,5 +1,4 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useWizard, Wizard } from "react-use-wizard"; import { useWizard, Wizard } from "react-use-wizard";
import clsx from "clsx"; import clsx from "clsx";
@@ -53,9 +52,7 @@ export default function OnboardingPage() {
const [serverName, setServerName] = useState(""); const [serverName, setServerName] = useState("");
return ( return (
<> <>
<Helmet>
<title>{t("onboarding.title") || ""}</title> <title>{t("onboarding.title") || ""}</title>
</Helmet>
<div className="h-screen bg-neutral-100 dark:bg-neutral-900 overflow-y-auto"> <div className="h-screen bg-neutral-100 dark:bg-neutral-900 overflow-y-auto">
<Wizard header={<Navigator />}> <Wizard header={<Navigator />}>
<WelcomePage /> <WelcomePage />
+1 -1
View File
@@ -1,4 +1,4 @@
import { FC, MouseEvent } from "react"; import { FC } from "react";
import { Trans, useTranslation } from "react-i18next"; import { Trans, useTranslation } from "react-i18next";
import BASE_URL from "@/app/config"; import BASE_URL from "@/app/config";
+1 -1
View File
@@ -1,4 +1,4 @@
import { ChangeEvent, useEffect, useRef, useState } from "react"; import { ChangeEvent, useEffect, useState } from "react";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@@ -3,7 +3,6 @@
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import SettingBlock from "@/components/SettingBlock"; import SettingBlock from "@/components/SettingBlock";
import StyledRadio from "@/components/styled/Radio";
import { useAppSelector } from "../../../app/store"; import { useAppSelector } from "../../../app/store";
import { shallowEqual, useDispatch } from "react-redux"; import { shallowEqual, useDispatch } from "react-redux";
import { updateMsgSoundSetting } from "@/app/slices/ui"; import { updateMsgSoundSetting } from "@/app/slices/ui";
@@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next";
import StyledRadio from "../../../components/styled/Radio"; import StyledRadio from "../../../components/styled/Radio";
type Props = {}; type Props = {};
const WhoCanSignUpSetting = (props: Props) => { const WhoCanSignUpSetting = ({}: Props) => {
const { t } = useTranslation("setting"); const { t } = useTranslation("setting");
const { values: loginConfig, updateConfig: updateLoginConfig } = useConfig("login"); const { values: loginConfig, updateConfig: updateLoginConfig } = useConfig("login");
const handleUpdateWhoCanSignUp = (value: WhoCanSignUp) => { const handleUpdateWhoCanSignUp = (value: WhoCanSignUp) => {
@@ -20,6 +20,8 @@ const RemoveConfirmModal: FC<Props> = ({ closeModal }) => {
try { try {
await removeCurrentAccount(); await removeCurrentAccount();
} catch (error) { } catch (error) {
console.error(error);
toast.error("Remove Account Failed!"); toast.error("Remove Account Failed!");
} }
}; };
+1 -1
View File
@@ -1,4 +1,4 @@
/* eslint-disable no-restricted-globals */
// This service worker can be customized! // This service worker can be customized!
// See https://developers.google.com/web/tools/workbox/modules // See https://developers.google.com/web/tools/workbox/modules
+6 -18
View File
@@ -390,13 +390,8 @@ export const compareVersion = (
return 0; return 0;
}; };
/*!
* Get the contrasting color for any hex color // Get the contrasting color for any hex color
* (c) 2021 Chris Ferdinandi, MIT License, https://gomakethings.com
* Derived from work by Brian Suda, https://24ways.org/2010/calculating-color-contrast/
* @param {String} A hexcolor value
* @return {String} The contrasting color (black or white)
*/
export const getContrastColor = (hexcolor: string) => { export const getContrastColor = (hexcolor: string) => {
if (!hexcolor) return ""; if (!hexcolor) return "";
// If a leading # is provided, remove it // If a leading # is provided, remove it
@@ -479,16 +474,6 @@ export const transformInviteLink = (link: string) => {
export const reloadCurrentPage = () => { export const reloadCurrentPage = () => {
if (isElectronContext()) { if (isElectronContext()) {
// // 改变 theme color 然后 electron reload(约定)
// const metaThemeColor = document.querySelector("meta[name=theme-color]");
// if (metaThemeColor) {
// metaThemeColor.setAttribute("content", "#123456");
// } else {
// const meta = document.createElement("meta");
// meta.name = "theme-color";
// meta.content = "#123456";
// document.head.appendChild(meta);
// }
// reload 两次 electron webview bug? // reload 两次 electron webview bug?
setTimeout(() => { setTimeout(() => {
location.reload(); location.reload();
@@ -511,7 +496,8 @@ export const getJSONField = (json: string | null, field: string) => {
try { try {
const obj = json ? JSON.parse(json) : {}; const obj = json ? JSON.parse(json) : {};
return obj[field]; return obj[field];
} catch (error) { } catch (err) {
console.warn(err);
return undefined; return undefined;
} }
}; };
@@ -521,6 +507,8 @@ export const upsertJSON = (json: string | null, obj: object) => {
const result = Object.assign({}, jsonObj, obj); const result = Object.assign({}, jsonObj, obj);
return JSON.stringify(result); return JSON.stringify(result);
} catch (error) { } catch (error) {
console.error(error);
return JSON.stringify(obj); return JSON.stringify(obj);
} }
}; };
+1 -1
View File
@@ -1,7 +1,7 @@
import BASE_URL from "@/app/config"; import BASE_URL from "@/app/config";
import { useAppSelector } from "@/app/store"; import { useAppSelector } from "@/app/store";
import { compareVersion } from "@/utils"; import { compareVersion } from "@/utils";
import React, { useEffect } from "react"; import { useEffect } from "react";
type Props = {}; type Props = {};
+4 -2
View File
@@ -1,6 +1,4 @@
/* eslint-disable @typescript-eslint/indent */
import { memo, useEffect, useRef, useState } from "react"; import { memo, useEffect, useRef, useState } from "react";
import { useAppSelector } from "../../app/store"; import { useAppSelector } from "../../app/store";
import Message from "./Message"; import Message from "./Message";
import { shallowEqual } from "react-redux"; import { shallowEqual } from "react-redux";
@@ -26,6 +24,10 @@ const MessageFeed = ({ hostId }: Props) => {
// 自己发送的消息 // 自己发送的消息
if (lastIsMyself && lastMsg.sending) { if (lastIsMyself && lastMsg.sending) {
container.scrollTop = container.scrollHeight; container.scrollTop = container.scrollHeight;
} }
// 在可视区域附近 // 在可视区域附近
if (deltaHeight <= triggerScrollHeight) { if (deltaHeight <= triggerScrollHeight) {
+2 -2
View File
@@ -1,4 +1,4 @@
import { ChangeEvent, memo, useEffect, useRef, useState } from "react"; import { ChangeEvent, memo, useRef, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import clsx from "clsx"; import clsx from "clsx";
@@ -17,7 +17,7 @@ type Props = {
let isComposing = false; let isComposing = false;
const MessageInput = (props: Props) => { const MessageInput = (props: Props) => {
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const { uploadFile, isUploading, isSuccess: uploadSuccess } = useUploadFile(); const { uploadFile, isUploading } = useUploadFile();
const { t } = useTranslation("widget"); const { t } = useTranslation("widget");
const { color } = useWidget(); const { color } = useWidget();
const { from, to } = props; const { from, to } = props;
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es6", "target": "es6",
"lib": ["dom", "dom.iterable", "esnext"], "lib": ["DOM", "dom.iterable", "esnext"],
"allowJs": true, "allowJs": true,
"skipLibCheck": true, "skipLibCheck": true,
"esModuleInterop": true, "esModuleInterop": true,