Thomas G. Lopes commited on
Commit
cb7934e
·
1 Parent(s): f57d852

add text size

Browse files
src/lib/components/inference-playground/generation-config.svelte CHANGED
@@ -1,5 +1,6 @@
1
  <script lang="ts">
2
  import type { ConversationClass } from "$lib/state/conversations.svelte.js";
 
3
  import { maxAllowedTokens } from "$lib/utils/business.svelte.js";
4
  import { cn } from "$lib/utils/cn.js";
5
  import { isNumber } from "$lib/utils/is.js";
@@ -11,6 +12,9 @@
11
  import StructuredOutputModal, { openStructuredOutputModal } from "./structured-output-modal.svelte";
12
  import { mcpServers } from "$lib/state/mcps.svelte.js";
13
  import { isMcpEnabled } from "$lib/constants.js";
 
 
 
14
  interface Props {
15
  conversation: ConversationClass;
16
  classNames?: string;
@@ -166,6 +170,36 @@
166
  class="peer relative h-5 w-9 rounded-full bg-gray-200 peer-checked:bg-black peer-focus:outline-hidden after:absolute after:start-[2px] after:top-[2px] after:h-4 after:w-4 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full peer-checked:after:border-white dark:border-gray-600 dark:bg-gray-700 dark:peer-checked:bg-blue-600"
167
  ></div>
168
  </label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  </div>
170
 
171
  <StructuredOutputModal {conversation} />
 
1
  <script lang="ts">
2
  import type { ConversationClass } from "$lib/state/conversations.svelte.js";
3
+ import { settings } from "$lib/state/settings.svelte.js";
4
  import { maxAllowedTokens } from "$lib/utils/business.svelte.js";
5
  import { cn } from "$lib/utils/cn.js";
6
  import { isNumber } from "$lib/utils/is.js";
 
12
  import StructuredOutputModal, { openStructuredOutputModal } from "./structured-output-modal.svelte";
13
  import { mcpServers } from "$lib/state/mcps.svelte.js";
14
  import { isMcpEnabled } from "$lib/constants.js";
15
+ import IconMinus from "~icons/carbon/subtract";
16
+ import IconPlus from "~icons/carbon/add-large";
17
+
18
  interface Props {
19
  conversation: ConversationClass;
20
  classNames?: string;
 
170
  class="peer relative h-5 w-9 rounded-full bg-gray-200 peer-checked:bg-black peer-focus:outline-hidden after:absolute after:start-[2px] after:top-[2px] after:h-4 after:w-4 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full peer-checked:after:border-white dark:border-gray-600 dark:bg-gray-700 dark:peer-checked:bg-blue-600"
171
  ></div>
172
  </label>
173
+
174
+ <!-- Text Size Setting -->
175
+ <div class="mt-4 flex items-center justify-between">
176
+ <span class="text-sm font-medium text-gray-900 dark:text-gray-300">Text Size</span>
177
+ <div class="flex items-center gap-2">
178
+ <button
179
+ type="button"
180
+ onclick={() => {
181
+ if (settings.textSize > 50) {
182
+ settings.textSize = settings.textSize - 10;
183
+ }
184
+ }}
185
+ class="btn-mini aspect-square"
186
+ >
187
+ <IconMinus />
188
+ </button>
189
+ <span class="text-sm">{settings.textSize}%</span>
190
+ <button
191
+ type="button"
192
+ onclick={() => {
193
+ if (settings.textSize < 200) {
194
+ settings.textSize = settings.textSize + 10;
195
+ }
196
+ }}
197
+ class="btn-mini aspect-square"
198
+ >
199
+ <IconPlus />
200
+ </button>
201
+ </div>
202
+ </div>
203
  </div>
204
 
205
  <StructuredOutputModal {conversation} />
src/lib/components/inference-playground/message-textarea.svelte CHANGED
@@ -4,6 +4,7 @@
4
  import { TextareaAutosize } from "$lib/spells/textarea-autosize.svelte.js";
5
  import { conversations } from "$lib/state/conversations.svelte";
6
  import { images } from "$lib/state/images.svelte";
 
7
  import type { ConversationMessage } from "$lib/types.js";
8
  import { fileToDataURL } from "$lib/utils/file.js";
9
  import { omit } from "$lib/utils/object.svelte";
@@ -14,6 +15,8 @@
14
  import IconMaximize from "~icons/carbon/maximize";
15
  import Tooltip from "../tooltip.svelte";
16
  import { previewImage } from "./img-preview.svelte";
 
 
17
 
18
  const multiple = $derived(conversations.active.length > 1);
19
  const loading = $derived(conversations.generating);
@@ -92,6 +95,17 @@
92
  });
93
 
94
  const autosized = new TextareaAutosize();
 
 
 
 
 
 
 
 
 
 
 
95
  </script>
96
 
97
  <svelte:window onkeydown={onKeydown} />
@@ -118,6 +132,7 @@
118
  bind:value={input}
