From 1d0c8dba531e6f10774f37ac041f4375f31059fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=90=8C=E8=90=8C=E5=93=92=E8=B5=AB=E8=90=9D?= Date: Mon, 10 Apr 2023 18:45:04 +0800 Subject: [PATCH] :hammer: Refactor: change macos clipboard watcher implementment --- src/main/apis/app/system/index.ts | 27 +++++++++-------- src/main/lifeCycle/index.ts | 24 +++++++++------- src/main/utils/clipboardPoll.ts | 48 +++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 src/main/utils/clipboardPoll.ts diff --git a/src/main/apis/app/system/index.ts b/src/main/apis/app/system/index.ts index bf8c656..8a4eb25 100644 --- a/src/main/apis/app/system/index.ts +++ b/src/main/apis/app/system/index.ts @@ -20,6 +20,7 @@ import { T } from '~/main/i18n' import { isMacOSVersionGreaterThanOrEqualTo } from '~/main/utils/getMacOSVersion' import { buildPicBedListMenu } from '~/main/events/remotes/menu' import clipboardListener from 'clipboard-event' +import clipboardPoll from '~/main/utils/clipboardPoll' import picgo from '../../core/picgo' import { uploadClipboardFiles } from '../uploader/apis' let contextMenu: Menu | null @@ -43,8 +44,8 @@ export function setDockMenu () { label: T('START_WATCH_CLIPBOARD'), click () { db.set('settings.isListeningClipboard', true) - clipboardListener.startListening() - clipboardListener.on('change', () => { + clipboardPoll.startListening() + clipboardPoll.on('change', () => { picgo.log.info('clipboard changed') uploadClipboardFiles() }) @@ -56,7 +57,7 @@ export function setDockMenu () { label: T('STOP_WATCH_CLIPBOARD'), click () { db.set('settings.isListeningClipboard', false) - clipboardListener.stopListening() + clipboardPoll.stopListening() setDockMenu() }, enabled: isListeningClipboard @@ -66,6 +67,7 @@ export function setDockMenu () { } export function createMenu () { + const ClipboardWatcher = process.platform === 'darwin' ? clipboardPoll : clipboardListener const submenu = buildPicBedListMenu() const isListeningClipboard = db.get('settings.isListeningClipboard') || false const appMenu = Menu.buildFromTemplate([ @@ -87,8 +89,8 @@ export function createMenu () { label: T('START_WATCH_CLIPBOARD'), click () { db.set('settings.isListeningClipboard', true) - clipboardListener.startListening() - clipboardListener.on('change', () => { + ClipboardWatcher.startListening() + ClipboardWatcher.on('change', () => { picgo.log.info('clipboard changed') uploadClipboardFiles() }) @@ -100,7 +102,7 @@ export function createMenu () { label: T('STOP_WATCH_CLIPBOARD'), click () { db.set('settings.isListeningClipboard', false) - clipboardListener.stopListening() + ClipboardWatcher.stopListening() createMenu() }, enabled: isListeningClipboard @@ -134,6 +136,7 @@ export function createMenu () { } export function createContextMenu () { + const ClipboardWatcher = process.platform === 'darwin' ? clipboardPoll : clipboardListener const isListeningClipboard = db.get('settings.isListeningClipboard') || false if (process.platform === 'darwin' || process.platform === 'win32') { const submenu = buildPicBedListMenu() @@ -159,8 +162,8 @@ export function createContextMenu () { label: T('START_WATCH_CLIPBOARD'), click () { db.set('settings.isListeningClipboard', true) - clipboardListener.startListening() - clipboardListener.on('change', () => { + ClipboardWatcher.startListening() + ClipboardWatcher.on('change', () => { picgo.log.info('clipboard changed') uploadClipboardFiles() }) @@ -172,7 +175,7 @@ export function createContextMenu () { label: T('STOP_WATCH_CLIPBOARD'), click () { db.set('settings.isListeningClipboard', false) - clipboardListener.stopListening() + ClipboardWatcher.stopListening() createContextMenu() }, enabled: isListeningClipboard @@ -273,8 +276,8 @@ export function createContextMenu () { label: T('START_WATCH_CLIPBOARD'), click () { db.set('settings.isListeningClipboard', true) - clipboardListener.startListening() - clipboardListener.on('change', () => { + ClipboardWatcher.startListening() + ClipboardWatcher.on('change', () => { picgo.log.info('clipboard changed') uploadClipboardFiles() }) @@ -286,7 +289,7 @@ export function createContextMenu () { label: T('STOP_WATCH_CLIPBOARD'), click () { db.set('settings.isListeningClipboard', false) - clipboardListener.stopListening() + ClipboardWatcher.stopListening() createContextMenu() }, enabled: isListeningClipboard diff --git a/src/main/lifeCycle/index.ts b/src/main/lifeCycle/index.ts index fc1d694..dd73079 100644 --- a/src/main/lifeCycle/index.ts +++ b/src/main/lifeCycle/index.ts @@ -45,6 +45,7 @@ import { T } from '~/main/i18n' import { UpdateInfo, autoUpdater } from 'electron-updater' import updateChecker from '../utils/updateChecker' import clipboardListener from 'clipboard-event' +import clipboardPoll from '../utils/clipboardPoll' import path from 'path' import { CLIPBOARD_IMAGE_FOLDER } from '~/universal/utils/static' import fs from 'fs-extra' @@ -140,6 +141,18 @@ class LifeCycle { } windowManager.create(IWindowList.TRAY_WINDOW) windowManager.create(IWindowList.SETTING_WINDOW) + const isAutoListenClipboard = db.get('settings.isAutoListenClipboard') || false + const ClipboardWatcher = process.platform === 'darwin' ? clipboardPoll : clipboardListener + if (isAutoListenClipboard) { + db.set('settings.isListeningClipboard', true) + ClipboardWatcher.startListening() + ClipboardWatcher.on('change', () => { + picgo.log.info('clipboard changed') + uploadClipboardFiles() + }) + } else { + db.set('settings.isListeningClipboard', false) + } if (process.platform === 'darwin') { setDockMenu() } @@ -202,17 +215,6 @@ class LifeCycle { settingWindow.show() settingWindow.focus() } - const isAutoListenClipboard = db.get('settings.isAutoListenClipboard') || false - if (isAutoListenClipboard) { - db.set('settings.isListeningClipboard', true) - clipboardListener.startListening() - clipboardListener.on('change', () => { - picgo.log.info('clipboard changed') - uploadClipboardFiles() - }) - } else { - db.set('settings.isListeningClipboard', false) - } const clipboardDir = path.join(picgo.baseDir, CLIPBOARD_IMAGE_FOLDER) fs.ensureDir(clipboardDir) } diff --git a/src/main/utils/clipboardPoll.ts b/src/main/utils/clipboardPoll.ts new file mode 100644 index 0000000..338bedc --- /dev/null +++ b/src/main/utils/clipboardPoll.ts @@ -0,0 +1,48 @@ +import { clipboard, nativeImage } from 'electron' +import { EventEmitter } from 'events' + +class ClipboardWatcher extends EventEmitter { + lastImage: Electron.NativeImage | null + timer: NodeJS.Timeout | null + + constructor () { + super() + this.lastImage = null + this.timer = null + } + + startListening (watchDelay = 500) { + if (this.timer) { + clearInterval(this.timer) + } + + this.timer = setInterval(() => { + const image = clipboard.readImage() + if (image.isEmpty()) { + return + } + + const dataUrl = image.toDataURL() + const currentImage = nativeImage.createFromDataURL(dataUrl) + + if (this.lastImage) { + const lastDataUrl = this.lastImage.toDataURL() + if (lastDataUrl === dataUrl) { + return + } + } + + this.lastImage = currentImage + this.emit('change', currentImage) + }, watchDelay) + } + + stopListening () { + if (this.timer) { + clearInterval(this.timer) + this.timer = null + } + } +} + +export default new ClipboardWatcher()