对话详情页 图片 类信息,单机右键弹出的操作栏中增加【复制】功能,复制后将该内容以图片形式保存在本地剪切板中,可直接粘贴到PC端输入栏中或文字内容编辑区(例如微信,飞书等其他IM会话软件内容输入区)
1. 复制比较简单,代码:
/***
@params
copyImgDom = {
src: img.image_elem_large_url,
width: img.image_elem_large_pic_width,
height: img.image_elem_large_pic_height
}
***/
handleCopyImg(copyImgDom){
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
canvas.width = copyImgDom.width;
canvas.height = copyImgDom.height;
img.crossOrigin = "Anonymous";
img.src = copyImgDom.src;
img.onload = () => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(img, 0, 0);
canvas.toBlob(async blob => {
const data = [
new ClipboardItem({
[blob.type]: blob,
}),
];
await navigator.clipboard.write(data).then(
() => {
this.$message({
text: '复制图片'
})
},
() => {
console.error("Unable to write to clipboard.");
});
});
}
},
2. 粘贴图片
粘贴图片有一个问题就是 从粘贴板获取到的File对象中没有 path 也就是文件路径, 需要我们自己保存下来获取到路径才能发送,腾讯IM的Electron SDK 目前只能这么操作。
2.1 粘贴
async onPaste (e) {
let _this = this
e.preventDefault();
let text = '';
// let imgUrlList = [];
text = e.clipboardData.getData('text')
if (text) {
this.insert(text);
}
let files = []
let promiseList = []
for(var i = 0; i < e.clipboardData.files.length; i++) {
let file = e.clipboardData.files[i];
if (file && i != 'length') {
let fileSrc = ''
let fileType = 'file'
let blob = e.clipboardData.items[i].getAsFile();
let j = i
while(!blob) {
j++
blob = e.clipboardData.items[j].getAsFile()
}
if (/\.(png|jpg|jpeg|gif|svg)(\?.*)?$/.test(file.name)) {
// 图片 获取一下缩略图
let reader = new FileReader();
reader.readAsDataURL(blob);
fileType = 'image'
let promise = new Promise((resolve,reject)=>{
reader.onload = function (e) {
fileSrc = e.target.result;
files.push({
name: file.name,
type: fileType,
src: fileSrc,
file: blob
})
resolve()
}
})
promiseList.push(promise)
} else {
files.push({
name: file.name,
type: fileType,
src: fileSrc,
file: blob
})
}
}
}
if (promiseList.length > 0) {
Promise.all(promiseList).then(()=>{
_this.$emit('pasteFile', files)
})
}
},
2.2 发送时候 发现没有PATH 发送不了 调用Electron controller 保存到本地 拿到本地路径
// 从微信输入框复制的图片是没有这个路径的 发送不了 需要保存在本地获取到一个路径
let filePath = ''
if (!file.file.path) {
filePath = await this.$ipcInvoke(ipcApiRoute.downloadFileToFolder, { name: file.name,
src: file.src})
}
// 其中Buffer 这样取 const { Buffer } = require("node:buffer");
downloadFileToFolder (file) {
let base64Src = file.src.slice(file.src.indexOf(',') + 1)
const _fileBuffer = Buffer.from(base64Src, 'base64');
const filePath = path.join(electronApp.getAppPath(), '/temp', `${file.name.replace('image', getUUID())}`);
let folderName = path.join(electronApp.getAppPath(), '/temp')
if (!fs.existsSync(folderName)) {
fs.mkdir(folderName, ()=>{});
}
fs.writeFile(filePath, _fileBuffer, err => console.log(err, Date.now()));
return filePath
}
initDrag () {
let dropTarget = this.$refs['conversationBody'] // 拖拽主题只负责进入 然后显示拖拽框
let dropTargetHover = this.$refs['conversationBodyHover'] // 拖拽框负责接收文件和离开事件
// 拖拽事件绑定
dropTarget.addEventListener("dragenter", this.handleDropTargetEvent);
dropTargetHover.addEventListener("dragover", this.handleDropTargetEvent);
dropTargetHover.addEventListener("drop", this.handleDropTargetEvent);
dropTargetHover.addEventListener("dragleave", this.handleDropTargetEvent);
},
handleDropTargetEvent(event) {
// 阻止事件的默认行为
event.preventDefault();
if (event.type === 'drop') {
// 文件进入并松开鼠标,文件边框恢复正常
// this.dragHoverShow = false
let files = []
let promiseList = []
for(let file of event.dataTransfer.files) {
if (file) {
let fileSrc = ''
let fileType = 'file'
if (/\.(png|jpg|jpeg|gif|svg)(\?.*)?$/.test(file.name)) {
// 图片 获取一下缩略图
let reader = new FileReader();
reader.readAsDataURL(file);
fileType = 'image'
let promise = new Promise((resolve,reject)=>{
reader.onload = function (e) {
fileSrc = e.target.result;
files.push({
name: file.name,
type: fileType,
src: fileSrc,
file: file
})
resolve()
}
})
promiseList.push(promise)
} else {
files.push({
name: file.name,
type: fileType,
src: fileSrc,
file: file
})
}
}
}
// 有图片
if (promiseList.length > 0) {
Promise.all(promiseList).then(()=>{
this.dragHoverShow = false
this.pasteFile(files)
})
} else {
this.dragHoverShow = false
this.pasteFile(files)
}
} else if (event.type === 'dragleave') {
// 离开
console.log('dragleave',event.type)
this.dragHoverShow = false
} else {
// 进入
console.log('进入',event.type)
this.dragHoverShow = true
}
},