119
  {@attach autosized.attachment}
120
  {@attach autofocus()}
 
121
  ></textarea>
122
  {#if canUploadImgs}
123
  <Tooltip openDelay={250}>
 
4
  import { TextareaAutosize } from "$lib/spells/textarea-autosize.svelte.js";
5
  import { conversations } from "$lib/state/conversations.svelte";
6
  import { images } from "$lib/state/images.svelte";
7
+ import { settings } from "$lib/state/settings.svelte.js";
8
  import type { ConversationMessage } from "$lib/types.js";
9
  import { fileToDataURL } from "$lib/utils/file.js";
10
  import { omit } from "$lib/utils/object.svelte";
 
15
  import IconMaximize from "~icons/carbon/maximize";
16
  import Tooltip from "../tooltip.svelte";
17
  import { previewImage } from "./img-preview.svelte";
18
+ import { watch } from "runed";
19
+ import { tick } from "svelte";
20
 
21
  const multiple = $derived(conversations.active.length > 1);
22
  const loading = $derived(conversations.generating);
 
95
  });
96
 
97
  const autosized = new TextareaAutosize();
98
+
99
+ // Watch for text size changes and trigger resize
100
+ watch(
101
+ () => settings.textSize,
102
+ () => {
103
+ // Trigger resize on next tick to ensure styles are applied
104
+ tick().then(() => {
105
+ autosized.triggerResize();
106
+ });
107
+ },
108
+ );
109
  </script>
110
 
111
  <svelte:window onkeydown={onKeydown} />
 
132
  bind:value={input}
133
  {@attach autosized.attachment}
134
  {@attach autofocus()}
135
+ style="font-size: {settings.textSize}%"
136
  ></textarea>
137
  {#if canUploadImgs}
138
  <Tooltip openDelay={250}>
src/lib/components/inference-playground/message.svelte CHANGED
@@ -4,6 +4,7 @@
4
  import { TextareaAutosize } from "$lib/spells/textarea-autosize.svelte.js";
5
  import { type ConversationClass } from "$lib/state/conversations.svelte.js";
6
  import { images } from "$lib/state/images.svelte";
 
7
  import { type ConversationMessage } from "$lib/types.js";
8
  import { copyToClipboard } from "$lib/utils/copy.js";
9
  import { cmdOrCtrl } from "$lib/utils/platform.js";
@@ -11,6 +12,8 @@
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";
@@ -91,6 +94,18 @@
91
  }
92
  return marked(parsedMessage.thinking);
93
  });
 
 
 
 
 
 
 
 
 
 
 
 
94
  </script>
95
 
96
  <div
@@ -142,6 +157,7 @@
142
  {#if conversation.data.parseMarkdown && !isEditing}
143
  <div
144
  class="relative w-full max-w-none 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"
 
145
  >
146
  <div class="prose prose-sm dark:prose-invert">
147
  {@html parsedReasoning}
@@ -171,6 +187,7 @@
171
  class="w-full resize-none overflow-hidden rounded-lg bg-transparent px-2 py-2.5 ring-gray-100 outline-none group-hover/message:ring-3 hover:bg-white focus:bg-white focus:ring-3 @2xl:px-3 dark:ring-gray-600 dark:hover:bg-gray-900 dark:focus:bg-gray-900"
172
  rows="1"
173
  {@attach reasoningAutosized.attachment}
 
174
  ></textarea>
175
  {/if}
176
  {/if}
@@ -184,6 +201,7 @@
184
  data-message
185
  data-test-id={TEST_IDS.message}
186
  {@attach clickOutside(() => (isEditing = false))}
 
187
  >
188
  <Tooltip>
189
  {#snippet trigger(tooltip)}
@@ -228,6 +246,7 @@
228
  class="w-full resize-none overflow-hidden border-none bg-transparent outline-none"
229
  rows="1"
230
  {@attach autosized.attachment}
 
231
  ></textarea>
232
  {/if}
233
  </div>
@@ -257,6 +276,7 @@
257
  data-message
258
  data-test-id={TEST_IDS.message}
259
  {@attach autosized.attachment}
 
260
  ></textarea>
261
  {/if}
262
  </div>
 
4
  import { TextareaAutosize } from "$lib/spells/textarea-autosize.svelte.js";
5
  import { type ConversationClass } from "$lib/state/conversations.svelte.js";
6
  import { images } from "$lib/state/images.svelte";
7
+ import { settings } from "$lib/state/settings.svelte.js";
8
  import { type ConversationMessage } from "$lib/types.js";
9
  import { copyToClipboard } from "$lib/utils/copy.js";
10
  import { cmdOrCtrl } from "$lib/utils/platform.js";
 
12
  import { clickOutside } from "$lib/attachments/click-outside.js";
13
  import { FileUpload } from "melt/builders";
14
  import { fade } from "svelte/transition";
15
+ import { watch } from "runed";
16
+ import { tick } from "svelte";
17
  import IconCopy from "~icons/carbon/copy";
18
  import IconImage from "~icons/carbon/image-reference";
19
  import IconMaximize from "~icons/carbon/maximize";
 
94
  }
95
  return marked(parsedMessage.thinking);
96
  });
