支持ui插件下载&运行

This commit is contained in:
muwoo
2021-12-02 17:55:45 +08:00
parent c2f43bea39
commit 0132a11d7e
32 changed files with 951 additions and 244 deletions

View File

@@ -0,0 +1,7 @@
export default (): string => {
let localDataFile: any = process.env.HOME;
if (!localDataFile) {
localDataFile = process.env.LOCALAPPDATA;
}
return localDataFile;
};

View File

@@ -0,0 +1,46 @@
import path from "path";
import fs from "fs";
import getLocalDataFile from "./getLocalDataFile";
import { app } from "electron";
import { PluginHandler } from "@/core";
const configPath = path.join(getLocalDataFile(), "./rubick-local-plugin.json");
const appPath = app.getPath("cache");
const baseDir = path.join(appPath, "./rubick-plugins");
const pluginInstance = new PluginHandler({
baseDir: baseDir,
});
global.LOCAL_PLUGINS = {
PLUGINS: [],
async downloadPlugin(plugin) {
await pluginInstance.install([plugin.name]);
global.LOCAL_PLUGINS.addPlugin(plugin);
return global.LOCAL_PLUGINS.PLUGINS;
},
getLocalPlugins() {
try {
if (!global.LOCAL_PLUGINS.PLUGINS.length) {
global.LOCAL_PLUGINS.PLUGINS = JSON.parse(
fs.readFileSync(configPath, "utf-8")
);
}
return global.LOCAL_PLUGINS.PLUGINS;
} catch (e) {
global.LOCAL_PLUGINS.PLUGINS = [];
return global.LOCAL_PLUGINS.PLUGINS;
}
},
addPlugin(plugin) {
let has = false;
global.LOCAL_PLUGINS.PLUGINS.some((p) => {
has = p.name === plugin.name;
return has;
});
if (!has) {
global.LOCAL_PLUGINS.PLUGINS.unshift(plugin);
fs.writeFileSync(configPath, JSON.stringify(global.LOCAL_PLUGINS.PLUGINS));
}
},
};

View File

@@ -31,7 +31,7 @@ async function getAppIcon(
const existsnone = fs.existsSync(iconnone);
if (exists) return true;
if (existsnone) return false;
const appName: string = appPath.split("/").pop() ?? "";
const appName: string = appPath.split("/").pop() || "";
const extname: string = path.extname(appName);
const appSubStr: string = appName.split(extname)[0];
const path1 = path.join(appPath, `/Contents/Resources/App.icns`);

View File

@@ -34,7 +34,8 @@ class AdapterHandler {
);
}
this.baseDir = options.baseDir;
this.registry = options.registry ?? "https://registry.npm.taobao.org";
console.log(this.baseDir);
this.registry = options.registry || "https://registry.npm.taobao.org";
}
/**
@@ -68,8 +69,8 @@ class AdapterHandler {
}
// 安装并启动插件
async install(adapters: Array<string>, opts?: any) {
const installCmd = opts.isDev ? "link" : "install";
async install(adapters: Array<string>) {
const installCmd = "install";
// 安装
await this.execCommand(installCmd, adapters);
}

View File

@@ -9,7 +9,7 @@ export default () => {
const createWindow = async () => {
win = new BrowserWindow({
height: 600,
height: 60,
useContentSize: true,
resizable: true,
width: 800,

View File

@@ -12,31 +12,22 @@ export default () => {
const createWindow = (plugin) => {
win = new BrowserWindow({
autoHideMenuBar: true,
width: 800,
height: 800,
width: 850,
height: 700,
alwaysOnTop: true,
resizable: false,
focusable: true,
show: false,
webPreferences: {
enableRemoteModule: true,
webSecurity: false,
nodeIntegration: true,
contextIsolation: false,
devTools: true,
webviewTag: true,
preload: `${__static}/preload.js`,
},
});
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
win.loadURL("http://localhost:8081" as string);
} else {
// Load the index.html when not in development
win.loadURL(`file://${__static}/runner/index.html`);
}
win.webContents.on("dom-ready", () => {
win.webContents.executeJavaScript(`window.setPluginInfo(${JSON.stringify(plugin)})`);
});
win.loadURL(plugin.indexPath);
win.once("ready-to-show", () => {
win.show();

View File

@@ -8,7 +8,6 @@ const API: any = {
win.setSize(800, height || 60);
},
openPlugin({plugin}) {
console.log(plugin);
runnerInstance.init(plugin);
},
};

View File

@@ -5,6 +5,7 @@ import commonConst from "../common/utils/commonConst";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import API from "./common/api";
import "../common/utils/localPlugin";
class App {
private windowCreator: { init: () => void; getWindow: () => BrowserWindow };

View File

@@ -1,11 +1,21 @@
import { reactive, toRefs, nextTick } from "vue";
import { nativeImage, remote } from "electron";
import { reactive, toRefs, toRaw } from "vue";
import { nativeImage, remote, ipcRenderer } from "electron";
import { appSearch, PluginHandler } from "@/core";
import path from "path";
import throttle from "lodash.throttle";
import commonConst from "@/common/utils/commonConst";
const appPath = remote.app.getPath("cache");
function searchKeyValues(lists, value) {
return lists.filter((item) => {
if (typeof item === "string") {
return item.toLowerCase().indexOf(value.toLowerCase()) >= 0;
}
return item.type.toLowerCase().indexOf(value.toLowerCase()) >= 0;
});
}
const createPluginManager = (): any => {
const baseDir = path.join(appPath, "./rubick-plugins");
const pluginInstance = new PluginHandler({
@@ -17,6 +27,7 @@ const createPluginManager = (): any => {
plugins: [],
options: [],
searchValue: "",
localPlugins: [],
});
const initPlugins = async () => {
@@ -35,9 +46,44 @@ const createPluginManager = (): any => {
const value = e.target.value;
state.searchValue = value;
if (!value) return;
// todo 先搜索 plugin
// todo 再搜索 app
state.localPlugins = remote.getGlobal("LOCAL_PLUGINS").getLocalPlugins();
let options: any = [];
// todo 先搜索 plugin
state.localPlugins.forEach((plugin) => {
const feature = plugin.features;
feature.forEach((fe) => {
const cmds = searchKeyValues(fe.cmds, value);
options = [
...options,
...cmds.map((cmd) => ({
name: cmd,
value: "plugin",
icon: plugin.logo,
desc: fe.explain,
type: plugin.pluginType,
click: () => {
const pluginPath = path.resolve(
pluginInstance.baseDir,
"node_modules",
plugin.name
);
ipcRenderer.sendSync("msg-trigger", {
type: "openPlugin",
plugin: {
...toRaw(plugin),
indexPath: `file://${path.join(
pluginPath,
"./",
plugin.main
)}`,
},
});
},
})),
];
});
});
// todo 再搜索 app
const descMap = new Map();
options = [
...options,
@@ -77,7 +123,9 @@ const createPluginManager = (): any => {
const pluginInfo = await pluginInstance.getAdapterInfo(pluginName, pluginPath);
return {
...pluginInfo,
indexPath: path.join(pluginPath, "../", pluginInfo.main),
indexPath: commonConst.dev()
? "http://localhost:8080/#/"
: `file://${path.join(pluginPath, "../", pluginInfo.main)}`,
};
};