Skip to content

Commit

Permalink
fix: 调整记录剪贴板方式 修复漏数据的问题 #21 #28
Browse files Browse the repository at this point in the history
  • Loading branch information
ZiuChen committed Sep 5, 2022
1 parent 7d551e9 commit 6219115
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 57 deletions.
92 changes: 35 additions & 57 deletions public/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
const fs = require('fs')
const crypto = require('crypto')
const { clipboard } = require('electron')
const time = require('./time')

const homePath = utools.getPath('home')
const userDataPath = utools.getPath('userData')
Expand All @@ -17,7 +18,6 @@ const isWindows = utools.isWindows()
const DBPath = `${isMacOs ? userDataPath : homePath}${isWindows ? '\\' : '/'}${dbName}`

let globalImageOversize = false
let globalTimmerSet = false

class DB {
constructor(path) {
Expand Down Expand Up @@ -119,46 +119,46 @@ class DB {
}
}

const pbpaste = async () => {
return new Promise((res) => {
// file
const files = utools.getCopyedFiles() // null | Array
if (files) {
res({
type: 'file',
data: JSON.stringify(files)
})
const pbpaste = () => {
// file
const files = utools.getCopyedFiles() // null | Array
if (files) {
return {
type: 'file',
data: JSON.stringify(files)
}
// text
const text = clipboard.readText()
if (text.trim()) res({ type: 'text', data: text })
// image
const image = clipboard.readImage() // 大图卡顿来源
const data = image.toDataURL()
globalImageOversize = data.length > 4e5
if (!image.isEmpty()) {
res({
type: 'image',
data: data
})
}
// text
const text = clipboard.readText()
if (text.trim()) return { type: 'text', data: text }
// image
const image = clipboard.readImage() // 大图卡顿来源
const data = image.toDataURL()
globalImageOversize = data.length > 4e5
if (!image.isEmpty()) {
return {
type: 'image',
data: data
}
})
}
}

const watchClipboard = async (db, fn) => {
let prev = db.dataBase.data[0] || {}
return setInterval(() => {
pbpaste().then((item) => {
item.id = crypto.createHash('md5').update(item.data).digest('hex')
if (item && prev.id != item.id) {
// 剪切板元素 与最近一次复制内容不同
prev = item
fn(item)
} else {
// 剪切板元素 与上次复制内容相同
}
})
}, 250)
function loop() {
time.sleep(250).then(loop)
const item = pbpaste()
if (!item) return
item.id = crypto.createHash('md5').update(item.data).digest('hex')
if (item && prev.id != item.id) {
// 剪切板元素 与最近一次复制内容不同
prev = item
fn(item)
} else {
// 剪切板元素 与上次复制内容相同
}
}
loop()
}

const copy = (item, isHideMainWindow = true) => {
Expand Down Expand Up @@ -210,39 +210,17 @@ let timmer = watchClipboard(db, (item) => {
db.addItem(item)
})

globalTimmerSet = true // 计时器成功添加

utools.onPluginEnter(() => {
if (globalImageOversize) {
utools.copyText('ImageOverSized')
globalImageOversize = false
}
if (!globalTimmerSet) {
// 定时器被清除了 重新添加计时器
// same to code above
timmer = watchClipboard(db, (item) => {
if (!item) return
if (db.updateItemViaId(item.id)) {
return
}
item.createTime = new Date().getTime()
item.updateTime = new Date().getTime()
db.addItem(item)
})
}
focus()
select() // 进入插件将搜索框内容全选
toTop()
resetNav()
})

utools.onPluginOut((processExit) => {
// 卡顿来源: 似乎插件每次启动 uTools不会清除插件设置的 interval定时器
// 插件重复进入/退出会产生多个计时器导致插件卡退
// 插件退出 清除计时器 插件隐藏后台 不清除
processExit ? (clearInterval(timmer), (globalTimmerSet = false)) : (globalTimmerSet = true)
})

window.db = db
window.copy = copy
window.paste = paste
Expand Down
68 changes: 68 additions & 0 deletions public/time.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// author: inu1255

const path = require('path')

function newPromise(fn) {
let a, b
var tmp = {
resolve(x) {
if (this.pending) {
a(x)
this.resolved = true
this.pending = false
}
},
reject(e) {
if (this.pending) {
b(e)
this.rejectd = true
this.pending = false
}
},
pending: true,
resolved: false,
rejected: false
}
/** @type {Promise<T>} */
var pms = new Promise(function (resolve, reject) {
a = resolve
b = reject
if (fn) fn(tmp.resolve, tmp.reject)
})
return Object.assign(pms, tmp)
}

let cbIdx = 1
const cbMap = new Map()
function getWorker() {
if (getWorker.worker) return getWorker.worker
const worker = new Worker(path.join(__dirname, 'time.worker.js'))
getWorker.worker = worker
worker.onmessage = (e) => {
if (e.data && cbMap.has(e.data.cb)) {
cbMap.get(e.data.cb).apply(null, e.data.args)
}
}
return worker
}

function call(method, args) {
const cb = cbIdx++
let pms = newPromise()
cbMap.set(cb, function (err, data) {
if (err) pms.reject(err)
else pms.resolve(data)
})
getWorker().postMessage({
method,
args,
cb
})
return pms
}

function sleep(ms) {
return call('sleep', [ms])
}

exports.sleep = sleep
21 changes: 21 additions & 0 deletions public/time.worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// author: inu1255

const apis = {
sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}
}

onmessage = (event) => {
const data = event.data
if (!data) return
const { cb, method, args } = data
if (!apis[method]) {
postMessage({ cb, err: 'no such method' })
return
}
apis[method].apply(null, args).then(
(res) => postMessage({ cb, data: res }),
(err) => postMessage({ cb, err })
)
}

0 comments on commit 6219115

Please sign in to comment.