mirror of
https://github.com/rubickCenter/rubick
synced 2026-03-07 06:20:41 +08:00
✨ 支持ui插件下载&运行
This commit is contained in:
7
src/common/utils/getLocalDataFile.ts
Normal file
7
src/common/utils/getLocalDataFile.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export default (): string => {
|
||||
let localDataFile: any = process.env.HOME;
|
||||
if (!localDataFile) {
|
||||
localDataFile = process.env.LOCALAPPDATA;
|
||||
}
|
||||
return localDataFile;
|
||||
};
|
||||
46
src/common/utils/localPlugin.ts
Normal file
46
src/common/utils/localPlugin.ts
Normal 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));
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -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`);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ export default () => {
|
||||
|
||||
const createWindow = async () => {
|
||||
win = new BrowserWindow({
|
||||
height: 600,
|
||||
height: 60,
|
||||
useContentSize: true,
|
||||
resizable: true,
|
||||
width: 800,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -8,7 +8,6 @@ const API: any = {
|
||||
win.setSize(800, height || 60);
|
||||
},
|
||||
openPlugin({plugin}) {
|
||||
console.log(plugin);
|
||||
runnerInstance.init(plugin);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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)}`,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user