Spaces:
Paused
Paused
Add a message wide copy button (#453)
Browse files* add-copytoclipboardbtn for the all message
* fix padding
* fix padding
* Fix styling
* Move before like and dislike button
* position and spacing
* mobile fix
---------
Co-authored-by: Victor Mustar <victor.mustar@gmail.com>
src/lib/components/CopyToClipBoardBtn.svelte
CHANGED
|
@@ -41,6 +41,7 @@
|
|
| 41 |
"
|
| 42 |
title={"Copy to clipboard"}
|
| 43 |
type="button"
|
|
|
|
| 44 |
on:click={handleClick}
|
| 45 |
>
|
| 46 |
<span class="relative">
|
|
|
|
| 41 |
"
|
| 42 |
title={"Copy to clipboard"}
|
| 43 |
type="button"
|
| 44 |
+
on:click
|
| 45 |
on:click={handleClick}
|
| 46 |
>
|
| 47 |
<span class="relative">
|
src/lib/components/chat/ChatMessage.svelte
CHANGED
|
@@ -7,6 +7,7 @@
|
|
| 7 |
import { page } from "$app/stores";
|
| 8 |
|
| 9 |
import CodeBlock from "../CodeBlock.svelte";
|
|
|
|
| 10 |
import IconLoading from "../icons/IconLoading.svelte";
|
| 11 |
import CarbonRotate360 from "~icons/carbon/rotate-360";
|
| 12 |
import CarbonDownload from "~icons/carbon/download";
|
|
@@ -58,6 +59,7 @@
|
|
| 58 |
let contentEl: HTMLElement;
|
| 59 |
let loadingEl: IconLoading;
|
| 60 |
let pendingTimeout: ReturnType<typeof setTimeout>;
|
|
|
|
| 61 |
|
| 62 |
const renderer = new marked.Renderer();
|
| 63 |
// For code blocks with simple backticks
|
|
@@ -121,6 +123,12 @@
|
|
| 121 |
$: webSearchSources =
|
| 122 |
searchUpdates &&
|
| 123 |
searchUpdates?.filter(({ messageType }) => messageType === "sources")?.[0]?.sources;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
</script>
|
| 125 |
|
| 126 |
{#if message.from === "assistant"}
|
|
@@ -186,7 +194,7 @@
|
|
| 186 |
<div
|
| 187 |
class="absolute bottom-1 right-0 flex max-md:transition-all md:bottom-0 md:group-hover:visible md:group-hover:opacity-100
|
| 188 |
{message.score ? 'visible opacity-100' : 'invisible max-md:-translate-y-4 max-md:opacity-0'}
|
| 189 |
-
{isTapped ? 'max-md:visible max-md:translate-y-0 max-md:opacity-100' : ''}
|
| 190 |
"
|
| 191 |
>
|
| 192 |
<button
|
|
@@ -212,6 +220,13 @@
|
|
| 212 |
>
|
| 213 |
<CarbonThumbsDown class="h-[1.14em] w-[1.14em]" />
|
| 214 |
</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
</div>
|
| 216 |
{/if}
|
| 217 |
</div>
|
|
|
|
| 7 |
import { page } from "$app/stores";
|
| 8 |
|
| 9 |
import CodeBlock from "../CodeBlock.svelte";
|
| 10 |
+
import CopyToClipBoardBtn from "../CopyToClipBoardBtn.svelte";
|
| 11 |
import IconLoading from "../icons/IconLoading.svelte";
|
| 12 |
import CarbonRotate360 from "~icons/carbon/rotate-360";
|
| 13 |
import CarbonDownload from "~icons/carbon/download";
|
|
|
|
| 59 |
let contentEl: HTMLElement;
|
| 60 |
let loadingEl: IconLoading;
|
| 61 |
let pendingTimeout: ReturnType<typeof setTimeout>;
|
| 62 |
+
let isCopied = false;
|
| 63 |
|
| 64 |
const renderer = new marked.Renderer();
|
| 65 |
// For code blocks with simple backticks
|
|
|
|
| 123 |
$: webSearchSources =
|
| 124 |
searchUpdates &&
|
| 125 |
searchUpdates?.filter(({ messageType }) => messageType === "sources")?.[0]?.sources;
|
| 126 |
+
|
| 127 |
+
$: if (isCopied) {
|
| 128 |
+
setTimeout(() => {
|
| 129 |
+
isCopied = false;
|
| 130 |
+
}, 1000);
|
| 131 |
+
}
|
| 132 |
</script>
|
| 133 |
|
| 134 |
{#if message.from === "assistant"}
|
|
|
|
| 194 |
<div
|
| 195 |
class="absolute bottom-1 right-0 flex max-md:transition-all md:bottom-0 md:group-hover:visible md:group-hover:opacity-100
|
| 196 |
{message.score ? 'visible opacity-100' : 'invisible max-md:-translate-y-4 max-md:opacity-0'}
|
| 197 |
+
{isTapped || isCopied ? 'max-md:visible max-md:translate-y-0 max-md:opacity-100' : ''}
|
| 198 |
"
|
| 199 |
>
|
| 200 |
<button
|
|
|
|
| 220 |
>
|
| 221 |
<CarbonThumbsDown class="h-[1.14em] w-[1.14em]" />
|
| 222 |
</button>
|
| 223 |
+
<CopyToClipBoardBtn
|
| 224 |
+
on:click={() => {
|
| 225 |
+
isCopied = true;
|
| 226 |
+
}}
|
| 227 |
+
classNames="ml-1.5 !rounded-sm !p-1 !text-sm !text-gray-400 focus:!ring-0 hover:!text-gray-500 dark:!text-gray-400 dark:hover:!text-gray-300 !border-none !shadow-none"
|
| 228 |
+
value={message.content}
|
| 229 |
+
/>
|
| 230 |
</div>
|
| 231 |
{/if}
|
| 232 |
</div>
|