Claude: Support downloading the conversation history as PNG
Using the html2canvas-pro library
This commit is contained in:
parent
680df7ace1
commit
b0f9249b0b
50
package-lock.json
generated
50
package-lock.json
generated
@ -20,6 +20,7 @@
|
||||
"@xterm/addon-web-links": "^0.11.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"html2canvas-pro": "^1.5.8",
|
||||
"labs": "git@github.com:leaningtech/labs.git",
|
||||
"node-html-parser": "^6.1.13",
|
||||
"postcss": "^8.4.47",
|
||||
@ -1119,6 +1120,15 @@
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/base64-arraybuffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
|
||||
"integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
@ -1355,6 +1365,15 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/css-line-break": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
|
||||
"integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/css-select": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
|
||||
@ -1960,6 +1979,19 @@
|
||||
"he": "bin/he"
|
||||
}
|
||||
},
|
||||
"node_modules/html2canvas-pro": {
|
||||
"version": "1.5.8",
|
||||
"resolved": "https://registry.npmjs.org/html2canvas-pro/-/html2canvas-pro-1.5.8.tgz",
|
||||
"integrity": "sha512-bVGAU7IvhBwBlRAmX6QhekX8lsaxmYoF6zIwf/HNlHscjx+KN8jw/U4PQRYqeEVm9+m13hcS1l5ChJB9/e29Lw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"css-line-break": "^2.1.0",
|
||||
"text-segmentation": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/humanize-ms": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
|
||||
@ -3059,6 +3091,15 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/text-segmentation": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
|
||||
"integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"utrie": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/thenify": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
|
||||
@ -3164,6 +3205,15 @@
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/utrie": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
|
||||
"integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"base64-arraybuffer": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.4.14",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz",
|
||||
|
@ -7,6 +7,7 @@
|
||||
"build": "vite build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@anthropic-ai/sdk": "^0.33.0",
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
"@leaningtech/cheerpx": "latest",
|
||||
"@oddbird/popover-polyfill": "^0.4.4",
|
||||
@ -26,7 +27,7 @@
|
||||
"tailwindcss": "^3.4.9",
|
||||
"vite": "^5.0.3",
|
||||
"vite-plugin-static-copy": "^1.0.6",
|
||||
"@anthropic-ai/sdk": "^0.33.0"
|
||||
"html2canvas-pro": "^1.5.8"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ export default {
|
||||
case '.fa-hourglass-half:before':
|
||||
case '.fa-hand:before':
|
||||
case '.fa-brain:before':
|
||||
case '.fa-download:before':
|
||||
case '.fa-keyboard:before':
|
||||
case '.fa-brands:before':
|
||||
case '.fa-solid:before':
|
||||
|
@ -5,6 +5,7 @@
|
||||
import PanelButton from './PanelButton.svelte';
|
||||
import SmallButton from './SmallButton.svelte';
|
||||
import { aiActivity } from './activities.js';
|
||||
import html2canvas from 'html2canvas-pro';
|
||||
export let handleTool;
|
||||
let stopRequested = false;
|
||||
function handleKeyEnter(e)
|
||||
@ -112,6 +113,18 @@
|
||||
stopRequested = false;
|
||||
}
|
||||
|
||||
async function handleDownload() {
|
||||
const messageListElement = document.getElementById('message-list');
|
||||
// Temporarily add padding and background for the list
|
||||
messageListElement.classList.add("p-1");
|
||||
const canvas = await html2canvas(messageListElement);
|
||||
messageListElement.classList.remove("p-1");
|
||||
const link = document.createElement('a');
|
||||
link.href = canvas.toDataURL('image/png');
|
||||
link.download = 'WebVM_Claude.png';
|
||||
link.click();
|
||||
}
|
||||
|
||||
function toggleThinkingMode() {
|
||||
enableThinking.set(!get(enableThinking));
|
||||
}
|
||||
@ -122,12 +135,13 @@
|
||||
<div class="flex grow flex-col overflow-y-hidden gap-2">
|
||||
<p class="flex flex-row gap-2">
|
||||
<span class="mr-auto flex items-center">Conversation history</span>
|
||||
<SmallButton buttonIcon="fa-solid fa-download" clickHandler={handleDownload} buttonTooltip="Save conversation as image"></SmallButton>
|
||||
<SmallButton buttonIcon="fa-solid fa-brain" clickHandler={toggleThinkingMode} buttonTooltip="{$enableThinking ? "Disable" : "Enable"} thinking mode" bgColor={$enableThinking ? "bg-neutral-500" : "bg-neutral-700"}></SmallButton>
|
||||
<SmallButton buttonIcon="fa-solid fa-trash-can" clickHandler={clearMessageHistory} buttonTooltip="Clear conversation history"></SmallButton>
|
||||
</p>
|
||||
<div class="flex grow overflow-y-scroll scrollbar" use:scrollMessage={$messageList}>
|
||||
<div class="h-full w-full">
|
||||
<div class="w-full min-h-full flex flex-col gap-2 justify-end">
|
||||
<div class="w-full min-h-full flex flex-col gap-2 justify-end bg-neutral-600" id="message-list">
|
||||
{#each $messageList as msg}
|
||||
{@const details = getMessageDetails(msg)}
|
||||
{#if details.isToolUse}
|
||||
|
Loading…
x
Reference in New Issue
Block a user