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
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"prettier.prettierPath": "./node_modules/prettier/index.cjs",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
@@ -69,5 +68,6 @@
},
"[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",
"version": "0.8.11",
"version": "0.9.0",
"homepage": "https://voce.chat",
"dependencies": {
"@metamask/onboarding": "^1.0.1",
"@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",
"@reduxjs/toolkit": "^2.3.0",
"@reduxjs/toolkit": "^2.5.1",
"@svgr/webpack": "^8.1.0",
"@tippyjs/react": "^4.2.6",
"@toast-ui/editor": "^3.2.2",
@@ -24,63 +24,60 @@
"@udecode/plate-paragraph": "^33.0.0",
"@udecode/plate-trailing-block": "^33.0.0",
"@uiball/loaders": "^1.3.1",
"agora-rtc-sdk-ng": "^4.22.2",
"agora-rtc-sdk-ng": "^4.23.1",
"broadcast-channel": "^7.0.0",
"browserslist": "^4.24.2",
"browserslist": "^4.24.4",
"clsx": "^2.1.1",
"copy-image-clipboard": "^2.1.2",
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.0",
"dayjs": "^1.11.13",
"eslint": "^8.57.0",
"firebase": "^11.0.1",
"framer-motion": "11.11.11",
"fs-extra": "^11.2.0",
"firebase": "^11.3.0",
"framer-motion": "12.4.1",
"fs-extra": "^11.3.0",
"heic2any": "^0.0.4",
"html-webpack-plugin": "^5.6.3",
"i18next": "^23.16.4",
"i18next-browser-languagedetector": "^8.0.0",
"i18next-http-backend": "^2.6.2",
"linkify-plugin-mention": "^4.1.3",
"linkify-react": "^4.1.3",
"linkifyjs": "^4.1.3",
"i18next": "^24.2.2",
"i18next-browser-languagedetector": "^8.0.2",
"i18next-http-backend": "^3.0.2",
"linkify-plugin-mention": "^4.2.0",
"linkify-react": "^4.2.0",
"linkifyjs": "^4.2.0",
"localforage": "^1.10.0",
"localforage-setitems": "^1.4.0",
"lodash": "^4.17.21",
"masonry-layout": "^4.2.2",
"mini-css-extract-plugin": "^2.9.2",
"prismjs": "^1.29.0",
"qrcode.react": "^4.1.0",
"react": "^18.3.1",
"qrcode.react": "^4.2.0",
"react": "^19.0.0",
"react-dev-utils": "^12.0.1",
"react-dnd": "16.0.1",
"react-dnd-html5-backend": "16.0.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.1.2",
"react-helmet": "^6.1.0",
"react-hot-toast": "^2.4.1",
"react-i18next": "^15.1.0",
"react-redux": "^9.1.2",
"react-refresh": "0.14.2",
"react-router-dom": "^6.28.0",
"react-dom": "^19.0.0",
"react-error-boundary": "^5.0.0",
"react-hot-toast": "^2.5.1",
"react-i18next": "^15.4.0",
"react-redux": "^9.2.0",
"react-refresh": "0.16.0",
"react-router-dom": "^7.1.5",
"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-viewport-list": "^7.1.2",
"react-virtuoso": "^4.12.0",
"react-virtuoso": "^4.12.5",
"rooks": "^7.14.1",
"slate": "^0.110.2",
"slate": "^0.112.0",
"slate-history": "^0.110.3",
"slate-hyperscript": "^0.100.0",
"slate-react": "0.111.0",
"slate-react": "0.112.1",
"source-map-loader": "^5.0.0",
"style-loader": "^4.0.0",
"tailwind-merge": "2.5.4",
"terser-webpack-plugin": "^5.3.10",
"terser-webpack-plugin": "^5.3.11",
"tippy.js": "^6.3.7",
"typescript": "^5.6.3",
"wavesurfer.js": "^7.8.8",
"webpack": "^5.96.1",
"wavesurfer.js": "^7.9.0",
"webpack": "^5.97.1",
"webpack-dev-server": "^4.15.1",
"webpack-manifest-plugin": "^5.0.0",
"workbox-core": "^7.3.0",
@@ -115,34 +112,29 @@
]
},
"devDependencies": {
"@babel/core": "^7.26.0",
"@ianvs/prettier-plugin-sort-imports": "^4.4.0",
"@types/lodash": "^4.17.13",
"@babel/core": "^7.26.8",
"@eslint/js": "^9.20.0",
"@types/lodash": "^4.17.15",
"@types/masonry-layout": "^4.2.8",
"@types/node": "^22.9.0",
"@types/react": "18.3.12",
"@types/react-dom": "^18.3.1",
"@types/node": "^22.13.1",
"@types/react": "18.3.18",
"@types/react-dom": "^18.3.5",
"@types/react-helmet": "^6.1.11",
"@types/react-syntax-highlighter": "^15.5.13",
"@typescript-eslint/eslint-plugin": "^7.15.0",
"@typescript-eslint/parser": "^7.15.0",
"autoprefixer": "^10.4.20",
"babel-loader": "^9.2.1",
"babel-plugin-named-asset-import": "^0.3.8",
"babel-preset-react-app": "^10.0.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.31.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",
"eslint": "^9.20.0",
"gh-pages": "^6.3.0",
"md5-file": "^5.0.0",
"patch-package": "^8.0.0",
"postcss": "^8.4.47",
"postcss": "^8.5.1",
"postcss-loader": "^8.1.1",
"postinstall-postinstall": "^2.1.0",
"prettier": "^3.3.3",
"tailwindcss": "^3.4.14",
"typescript": "^5.7.3",
"typescript-eslint": "^8.23.0",
"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",
limit: 999999,
pid: "price_1MbF30GGoUDRyc3jwOg30dVQ"
pid: "price_1MbF30GGoUDRyc3jwOg30dVQ",
},
{
type: "booking"
}
type: "booking",
},
];
const official_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 local_dev = `https://im.ttt.td`;
@@ -56,7 +56,7 @@ export const getLicensePriceList = () => {
title: "Test VoceChat Enterprise",
limit: 99999,
pid: "price_1LkQGpGGoUDRyc3jGTh3GYHw",
desc: "test price"
desc: "test price",
},
{
title: "VoceChat Pro",
@@ -65,8 +65,8 @@ export const getLicensePriceList = () => {
pid: "price_1MMNNCGGoUDRyc3jSIGIsb3C",
desc: "test subscription price",
type: "subscription",
sub_dur: "year" //day month year
}
sub_dur: "year", //day month year
},
]
: ps;
};
@@ -84,14 +84,14 @@ export const ContentTypes = {
audio: "vocechat/audio",
archive: "vocechat/archive",
formData: "multipart/form-data",
json: "application/json"
json: "application/json",
};
export const MessageTypes = {
text: "text/plain",
markdown: "text/markdown",
audio: "vocechat/audio",
file: "vocechat/file",
archive: "vocechat/archive"
archive: "vocechat/archive",
};
export const firebaseConfig = {
apiKey: "AIzaSyCc3VuCJZgzQLIH2wrYdQzsUOc1DuZiIOA",
@@ -100,11 +100,11 @@ export const firebaseConfig = {
storageBucket: "vocechatdev.appspot.com",
messagingSenderId: "526613312184",
appId: "1:526613312184:web:d13c92582baf470d487a4d",
measurementId: "G-82RQ3YSCP7"
measurementId: "G-82RQ3YSCP7",
};
export const ChatPrefixes = {
channel: "#",
dm: "@"
dm: "@",
};
export const vapidKey = `BOmzyZhw-DcIGYQ77mzQUVqLlcvn0bm_76P_kc7rpwRxzXNbui-JP8iPyEQYfyoxyJeq43Ud4IiIsJSMNHNujn0`;
export const tokenHeader = "X-API-Key";
@@ -129,84 +129,84 @@ export const Emojis = ["👍", "❤️", "😄", "👀", "👎", "🎉", "🙁",
export const getInviteLinkExpireList = () => [
{
label: i18n.t("auth:invite_expire.min30"),
value: 30 * 60
value: 30 * 60,
},
{
label: i18n.t("auth:invite_expire.h1"),
value: 60 * 60
value: 60 * 60,
},
{
label: i18n.t("auth:invite_expire.h6"),
value: 6 * 60 * 60
value: 6 * 60 * 60,
},
{
label: i18n.t("auth:invite_expire.h12"),
value: 12 * 60 * 60
value: 12 * 60 * 60,
},
{
label: i18n.t("auth:invite_expire.d1"),
value: 24 * 60 * 60
value: 24 * 60 * 60,
},
{
label: i18n.t("auth:invite_expire.d7"),
value: 7 * 24 * 60 * 60
value: 7 * 24 * 60 * 60,
},
{
label: i18n.t("auth:invite_expire.d30"),
value: 30 * 24 * 60 * 60
}
value: 30 * 24 * 60 * 60,
},
];
export const getInviteLinkTimesList = () => [
{
label: i18n.t("auth:invite_times.no_limit"),
value: 10000000
value: 10000000,
},
{
label: i18n.t("auth:invite_times.time1"),
value: 1
value: 1,
},
{
label: i18n.t("auth:invite_times.times5"),
value: 5
value: 5,
},
{
label: i18n.t("auth:invite_times.times10"),
value: 10
value: 10,
},
{
label: i18n.t("auth:invite_times.times25"),
value: 25
value: 25,
},
{
label: i18n.t("auth:invite_times.times50"),
value: 50
value: 50,
},
{
label: i18n.t("auth:invite_times.times100"),
value: 100
}
value: 100,
},
];
export const getEmailNotifyDelayList = () => [
{
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"),
value: 15 * 60
value: 15 * 60,
},
{
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"),
value: 3 * 60 * 60
value: 3 * 60 * 60,
},
{
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_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 baseQuery from "./base.query";
import { GetFilesDTO, VoceChatFile } from "@/types/resource";
import { IPData } from "@/types/common";
export const serverApi = createApi({
reducerPath: "serverApi",
+1 -1
View File
@@ -59,7 +59,7 @@ const uiSlice = createSlice({
...rest
} = action.payload;
window.MSG_SOUND = msgSound;
return { ...state, msgSound, ...rest };
return { ...state, msgSound,fileListView, ...rest };
},
setReady(state, action: PayloadAction<boolean>) {
state.ready = action.payload;
+2 -1
View File
@@ -4,7 +4,6 @@ import clsx from "clsx";
import { useAppSelector } from "@/app/store";
import useExpiredResMap from "@/hooks/useExpiredResMap";
import { formatBytes, fromNowTime, getFileIcon } from "@/utils";
import IconDownload from "@/assets/icons/download.svg";
import {
AudioPreview,
CodePreview,
@@ -95,6 +94,8 @@ const FileBox: FC<Props> = ({
setFetchError(true);
}
} catch (e) {
console.warn(e);
setFetchError(true);
}
};
@@ -1,7 +1,6 @@
import { useState } from "react";
import clsx from "clsx";
import IconDownload from "@/assets/icons/download.svg";
import IconAudio from "@/assets/icons/file.audio.svg";
import { formatBytes } from "../../utils";
import ExpiredMessage from "./ExpiredMessage";
@@ -2,7 +2,6 @@ import { SyntheticEvent, useState } from "react";
import { Orbit } from "@uiball/loaders";
import clsx from "clsx";
import IconDownload from "@/assets/icons/download.svg";
import IconVideo from "@/assets/icons/file.video.svg";
import { formatBytes } from "../../utils";
import ExpiredMessage from "./ExpiredMessage";
@@ -10,7 +10,7 @@ type Props = {
};
const ViewPassword = ({ uid, onClose }: Props) => {
const { isLoading, data } = useGetUserByAdminQuery(uid ?? 0, { skip: !uid });
const { data } = useGetUserByAdminQuery(uid ?? 0, { skip: !uid });
console.log({ data });
if (!uid) return null;
@@ -26,7 +26,6 @@ const PinMessageModal: FC<Props> = ({ closeModal, mid = 0, gid = 0 }) => {
closeModal();
toast.success(t("tip.pin"));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isSuccess]);
if (!mid) return null;
@@ -27,7 +27,7 @@ export function ComboboxItem<TData extends Data = NoData>({
item,
onRenderItem
}: ComboboxContentItemProps<TData>) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { props } = useComboboxItem({ item, index, combobox, onRenderItem });
return (
@@ -51,7 +51,7 @@ export function ComboboxContent<TData extends Data = NoData>(props: ComboboxCont
const activeComboboxStore = useActiveComboboxStore()!;
const state = useComboboxContentState({ items, combobox });
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { menuProps, targetRange } = useComboboxContent(state);
return (
+2 -3
View File
@@ -1,5 +1,4 @@
import { FC } from "react";
import { Helmet } from "react-helmet";
import { useAppSelector } from "@/app/store";
import { useGetServerQuery } from "@/app/services/server";
import { shallowEqual } from "react-redux";
@@ -9,10 +8,10 @@ const Meta: FC<Props> = () => {
useGetServerQuery();
const { name, logo } = useAppSelector((store) => store.server, shallowEqual);
return (
<Helmet>
<>
{name && <title>{name} Web App</title>}
{logo && <link rel="icon" href={`${logo}?ts=${new Date().getTime()}`} />}
</Helmet>
</>
);
};
export default Meta;
+3 -1
View File
@@ -14,7 +14,7 @@ export type VoiceMessageProps = {
url: string;
secure_url: string;
};
// 全局存储Voice信息
// 全局存储 Voice 信息
const VoiceMap: { [key: string]: WaveSurfer | null } = {};
const VoiceMessage = ({ file_path }: { file_path: string }) => {
const containerRef = useRef(null);
@@ -56,6 +56,8 @@ const VoiceMessage = ({ file_path }: { file_path: string }) => {
});
VoiceMap[file_path] = wave;
} catch (error) {
console.error(error);
setStatus("error");
}
};
-1
View File
@@ -22,7 +22,6 @@ const Radio: FC<Props> = ({
onChange = undefined
}) => {
const id = useId();
const [fallbackValue, setFallbackValue] = useState(defaultValue);
const _value = value !== VALUE_NOT_SET ? value : fallbackValue;
return (
+3 -1
View File
@@ -18,7 +18,9 @@ const useServerExtSetting = (config?: { successTip?: boolean; key?: string }) =>
let setting = {};
try {
setting = JSON.parse(jsonSetting);
} catch (error) {}
} catch (error) {
console.warn(error);
}
const defaultValueMap = {
string: "",
boolean: false
+1 -1
View File
@@ -98,7 +98,7 @@ const handler = (
// }
});
// 推给 PC 端
console.info("{{NEW_MSG}}")
console.info("{{NEW_MSG}}");
break;
}
case "reply":
-1
View File
@@ -19,7 +19,6 @@ import VoiceChat from "../VoiceChat";
import Dashboard from "../VoiceChat/Dashboard";
import Members from "./Members";
import PinList from "./PinList";
import { getJSONField } from "@/utils";
import { KEY_ADMIN_SEE_CHANNEL_MEMBERS } from "@/app/config";
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 { NativeTypes } from "react-dnd-html5-backend";
import { toast } from "react-hot-toast";
-21
View File
@@ -11,27 +11,6 @@ import View from "./View";
import { useLazyGetFilesQuery } from "@/app/services/server";
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() {
const [getFiles, { data }] = useLazyGetFilesQuery();
const listContainerRef = useRef<HTMLDivElement>();
-1
View File
@@ -16,7 +16,6 @@ import InvitePrivate from "./invitePrivate";
import LazyIt from "./lazy";
import InviteInMobile from "./reg/InviteInMobile";
import usePrefetchData from "@/hooks/usePrefetchData";
import ServerVersionChecker from "@/components/ServerVersionChecker";
const RegBasePage = lazy(() => import("./reg"));
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 { useTranslation } from "react-i18next";
import MetaMaskOnboarding from "@metamask/onboarding";
@@ -82,6 +82,8 @@ export default function MetamaskLoginButton({
});
setAccounts(tmps);
} catch (error) {
console.error(error);
// toast.error(error.message);
window.ethereum.request({
method: "wallet_requestPermissions",
+1 -1
View File
@@ -1,4 +1,4 @@
/* eslint-disable no-undef */
import { FC, useState } from "react";
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 toast from "react-hot-toast";
import { useTranslation } from "react-i18next";
-3
View File
@@ -1,5 +1,4 @@
import React, { useState } from "react";
import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { useWizard, Wizard } from "react-use-wizard";
import clsx from "clsx";
@@ -53,9 +52,7 @@ export default function OnboardingPage() {
const [serverName, setServerName] = useState("");
return (
<>
<Helmet>
<title>{t("onboarding.title") || ""}</title>
</Helmet>
<div className="h-screen bg-neutral-100 dark:bg-neutral-900 overflow-y-auto">
<Wizard header={<Navigator />}>
<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 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 { useTranslation } from "react-i18next";
@@ -3,7 +3,6 @@
import { useTranslation } from "react-i18next";
import SettingBlock from "@/components/SettingBlock";
import StyledRadio from "@/components/styled/Radio";
import { useAppSelector } from "../../../app/store";
import { shallowEqual, useDispatch } from "react-redux";
import { updateMsgSoundSetting } from "@/app/slices/ui";
@@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next";
import StyledRadio from "../../../components/styled/Radio";
type Props = {};
const WhoCanSignUpSetting = (props: Props) => {
const WhoCanSignUpSetting = ({}: Props) => {
const { t } = useTranslation("setting");
const { values: loginConfig, updateConfig: updateLoginConfig } = useConfig("login");
const handleUpdateWhoCanSignUp = (value: WhoCanSignUp) => {
@@ -20,6 +20,8 @@ const RemoveConfirmModal: FC<Props> = ({ closeModal }) => {
try {
await removeCurrentAccount();
} catch (error) {
console.error(error);
toast.error("Remove Account Failed!");
}
};
+1 -1
View File
@@ -1,4 +1,4 @@
/* eslint-disable no-restricted-globals */
// This service worker can be customized!
// See https://developers.google.com/web/tools/workbox/modules
+6 -18
View File
@@ -390,13 +390,8 @@ export const compareVersion = (
return 0;
};
/*!
* 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)
*/
// Get the contrasting color for any hex color
export const getContrastColor = (hexcolor: string) => {
if (!hexcolor) return "";
// If a leading # is provided, remove it
@@ -479,16 +474,6 @@ export const transformInviteLink = (link: string) => {
export const reloadCurrentPage = () => {
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?
setTimeout(() => {
location.reload();
@@ -511,7 +496,8 @@ export const getJSONField = (json: string | null, field: string) => {
try {
const obj = json ? JSON.parse(json) : {};
return obj[field];
} catch (error) {
} catch (err) {
console.warn(err);
return undefined;
}
};
@@ -521,6 +507,8 @@ export const upsertJSON = (json: string | null, obj: object) => {
const result = Object.assign({}, jsonObj, obj);
return JSON.stringify(result);
} catch (error) {
console.error(error);
return JSON.stringify(obj);
}
};
+1 -1
View File
@@ -1,7 +1,7 @@
import BASE_URL from "@/app/config";
import { useAppSelector } from "@/app/store";
import { compareVersion } from "@/utils";
import React, { useEffect } from "react";
import { useEffect } from "react";
type Props = {};
+4 -2
View File
@@ -1,6 +1,4 @@
/* eslint-disable @typescript-eslint/indent */
import { memo, useEffect, useRef, useState } from "react";
import { useAppSelector } from "../../app/store";
import Message from "./Message";
import { shallowEqual } from "react-redux";
@@ -26,6 +24,10 @@ const MessageFeed = ({ hostId }: Props) => {
// 自己发送的消息
if (lastIsMyself && lastMsg.sending) {
container.scrollTop = container.scrollHeight;
}
// 在可视区域附近
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 clsx from "clsx";
@@ -17,7 +17,7 @@ type Props = {
let isComposing = false;
const MessageInput = (props: Props) => {
const inputRef = useRef<HTMLInputElement>(null);
const { uploadFile, isUploading, isSuccess: uploadSuccess } = useUploadFile();
const { uploadFile, isUploading } = useUploadFile();
const { t } = useTranslation("widget");
const { color } = useWidget();
const { from, to } = props;
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"target": "es6",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": ["DOM", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,