97
+
98
+ // Watch for text size changes and trigger resize
99
+ watch(
100
+ () => settings.textSize,
101
+ () => {
102
+ // Trigger resize on next tick to ensure styles are applied
103
+ tick().then(() => {
104
+ autosized.triggerResize();
105
+ reasoningAutosized.triggerResize();
106
+ });
107
+ },
108
+ );
109
  </script>
110
 
111
  <div
 
157
  {#if conversation.data.parseMarkdown && !isEditing}
158
  <div
159
  class="relative w-full max-w-none 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"
160
+ style="font-size: {settings.textSize}%"
161
  >
162
  <div class="prose prose-sm dark:prose-invert">
163
  {@html parsedReasoning}
 
187
  class="w-full resize-none overflow-hidden rounded-lg bg-transparent px-2 py-2.5 ring-gray-100 outline-none group-hover/message:ring-3 hover:bg-white focus:bg-white focus:ring-3 @2xl:px-3 dark:ring-gray-600 dark:hover:bg-gray-900 dark:focus:bg-gray-900"
188
  rows="1"
189
  {@attach reasoningAutosized.attachment}
190
+ style="font-size: {settings.textSize}%"
191
  ></textarea>
192
  {/if}
193
  {/if}
 
201
  data-message
202
  data-test-id={TEST_IDS.message}
203
  {@attach clickOutside(() => (isEditing = false))}
204
+ style="font-size: {settings.textSize}%"
205
  >
206
  <Tooltip>
207
  {#snippet trigger(tooltip)}
 
246
  class="w-full resize-none overflow-hidden border-none bg-transparent outline-none"
247
  rows="1"
248
  {@attach autosized.attachment}
249
+ style="font-size: {settings.textSize}%"
250
  ></textarea>
251
  {/if}
252
  </div>
 
276
  data-message
277
  data-test-id={TEST_IDS.message}
278
  {@attach autosized.attachment}
279
+ style="font-size: {settings.textSize}%"
280
  ></textarea>
281
  {/if}
282
  </div>
src/lib/components/inference-playground/playground.svelte CHANGED
@@ -2,6 +2,7 @@
2
  import { observe, observed, ObservedElements } from "$lib/attachments/observe.svelte.js";
3
  import { conversations } from "$lib/state/conversations.svelte";
4
  import { projects } from "$lib/state/projects.svelte";
 
5
  import { token } from "$lib/state/token.svelte.js";
6
  import { isHFModel } from "$lib/types.js";
7
  import { iterate } from "$lib/utils/array.js";
@@ -96,6 +97,7 @@
96
  projects.update({ ...projects.current, systemMessage: e.currentTarget.value });
97
  }}
98
  class="absolute inset-x-0 bottom-0 h-full resize-none bg-transparent px-3 pt-10 text-sm outline-hidden"
 
99
  ></textarea>
100
  </div>
101
  </div>
 
2
  import { observe, observed, ObservedElements } from "$lib/attachments/observe.svelte.js";
3
  import { conversations } from "$lib/state/conversations.svelte";
4
  import { projects } from "$lib/state/projects.svelte";
5
+ import { settings } from "$lib/state/settings.svelte.js";
6
  import { token } from "$lib/state/token.svelte.js";
7
  import { isHFModel } from "$lib/types.js";
8
  import { iterate } from "$lib/utils/array.js";
 
97
  projects.update({ ...projects.current, systemMessage: e.currentTarget.value });
98
  }}
99
  class="absolute inset-x-0 bottom-0 h-full resize-none bg-transparent px-3 pt-10 text-sm outline-hidden"
100
+ style="font-size: {settings.textSize}%"
101
  ></textarea>
102
  </div>
103
  </div>
src/lib/state/settings.svelte.ts ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const TEXT_SIZE_KEY = "textSize";
2
+
3
+ class Settings {
4
+ #textSize = $state(100);
5
+
6
+ constructor() {
7
+ const storedTextSize = localStorage.getItem(TEXT_SIZE_KEY);
8
+ const parsed = storedTextSize ? parseInt(storedTextSize, 10) : null;
9
+ this.textSize = parsed && !isNaN(parsed) ? parsed : 100;
10
+ }
11
+
12
+ get textSize() {
13
+ return this.#textSize;
14
+ }
15
+
16
+ set textSize(size: number) {
17
+ localStorage.setItem(TEXT_SIZE_KEY, JSON.stringify(size));
18
+ this.#textSize = size;
19
+ }
20
+
21
+ // Reset to default
22
+ resetTextSize = () => {
23
+ this.textSize = 100;
24
+ };
25
+ }
26
+
27
+ export const settings = new Settings();