diff --git a/config-overrides.js b/config-overrides.js index 11475de..32b3bd9 100644 --- a/config-overrides.js +++ b/config-overrides.js @@ -109,7 +109,7 @@ const userscriptWebpack = (config, env) => { }; config.output.filename = "[name].js"; - config.output.publicPath = "./"; + config.output.publicPath = env === "production" ? "./" : "/"; config.optimization.splitChunks = { cacheGroups: { default: false } }; config.optimization.runtimeChunk = false; config.optimization.minimize = false; diff --git a/package.json b/package.json index 638eb65..1c08e9e 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ }, "scripts": { "start": "REACT_APP_CLIENT=web react-app-rewired start", + "start:userscript": "REACT_APP_CLIENT=userscript react-app-rewired start", "build": "rm -rf build/chrome && BUILD_PATH=./build/chrome REACT_APP_CLIENT=chrome react-app-rewired build", "build:edge": "rm -rf build/edge && cp -r build/chrome build/edge", "build:firefox": "rm -rf build/firefox && cp -r build/chrome build/firefox && cat ./build/firefox/manifest.firefox.json > ./build/firefox/manifest.json", diff --git a/src/libs/utils.js b/src/libs/utils.js index 8dcd92f..0cce146 100644 --- a/src/libs/utils.js +++ b/src/libs/utils.js @@ -27,3 +27,11 @@ export const matchValue = (arr, val) => { } return arr[0]; }; + +/** + * 等待 + * @param {*} delay + * @returns + */ +export const sleep = (delay) => + new Promise((resolve) => setTimeout(resolve, delay)); diff --git a/src/userscript.js b/src/userscript.js index 89044bc..8136a51 100644 --- a/src/userscript.js +++ b/src/userscript.js @@ -1,6 +1,5 @@ import React from "react"; import ReactDOM from "react-dom/client"; -import Options from "./views/Options"; import Action from "./views/Action"; import createCache from "@emotion/cache"; import { CacheProvider } from "@emotion/react"; @@ -20,12 +19,11 @@ import { Translator } from "./libs/translator"; document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE) || document.location.href.includes(process.env.REACT_APP_OPTIONSPAGE2) ) { - const root = ReactDOM.createRoot(document.getElementById("root")); - root.render( - - - - ); + window.unsafeWindow.GM = window.GM; + window.unsafeWindow.GM_xmlhttpRequest = window.GM_xmlhttpRequest; + window.unsafeWindow.GM_setValue = window.GM_setValue; + window.unsafeWindow.GM_getValue = window.GM_getValue; + window.unsafeWindow.GM_deleteValue = window.GM_deleteValue; return; } diff --git a/src/views/Options/index.js b/src/views/Options/index.js index 2f43b5c..cc86bed 100644 --- a/src/views/Options/index.js +++ b/src/views/Options/index.js @@ -6,8 +6,59 @@ import Layout from "./Layout"; import SyncSetting from "./SyncSetting"; import { StoragesProvider } from "../../hooks/Storage"; import ThemeProvider from "../../hooks/Theme"; +import { useEffect, useState } from "react"; +import { isGm } from "../../libs/browser"; +import { sleep } from "../../libs/utils"; export default function Options() { + const [error, setError] = useState(false); + const [ready, setReady] = useState(false); + + useEffect(() => { + if (!isGm) { + return; + } + + (async () => { + let i = 0; + for (;;) { + await sleep(1000); + if (window.GM) { + setReady(true); + break; + } + + if (++i > 8) { + setError(true); + break; + } + } + })(); + }, []); + + if (error) { + return ( +
+

+ Please confirm whether to install or enable{" "} + KISS Translator{" "} + GreaseMonkey script? +

+

+ or click here for help +

+
+ ); + } + + if (isGm && !ready) { + return ( +
+

loading...

+
+ ); + } + return ( diff --git a/src/views/Popup/index.js b/src/views/Popup/index.js index 8e00725..5e4ae5e 100644 --- a/src/views/Popup/index.js +++ b/src/views/Popup/index.js @@ -21,7 +21,7 @@ import { export default function Popup({ setShowPopup, translator: tran }) { const i18n = useI18n(); - const [rule, setRule] = useState(tran.rule); + const [rule, setRule] = useState(tran?.rule); const handleOpenSetting = () => { if (isExt) {