diff --git a/docs/docs/.vuepress/config.js b/docs/docs/.vuepress/config.js
index bb64bb3..072a127 100644
--- a/docs/docs/.vuepress/config.js
+++ b/docs/docs/.vuepress/config.js
@@ -36,13 +36,8 @@ module.exports = {
path: '/blogs/plugin/',
},
{
- title: '右击增强实现原理'
- },
- {
- title: '系统插件实现原理'
- },
- {
- title: '文件检索实现原理'
+ title: '超级面板实现原理',
+ path: '/blogs/superPannel/',
},
]
},
diff --git a/docs/docs/blogs/superPannel/README.md b/docs/docs/blogs/superPannel/README.md
new file mode 100644
index 0000000..26c612a
--- /dev/null
+++ b/docs/docs/blogs/superPannel/README.md
@@ -0,0 +1,175 @@
+## 前言
+超级面板用于增强用户右击能力,实现快速呼起插件的能力,本次实现方式是通过 `robotjs` 以及 `iohook` 一起来完成
+
+### 功能截图:
+
+#### 文件夹下长按右建
+
+
+#### 选择文件后长按右键
+
+
+#### 选择文字后长按右键
+
+
+## 实现原理
+
+### 获取选中文案
+要实现改功能核心是要读取当前用户选中的文案或者文件,根据当前选择内容进行不同功能展示。但是核心有一个问题是如何来实现获取当前选中的内容。这个问题思考了很久很久,要想获取选中的文案,感觉唯一的办法是使用 `ctrl + c` 或者 `command + c` 来先复制到剪切板,再通过 `electron clipboard` 来获取当前剪切板内容。但是 `utools` 可不是通过先复制再长按这样的操作来实现的,而是直接选中文本或者文件长按后呼起超级面板。**所以一定要在右击长按前获取到当前选中的内容。**
+
+如果要这么干,可能真的无解了,之前就因为这么想,才被无解了。正确的思路应该是先长按再获取选中的内容。别看只是掉了个个,但实现确实天壤之别:
+
+1. 先获取选中内容:这就要求我们必须监听原生系统选中事件,但是 `electron` 并没有提供能力,我们也无法监听系统选择事件。
+2. 先右击,后获取内容,这样的好处在于先右击可以通过监听鼠标右击事件,相比选择事件更加容易。
+
+所以思路就有了,先监听长按右击事件:
+
+```js
+// macos
+const mouseEvents = require("osx-mouse");
+
+const mouseTrack = mouseEvents();
+// 按下去的 time
+let down_time = 0;
+
+// 是否弹起
+let isPress = false;
+
+// 监听右击
+mouseTrack.on('right-down', () => {
+ isPress = true;
+ down_time = Date.now();
+ // 长按 500ms 后触发
+ setTimeout(async () => {
+ if (isPress) {
+ // 获取选中内容
+ const copyResult = await getSelectedText();
+ }, 500);
+})
+mouseTrack.on('right-up', () => {
+ isPress = false;
+});
+
+```
+
+接下来一步就是要去实现获取选中内容,要获取选中内容有个比较骚的操作,就是:
+
+1. 通过 `clipboard` 先获取当前剪切板内容,并存下 A
+2. 通过 `robot.js` 来调用系统 `command + c` 或者 `ctrl + c`
+3. 再通过 `clipboard` 先获取当前剪切板内容,并存下 B
+4. 再将 A 写到剪切板中,返回 B
+
+先存剪切板内容的目的在于我们是偷偷帮用户执行了复制动作,当读取完用户选择内容后,需要回复用户之前的剪切板内容。接下来看一下简单的实现:
+
+```js
+const getSelected = () => {
+ 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
+ })
+ }, 300);
+ })
+}
+```
+### 通知超级面板窗口当前选中内容
+当获取到了选中内容后,接下来就是需要创建超级面板的 `BrowserWindow`:
+```js
+const { BrowserWindow, ipcMain, app } = require("electron");
+
+module.exports = () => {
+ let win;
+
+ let init = (mainWindow) => {
+ if (win === null || win === undefined) {
+ createWindow();
+ }
+ };
+
+ 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;
+ });
+ };
+
+ let getWindow = () => win;
+
+ return {
+ init: init,
+ getWindow: getWindow,
+ };
+};
+```
+然后再通知 `superPanel` 进行内容展示:
+```js
+ win.webContents.send('trigger-super-panel', {
+ ...copyResult,
+ optionPlugin: optionPlugin.plugins,
+});
+```
+
+### 超级面板点击操作
+接下来要实现超级面板点击操作,这块也是比较简单的了,直接上代码好了:
+#### 1. 打开 Terminal
+
+```js
+const { spawn } = require ('child_process');
+
+spawn('open', [ '-a', 'Terminal', fileUrl ]);
+```
+
+#### 2. 新建文件
+
+```js
+remote.dialog.showSaveDialog({
+ title: "请选择要保存的文件名",
+ buttonLabel: "保存",
+ defaultPath: fileUrl.replace('file://', ''),
+ showsTagField: false,
+ nameFieldLabel: '',
+}).then(result => {
+ fs.writeFileSync(result.filePath, '');
+});
+```
+
+#### 3. 复制路径
+```js
+clipboard.writeText(fileUrl.replace('file://', ''))
+```
diff --git a/package.json b/package.json
index c8ea73f..001512a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "rubick2",
- "version": "0.0.3-beta.7",
+ "version": "0.0.3-beta.8",
"author": "muwoo <2424880409@qq.com>",
"description": "An electron-vue project",
"license": null,
diff --git a/src/renderer/App.vue b/src/renderer/App.vue
index f1d99de..77b8180 100644
--- a/src/renderer/App.vue
+++ b/src/renderer/App.vue
@@ -213,7 +213,7 @@ export default {
let filePath = '';
if (process.platform === 'win32') {
const rawFilePath = clipboard.read('FileNameW');
- filePath = rawFilePath.replace(new RegExp(String.fromCharCode(0), 'g'), ''); } else {
+ filePath = rawFilePath.replace(new RegExp(String.fromCharCode(0), 'g'), '');
if (filePath.indexOf('plugin.json') >= 0) {
this.search({
filePath,