feat: capture files and images in inbox

This commit is contained in:
2026-06-05 02:06:21 +08:00
parent 326f6f283d
commit a96a316883
10 changed files with 427 additions and 21 deletions
+54 -3
View File
@@ -144,6 +144,13 @@ async function runReadyScenario(cdp, url) {
await clickText(cdp, '.inbox-header .btn', 'Вставить из буфера')
await assertText(cdp, 'https://example.test/from-clipboard', 'inbox: clipboard URL captured')
await assertText(cdp, 'Ссылка', 'inbox: clipboard URL kind visible')
await emitDroppedFiles(cdp, ['/tmp/smoke-drop-folder'])
await assertText(cdp, 'smoke-drop-folder', 'inbox: dropped folder captured')
await assertText(cdp, 'Перетаскивание', 'inbox: dropped source visible')
await setClipboardImage(cdp, 'pasted-smoke.png', 'image/png', 'c21va2UtaW1hZ2U=')
await clickText(cdp, '.inbox-header .btn', 'Вставить из буфера')
await assertText(cdp, 'pasted-smoke.png', 'inbox: clipboard image captured')
await assertText(cdp, 'Изображение', 'inbox: clipboard image kind visible')
await screenshot(cdp, 'inbox.png')
await clickText(cdp, '.inbox-item', 'Inbox Smoke Item')
await assertText(cdp, 'Inbox Smoke Item', 'inbox: item opens from list')
@@ -346,6 +353,29 @@ async function setClipboardText(cdp, value) {
})
}
async function setClipboardImage(cdp, name, type, base64) {
await cdp.send('Runtime.evaluate', {
expression: `
window.__VERSTAK_GUI_SMOKE_CLIPBOARD__ = '';
window.__VERSTAK_GUI_SMOKE_CLIPBOARD_ITEMS__ = [{
types: [${JSON.stringify(type)}],
getType: async () => new File([Uint8Array.from(atob(${JSON.stringify(base64)}), c => c.charCodeAt(0))], ${JSON.stringify(name)}, { type: ${JSON.stringify(type)} }),
}];
`,
awaitPromise: true,
returnByValue: true,
})
}
async function emitDroppedFiles(cdp, paths) {
await cdp.send('Runtime.evaluate', {
expression: `window.__VERSTAK_GUI_SMOKE__.dropFiles(${JSON.stringify(paths)})`,
awaitPromise: true,
returnByValue: true,
})
await sleep(300)
}
async function clickFolderOpenButton(cdp, name) {
const ok = await evalValue(cdp, `
(() => {
@@ -574,6 +604,7 @@ function wailsMockSource() {
configurable: true,
value: {
readText: async () => window.__VERSTAK_GUI_SMOKE_CLIPBOARD__ || '',
read: async () => window.__VERSTAK_GUI_SMOKE_CLIPBOARD_ITEMS__ || [],
},
});
@@ -719,6 +750,18 @@ function wailsMockSource() {
state.nodes.push(node);
return clone({ ...node, captureKind: node.captureKind, captureSource: node.captureSource });
},
CapturePath: async (sourcePath) => {
const title = String(sourcePath || '').split('/').filter(Boolean).pop() || 'Dropped file';
const kind = title.includes('folder') ? 'folder' : 'file';
const node = { id: 'node-capture-path-' + Date.now(), title, type: kind === 'folder' ? 'folder' : 'file', section: '', captureInbox: true, captureKind: kind, captureSource: 'drop', createdAt: now, has_children: false, children: [] };
state.nodes.push(node);
return clone({ ...node, captureKind: node.captureKind, captureSource: node.captureSource });
},
CaptureFileData: async (filename) => {
const node = { id: 'node-capture-data-' + Date.now(), title: filename, type: 'file', section: '', captureInbox: true, captureKind: filename.endsWith('.png') ? 'image' : 'file', captureSource: 'clipboard', createdAt: now, has_children: false, children: [] };
state.nodes.push(node);
return clone({ ...node, captureKind: node.captureKind, captureSource: node.captureSource });
},
ListTrash: async () => clone({
trashPath: '/tmp/verstak-smoke-vault/.verstak/trash',
nodes: [{ id: 'node-trash', title: 'Trash Smoke Folder', type: 'folder', fsPath: 'Trash Smoke Folder', deletedAt: now }],
@@ -854,11 +897,19 @@ function wailsMockSource() {
};
window.go = { main: { App } };
const runtimeHandlers = {};
window.runtime = {
EventsOn: () => {},
EventsOff: () => {},
EventsOn: (name, handler) => { runtimeHandlers[name] = handler; },
EventsOff: (name) => { delete runtimeHandlers[name]; },
};
window.__VERSTAK_GUI_SMOKE__ = {
mode,
state,
events,
dropFiles: async (paths) => {
if (runtimeHandlers['files-dropped']) await runtimeHandlers['files-dropped'](paths);
},
};
window.__VERSTAK_GUI_SMOKE__ = { mode, state, events };
})();
`
}