diff --git a/.gitignore b/.gitignore index 04131fa..3c07993 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ src/plugins/*/*\[*\]*.ts .dist .DS_Store dist -total.svg \ No newline at end of file +total.svg +src/plugins/index.ts diff --git a/importPlugins.js b/importPlugins.js new file mode 100644 index 0000000..47a9625 --- /dev/null +++ b/importPlugins.js @@ -0,0 +1,25 @@ +import path from 'path'; +import fs from 'fs'; + +let content = `import { Plugin } from '@typings/plugin';\n`; +let pluginCounter = 0; +const PLUGIN_DIR = 'src/plugins'; + +fs.readdirSync(PLUGIN_DIR) + .filter(f => !f.includes('index')) + .forEach(langName => { + const LANG_DIR = PLUGIN_DIR + '/' + langName; + fs.readdirSync(LANG_DIR) + .filter(f => !f.includes('broken') && !f.startsWith('.')) + .forEach(pluginName => { + content += `import p_${pluginCounter} from './${langName}/${pluginName.replace(/\.ts$/, '')}';\n`; + pluginCounter += 1; + }); + }); + +content += `\nconst PLUGINS: Plugin.PluginBase[] = [${Array(pluginCounter) + .fill() + .map((v, index) => 'p_' + index.toString()) + .join(', ')}];\nexport default PLUGINS`; + +fs.writeFileSync('./src/plugins/index.ts', content, { encoding: 'utf-8' }); diff --git a/package.json b/package.json index c2f31cc..ba6a7d9 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "index.js", "type": "module", "scripts": { - "start": "concurrently \"npm run dev\" \"npm run proxy\"", + "start": "node importPlugins.js && concurrently \"npm run dev\" \"npm run proxy\"", "dev": "vite", "proxy": "node proxy_server.js", "test": "exit 0", diff --git a/proxy_server.js b/proxy_server.js index 7355bd2..49106db 100644 --- a/proxy_server.js +++ b/proxy_server.js @@ -86,31 +86,11 @@ const cookiesHandler = (req, res) => { }); }; -const pluginPathsHandler = (req, res) => { - const pluginsDir = 'src/plugins'; - const pluginPaths = []; - const langNames = fs.readdirSync(pluginsDir); - langNames.forEach(langName => { - const langDir = pluginsDir + '/' + langName; - const pluginNames = fs.readdirSync(langDir); - pluginNames.forEach(pluginName => { - if (!pluginName.startsWith('.') && !pluginName.includes('broken')) { - pluginPaths.push(langName + '/' + pluginName); - } - }); - }); - res.setHeader('Access-Control-Allow-Origin', CLIENT_HOST); - res.setHeader('Access-Control-Allow-Credentials', true); - res.end(JSON.stringify(pluginPaths)); -}; - http .createServer(function (req, res) { const path = req.url.replace(/^\//, ''); if (path === 'cookies') { cookiesHandler(req, res); - } else if (path === 'pluginPaths') { - pluginPathsHandler(req, res); } else { const _url = new URL(path); for (const _header of disAllowedHeaders) { diff --git a/src/components/Appbar/index.tsx b/src/components/Appbar/index.tsx index 6b71326..0adc02b 100644 --- a/src/components/Appbar/index.tsx +++ b/src/components/Appbar/index.tsx @@ -21,6 +21,7 @@ import { FixedSizeList, ListChildComponentProps } from 'react-window'; import { useDispatch, useSelector } from 'react-redux'; import { AppState } from '@redux/store'; import { selectPlugin } from '@redux/pluginSlice'; +import usePlugin from '@hooks/usePlugin'; const resovleIcon = (iconPath: string) => { return '/icons/' + iconPath; @@ -30,9 +31,7 @@ export default function () { const [searchedPlugins, setSearchPlugins] = useState([]); const [keyword, setKeyword] = useState(''); const [listVisible, setListVisible] = useState(false); - const selectedPlugin = useSelector( - (state: AppState) => state.plugin.selected, - ); + const plugin = usePlugin(); const dispatch = useDispatch(); useEffect(() => { const plugins = searchPlugins(keyword); @@ -128,15 +127,15 @@ export default function () { Language - {selectedPlugin ? ( + {plugin ? ( - - {selectedPlugin.name} - v{selectedPlugin.version} + + {plugin.name} - v{plugin.version} ) : null} diff --git a/src/index.d.ts b/src/index.d.ts index 896195e..11f02fe 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,4 +1 @@ -declare module '*.jpg'; -declare module '*.png'; -declare module '*.svg'; -declare module '*.jpeg'; +/// diff --git a/src/plugins/index.d.ts b/src/plugins/index.d.ts new file mode 100644 index 0000000..a50fccb --- /dev/null +++ b/src/plugins/index.d.ts @@ -0,0 +1,3 @@ +import { Plugin } from '@typings/plugin'; + +export default [] as Plugin.PluginBase[]; diff --git a/src/provider/index.tsx b/src/provider/index.tsx index e310d0f..6a38ec1 100644 --- a/src/provider/index.tsx +++ b/src/provider/index.tsx @@ -1,18 +1,11 @@ import React, { ReactNode, useEffect } from 'react'; import DialogProvider from './DialogProvider'; import { Backdrop, Box, CircularProgress, Container } from '@mui/material'; -import { useDispatch, useSelector } from 'react-redux'; +import { useSelector } from 'react-redux'; import { AppState } from '@redux/store'; -import { loadPlugins } from './plugins'; -import { hideLoading } from '@redux/overlaySlice'; export default function AppProvider() { const loading = useSelector((state: AppState) => state.overlay.loading); - const dispatch = useDispatch(); - - useEffect(() => { - loadPlugins().then(() => dispatch(hideLoading())); - }, []); return ( { - const paths = await fetch('pluginPaths').then(res => res.json()); - const fetchedPlugins: Plugin.PluginBase[] = []; - for (const path of paths) { - const relativePath = '../plugins/' + path; - const plugin: Plugin.PluginBase = ( - await import(/* @vite-ignore */ relativePath) - ).default; - fetchedPlugins.push(plugin); - } - plugins.splice(0, plugins.length, ...fetchedPlugins); -}; +import plugins from '../plugins'; export const searchPlugins = (keyword: string) => { return plugins.filter( diff --git a/src/redux/overlaySlice.ts b/src/redux/overlaySlice.ts index 9178c7b..6b7f2e0 100644 --- a/src/redux/overlaySlice.ts +++ b/src/redux/overlaySlice.ts @@ -1,7 +1,7 @@ import { createSlice } from '@reduxjs/toolkit'; const initialState = { - loading: true, + loading: false, }; export const overlaySlice = createSlice({