mirror of
https://github.com/rubickCenter/rubick
synced 2025-12-17 16:24:16 +08:00
feat: 支持快捷键设置;支持超级面板
This commit is contained in:
BIN
static/plugins/superPanel/assets/link.png
Normal file
BIN
static/plugins/superPanel/assets/link.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
BIN
static/plugins/superPanel/assets/logo.png
Normal file
BIN
static/plugins/superPanel/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
BIN
static/plugins/superPanel/assets/new.png
Normal file
BIN
static/plugins/superPanel/assets/new.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 345 B |
BIN
static/plugins/superPanel/assets/terminal.png
Normal file
BIN
static/plugins/superPanel/assets/terminal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 309 B |
101
static/plugins/superPanel/index.html
Normal file
101
static/plugins/superPanel/index.html
Normal file
@@ -0,0 +1,101 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<script crossorigin="anonymous" src="https://lib.baomitu.com/vue/2.6.12/vue.min.js"></script>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#app {
|
||||
-webkit-app-region: drag;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
overflow: hidden;
|
||||
}
|
||||
.top {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px #ddd dashed;
|
||||
padding: 0 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.top .img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #314659;
|
||||
}
|
||||
.top .img img {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
.top .text {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
.translate {
|
||||
width: 100%;
|
||||
background: #F7F7F9;
|
||||
font-size: 12px;
|
||||
color: #555;
|
||||
box-sizing: border-box;
|
||||
padding: 5px;
|
||||
}
|
||||
.trans-item {
|
||||
line-height: 20px;
|
||||
}
|
||||
.options-item {
|
||||
border-bottom: 1px #ddd dashed;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
padding: 0 10px;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.options-item:last-child {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.select-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
<script src="./index.js" type="module"></script>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="top" @click="openMainWindow">
|
||||
<span class="img"><img src="./assets/logo.png" /></span>
|
||||
<span class="text" v-if="selectData.text && selectData.text.length">选择的文本 {{selectData.text.length}} 个</span>
|
||||
</div>
|
||||
<div class="translate" v-if="selectData.translate">
|
||||
<div class="trans-item" v-for="trans in selectData.translate">
|
||||
<div>{{trans.src}}</div>
|
||||
<div>n. {{trans.dst}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div @click="() => commonClick(op, selectData.fileUrl)" class="options-item" v-for="op in targetOptions">
|
||||
<div class="select-item">
|
||||
<img class="icon" :src="op.icon" />
|
||||
{{op.name}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
185
static/plugins/superPanel/index.js
Normal file
185
static/plugins/superPanel/index.js
Normal file
@@ -0,0 +1,185 @@
|
||||
const {ipcRenderer, nativeImage, remote, clipboard} = require('electron')
|
||||
const md5 = require("md5");
|
||||
const rp = require("request-promise");
|
||||
const isChinese = require('is-chinese');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { spawn } = require ('child_process');
|
||||
const mineType = require("mime-types");
|
||||
|
||||
const opConfig = remote.getGlobal('opConfig');
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
code: '',
|
||||
current: {},
|
||||
selectData: {
|
||||
translate: {},
|
||||
optionPlugin: [],
|
||||
},
|
||||
options: {
|
||||
translate: [],
|
||||
common: [
|
||||
{
|
||||
type: 'default',
|
||||
name: '终端中打开',
|
||||
icon: './assets/terminal.png',
|
||||
click: (fileUrl) => {
|
||||
spawn('open', [ '-a', 'Terminal', fileUrl ]);
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'default',
|
||||
name: '新建文件',
|
||||
icon: './assets/new.png',
|
||||
click: (fileUrl) => {
|
||||
remote.dialog.showSaveDialog({
|
||||
title: "请选择要保存的文件名",
|
||||
buttonLabel: "保存",
|
||||
defaultPath: fileUrl.replace('file://', ''),
|
||||
showsTagField: false,
|
||||
nameFieldLabel: '',
|
||||
}).then(result => {
|
||||
fs.writeFileSync(result.filePath, '');
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'default',
|
||||
name: '复制当前路径',
|
||||
icon: './assets/link.png',
|
||||
click: (fileUrl) => {
|
||||
clipboard.writeText(fileUrl.replace('file://', ''))
|
||||
}
|
||||
}
|
||||
],
|
||||
selected: [
|
||||
{
|
||||
type: 'default',
|
||||
name: '复制当前路径',
|
||||
icon: './assets/link.png',
|
||||
click: (fileUrl) => {
|
||||
clipboard.writeText(fileUrl.replace('file://', ''))
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
targetOptions: [],
|
||||
},
|
||||
created() {
|
||||
// 简单唤起超级面板
|
||||
ipcRenderer.on('trigger-super-panel', (e, args) => {
|
||||
this.selectData = args;
|
||||
const ext = path.extname(this.selectData.fileUrl);
|
||||
// 剪切板只有文本时,显示翻译
|
||||
if (!this.selectData.fileUrl) {
|
||||
const word = this.selectData.text;
|
||||
const isCh = isChinese(word);
|
||||
this.translate(word, isCh ? 'en' : 'zh');
|
||||
this.targetOptions = this.options.translate;
|
||||
} else if (!ext || path.parse(this.selectData.fileUrl).base === 'Desktop') {
|
||||
// 如果在桌面上或者没有选择任何文件,则展示通用选项
|
||||
this.targetOptions = this.options.common;
|
||||
} else {
|
||||
// 有文件选择
|
||||
this.targetOptions = JSON.parse(JSON.stringify(this.options.selected));
|
||||
// 检测上传
|
||||
(this.selectData.optionPlugin || []).forEach(plugin => {
|
||||
plugin.features.forEach(fe => {
|
||||
fe.cmds.forEach(cmd => {
|
||||
// 如果是图片,则唤起图片选项
|
||||
const regImg = /\.(png|jpg|gif|jpeg|webp)$/;
|
||||
if (cmd.type === 'img' && regImg.test(ext)) {
|
||||
console.log(plugin);
|
||||
this.targetOptions.push({
|
||||
type: 'ext',
|
||||
name: cmd.label,
|
||||
icon: plugin.icon,
|
||||
click: (fileUrl) => {
|
||||
const base64 = this.fileToBase64(fileUrl);
|
||||
ipcRenderer.send('superPanel-openPlugin', {
|
||||
cmd: cmd,
|
||||
plugin: plugin,
|
||||
feature: fe,
|
||||
data: base64,
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
// 如果是文件,且符合文件正则类型
|
||||
if (cmd.type === 'file' && new RegExp(cmd.match).test(ext)) {
|
||||
this.targetOptions.push({
|
||||
type: 'ext',
|
||||
name: cmd.label,
|
||||
icon: '',
|
||||
click: () => {
|
||||
ipcRenderer.send('superPanel-openPlugin', {
|
||||
cmd: cmd,
|
||||
plugin: plugin,
|
||||
feature: fe,
|
||||
data: {
|
||||
isFile: true,
|
||||
isDirectory: false,
|
||||
name: path.basename(this.selectData.fileUrl),
|
||||
path: this.selectData.fileUrl
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
translate(msg, to) {
|
||||
const {appid, key} = opConfig.get().superPanel.baiduAPI;
|
||||
if (!appid || !key) return;
|
||||
const q = msg;
|
||||
const salt = parseInt(Math.random() * 1000000000); //加盐
|
||||
const sign = md5(appid + q + salt + key); //生成签名
|
||||
const params = encodeURI(
|
||||
`q=${q}&from=auto&to=${to}&appid=${appid}&salt=${salt}&sign=${sign}`
|
||||
);
|
||||
const options = {
|
||||
uri: `https://fanyi-api.baidu.com/api/trans/vip/translate?${params}`,
|
||||
};
|
||||
return rp(options).then((res) => {
|
||||
this.$set(this.selectData, 'translate', JSON.parse(res).trans_result)
|
||||
})
|
||||
},
|
||||
commonClick(item, fileUrl) {
|
||||
ipcRenderer.send('superPanel-hidden')
|
||||
item.click(fileUrl);
|
||||
},
|
||||
|
||||
fileToBase64 (filePath) {
|
||||
let data = fs.readFileSync(filePath.replace('file://', ''));
|
||||
data = new Buffer(data).toString("base64");
|
||||
let base64 = "data:" + mineType.lookup(filePath) + ";base64," + data;
|
||||
return base64;
|
||||
},
|
||||
|
||||
openMainWindow() {
|
||||
ipcRenderer.send('msg-trigger', {
|
||||
type: 'showMainWindow',
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
selectData: {
|
||||
deep: true,
|
||||
handler() {
|
||||
this.$nextTick(() => {
|
||||
ipcRenderer.send('superPanel-setSize', parseInt(getComputedStyle(document.getElementById('app')).height))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user