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 <[email protected]>
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>
|