Thomas G. Lopes commited on
Commit
cdc312f
·
1 Parent(s): 2a40f3a

quick edit on markdown view

Browse files
AGENTS.md CHANGED
@@ -88,4 +88,3 @@
88
 
89
  - https://svelte.dev/docs/svelte/llms.txt
90
  - https://svelte.dev/docs/kit/llms.txt
91
-
 
88
 
89
  - https://svelte.dev/docs/svelte/llms.txt
90
  - https://svelte.dev/docs/kit/llms.txt
 
src/lib/components/inference-playground/message.svelte CHANGED
@@ -8,11 +8,13 @@
8
  import { copyToClipboard } from "$lib/utils/copy.js";
9
  import { cmdOrCtrl } from "$lib/utils/platform.js";
10
  import { AsyncQueue } from "$lib/utils/queue.js";
 
11
  import { FileUpload } from "melt/builders";
12
  import { fade } from "svelte/transition";
13
  import IconCopy from "~icons/carbon/copy";
14
  import IconImage from "~icons/carbon/image-reference";
15
  import IconMaximize from "~icons/carbon/maximize";
 
16
  import IconCustom from "../icon-custom.svelte";
17
  import LocalToasts from "../local-toasts.svelte";
18
  import { previewImage } from "./img-preview.svelte";
@@ -34,6 +36,8 @@
34
 
35
  const canUploadImgs = $derived(message.role === "user" && conversation.supportsImgUpload);
36
 
 
 
37
  const fileQueue = new AsyncQueue();
38
  const fileUpload = new FileUpload({
39
  accept: "image/*",
@@ -98,11 +102,56 @@
98
  <div class="flex w-full gap-4">
99
  {#if conversation.data.parseMarkdown && message?.role === "assistant"}
100
  <div
101
- class="prose prose-sm dark:prose-invert max-w-none grow rounded-lg bg-transparent px-2 py-2.5 ring-gray-100 outline-none group-hover/message:ring-3 hover:bg-white @2xl:px-3 dark:ring-gray-600 dark:hover:bg-gray-900"
102
  data-message
103
  data-test-id={TEST_IDS.message}
 
104
  >
105
- {@html parsedContent}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  </div>
107
  {:else}
108
  <textarea
 
8
  import { copyToClipboard } from "$lib/utils/copy.js";
9
  import { cmdOrCtrl } from "$lib/utils/platform.js";
10
  import { AsyncQueue } from "$lib/utils/queue.js";
11
+ import { clickOutside } from "$lib/attachments/click-outside.js";
12
  import { FileUpload } from "melt/builders";
13
  import { fade } from "svelte/transition";
14
  import IconCopy from "~icons/carbon/copy";
15
  import IconImage from "~icons/carbon/image-reference";
16
  import IconMaximize from "~icons/carbon/maximize";
17
+ import IconEdit from "~icons/carbon/edit";
18
  import IconCustom from "../icon-custom.svelte";
19
  import LocalToasts from "../local-toasts.svelte";
20
  import { previewImage } from "./img-preview.svelte";
 
36
 
37
  const canUploadImgs = $derived(message.role === "user" && conversation.supportsImgUpload);
38
 
39
+ let isEditing = $state(false);
40
+
41
  const fileQueue = new AsyncQueue();
42
  const fileUpload = new FileUpload({
43
  accept: "image/*",
 
102
  <div class="flex w-full gap-4">
103
  {#if conversation.data.parseMarkdown && message?.role === "assistant"}
104
  <div
105
+ class="relative max-w-none grow rounded-lg bg-transparent px-2 py-2.5 ring-gray-100 outline-none group-hover/message:ring-3 hover:bg-white @2xl:px-3 dark:ring-gray-600 dark:hover:bg-gray-900"
106
  data-message
107
  data-test-id={TEST_IDS.message}
108
+ {@attach clickOutside(() => (isEditing = false))}
109
  >
110
+ <Tooltip>
111
+ {#snippet trigger(tooltip)}
112
+ <button
113
+ tabindex="0"
114
+ onclick={() => {
115
+ isEditing = !isEditing;
116
+ }}
117
+ type="button"
118
+ class="absolute top-1 right-1 grid size-6 place-items-center rounded border border-gray-200 bg-white text-xs transition-opacity hover:bg-gray-100 hover:text-blue-700 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white {isEditing
119
+ ? 'opacity-100'
120
+ : 'opacity-0 group-hover/message:opacity-100'}"
121
+ {...tooltip.trigger}
122
+ >
123
+ <IconEdit />
124
+ </button>
125
+ {/snippet}
126
+ {isEditing ? "Stop editing" : "Edit"}
127
+ </Tooltip>
128
+
129
+ {#if !isEditing}
130
+ <div class="prose prose-sm dark:prose-invert">
131
+ {@html parsedContent}
132
+ </div>
133
+ {:else}
134
+ <textarea
135
+ value={message?.content}
136
+ onchange={e => {
137
+ const el = e.target as HTMLTextAreaElement;
138
+ const content = el?.value;
139
+ if (!message || !content) return;
140
+ conversation.updateMessage({ index, message: { ...message, content } });
141
+ }}
142
+ onkeydown={e => {
143
+ if ((e.ctrlKey || e.metaKey) && e.key === "g") {
144
+ e.preventDefault();
145
+ e.stopPropagation();
146
+ onRegen?.();
147
+ }
148
+ }}
149
+ placeholder="Enter {message?.role} message"
150
+ class="w-full resize-none overflow-hidden border-none bg-transparent outline-none"
151
+ rows="1"
152
+ {@attach autosized.attachment}
153
+ ></textarea>
154
+ {/if}
155
  </div>
156
  {:else}
157
  <textarea