feat: multi-image paste — collect all images + text from one clipboard event
This commit is contained in:
@@ -355,29 +355,47 @@
|
||||
} catch(e) {} finally { inFlight = false; }
|
||||
}
|
||||
|
||||
// Auto-send on paste (text or image)
|
||||
inputEl.addEventListener('paste', (e) => {
|
||||
const items = (e.clipboardData || window.clipboardData)?.items || [];
|
||||
let imgItem = null;
|
||||
for (const it of items) {
|
||||
if (it.kind === 'file' && it.type.startsWith('image/')) { imgItem = it; break; }
|
||||
}
|
||||
if (imgItem) {
|
||||
e.preventDefault();
|
||||
const file = imgItem.getAsFile();
|
||||
// Auto-send on paste — all images + all text in one clipboard event go as ONE request
|
||||
function readFileB64(file) {
|
||||
return new Promise(resolve => {
|
||||
const fr = new FileReader();
|
||||
fr.onload = () => {
|
||||
const dataUrl = fr.result;
|
||||
const base64 = dataUrl.split(',')[1];
|
||||
send({ image: { data: base64, media_type: file.type || 'image/png' } });
|
||||
};
|
||||
fr.onload = () => resolve({
|
||||
data: fr.result.split(',')[1],
|
||||
media_type: file.type || 'image/png',
|
||||
});
|
||||
fr.readAsDataURL(file);
|
||||
} else {
|
||||
});
|
||||
}
|
||||
function getAsStringP(item) {
|
||||
return new Promise(r => item.getAsString(r));
|
||||
}
|
||||
|
||||
inputEl.addEventListener('paste', async (e) => {
|
||||
const items = Array.from((e.clipboardData || window.clipboardData)?.items || []);
|
||||
const imageFiles = [];
|
||||
let pastedTextP = Promise.resolve('');
|
||||
for (const it of items) {
|
||||
if (it.kind === 'file' && it.type.startsWith('image/')) {
|
||||
imageFiles.push(it.getAsFile());
|
||||
} else if (it.kind === 'string' && it.type === 'text/plain') {
|
||||
pastedTextP = getAsStringP(it);
|
||||
}
|
||||
}
|
||||
|
||||
if (imageFiles.length === 0) {
|
||||
setTimeout(() => {
|
||||
const t = inputEl.value.trim();
|
||||
if (t) send({ text: t });
|
||||
}, 50);
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
const images = await Promise.all(imageFiles.map(readFileB64));
|
||||
const pastedText = (await pastedTextP).trim();
|
||||
const existing = inputEl.value.trim();
|
||||
const fullText = [existing, pastedText].filter(Boolean).join('\n');
|
||||
send({ text: fullText, images });
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user