优化细节
This commit is contained in:
parent
e1a890a400
commit
a26f1c5014
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "scriptcat",
|
"name": "scriptcat",
|
||||||
"version": "0.17.0-alpha.2",
|
"version": "0.17.0-alpha.4",
|
||||||
"description": "脚本猫,一个可以执行用户脚本的浏览器扩展,万物皆可脚本化,让你的浏览器可以做更多的事情!",
|
"description": "脚本猫,一个可以执行用户脚本的浏览器扩展,万物皆可脚本化,让你的浏览器可以做更多的事情!",
|
||||||
"author": "CodFrm",
|
"author": "CodFrm",
|
||||||
"license": "GPLv3",
|
"license": "GPLv3",
|
||||||
|
@ -113,7 +113,6 @@ function renameField() {
|
|||||||
if (subscribe.length) {
|
if (subscribe.length) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
subscribe.map((s: Subscribe) => {
|
subscribe.map((s: Subscribe) => {
|
||||||
console.log("1234", s);
|
|
||||||
const { url, name, code, author, scripts, metadata, status, createtime, updatetime, checktime } = s;
|
const { url, name, code, author, scripts, metadata, status, createtime, updatetime, checktime } = s;
|
||||||
return subscribeDAO.save({
|
return subscribeDAO.save({
|
||||||
url,
|
url,
|
||||||
|
@ -23,6 +23,7 @@ export default class ContentRuntime {
|
|||||||
// 转发给inject
|
// 转发给inject
|
||||||
return sendMessage(this.msg, "inject/runtime/valueUpdate", data);
|
return sendMessage(this.msg, "inject/runtime/valueUpdate", data);
|
||||||
});
|
});
|
||||||
|
forwardMessage("serviceWorker", "script/isInstalled", this.server, this.extSend);
|
||||||
forwardMessage(
|
forwardMessage(
|
||||||
"serviceWorker",
|
"serviceWorker",
|
||||||
"runtime/gmApi",
|
"runtime/gmApi",
|
||||||
|
@ -4,6 +4,8 @@ import ExecScript, { ValueUpdateData } from "./exec_script";
|
|||||||
import { addStyle, ScriptFunc } from "./utils";
|
import { addStyle, ScriptFunc } from "./utils";
|
||||||
import { getStorageName } from "@App/pkg/utils/utils";
|
import { getStorageName } from "@App/pkg/utils/utils";
|
||||||
import { EmitEventRequest } from "../service_worker/runtime";
|
import { EmitEventRequest } from "../service_worker/runtime";
|
||||||
|
import { ExternalWhitelist } from "@App/app/const";
|
||||||
|
import { sendMessage } from "@Packages/message/client";
|
||||||
|
|
||||||
export class InjectRuntime {
|
export class InjectRuntime {
|
||||||
execList: ExecScript[] = [];
|
execList: ExecScript[] = [];
|
||||||
@ -44,6 +46,40 @@ export class InjectRuntime {
|
|||||||
val.valueUpdate(data);
|
val.valueUpdate(data);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// 注入允许外部调用
|
||||||
|
this.externalMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
externalMessage() {
|
||||||
|
// 对外接口白名单
|
||||||
|
let msg = this.msg;
|
||||||
|
for (let i = 0; i < ExternalWhitelist.length; i += 1) {
|
||||||
|
if (window.location.host.endsWith(ExternalWhitelist[i])) {
|
||||||
|
// 注入
|
||||||
|
(<{ external: any }>(<unknown>window)).external = window.external || {};
|
||||||
|
(<
|
||||||
|
{
|
||||||
|
external: {
|
||||||
|
Scriptcat: {
|
||||||
|
isInstalled: (name: string, namespace: string, callback: any) => void;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
>(<unknown>window)).external.Scriptcat = {
|
||||||
|
async isInstalled(name: string, namespace: string, callback: any) {
|
||||||
|
const resp = await sendMessage(msg, "content/script/isInstalled", {
|
||||||
|
name,
|
||||||
|
namespace,
|
||||||
|
});
|
||||||
|
callback(resp);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(<{ external: { Tampermonkey: any } }>(<unknown>window)).external.Tampermonkey = (<
|
||||||
|
{ external: { Scriptcat: any } }
|
||||||
|
>(<unknown>window)).external.Scriptcat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
execScript(script: ScriptRunResouce, scriptFunc: ScriptFunc) {
|
execScript(script: ScriptRunResouce, scriptFunc: ScriptFunc) {
|
||||||
|
@ -9,6 +9,8 @@ import { PopupService } from "./popup";
|
|||||||
import { SystemConfig } from "@App/pkg/config/config";
|
import { SystemConfig } from "@App/pkg/config/config";
|
||||||
import { SynchronizeService } from "./synchronize";
|
import { SynchronizeService } from "./synchronize";
|
||||||
import { SubscribeService } from "./subscribe";
|
import { SubscribeService } from "./subscribe";
|
||||||
|
import { ExtServer, ExtVersion } from "@App/app/const";
|
||||||
|
import { systemConfig } from "@App/pages/store/global";
|
||||||
|
|
||||||
export type InstallSource = "user" | "system" | "sync" | "subscribe" | "vscode";
|
export type InstallSource = "user" | "system" | "sync" | "subscribe" | "vscode";
|
||||||
|
|
||||||
@ -78,8 +80,17 @@ export default class ServiceWorkerManager {
|
|||||||
case "checkSubscribeUpdate":
|
case "checkSubscribeUpdate":
|
||||||
subscribe.checkSubscribeUpdate();
|
subscribe.checkSubscribeUpdate();
|
||||||
break;
|
break;
|
||||||
|
case "checkUpdate":
|
||||||
|
// 检查扩展更新
|
||||||
|
this.checkUpdate();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// 8小时检查一次扩展更新
|
||||||
|
chrome.alarms.create("checkUpdate", {
|
||||||
|
delayInMinutes: 0,
|
||||||
|
periodInMinutes: 8 * 60,
|
||||||
|
});
|
||||||
|
|
||||||
// 监听配置变化
|
// 监听配置变化
|
||||||
this.mq.subscribe("systemConfigChange", (msg) => {
|
this.mq.subscribe("systemConfigChange", (msg) => {
|
||||||
@ -96,4 +107,18 @@ export default class ServiceWorkerManager {
|
|||||||
synchronize.cloudSyncConfigChange(config);
|
synchronize.cloudSyncConfigChange(config);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkUpdate() {
|
||||||
|
fetch(`${ExtServer}api/v1/system/version?version=${ExtVersion}`)
|
||||||
|
.then((resp) => resp.json())
|
||||||
|
.then((resp: { data: { notice: string; version: string } }) => {
|
||||||
|
systemConfig.getCheckUpdate().then((items) => {
|
||||||
|
if (items.notice !== resp.data.notice) {
|
||||||
|
systemConfig.setCheckUpdate(Object.assign(resp.data, { isRead: false }));
|
||||||
|
} else {
|
||||||
|
systemConfig.setCheckUpdate(Object.assign(resp.data, { isRead: items.isRead }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import { subscribeScriptDelete, subscribeScriptEnable, subscribeScriptInstall }
|
|||||||
import { ScriptService } from "./script";
|
import { ScriptService } from "./script";
|
||||||
import { runScript, stopScript } from "../offscreen/client";
|
import { runScript, stopScript } from "../offscreen/client";
|
||||||
import { getRunAt } from "./utils";
|
import { getRunAt } from "./utils";
|
||||||
import { randomString } from "@App/pkg/utils/utils";
|
import { isUserScriptsAvailable, randomString } from "@App/pkg/utils/utils";
|
||||||
import Cache from "@App/app/cache";
|
import Cache from "@App/app/cache";
|
||||||
import { dealPatternMatches, UrlMatch } from "@App/pkg/utils/match";
|
import { dealPatternMatches, UrlMatch } from "@App/pkg/utils/match";
|
||||||
import { ExtensionContentMessageSend } from "@Packages/message/extension_message";
|
import { ExtensionContentMessageSend } from "@Packages/message/extension_message";
|
||||||
@ -70,6 +70,11 @@ export class RuntimeService {
|
|||||||
this.group.on("runScript", this.runScript.bind(this));
|
this.group.on("runScript", this.runScript.bind(this));
|
||||||
this.group.on("pageLoad", this.pageLoad.bind(this));
|
this.group.on("pageLoad", this.pageLoad.bind(this));
|
||||||
|
|
||||||
|
// 检查是否开启了开发者模式
|
||||||
|
if(!isUserScriptsAvailable()){
|
||||||
|
// 未开启加上警告引导
|
||||||
|
|
||||||
|
}
|
||||||
// 读取inject.js注入页面
|
// 读取inject.js注入页面
|
||||||
this.registerInjectScript();
|
this.registerInjectScript();
|
||||||
// 监听脚本开启
|
// 监听脚本开启
|
||||||
|
@ -21,6 +21,7 @@ import { ResourceService } from "./resource";
|
|||||||
import { ValueService } from "./value";
|
import { ValueService } from "./value";
|
||||||
import { compileScriptCode } from "../content/utils";
|
import { compileScriptCode } from "../content/utils";
|
||||||
import { SystemConfig } from "@App/pkg/config/config";
|
import { SystemConfig } from "@App/pkg/config/config";
|
||||||
|
import i18n from "@App/locales/locales";
|
||||||
|
|
||||||
export class ScriptService {
|
export class ScriptService {
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
@ -59,50 +60,59 @@ export class ScriptService {
|
|||||||
// 读取脚本url内容, 进行安装
|
// 读取脚本url内容, 进行安装
|
||||||
const logger = this.logger.with({ url: targetUrl });
|
const logger = this.logger.with({ url: targetUrl });
|
||||||
logger.debug("install script");
|
logger.debug("install script");
|
||||||
this.openInstallPageByUrl(targetUrl, "user").catch((e) => {
|
this.openInstallPageByUrl(targetUrl, "user")
|
||||||
logger.error("install script error", Logger.E(e));
|
.catch((e) => {
|
||||||
// 如果打开失败, 则重定向到安装页
|
logger.error("install script error", Logger.E(e));
|
||||||
chrome.scripting.executeScript({
|
// 不再重定向当前url
|
||||||
target: { tabId: req.tabId },
|
chrome.declarativeNetRequest.updateDynamicRules(
|
||||||
func: function () {
|
{
|
||||||
history.back();
|
removeRuleIds: [2],
|
||||||
},
|
addRules: [
|
||||||
});
|
{
|
||||||
// 并不再重定向当前url
|
id: 2,
|
||||||
chrome.declarativeNetRequest.updateDynamicRules(
|
priority: 1,
|
||||||
{
|
action: {
|
||||||
removeRuleIds: [2],
|
type: chrome.declarativeNetRequest.RuleActionType.ALLOW,
|
||||||
addRules: [
|
},
|
||||||
{
|
condition: {
|
||||||
id: 2,
|
regexFilter: targetUrl,
|
||||||
priority: 1,
|
resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME],
|
||||||
action: {
|
requestMethods: [chrome.declarativeNetRequest.RequestMethod.GET],
|
||||||
type: chrome.declarativeNetRequest.RuleActionType.ALLOW,
|
},
|
||||||
},
|
},
|
||||||
condition: {
|
],
|
||||||
regexFilter: targetUrl,
|
},
|
||||||
resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME],
|
() => {
|
||||||
requestMethods: [chrome.declarativeNetRequest.RequestMethod.GET],
|
if (chrome.runtime.lastError) {
|
||||||
},
|
console.error(chrome.runtime.lastError);
|
||||||
},
|
}
|
||||||
],
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
if (chrome.runtime.lastError) {
|
|
||||||
console.error(chrome.runtime.lastError);
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
);
|
})
|
||||||
});
|
.finally(() => {
|
||||||
|
// 回退到到安装页
|
||||||
|
chrome.scripting.executeScript({
|
||||||
|
target: { tabId: req.tabId },
|
||||||
|
func: function () {
|
||||||
|
history.back();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
urls: [
|
urls: [
|
||||||
"https://docs.scriptcat.org/docs/script_installation",
|
"https://docs.scriptcat.org/docs/script_installation/",
|
||||||
|
"https://docs.scriptcat.org/en/docs/script_installation/",
|
||||||
"https://www.tampermonkey.net/script_installation.php",
|
"https://www.tampermonkey.net/script_installation.php",
|
||||||
],
|
],
|
||||||
types: ["main_frame"],
|
types: ["main_frame"],
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
// 获取i18n
|
||||||
|
let localePath = "";
|
||||||
|
if (i18n.language !== "zh-CN") {
|
||||||
|
localePath = `/en`;
|
||||||
|
}
|
||||||
// 重定向到脚本安装页
|
// 重定向到脚本安装页
|
||||||
chrome.declarativeNetRequest.updateDynamicRules(
|
chrome.declarativeNetRequest.updateDynamicRules(
|
||||||
{
|
{
|
||||||
@ -114,7 +124,7 @@ export class ScriptService {
|
|||||||
action: {
|
action: {
|
||||||
type: chrome.declarativeNetRequest.RuleActionType.REDIRECT,
|
type: chrome.declarativeNetRequest.RuleActionType.REDIRECT,
|
||||||
redirect: {
|
redirect: {
|
||||||
regexSubstitution: "https://docs.scriptcat.org/docs/script_installation#url=\\0",
|
regexSubstitution: `https://docs.scriptcat.org${localePath}/docs/script_installation/#url=\\0`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
condition: {
|
condition: {
|
||||||
@ -479,6 +489,15 @@ export class ScriptService {
|
|||||||
return this.checkUpdate(uuid, "user");
|
return this.checkUpdate(uuid, "user");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isInstalled({ name, namespace }: { name: string; namespace: string }) {
|
||||||
|
return this.scriptDAO.findByNameAndNamespace(name, namespace).then((script) => {
|
||||||
|
if (script) {
|
||||||
|
return { installed: true, version: script.metadata.version && script.metadata.version[0] };
|
||||||
|
}
|
||||||
|
return { installed: false };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.listenerScriptInstall();
|
this.listenerScriptInstall();
|
||||||
|
|
||||||
@ -494,6 +513,7 @@ export class ScriptService {
|
|||||||
this.group.on("resetMatch", this.resetMatch.bind(this));
|
this.group.on("resetMatch", this.resetMatch.bind(this));
|
||||||
this.group.on("resetExclude", this.resetExclude.bind(this));
|
this.group.on("resetExclude", this.resetExclude.bind(this));
|
||||||
this.group.on("requestCheckUpdate", this.requestCheckUpdate.bind(this));
|
this.group.on("requestCheckUpdate", this.requestCheckUpdate.bind(this));
|
||||||
|
this.group.on("isInstalled", this.isInstalled.bind(this));
|
||||||
|
|
||||||
// 定时检查更新, 每10分钟检查一次
|
// 定时检查更新, 每10分钟检查一次
|
||||||
chrome.alarms.create("checkScriptUpdate", {
|
chrome.alarms.create("checkScriptUpdate", {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "__MSG_scriptcat__",
|
"name": "__MSG_scriptcat__",
|
||||||
"version": "0.17.0.1003",
|
"version": "0.17.0.1005",
|
||||||
"author": "CodFrm",
|
"author": "CodFrm",
|
||||||
"description": "__MSG_scriptcat_description__",
|
"description": "__MSG_scriptcat_description__",
|
||||||
"options_ui": {
|
"options_ui": {
|
||||||
|
@ -39,11 +39,9 @@ const CodeEditor: React.ForwardRefRenderFunction<{ editor: editor.IStandaloneCod
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("1231", code);
|
|
||||||
if (diffCode === undefined || code === undefined || !div.current) {
|
if (diffCode === undefined || code === undefined || !div.current) {
|
||||||
return () => {};
|
return () => {};
|
||||||
}
|
}
|
||||||
console.log("1232");
|
|
||||||
let edit: editor.IStandaloneDiffEditor | editor.IStandaloneCodeEditor;
|
let edit: editor.IStandaloneDiffEditor | editor.IStandaloneCodeEditor;
|
||||||
const inlineDiv = document.getElementById(id) as HTMLDivElement;
|
const inlineDiv = document.getElementById(id) as HTMLDivElement;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Script, ScriptAndCode, ScriptCodeDAO, ScriptDAO } from "@App/app/repo/scripts";
|
import { Script, SCRIPT_TYPE_NORMAL, ScriptAndCode, ScriptCodeDAO, ScriptDAO } from "@App/app/repo/scripts";
|
||||||
import CodeEditor from "@App/pages/components/CodeEditor";
|
import CodeEditor from "@App/pages/components/CodeEditor";
|
||||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
|
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
|
||||||
@ -16,7 +16,7 @@ import { prepareScriptByCode } from "@App/pkg/utils/script";
|
|||||||
import ScriptStorage from "@App/pages/components/ScriptStorage";
|
import ScriptStorage from "@App/pages/components/ScriptStorage";
|
||||||
import ScriptResource from "@App/pages/components/ScriptResource";
|
import ScriptResource from "@App/pages/components/ScriptResource";
|
||||||
import ScriptSetting from "@App/pages/components/ScriptSetting";
|
import ScriptSetting from "@App/pages/components/ScriptSetting";
|
||||||
import { scriptClient } from "@App/pages/store/features/script";
|
import { runtimeClient, scriptClient } from "@App/pages/store/features/script";
|
||||||
import { i18nName } from "@App/locales/locales";
|
import { i18nName } from "@App/locales/locales";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
@ -188,57 +188,58 @@ function ScriptEditor() {
|
|||||||
|
|
||||||
const save = (script: Script, e: editor.IStandaloneCodeEditor): Promise<Script> => {
|
const save = (script: Script, e: editor.IStandaloneCodeEditor): Promise<Script> => {
|
||||||
// 解析code生成新的script并更新
|
// 解析code生成新的script并更新
|
||||||
return new Promise(() => {
|
return prepareScriptByCode(e.getValue(), script.origin || "", script.uuid)
|
||||||
prepareScriptByCode(e.getValue(), script.origin || "", script.uuid)
|
.then((prepareScript) => {
|
||||||
.then((prepareScript) => {
|
const newScript = prepareScript.script;
|
||||||
const newScript = prepareScript.script;
|
if (!newScript.name) {
|
||||||
if (!newScript.name) {
|
Message.warning(t("script_name_cannot_be_set_to_empty"));
|
||||||
Message.warning(t("script_name_cannot_be_set_to_empty"));
|
return Promise.reject(new Error("script name cannot be empty"));
|
||||||
return;
|
}
|
||||||
}
|
return scriptClient
|
||||||
scriptClient.install(newScript, e.getValue()).then(
|
.install(newScript, e.getValue())
|
||||||
(update) => {
|
.then((update): Script => {
|
||||||
if (!update) {
|
if (!update) {
|
||||||
Message.success("新建成功,请注意后台脚本不会默认开启");
|
Message.success("新建成功,请注意后台脚本不会默认开启");
|
||||||
// 保存的时候如何左侧没有脚本即新建
|
// 保存的时候如何左侧没有脚本即新建
|
||||||
setScriptList((prev) => {
|
setScriptList((prev) => {
|
||||||
setSelectSciptButtonAndTab(newScript.uuid);
|
setSelectSciptButtonAndTab(newScript.uuid);
|
||||||
return [newScript, ...prev];
|
return [newScript, ...prev];
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
setScriptList((prev) => {
|
setScriptList((prev) => {
|
||||||
// eslint-disable-next-line no-shadow, array-callback-return
|
prev.map((script: Script) => {
|
||||||
prev.map((script: Script) => {
|
if (script.uuid === newScript.uuid) {
|
||||||
if (script.uuid === newScript.uuid) {
|
script.name = newScript.name;
|
||||||
script.name = newScript.name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return [...prev];
|
|
||||||
});
|
|
||||||
Message.success("保存成功");
|
|
||||||
}
|
|
||||||
setEditors((prev) => {
|
|
||||||
for (let i = 0; i < prev.length; i += 1) {
|
|
||||||
if (prev[i].script.uuid === newScript.uuid) {
|
|
||||||
prev[i].code = e.getValue();
|
|
||||||
prev[i].isChanged = false;
|
|
||||||
prev[i].script.name = newScript.name;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return [...prev];
|
return [...prev];
|
||||||
});
|
});
|
||||||
},
|
Message.success("保存成功");
|
||||||
(err: any) => {
|
|
||||||
Message.error(`保存失败: ${err}`);
|
|
||||||
}
|
}
|
||||||
);
|
setEditors((prev) => {
|
||||||
})
|
for (let i = 0; i < prev.length; i += 1) {
|
||||||
.catch((err) => {
|
if (prev[i].script.uuid === newScript.uuid) {
|
||||||
Message.error(`错误的脚本代码: ${err}`);
|
prev[i].code = e.getValue();
|
||||||
});
|
prev[i].isChanged = false;
|
||||||
});
|
prev[i].script.name = newScript.name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [...prev];
|
||||||
|
});
|
||||||
|
return newScript;
|
||||||
|
})
|
||||||
|
.catch((err: any) => {
|
||||||
|
Message.error(`保存失败: ${err}`);
|
||||||
|
return Promise.reject(err);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
Message.error(`错误的脚本代码: ${err}`);
|
||||||
|
return Promise.reject(err);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveAs = (script: Script, e: editor.IStandaloneCodeEditor) => {
|
const saveAs = (script: Script, e: editor.IStandaloneCodeEditor) => {
|
||||||
return new Promise<void>((resolve) => {
|
return new Promise<void>((resolve) => {
|
||||||
chrome.downloads.download(
|
chrome.downloads.download(
|
||||||
@ -289,30 +290,35 @@ function ScriptEditor() {
|
|||||||
title: t("run"),
|
title: t("run"),
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
id: "debug",
|
id: "run",
|
||||||
title: t("debug"),
|
title: t("run"),
|
||||||
hotKey: KeyMod.CtrlCmd | KeyCode.F5,
|
hotKey: KeyMod.CtrlCmd | KeyCode.F5,
|
||||||
hotKeyString: "Ctrl+F5",
|
hotKeyString: "Ctrl+F5",
|
||||||
tooltip: "只有后台脚本/定时脚本才能调试, 且调试模式下不对进行权限校验(例如@connect)",
|
tooltip: "只有后台脚本/定时脚本才能运行",
|
||||||
action: async (script, e) => {
|
action: async (script, e) => {
|
||||||
// 保存更新代码之后再调试
|
// 保存更新代码之后再调试
|
||||||
const newScript = await save(script, e);
|
const newScript = await save(script, e);
|
||||||
|
// 判断脚本类型
|
||||||
|
if (newScript.type === SCRIPT_TYPE_NORMAL) {
|
||||||
|
Message.error("只有后台脚本/定时脚本才能运行");
|
||||||
|
return;
|
||||||
|
}
|
||||||
Message.loading({
|
Message.loading({
|
||||||
id: "debug_script",
|
id: "debug_script",
|
||||||
content: "正在准备脚本资源...",
|
content: "正在准备脚本资源...",
|
||||||
duration: 3000,
|
duration: 3000,
|
||||||
});
|
});
|
||||||
runtimeCtrl
|
runtimeClient
|
||||||
.debugScript(newScript)
|
.runScript(newScript.uuid)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
Message.success({
|
Message.success({
|
||||||
id: "debug_script",
|
id: "debug_script",
|
||||||
content: "构建成功, 可以打开开发者工具在控制台中查看输出",
|
content: "构建成功, 可以在扩展页打开开发者工具在控制台中查看输出",
|
||||||
duration: 3000,
|
duration: 3000,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
LoggerCore.logger(Logger.E(err)).debug("debug script error");
|
LoggerCore.logger(Logger.E(err)).debug("run script error");
|
||||||
Message.error({
|
Message.error({
|
||||||
id: "debug_script",
|
id: "debug_script",
|
||||||
content: `构建失败: ${err}`,
|
content: `构建失败: ${err}`,
|
||||||
|
@ -17,6 +17,8 @@ import { useTranslation } from "react-i18next";
|
|||||||
import ScriptMenuList from "../components/ScriptMenuList";
|
import ScriptMenuList from "../components/ScriptMenuList";
|
||||||
import { popupClient } from "../store/features/script";
|
import { popupClient } from "../store/features/script";
|
||||||
import { ScriptMenu } from "@App/app/service/service_worker/popup";
|
import { ScriptMenu } from "@App/app/service/service_worker/popup";
|
||||||
|
import { systemConfig } from "../store/global";
|
||||||
|
import { SystemConfig } from "@App/pkg/config/config";
|
||||||
|
|
||||||
const CollapseItem = Collapse.Item;
|
const CollapseItem = Collapse.Item;
|
||||||
|
|
||||||
@ -30,9 +32,11 @@ function App() {
|
|||||||
const [scriptList, setScriptList] = useState<ScriptMenu[]>([]);
|
const [scriptList, setScriptList] = useState<ScriptMenu[]>([]);
|
||||||
const [backScriptList, setBackScriptList] = useState<ScriptMenu[]>([]);
|
const [backScriptList, setBackScriptList] = useState<ScriptMenu[]>([]);
|
||||||
const [showAlert, setShowAlert] = useState(false);
|
const [showAlert, setShowAlert] = useState(false);
|
||||||
const [notice, setNotice] = useState("");
|
const [checkUpdate, setCheckUpdate] = useState<Parameters<typeof systemConfig.setCheckUpdate>[0]>({
|
||||||
const [isRead, setIsRead] = useState(true);
|
version: ExtVersion,
|
||||||
const [version, setVersion] = useState(ExtVersion);
|
notice: "",
|
||||||
|
isRead: false,
|
||||||
|
});
|
||||||
const [currentUrl, setCurrentUrl] = useState("");
|
const [currentUrl, setCurrentUrl] = useState("");
|
||||||
const [isEnableScript, setIsEnableScript] = useState(localStorage.enable_script !== "false");
|
const [isEnableScript, setIsEnableScript] = useState(localStorage.enable_script !== "false");
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -45,22 +49,15 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// systemManage.getNotice().then((res) => {
|
systemConfig.getCheckUpdate().then((res) => {
|
||||||
// if (res) {
|
setCheckUpdate(res);
|
||||||
// setNotice(res.notice);
|
});
|
||||||
// setIsRead(res.isRead);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// systemManage.getVersion().then((res) => {
|
|
||||||
// res && setVersion(res);
|
|
||||||
// });
|
|
||||||
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
|
||||||
if (!tabs.length) {
|
if (!tabs.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setCurrentUrl(tabs[0].url || "");
|
setCurrentUrl(tabs[0].url || "");
|
||||||
popupClient.getPopupData({ url: tabs[0].url!, tabId: tabs[0].id! }).then((resp) => {
|
popupClient.getPopupData({ url: tabs[0].url!, tabId: tabs[0].id! }).then((resp) => {
|
||||||
console.log(resp);
|
|
||||||
// 按照开启状态和更新时间排序
|
// 按照开启状态和更新时间排序
|
||||||
const list = resp.scriptList;
|
const list = resp.scriptList;
|
||||||
list.sort((a, b) => {
|
list.sort((a, b) => {
|
||||||
@ -109,15 +106,17 @@ function App() {
|
|||||||
window.open("/src/options.html", "_blank");
|
window.open("/src/options.html", "_blank");
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Badge count={isRead ? 0 : 1} dot offset={[-8, 6]}>
|
<Badge count={checkUpdate.isRead ? 0 : 1} dot offset={[-8, 6]}>
|
||||||
<Button
|
<Button
|
||||||
type="text"
|
type="text"
|
||||||
icon={<IconNotification />}
|
icon={<IconNotification />}
|
||||||
iconOnly
|
iconOnly
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setShowAlert(!showAlert);
|
setShowAlert(!showAlert);
|
||||||
setIsRead(true);
|
console.log(checkUpdate);
|
||||||
systemManage.setRead(true);
|
checkUpdate.isRead = true;
|
||||||
|
setCheckUpdate(checkUpdate);
|
||||||
|
systemConfig.setCheckUpdate(checkUpdate);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Badge>
|
</Badge>
|
||||||
@ -179,9 +178,9 @@ function App() {
|
|||||||
bodyStyle={{ padding: 0 }}
|
bodyStyle={{ padding: 0 }}
|
||||||
>
|
>
|
||||||
<Alert
|
<Alert
|
||||||
style={{ marginBottom: 20, display: showAlert ? "flex" : "none" }}
|
style={{ display: showAlert ? "flex" : "none" }}
|
||||||
type="info"
|
type="info"
|
||||||
content={<div dangerouslySetInnerHTML={{ __html: notice }} />}
|
content={<div dangerouslySetInnerHTML={{ __html: checkUpdate.notice || "" }} />}
|
||||||
/>
|
/>
|
||||||
<Collapse bordered={false} defaultActiveKey={["script", "background"]} style={{ maxWidth: 640 }}>
|
<Collapse bordered={false} defaultActiveKey={["script", "background"]} style={{ maxWidth: 640 }}>
|
||||||
<CollapseItem
|
<CollapseItem
|
||||||
@ -204,7 +203,7 @@ function App() {
|
|||||||
</Collapse>
|
</Collapse>
|
||||||
<div className="flex flex-row arco-card-header !h-6">
|
<div className="flex flex-row arco-card-header !h-6">
|
||||||
<span className="text-[12px] font-500">{`v${ExtVersion}`}</span>
|
<span className="text-[12px] font-500">{`v${ExtVersion}`}</span>
|
||||||
{semver.lt(ExtVersion, version) && (
|
{semver.lt(ExtVersion, checkUpdate.version) && (
|
||||||
<span
|
<span
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
window.open(`https://github.com/scriptscat/scriptcat/releases/tag/v${version}`);
|
window.open(`https://github.com/scriptscat/scriptcat/releases/tag/v${version}`);
|
||||||
|
@ -5,6 +5,7 @@ import { FileSystemType } from "@Packages/filesystem/factory";
|
|||||||
import { MessageQueue } from "@Packages/message/message_queue";
|
import { MessageQueue } from "@Packages/message/message_queue";
|
||||||
import i18n from "@App/locales/locales";
|
import i18n from "@App/locales/locales";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
import { ExtVersion } from "@App/app/const";
|
||||||
|
|
||||||
export const SystamConfigChange = "systemConfigChange";
|
export const SystamConfigChange = "systemConfigChange";
|
||||||
|
|
||||||
@ -65,9 +66,7 @@ export class SystemConfig {
|
|||||||
|
|
||||||
public set(key: string, val: any) {
|
public set(key: string, val: any) {
|
||||||
this.cache.set(key, val);
|
this.cache.set(key, val);
|
||||||
this.storage.set(key, val).then(() => {
|
this.storage.set(key, val);
|
||||||
console.log(chrome.runtime.lastError, val);
|
|
||||||
});
|
|
||||||
// 发送消息通知更新
|
// 发送消息通知更新
|
||||||
this.mq.publish(SystamConfigChange, {
|
this.mq.publish(SystamConfigChange, {
|
||||||
key,
|
key,
|
||||||
@ -247,4 +246,20 @@ export class SystemConfig {
|
|||||||
i18n.changeLanguage(value);
|
i18n.changeLanguage(value);
|
||||||
dayjs.locale(value.toLocaleLowerCase());
|
dayjs.locale(value.toLocaleLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCheckUpdate(data: { notice: string; version: string; isRead: boolean }) {
|
||||||
|
this.set("check_update", {
|
||||||
|
notice: data.notice,
|
||||||
|
version: data.version,
|
||||||
|
isRead: data.isRead,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getCheckUpdate(): Promise<Parameters<typeof this.setCheckUpdate>[0]> {
|
||||||
|
return this.get("check_update", {
|
||||||
|
notice: "",
|
||||||
|
isRead: false,
|
||||||
|
version: ExtVersion,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,3 +264,15 @@ export function errorMsg(e: any): string {
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isUserScriptsAvailable() {
|
||||||
|
return false;
|
||||||
|
try {
|
||||||
|
// Property access which throws if developer mode is not enabled.
|
||||||
|
chrome.userScripts;
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
// Not available.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user