refactor: remove unused notification permission hook and related code
This commit is contained in:
10
package.json
10
package.json
@@ -43,17 +43,14 @@
|
|||||||
"@tauri-apps/plugin-clipboard-manager": "^2.3.0",
|
"@tauri-apps/plugin-clipboard-manager": "^2.3.0",
|
||||||
"@tauri-apps/plugin-dialog": "^2.4.0",
|
"@tauri-apps/plugin-dialog": "^2.4.0",
|
||||||
"@tauri-apps/plugin-fs": "^2.4.2",
|
"@tauri-apps/plugin-fs": "^2.4.2",
|
||||||
"@tauri-apps/plugin-notification": "^2.3.1",
|
|
||||||
"@tauri-apps/plugin-process": "^2.3.0",
|
"@tauri-apps/plugin-process": "^2.3.0",
|
||||||
"@tauri-apps/plugin-shell": "2.3.1",
|
"@tauri-apps/plugin-shell": "2.3.1",
|
||||||
"@tauri-apps/plugin-updater": "2.9.0",
|
"@tauri-apps/plugin-updater": "2.9.0",
|
||||||
"@types/json-schema": "^7.0.15",
|
"@types/json-schema": "^7.0.15",
|
||||||
"ahooks": "^3.9.5",
|
"ahooks": "^3.9.5",
|
||||||
"axios": "^1.12.2",
|
"axios": "^1.12.2",
|
||||||
"cli-color": "^2.0.4",
|
|
||||||
"dayjs": "1.11.18",
|
"dayjs": "1.11.18",
|
||||||
"foxact": "^0.2.49",
|
"foxact": "^0.2.49",
|
||||||
"glob": "^11.0.3",
|
|
||||||
"i18next": "^25.5.2",
|
"i18next": "^25.5.2",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"json-schema": "^0.4.0",
|
"json-schema": "^0.4.0",
|
||||||
@@ -70,13 +67,14 @@
|
|||||||
"react-monaco-editor": "0.59.0",
|
"react-monaco-editor": "0.59.0",
|
||||||
"react-router-dom": "7.9.1",
|
"react-router-dom": "7.9.1",
|
||||||
"react-virtuoso": "^4.14.0",
|
"react-virtuoso": "^4.14.0",
|
||||||
"sockette": "^2.0.6",
|
|
||||||
"swr": "^2.3.6",
|
"swr": "^2.3.6",
|
||||||
"tar": "^7.4.3",
|
|
||||||
"types-pac": "^1.0.3",
|
"types-pac": "^1.0.3",
|
||||||
"zustand": "^5.0.8"
|
"zustand": "^5.0.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"tar": "^7.4.3",
|
||||||
|
"glob": "^11.0.3",
|
||||||
|
"cli-color": "^2.0.4",
|
||||||
"@actions/github": "^6.0.1",
|
"@actions/github": "^6.0.1",
|
||||||
"@eslint/js": "^9.35.0",
|
"@eslint/js": "^9.35.0",
|
||||||
"@tauri-apps/cli": "2.8.4",
|
"@tauri-apps/cli": "2.8.4",
|
||||||
@@ -96,9 +94,7 @@
|
|||||||
"jiti": "^2.5.1",
|
"jiti": "^2.5.1",
|
||||||
"meta-json-schema": "^1.19.13",
|
"meta-json-schema": "^1.19.13",
|
||||||
"node-fetch": "^3.3.2",
|
"node-fetch": "^3.3.2",
|
||||||
"path": "^0.12.7",
|
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"process": "^0.11.10",
|
|
||||||
"sass": "^1.92.1",
|
"sass": "^1.92.1",
|
||||||
"terser": "^5.44.0",
|
"terser": "^5.44.0",
|
||||||
"typescript": "^5.9.2",
|
"typescript": "^5.9.2",
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import { AppDataProvider } from "./providers/app-data-provider";
|
import { AppDataProvider } from "./providers/app-data-provider";
|
||||||
import Layout from "./pages/_layout";
|
import Layout from "./pages/_layout";
|
||||||
import { useNotificationPermission } from "./hooks/useNotificationPermission";
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
useNotificationPermission();
|
|
||||||
return (
|
return (
|
||||||
<AppDataProvider>
|
<AppDataProvider>
|
||||||
<Layout />
|
<Layout />
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Box, CircularProgress } from "@mui/material";
|
import { Box, CircularProgress } from "@mui/material";
|
||||||
|
|
||||||
export interface BaseLoadingOverlayProps {
|
interface BaseLoadingOverlayProps {
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,5 +29,3 @@ export const BaseLoadingOverlay: React.FC<BaseLoadingOverlayProps> = ({
|
|||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BaseLoadingOverlay;
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ interface ProxyOption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 排序类型: 默认 | 按延迟 | 按字母
|
// 排序类型: 默认 | 按延迟 | 按字母
|
||||||
export type ProxySortType = 0 | 1 | 2;
|
type ProxySortType = 0 | 1 | 2;
|
||||||
|
|
||||||
function convertDelayColor(delayValue: number) {
|
function convertDelayColor(delayValue: number) {
|
||||||
const colorStr = delayManager.formatDelayColor(delayValue);
|
const colorStr = delayManager.formatDelayColor(delayValue);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
} from "@/hooks/use-traffic-monitor";
|
} from "@/hooks/use-traffic-monitor";
|
||||||
|
|
||||||
// 流量数据项接口
|
// 流量数据项接口
|
||||||
export interface ITrafficItem {
|
interface ITrafficItem {
|
||||||
up: number;
|
up: number;
|
||||||
down: number;
|
down: number;
|
||||||
timestamp?: number;
|
timestamp?: number;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Box, Typography, alpha, useTheme } from "@mui/material";
|
|||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
// 自定义卡片组件接口
|
// 自定义卡片组件接口
|
||||||
export interface EnhancedCardProps {
|
interface EnhancedCardProps {
|
||||||
title: ReactNode;
|
title: ReactNode;
|
||||||
icon: ReactNode;
|
icon: ReactNode;
|
||||||
action?: ReactNode;
|
action?: ReactNode;
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ interface ProfileExtra {
|
|||||||
expire: number;
|
expire: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProfileItem {
|
interface ProfileItem {
|
||||||
uid: string;
|
uid: string;
|
||||||
type?: "local" | "remote" | "merge" | "script";
|
type?: "local" | "remote" | "merge" | "script";
|
||||||
name?: string;
|
name?: string;
|
||||||
@@ -68,7 +68,7 @@ export interface ProfileItem {
|
|||||||
option?: any;
|
option?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HomeProfileCardProps {
|
interface HomeProfileCardProps {
|
||||||
current: ProfileItem | null | undefined;
|
current: ProfileItem | null | undefined;
|
||||||
onProfileUpdated?: () => void;
|
onProfileUpdated?: () => void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import VisibilityOff from "@mui/icons-material/VisibilityOff";
|
|||||||
import { saveWebdavConfig, createWebdavBackup } from "@/services/cmds";
|
import { saveWebdavConfig, createWebdavBackup } from "@/services/cmds";
|
||||||
import { showNotice } from "@/services/noticeService";
|
import { showNotice } from "@/services/noticeService";
|
||||||
|
|
||||||
export interface BackupConfigViewerProps {
|
interface BackupConfigViewerProps {
|
||||||
onBackupSuccess: () => Promise<void>;
|
onBackupSuccess: () => Promise<void>;
|
||||||
onSaveSuccess: () => Promise<void>;
|
onSaveSuccess: () => Promise<void>;
|
||||||
onRefresh: () => Promise<void>;
|
onRefresh: () => Promise<void>;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export type BackupFile = IWebDavFile & {
|
|||||||
|
|
||||||
export const DEFAULT_ROWS_PER_PAGE = 5;
|
export const DEFAULT_ROWS_PER_PAGE = 5;
|
||||||
|
|
||||||
export interface BackupTableViewerProps {
|
interface BackupTableViewerProps {
|
||||||
datasource: BackupFile[];
|
datasource: BackupFile[];
|
||||||
page: number;
|
page: number;
|
||||||
onPageChange: (
|
onPageChange: (
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ import {
|
|||||||
useGlobalLogData,
|
useGlobalLogData,
|
||||||
clearGlobalLogs,
|
clearGlobalLogs,
|
||||||
LogLevel,
|
LogLevel,
|
||||||
ILogItem,
|
|
||||||
} from "@/services/global-log-service";
|
} from "@/services/global-log-service";
|
||||||
|
|
||||||
// 为了向后兼容,导出相同的类型
|
// 为了向后兼容,导出相同的类型
|
||||||
export type { LogLevel };
|
export type { LogLevel };
|
||||||
export type { ILogItem };
|
|
||||||
|
|
||||||
export const useLogData = useGlobalLogData;
|
export const useLogData = useGlobalLogData;
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const cleanupConnections = async (previousProxy: string) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ProxySelectionOptions {
|
interface ProxySelectionOptions {
|
||||||
onSuccess?: () => void;
|
onSuccess?: () => void;
|
||||||
onError?: (error: any) => void;
|
onError?: (error: any) => void;
|
||||||
enableConnectionCleanup?: boolean;
|
enableConnectionCleanup?: boolean;
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
import { setupNotificationPermission } from "../utils/notification-permission";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
|
|
||||||
export function useNotificationPermission() {
|
|
||||||
useEffect(() => {
|
|
||||||
setupNotificationPermission();
|
|
||||||
}, []);
|
|
||||||
}
|
|
||||||
@@ -201,7 +201,7 @@ const HomeSettingsDialog = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const HomePage = () => {
|
const HomePage = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { verge } = useVerge();
|
const { verge } = useVerge();
|
||||||
const { current, mutateProfiles } = useProfiles();
|
const { current, mutateProfiles } = useProfiles();
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const MAX_LOG_NUM = 1000;
|
|||||||
|
|
||||||
export type LogLevel = "debug" | "info" | "warning" | "error" | "all";
|
export type LogLevel = "debug" | "info" | "warning" | "error" | "all";
|
||||||
|
|
||||||
export interface ILogItem {
|
interface ILogItem {
|
||||||
time?: string;
|
time?: string;
|
||||||
type: string;
|
type: string;
|
||||||
payload: string;
|
payload: string;
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import {
|
|||||||
} from "@/services/cmds";
|
} from "@/services/cmds";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
export type LogLevel = "debug" | "info" | "warning" | "error" | "all";
|
type LogLevel = "debug" | "info" | "warning" | "error" | "all";
|
||||||
|
|
||||||
export interface ILogItem {
|
interface ILogItem {
|
||||||
time?: string;
|
time?: string;
|
||||||
type: string;
|
type: string;
|
||||||
payload: string;
|
payload: string;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
|
|
||||||
export interface NoticeItem {
|
interface NoticeItem {
|
||||||
id: number;
|
id: number;
|
||||||
type: "success" | "error" | "info";
|
type: "success" | "error" | "info";
|
||||||
message: ReactNode;
|
message: ReactNode;
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
import {
|
|
||||||
isPermissionGranted,
|
|
||||||
requestPermission,
|
|
||||||
} from "@tauri-apps/plugin-notification";
|
|
||||||
|
|
||||||
export async function setupNotificationPermission() {
|
|
||||||
let permission = await isPermissionGranted();
|
|
||||||
if (!permission) {
|
|
||||||
const result = await requestPermission();
|
|
||||||
permission = result === "granted";
|
|
||||||
}
|
|
||||||
if (permission) {
|
|
||||||
console.log("通知权限已授予");
|
|
||||||
} else {
|
|
||||||
console.log("通知权限被拒绝");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,262 +0,0 @@
|
|||||||
import Sockette, { type SocketteOptions } from "sockette";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A wrapper of Sockette that will automatically reconnect up to `maxError` before emitting an error event.
|
|
||||||
*/
|
|
||||||
export const createSockette = (
|
|
||||||
url: string,
|
|
||||||
opt: SocketteOptions,
|
|
||||||
maxError = 10,
|
|
||||||
) => {
|
|
||||||
let remainRetryCount = maxError;
|
|
||||||
|
|
||||||
return new Sockette(url, {
|
|
||||||
...opt,
|
|
||||||
// Sockette has a built-in reconnect when ECONNREFUSED feature
|
|
||||||
// Use maxError if opt.maxAttempts is not specified
|
|
||||||
maxAttempts: opt.maxAttempts ?? maxError,
|
|
||||||
onmessage(this: Sockette, ev) {
|
|
||||||
remainRetryCount = maxError; // reset counter
|
|
||||||
opt.onmessage?.call(this, ev);
|
|
||||||
},
|
|
||||||
onerror(this: Sockette, ev) {
|
|
||||||
remainRetryCount -= 1;
|
|
||||||
|
|
||||||
if (remainRetryCount >= 0) {
|
|
||||||
if (this instanceof Sockette) {
|
|
||||||
this.close();
|
|
||||||
this.reconnect();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
opt.onerror?.call(this, ev);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onmaximum(this: Sockette, ev) {
|
|
||||||
opt.onmaximum?.call(this, ev);
|
|
||||||
// onmaximum will be fired when Sockette reaches built-in reconnect limit,
|
|
||||||
// We will also set remainRetryCount to 0 to prevent further reconnect.
|
|
||||||
remainRetryCount = 0;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建一个支持认证的WebSocket连接
|
|
||||||
* 使用标准的URL参数方式添加token
|
|
||||||
*
|
|
||||||
* 注意:mihomo服务器对WebSocket的认证支持不佳,使用URL参数方式传递token
|
|
||||||
*/
|
|
||||||
export const createAuthSockette = (
|
|
||||||
baseUrl: string,
|
|
||||||
secret: string,
|
|
||||||
opt: SocketteOptions,
|
|
||||||
maxError = 10,
|
|
||||||
) => {
|
|
||||||
// 确保baseUrl格式正确
|
|
||||||
let url = baseUrl;
|
|
||||||
if (!url.startsWith("ws://") && !url.startsWith("wss://")) {
|
|
||||||
url = `ws://${url}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重试控制
|
|
||||||
let reconnectAttempts = 0;
|
|
||||||
const MAX_RECONNECT = maxError;
|
|
||||||
let reconnectTimeout: any = null;
|
|
||||||
let ws: WebSocket | null = null;
|
|
||||||
|
|
||||||
// 使用URL API解析和构建URL
|
|
||||||
try {
|
|
||||||
const urlObj = new URL(url);
|
|
||||||
|
|
||||||
// 添加token参数(如果有secret)
|
|
||||||
if (secret) {
|
|
||||||
urlObj.searchParams.delete("token");
|
|
||||||
urlObj.searchParams.append("token", secret);
|
|
||||||
}
|
|
||||||
|
|
||||||
url = urlObj.toString();
|
|
||||||
console.log(`[WebSocket] 创建连接: ${url.replace(secret || "", "***")}`);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`[WebSocket] URL格式错误: ${url}`, e);
|
|
||||||
if (opt.onerror) {
|
|
||||||
// 使用任意类型避免类型错误
|
|
||||||
const anyOpt = opt as any;
|
|
||||||
anyOpt.onerror(
|
|
||||||
new ErrorEvent("error", { message: `URL格式错误: ${e}` } as any),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return createDummySocket();
|
|
||||||
}
|
|
||||||
|
|
||||||
function connect() {
|
|
||||||
try {
|
|
||||||
ws = new WebSocket(url);
|
|
||||||
|
|
||||||
ws.onopen = function (event) {
|
|
||||||
console.log(
|
|
||||||
`[WebSocket] 连接成功: ${url.replace(secret || "", "***")}`,
|
|
||||||
);
|
|
||||||
reconnectAttempts = 0; // 重置重连计数
|
|
||||||
if (opt.onopen) {
|
|
||||||
// 使用任意类型避免类型错误
|
|
||||||
const anyOpt = opt as any;
|
|
||||||
anyOpt.onopen(event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onmessage = function (event) {
|
|
||||||
if (opt.onmessage) {
|
|
||||||
// 使用任意类型避免类型错误
|
|
||||||
const anyOpt = opt as any;
|
|
||||||
anyOpt.onmessage(event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onerror = function (event) {
|
|
||||||
console.error(
|
|
||||||
`[WebSocket] 连接错误: ${url.replace(secret || "", "***")}`,
|
|
||||||
);
|
|
||||||
// 错误处理
|
|
||||||
if (reconnectAttempts < MAX_RECONNECT) {
|
|
||||||
scheduleReconnect();
|
|
||||||
} else if (opt.onerror) {
|
|
||||||
// 使用任意类型避免类型错误
|
|
||||||
const anyOpt = opt as any;
|
|
||||||
anyOpt.onerror(event);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onclose = function (event) {
|
|
||||||
console.log(
|
|
||||||
`[WebSocket] 连接关闭: ${url.replace(secret || "", "***")}, 代码: ${event.code}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
// 如果不是正常关闭(1000, 1001),尝试重连
|
|
||||||
if (
|
|
||||||
event.code !== 1000 &&
|
|
||||||
event.code !== 1001 &&
|
|
||||||
reconnectAttempts < MAX_RECONNECT
|
|
||||||
) {
|
|
||||||
scheduleReconnect();
|
|
||||||
} else {
|
|
||||||
if (opt.onclose) {
|
|
||||||
// 使用任意类型避免类型错误
|
|
||||||
const anyOpt = opt as any;
|
|
||||||
anyOpt.onclose(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果已达到最大重试次数
|
|
||||||
if (reconnectAttempts >= MAX_RECONNECT && opt.onmaximum) {
|
|
||||||
console.error(
|
|
||||||
`[WebSocket] 达到最大重试次数: ${url.replace(secret || "", "***")}`,
|
|
||||||
);
|
|
||||||
const anyOpt = opt as any;
|
|
||||||
anyOpt.onmaximum(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`[WebSocket] 创建连接失败:`, error);
|
|
||||||
if (opt.onerror) {
|
|
||||||
// 使用任意类型避免类型错误
|
|
||||||
const anyOpt = opt as any;
|
|
||||||
anyOpt.onerror(
|
|
||||||
new ErrorEvent("error", { message: `创建连接失败: ${error}` } as any),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function scheduleReconnect() {
|
|
||||||
if (reconnectTimeout) {
|
|
||||||
clearTimeout(reconnectTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
reconnectAttempts++;
|
|
||||||
const delay = Math.min(1000 * Math.pow(1.5, reconnectAttempts), 10000); // 指数退避,最大10秒
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`[WebSocket] 计划重连 (${reconnectAttempts}/${MAX_RECONNECT}) 延迟: ${delay}ms`,
|
|
||||||
);
|
|
||||||
|
|
||||||
reconnectTimeout = setTimeout(() => {
|
|
||||||
console.log(
|
|
||||||
`[WebSocket] 尝试重连 (${reconnectAttempts}/${MAX_RECONNECT})`,
|
|
||||||
);
|
|
||||||
cleanup();
|
|
||||||
connect();
|
|
||||||
}, delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
function cleanup() {
|
|
||||||
if (ws) {
|
|
||||||
// 移除所有事件监听器
|
|
||||||
ws.onopen = null;
|
|
||||||
ws.onmessage = null;
|
|
||||||
ws.onerror = null;
|
|
||||||
ws.onclose = null;
|
|
||||||
|
|
||||||
// 如果连接仍然打开,关闭它
|
|
||||||
if (
|
|
||||||
ws.readyState === WebSocket.OPEN ||
|
|
||||||
ws.readyState === WebSocket.CONNECTING
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
ws.close();
|
|
||||||
} catch (e) {
|
|
||||||
console.error("[WebSocket] 关闭连接时出错:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ws = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 清除重连计时器
|
|
||||||
if (reconnectTimeout) {
|
|
||||||
clearTimeout(reconnectTimeout);
|
|
||||||
reconnectTimeout = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建一个类似Sockette的接口对象
|
|
||||||
const socketLike = {
|
|
||||||
ws,
|
|
||||||
close: () => {
|
|
||||||
console.log(
|
|
||||||
`[WebSocket] 手动关闭连接: ${url.replace(secret || "", "***")}`,
|
|
||||||
);
|
|
||||||
cleanup();
|
|
||||||
},
|
|
||||||
reconnect: () => {
|
|
||||||
cleanup();
|
|
||||||
connect();
|
|
||||||
},
|
|
||||||
json: (data: any) => {
|
|
||||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
||||||
ws.send(JSON.stringify(data));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
send: (data: string) => {
|
|
||||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
||||||
ws.send(data);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
open: connect,
|
|
||||||
};
|
|
||||||
|
|
||||||
// 立即连接
|
|
||||||
connect();
|
|
||||||
|
|
||||||
return socketLike;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 创建一个空的WebSocket对象
|
|
||||||
function createDummySocket() {
|
|
||||||
return {
|
|
||||||
close: () => {},
|
|
||||||
reconnect: () => {},
|
|
||||||
json: () => {},
|
|
||||||
send: () => {},
|
|
||||||
open: () => {},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -112,7 +112,6 @@ export default defineConfig({
|
|||||||
id.includes("@tauri-apps/plugin-dialog") ||
|
id.includes("@tauri-apps/plugin-dialog") ||
|
||||||
id.includes("@tauri-apps/plugin-fs") ||
|
id.includes("@tauri-apps/plugin-fs") ||
|
||||||
id.includes("@tauri-apps/plugin-global-shortcut") ||
|
id.includes("@tauri-apps/plugin-global-shortcut") ||
|
||||||
id.includes("@tauri-apps/plugin-notification") ||
|
|
||||||
id.includes("@tauri-apps/plugin-process") ||
|
id.includes("@tauri-apps/plugin-process") ||
|
||||||
id.includes("@tauri-apps/plugin-shell") ||
|
id.includes("@tauri-apps/plugin-shell") ||
|
||||||
id.includes("@tauri-apps/plugin-updater")
|
id.includes("@tauri-apps/plugin-updater")
|
||||||
|
|||||||
Reference in New Issue
Block a user