diff --git a/api/index.js b/api/index.js deleted file mode 100644 index fedcec9..0000000 --- a/api/index.js +++ /dev/null @@ -1,9 +0,0 @@ -const notice = require('./operators/notice'); -const network = require('./operators/network'); -const common = require('./operators/common'); - -window.rubick = { - notice, - network, - common, -} diff --git a/api/operators/common.js b/api/operators/common.js deleted file mode 100644 index 49d33b5..0000000 --- a/api/operators/common.js +++ /dev/null @@ -1,7 +0,0 @@ -const { shell } = require('electron'); - -module.exports = { - openInBrowser(url) { - shell.openExternal(url); - } -} diff --git a/api/operators/network.js b/api/operators/network.js deleted file mode 100644 index 97a9a08..0000000 --- a/api/operators/network.js +++ /dev/null @@ -1,71 +0,0 @@ -const {ipcRenderer} = require("electron"); -const AnyProxy = require('anyproxy'); - -const options = { - port: 8001, - webInterface: { - enable: true, - webPort: 8002 - }, - forceProxyHttps: false, - wsIntercept: false, // 不开启websocket代理 - silent: true -}; - -class Network { - constructor() { - this.mockList = []; - this.proxyServer = null; - } - initNetwork(op, { - beforeSendRequest, - beforeSendResponse, - success, - }) { - if (op === 'start') { - if (!this.proxyServer || !this.proxyServer.recorder) { - const _this = this; - options.rule = { - *beforeSendRequest(requestDetail) { - if (beforeSendRequest) { - return beforeSendRequest(requestDetail); - } - return requestDetail - }, - *beforeSendResponse (requestDetail, responseDetail) { - if (beforeSendResponse) { - return beforeSendResponse(requestDetail, responseDetail); - } - return responseDetail; - } - }; - this.proxyServer = new AnyProxy.ProxyServer(options); - this.proxyServer.once('ready', () => { - console.log('启动完成'); - success && success(this.proxyServer); - }); - } - this.proxyServer.start(); - } else { - AnyProxy.utils.systemProxyMgr.disableGlobalProxy('http'); - AnyProxy.utils.systemProxyMgr.disableGlobalProxy('https'); - this.proxyServer.close(); - success && success(); - } - } - getIPAddress() { - const interfaces = require('os').networkInterfaces(); - for (const devName in interfaces) { - const iface = interfaces[devName]; - for (let i = 0; i < iface.length; i++) { - const alias = iface[i]; - if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) { - return alias.address; - } - } - } - } -} - -module.exports = new Network(); - diff --git a/api/operators/notice.js b/api/operators/notice.js deleted file mode 100644 index a79b416..0000000 --- a/api/operators/notice.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - system({title, body}, cb) { - const myNotification = new Notification(title, { - body - }); - - myNotification.onclick = () => { - cb(); - } - } -} diff --git a/package.json b/package.json index 8f3e7b9..622173d 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "pack": "npm run pack:main && npm run pack:renderer", "pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js", "pack:renderer": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.renderer.config.js", - "postinstall": "" + "postinstall": "", + "rebuild": " ./node_modules/.bin/electron-rebuild" }, "build": { "asar": false, @@ -59,12 +60,16 @@ "ant-design-vue": "^1.7.5", "anyproxy": "^4.1.3", "axios": "^0.18.1", + "chokidar": "^3.5.1", "download-git-repo": "^3.0.2", "electron-store": "^8.0.0", "marked": "^2.0.7", "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", + "robotjs": "git+ssh://git@github.com/Toinane/robotjs.git", "uuid": "^8.3.2", "vue": "^2.5.16", "vue-electron": "^1.0.6", @@ -92,15 +97,16 @@ "electron-builder": "22.10.5", "electron-debug": "^1.5.0", "electron-devtools-installer": "^2.2.4", + "electron-rebuild": "^2.3.5", "file-loader": "^1.1.11", "html-webpack-plugin": "^3.2.0", + "less": "^4.1.1", + "less-loader": "^5.0.0", "listr": "^0.14.3", "mini-css-extract-plugin": "0.4.0", "multispinner": "^0.2.1", "node-loader": "^0.6.0", - "node-sass": "^4.9.2", "react": "^17.0.2", - "sass-loader": "^7.0.3", "style-loader": "^0.21.0", "url-loader": "^1.0.1", "vue-html-loader": "^1.2.4", diff --git a/src/main/browsers/index.js b/src/main/browsers/index.js new file mode 100644 index 0000000..092a8a0 --- /dev/null +++ b/src/main/browsers/index.js @@ -0,0 +1,4 @@ +module.exports = () => ({ + picker: require("./picker")(), + separator: require("./separate")(), +}); diff --git a/src/main/browsers/picker.js b/src/main/browsers/picker.js new file mode 100644 index 0000000..7e8b079 --- /dev/null +++ b/src/main/browsers/picker.js @@ -0,0 +1,42 @@ +const { BrowserWindow, nativeImage } = require("electron"); + +module.exports = () => { + let win; + + let init = () => { + if (win === null || win === undefined) { + createWindow(); + } + }; + + let createWindow = () => { + win = new BrowserWindow({ + frame: false, + autoHideMenuBar: true, + width: 100, + height: 100, + transparent: true, + alwaysOnTop: true, + resizable: false, + focusable: true, + hasShadow: false, + // icon: nativeImage.createFromPath(`${dirname}/build/icon.png`), + webPreferences: { + nodeIntegration: true, + devTools: false, + }, + }); + + win.loadURL(`file://${__static}/plugins/picker/index.html`); + win.on("closed", () => { + win = undefined; + }); + }; + + let getWindow = () => win; + + return { + init: init, + getWindow: getWindow, + }; +}; diff --git a/src/main/browsers/separate.js b/src/main/browsers/separate.js new file mode 100644 index 0000000..d7515cb --- /dev/null +++ b/src/main/browsers/separate.js @@ -0,0 +1,46 @@ +const {stringify} = require('query-string'); +const { BrowserWindow, nativeImage } = require("electron"); + +module.exports = () => { + let win; + + let init = (opts) => { + createWindow(opts); + }; + + let createWindow = (opts) => { + const winURL = process.env.NODE_ENV === 'development' + ? `http://localhost:9080/#/plugin?${stringify(opts)}` + : `${__dirname}/index.html` + win = new BrowserWindow({ + height: 600, + useContentSize: true, + width: 800, + titleBarStyle: 'hiddenInset', + title: '拉比克', + show: false, + webPreferences: { + webSecurity: false, + enableRemoteModule: true, + backgroundThrottling: false, + webviewTag: true, + nodeIntegration: true // 在网页中集成Node + } + }); + + process.env.NODE_ENV === 'development' ? win.loadURL(winURL) : win.loadFile(winURL, { + hash: `#/plugin?${stringify(opts)}`, + }); + win.once('ready-to-show', () => win.show()); + win.on("closed", () => { + win = undefined; + }); + }; + + let getWindow = () => win; + + return { + init: init, + getWindow: getWindow, + }; +}; diff --git a/src/main/common.js b/src/main/common.js deleted file mode 100644 index 96ea579..0000000 --- a/src/main/common.js +++ /dev/null @@ -1,71 +0,0 @@ -import {globalShortcut, ipcMain, BrowserWindow} from 'electron'; -import {stringify} from 'query-string'; -import Api from './api'; -import path from 'path'; - -export default function init(mainWindow) { - ipcMain.on('changeWindowSize', (event, arg) => { - mainWindow.setSize(arg.width || 788, arg.height); - }); - - mainWindow.on('blur', () => { - // mainWindow.hide(); - }); - - globalShortcut.register('Alt+R', () => { - mainWindow.show(); - }); - - ipcMain.on('init-shortcut', (event) => { - globalShortcut.register('Esc', () => { - mainWindow.show(); - event.sender.send('init-rubick'); - }); - globalShortcut.register('ctrl+d', () => { - event.sender.send('new-window'); - }); - }) - - - ipcMain.on('msg-trigger', async (event, arg) => { - const window = arg.winId ? BrowserWindow.fromId(arg.winId) : mainWindow - const operators = arg.type.split('.'); - let fn = Api; - operators.forEach((op) => { - fn = fn[op]; - }); - const data = await fn(arg, window); - event.sender.send(`msg-back-${arg.type}`, data); - }); - - ipcMain.on('new-window', (event, arg) => { - const opts = { - ...arg, - searchType: 'subWindow', - } - const winURL = process.env.NODE_ENV === 'development' - ? `http://localhost:9080/#/plugin?${stringify(opts)}` - : `${__dirname}/index.html` - const win = new BrowserWindow({ - height: 600, - useContentSize: true, - width: 788, - titleBarStyle: 'hiddenInset', - title: '拉比克', - show: false, - webPreferences: { - webSecurity: false, - enableRemoteModule: true, - backgroundThrottling: false, - webviewTag: true, - nodeIntegration: true // 在网页中集成Node - } - }); - process.env.NODE_ENV === 'development' ? win.loadURL(winURL) : win.loadFile(winURL, { - hash: `#/plugin?${stringify(opts)}`, - }); - win.once('ready-to-show', () => win.show()); - }) -} - - diff --git a/src/main/api.js b/src/main/common/api.js similarity index 97% rename from src/main/api.js rename to src/main/common/api.js index 8aff460..fd8bfb7 100644 --- a/src/main/api.js +++ b/src/main/common/api.js @@ -1,5 +1,5 @@ import {app, BrowserWindow} from 'electron'; -import {getlocalDataFile, saveData, getData} from './common/utils'; +import {getlocalDataFile, saveData, getData} from './utils'; import path from "path"; const puppeteer = require("puppeteer-core"); diff --git a/src/main/common/common.js b/src/main/common/common.js new file mode 100644 index 0000000..c55308a --- /dev/null +++ b/src/main/common/common.js @@ -0,0 +1,112 @@ +import { + globalShortcut, + ipcMain, + BrowserWindow, + clipboard, + Notification, +} from 'electron'; +import Api from './api'; +import robot from 'robotjs'; + +const browsers = require("../browsers")(); +const mouseEvents = require("osx-mouse"); +const {picker, separator} = browsers; + +let closePicker = (newColor) => { + if (picker.getWindow()) { + ipcMain.removeListener("closePicker", closePicker); + ipcMain.removeListener("pickerRequested", (event) => {}); + picker.getWindow().close(); + } +}; + +export default function init(mainWindow) { + const mouseTrack = mouseEvents(); + let down_time = 0; + mouseTrack.on('right-down', () => { + down_time = Date.now(); + }) + mouseTrack.on('right-up', () => { + if ((Date.now() - down_time) > 1000) { + new Notification({ title: 'Rubick 通知', body: '长按了' }).show(); + } + }); + + ipcMain.on('changeWindowSize-rubick', (event, arg) => { + mainWindow.setSize(arg.width || 788, arg.height); + }); + + mainWindow.on('blur', () => { + // mainWindow.hide(); + }); + + globalShortcut.register('Alt+R', () => { + mainWindow.show(); + }); + + ipcMain.on('init-shortcut', (event) => { + globalShortcut.register('Esc', () => { + mainWindow.show(); + event.sender.send('init-rubick'); + }); + globalShortcut.register('ctrl+d', () => { + event.sender.send('new-window'); + }); + }) + + + ipcMain.on('msg-trigger', async (event, arg) => { + const window = arg.winId ? BrowserWindow.fromId(arg.winId) : mainWindow + const operators = arg.type.split('.'); + let fn = Api; + operators.forEach((op) => { + fn = fn[op]; + }); + const data = await fn(arg, window); + window.webContents.send(`msg-back-${arg.type}`, data); + }); + + ipcMain.on('new-window', (event, arg) => { + const opts = { + ...arg, + searchType: 'subWindow', + } + separator.init(opts); + }); + + ipcMain.on('start-picker', () => { + const mouseTrack = mouseEvents(); + picker.init(); + picker.getWindow().on("close", () => { + mouseTrack.destroy(); + }); + mouseTrack.on('move', (x, y) => { + if (!picker.getWindow()) return; + let color = "#" + robot.getPixelColor(parseInt(x), parseInt(y)); + picker.getWindow().setPosition(parseInt(x) - 50, parseInt(y) - 50); + picker.getWindow().webContents.send("updatePicker", color); + }) + mouseTrack.on("left-up", (x, y) => { + const color = "#" + robot.getPixelColor(parseInt(x), parseInt(y)); + clipboard.writeText("#" + robot.getPixelColor(parseInt(x), parseInt(y))); + new Notification({ title: 'Rubick 通知', body: `${color} 已保存到剪切板` }).show(); + closePicker(); + }); + let pos = robot.getMousePos(); + picker + .getWindow() + .setPosition(parseInt(pos.x) - 50, parseInt(pos.y) - 50); + + picker + .getWindow() + .webContents.send( + "updatePicker", + robot.getPixelColor(pos.x, pos.y) + ); + + ipcMain.on("closePicker", closePicker); + mouseTrack.on("right-up", closePicker); + }) +} + + diff --git a/src/main/index.js b/src/main/index.js index 9116cc4..ec29a51 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -1,6 +1,6 @@ import { app, BrowserWindow, protocol } from 'electron' import '../renderer/store' -import init from './common'; +import init from './common/common'; import createTray from './tray'; /** * Set `__static` path to static files in production diff --git a/src/renderer/App.vue b/src/renderer/App.vue index 8113bc0..424fbe6 100644 --- a/src/renderer/App.vue +++ b/src/renderer/App.vue @@ -16,7 +16,7 @@ id="search" :placeholder="subPlaceHolder && selected && selected.key === 'plugin-container' ? subPlaceHolder : 'Hi, Rubick'" class="main-input" - @change="onSearch" + @change="e => onSearch({value: e.target.value})" :value="searchValue" :maxLength="selected && selected.key !== 'plugin-container' ? 0 : 1000" > @@ -49,7 +49,7 @@ @@ -84,8 +84,6 @@ export default { const searchNd = document.getElementById('search'); searchNd && searchNd.addEventListener('keydown', this.checkNeedInit) }, - beforeDestroy() { - }, methods: { ...mapActions('main', ['onSearch', 'showMainUI']), ...mapMutations('main', ['commonUpdate']), @@ -104,8 +102,9 @@ export default { this.commonUpdate({ selected: null, showMain: false, + options: [], }); - ipcRenderer.send('changeWindowSize', { + ipcRenderer.send('changeWindowSize-rubick', { height: getWindowHeight([]), }); this.$router.push({ @@ -167,7 +166,7 @@ export default { } }; - diff --git a/src/renderer/pages/search/index.vue b/src/renderer/pages/search/index.vue index d20dfd1..e4240e6 100644 --- a/src/renderer/pages/search/index.vue +++ b/src/renderer/pages/search/index.vue @@ -45,7 +45,7 @@ export default { } -