diff --git a/package.json b/package.json
index 40d85db..2c47471 100644
--- a/package.json
+++ b/package.json
@@ -62,13 +62,17 @@
"download": "^8.0.0",
"download-git-repo": "^3.0.2",
"electron-store": "^8.0.0",
+ "is-chinese": "^1.4.2",
"keycode": "^2.2.0",
"marked": "^2.0.7",
+ "md5": "^2.3.0",
+ "mime-types": "^2.1.31",
"node-fetch": "^2.6.1",
"osx-mouse": "git+https://github.com/Toinane/osx-mouse.git",
"puppeteer-core": "^10.0.0",
"puppeteer-in-electron": "^3.0.3",
"query-string": "^7.0.0",
+ "request-promise": "^4.2.6",
"robotjs": "git+ssh://git@github.com/Toinane/robotjs.git",
"semver": "^7.3.5",
"sudo-prompt": "^9.2.1",
diff --git a/src/main/browsers/index.js b/src/main/browsers/index.js
index d2d059d..1c095bb 100644
--- a/src/main/browsers/index.js
+++ b/src/main/browsers/index.js
@@ -2,4 +2,5 @@ module.exports = () => ({
picker: require("./picker")(),
separator: require("./separate")(),
capture: require("./capture")(),
+ superPanel: require("./superPanel")(),
});
diff --git a/src/main/browsers/superPanel.js b/src/main/browsers/superPanel.js
new file mode 100644
index 0000000..6113bcd
--- /dev/null
+++ b/src/main/browsers/superPanel.js
@@ -0,0 +1,54 @@
+const { BrowserWindow, ipcMain, app } = require("electron");
+
+module.exports = () => {
+ let win;
+
+ let init = (mainWindow) => {
+ if (win === null || win === undefined) {
+ createWindow();
+ ipcMain.on('superPanel-hidden', () => {
+ win.hide();
+ });
+ ipcMain.on('superPanel-setSize', (e, height) => {
+ win.setSize(250, height);
+ });
+ ipcMain.on('superPanel-openPlugin', (e, args) => {
+ mainWindow.webContents.send('superPanel-openPlugin', args);
+ });
+ }
+ };
+
+ let createWindow = () => {
+ win = new BrowserWindow({
+ frame: false,
+ autoHideMenuBar: true,
+ width: 250,
+ height: 50,
+ show: false,
+ alwaysOnTop: true,
+ webPreferences: {
+ webSecurity: false,
+ enableRemoteModule: true,
+ backgroundThrottling: false,
+ nodeIntegration: true,
+ devTools: false,
+ },
+ });
+ win.loadURL(`file://${__static}/plugins/superPanel/index.html`);
+ win.once('ready-to-show', () => win.show());
+ win.on("closed", () => {
+ win = undefined;
+ });
+ // 打包后,失焦隐藏
+ win.on('blur', () => {
+ win.hide();
+ });
+ };
+
+ let getWindow = () => win;
+
+ return {
+ init: init,
+ getWindow: getWindow,
+ };
+};
diff --git a/src/main/common/common.js b/src/main/common/common.js
index 610aaee..336d7c7 100644
--- a/src/main/common/common.js
+++ b/src/main/common/common.js
@@ -4,6 +4,7 @@ import {
BrowserWindow,
clipboard,
Notification,
+ app,
} from 'electron';
import Api from './api';
import robot from 'robotjs';
@@ -11,7 +12,9 @@ import './config';
const browsers = require("../browsers")();
const mouseEvents = require("osx-mouse");
-const {picker, separator} = browsers;
+const {picker, separator, superPanel} = browsers;
+// 需要在超级面板展示的插件
+let optionPlugin = [];
let closePicker = (newColor) => {
if (picker.getWindow()) {
@@ -34,18 +37,88 @@ function registerShortCut(mainWindow) {
});
}
+const getSelectedText = () => {
+ return new Promise((resolve) => {
+ const lastText = clipboard.readText('clipboard');
+
+ const platform = process.platform;
+ if (platform === 'darwin') {
+ robot.keyTap('c', 'command');
+ } else {
+ robot.keyTap('c', 'control');
+ }
+
+ setTimeout(() => {
+ const text = clipboard.readText('clipboard') || ''
+ const fileUrl = clipboard.read('public.file-url');
+ clipboard.writeText(lastText);
+
+ resolve({
+ text,
+ fileUrl
+ })
+ }, 100);
+ })
+}
+
export default function init(mainWindow) {
+ ipcMain.on('optionPlugin', (e, args) => {
+ optionPlugin = args;
+ });
const mouseTrack = mouseEvents();
let down_time = 0;
+ let isPress = false;
mouseTrack.on('right-down', () => {
+ isPress = true;
down_time = Date.now();
+ const config = global.opConfig.get();
+ setTimeout(async () => {
+ if (isPress) {
+ const copyResult = await getSelectedText();
+ let win = superPanel.getWindow();
+
+ if (win) {
+ win.webContents.send('trigger-super-panel', {
+ ...copyResult,
+ optionPlugin: optionPlugin.plugins,
+ });
+ } else {
+ superPanel.init(mainWindow);
+ win = superPanel.getWindow();
+
+ win.once('ready-to-show', () => {
+ win.webContents.send('trigger-super-panel', {
+ ...copyResult,
+ optionPlugin: optionPlugin.plugins,
+ });
+ });
+ }
+ const pos = robot.getMousePos();
+ win.setPosition(parseInt(pos.x), parseInt(pos.y));
+ win.show();
+ }
+ }, config.superPanel.mouseDownTime);
})
mouseTrack.on('right-up', () => {
- if ((Date.now() - down_time) > 1000) {
- new Notification({ title: 'Rubick 通知', body: '长按了' }).show();
+ isPress = false;
+ });
+
+ // 注册快捷键
+ registerShortCut(mainWindow);
+
+ // 设置开机启动
+ const config = global.opConfig.get();
+ app.setLoginItemSettings({
+ openAtLogin: config.perf.common.start,
+ openAsHidden: true,
+ });
+
+ mainWindow.once("ready-to-show", () => {
+ // 非隐藏式启动需要显示主窗口
+ if (!app.getLoginItemSettings().wasOpenedAsHidden) {
+ mainWindow.show();
}
});
- registerShortCut(mainWindow);
ipcMain.on('re-register', (event, arg) => {
registerShortCut(mainWindow);
@@ -55,10 +128,12 @@ export default function init(mainWindow) {
mainWindow.setSize(arg.width || 800, arg.height);
});
+ // 打包后,失焦隐藏
mainWindow.on('blur', () => {
- mainWindow.hide();
+ app.isPackaged && mainWindow.hide();
});
+ // 响应 preload.js 事件
ipcMain.on('msg-trigger', async (event, arg) => {
const window = arg.winId ? BrowserWindow.fromId(arg.winId) : mainWindow
const operators = arg.type.split('.');
@@ -70,6 +145,7 @@ export default function init(mainWindow) {
event.sender.send(`msg-back-${arg.type}`, data);
});
+ // 窗口分离
ipcMain.on('new-window', (event, arg) => {
const opts = {
...arg,
@@ -78,6 +154,7 @@ export default function init(mainWindow) {
separator.init(opts);
});
+ // 拾色器
ipcMain.on('start-picker', () => {
const mouseTrack = mouseEvents();
picker.init();
diff --git a/src/main/common/config.js b/src/main/common/config.js
index c5e8b5a..028ad1b 100644
--- a/src/main/common/config.js
+++ b/src/main/common/config.js
@@ -20,9 +20,15 @@ let defaultConfig = {
search: true,
}
},
+ superPanel: {
+ baiduAPI: {
+ key: '',
+ appid: '',
+ },
+ mouseDownTime: 500
+ }
}
}
-
global.opConfig = {
config: null,
get() {
@@ -38,7 +44,6 @@ global.opConfig = {
}
},
set(key, value) {
- console.log(opConfig.config);
opConfig.config[key] = value;
fs.writeFileSync(configPath, JSON.stringify(opConfig.config));
}
diff --git a/src/renderer/App.vue b/src/renderer/App.vue
index 6a23680..09f51f9 100644
--- a/src/renderer/App.vue
+++ b/src/renderer/App.vue
@@ -80,15 +80,23 @@ export default {
}
},
mounted() {
- // 注册快捷键
- ipcRenderer.send('init-shortcut');
ipcRenderer.on('init-rubick', this.closeTag);
ipcRenderer.on('new-window', this.newWindow);
+ // 超级面板打开插件
+ ipcRenderer.on('superPanel-openPlugin', (e, args) => {
+ this.openPlugin({
+ cmd: args.cmd,
+ plugin: args.plugin,
+ feature: args.feature,
+ router: this.$router,
+ payload: args.data,
+ })
+ });
const searchNd = document.getElementById('search');
searchNd && searchNd.addEventListener('keydown', this.checkNeedInit)
},
methods: {
- ...mapActions('main', ['onSearch', 'showMainUI']),
+ ...mapActions('main', ['onSearch', 'showMainUI', 'openPlugin']),
...mapMutations('main', ['commonUpdate']),
search(v) {
if (!this.searchFn) {
diff --git a/src/renderer/assets/common/utils.js b/src/renderer/assets/common/utils.js
index d233181..1668661 100644
--- a/src/renderer/assets/common/utils.js
+++ b/src/renderer/assets/common/utils.js
@@ -4,7 +4,7 @@ import fs from 'fs';
import process from 'child_process';
import Store from 'electron-store';
import downloadFile from 'download';
-import {nativeImage} from 'electron';
+import {nativeImage, ipcRenderer} from 'electron';
import {APP_FINDER_PATH} from './constans';
import {getlocalDataFile} from "../../../main/common/utils";
@@ -57,6 +57,19 @@ async function downloadZip(downloadRepoUrl, name) {
const sysFile = {
savePlugins(plugins) {
+ ipcRenderer.send('optionPlugin', {
+ plugins: plugins.filter((plugin) => {
+ let hasOption = false;
+ plugin.features.forEach(fe => {
+ fe.cmds.forEach(cmd => {
+ if (cmd.type) {
+ hasOption = true;
+ }
+ })
+ });
+ return hasOption;
+ })
+ });
store.set('user-plugins', plugins);
},
getUserPlugins() {
@@ -72,7 +85,7 @@ const sysFile = {
}
function mergePlugins(plugins) {
- return [
+ const result = [
...plugins,
...SYSTEM_PLUGINS.map(plugin => {
return {
@@ -81,8 +94,18 @@ function mergePlugins(plugins) {
sourceFile: '',
type: 'system',
}
- }),
+ })
]
+
+ return result.filter((item, i) => {
+ let targetIndex;
+ result.forEach((tg, j) => {
+ if (tg.tag === item.tag && tg.type === 'system') {
+ targetIndex = j
+ }
+ });
+ return i === targetIndex;
+ });
}
function find(p, target = 'plugin.json') {
diff --git a/src/renderer/assets/keycode.js b/src/renderer/assets/keycode.js
index 13adf27..59fcc11 100644
--- a/src/renderer/assets/keycode.js
+++ b/src/renderer/assets/keycode.js
@@ -18,19 +18,14 @@ export default {
32: 'space',
33: 'page up',
34: 'page down',
- 35: 'end',
- 36: 'home',
- 37: 'left arrow',
- 38: 'up arrow',
- 39: 'right arrow',
- 40: 'down arrow',
- 41: 'select',
- 42: 'print',
- 43: 'execute',
- 44: 'Print Screen',
- 45: 'insert',
- 46: 'delete',
- 47: 'help',
+ 35: 'End',
+ 36: 'Home',
+ 37: 'Left',
+ 38: 'Up',
+ 39: 'Right',
+ 40: 'Down',
+ 45: 'Insert',
+ 46: 'Delete',
48: '0',
49: '1',
50: '2',
@@ -41,130 +36,55 @@ export default {
55: '7',
56: '8',
57: '9',
- 58: ':',
- 59: 'semicolon (firefox), equals',
- 60: '<',
- 61: 'equals (firefox)',
- 63: 'ß',
- 64: '@ (firefox)',
- 65: 'a',
- 66: 'b',
- 67: 'c',
- 68: 'd',
- 69: 'e',
- 70: 'f',
- 71: 'g',
- 72: 'h',
- 73: 'i',
- 74: 'j',
- 75: 'k',
- 76: 'l',
- 77: 'm',
- 78: 'n',
- 79: 'o',
- 80: 'p',
- 81: 'q',
- 82: 'r',
- 83: 's',
- 84: 't',
- 85: 'u',
- 86: 'v',
- 87: 'w',
- 88: 'x',
- 89: 'y',
- 90: 'z',
- 91: 'Windows Key / Left ⌘ / Chromebook Search key',
- 92: 'right window key',
- 93: 'Windows Menu / Right ⌘',
- 95: 'sleep',
- 96: 'numpad 0',
- 97: 'numpad 1',
- 98: 'numpad 2',
- 99: 'numpad 3',
- 100: 'numpad 4',
- 101: 'numpad 5',
- 102: 'numpad 6',
- 103: 'numpad 7',
- 104: 'numpad 8',
- 105: 'numpad 9',
- 106: 'multiply',
- 107: 'add',
- 108: 'numpad period (firefox)',
- 109: 'subtract',
- 110: 'decimal point',
- 111: 'divide',
- 112: 'f1',
- 113: 'f2',
- 114: 'f3',
- 115: 'f4',
- 116: 'f5',
- 117: 'f6',
- 118: 'f7',
- 119: 'f8',
- 120: 'f9',
- 121: 'f10',
- 122: 'f11',
- 123: 'f12',
- 124: 'f13',
- 125: 'f14',
- 126: 'f15',
- 127: 'f16',
- 128: 'f17',
- 129: 'f18',
- 130: 'f19',
- 131: 'f20',
- 132: 'f21',
- 133: 'f22',
- 134: 'f23',
- 135: 'f24',
- 136: 'f25',
- 137: 'f26',
- 138: 'f27',
- 139: 'f28',
- 140: 'f29',
- 141: 'f30',
- 142: 'f31',
- 143: 'f32',
- 144: 'num lock',
- 145: 'scroll lock',
- 151: 'airplane mode',
- 160: '^',
- 161: '!',
- 162: '؛ (arabic semicolon)',
- 163: '#',
- 164: '$',
- 165: 'ù',
- 166: 'page backward',
- 167: 'page forward',
- 168: 'refresh',
- 169: 'closing paren (AZERTY)',
- 170: '*',
- 171: '~ + * key',
- 172: 'home key',
- 173: 'minus (firefox), mute/unmute',
- 174: 'decrease volume level',
- 175: 'increase volume level',
- 176: 'next',
- 177: 'previous',
- 178: 'stop',
- 179: 'play/pause',
- 180: 'e-mail',
- 181: 'mute/unmute (firefox)',
- 182: 'decrease volume level (firefox)',
- 183: 'increase volume level (firefox)',
- 186: 'semi-colon / ñ',
- 187: 'equal sign',
- 188: 'comma',
- 189: 'dash',
- 190: 'period',
- 191: 'forward slash / ç',
- 192: 'grave accent / ñ / æ / ö',
- 193: '?, / or °',
- 194: 'numpad period (chrome)',
- 219: 'open bracket',
- 220: 'back slash',
- 221: 'close bracket / å',
- 222: 'single quote / ø / ä',
+ 65: 'A',
+ 66: 'B',
+ 67: 'C',
+ 68: 'D',
+ 69: 'E',
+ 70: 'F',
+ 71: 'G',
+ 72: 'H',
+ 73: 'I',
+ 74: 'J',
+ 75: 'K',
+ 76: 'L',
+ 77: 'M',
+ 78: 'N',
+ 79: 'O',
+ 80: 'P',
+ 81: 'Q',
+ 82: 'R',
+ 83: 'S',
+ 84: 'T',
+ 85: 'U',
+ 86: 'V',
+ 87: 'W',
+ 88: 'X',
+ 89: 'Y',
+ 90: 'Z',
+ 112: 'F1',
+ 113: 'F2',
+ 114: 'F3',
+ 115: 'F4',
+ 116: 'F5',
+ 117: 'F6',
+ 118: 'F7',
+ 119: 'F8',
+ 120: 'F9',
+ 121: 'F10',
+ 122: 'F11',
+ 123: 'F12',
+ 186: ';',
+ 187: '=',
+ 188: ',',
+ 189: '-',
+ 190: '.',
+ 191: '/',
+ 192: '`',
+ 219: '[',
+ 220: '\\',
+ 221: ']',
+ 222: "'",
223: '`',
224: 'left or right ⌘ key (firefox)',
225: 'altgr',
diff --git a/src/renderer/pages/plugins/index.vue b/src/renderer/pages/plugins/index.vue
index adf872e..2d7b895 100644
--- a/src/renderer/pages/plugins/index.vue
+++ b/src/renderer/pages/plugins/index.vue
@@ -30,8 +30,8 @@ export default {
mounted() {
this.webview = document.querySelector('webview');
this.webview.addEventListener('dom-ready', () => {
- this.webview.send('onPluginReady', this.$route.query);
- this.webview.send('onPluginEnter', this.$route.query);
+ this.webview.send('onPluginReady', this.pluginInfo);
+ this.webview.send('onPluginEnter', this.pluginInfo);
});
this.setSubPlaceHolder('Hi, Rubick');
this.webview.addEventListener('ipc-message', (event) => {
@@ -74,14 +74,16 @@ export default {
...mapMutations('main', ['setSubPlaceHolder', 'commonUpdate']),
},
beforeRouteUpdate() {
- this.path = `File://${this.$route.query.sourceFile}`
+ this.path = `File://${this.$route.query.sourceFile}`;
+ console.log(this.pluginInfo)
+ this.webview.send('onPluginEnter', this.pluginInfo);
},
beforeDestroy() {
const webview = document.querySelector('webview');
webview && webview.send('onPluginOut', this.$route.query)
},
computed: {
- ...mapState('main', ['searchValue', 'devPlugins']),
+ ...mapState('main', ['searchValue', 'devPlugins', 'pluginInfo']),
pluginDetail() {
return (this.devPlugins.filter(plugin => plugin.name === this.query.name)[0] || {}).features
},
diff --git a/src/renderer/pages/search/subpages/settings.vue b/src/renderer/pages/search/subpages/settings.vue
index 589bdf8..7302761 100644
--- a/src/renderer/pages/search/subpages/settings.vue
+++ b/src/renderer/pages/search/subpages/settings.vue
@@ -6,13 +6,7 @@
偏好设置