radames commited on
Commit
d11af81
1 Parent(s): 2e21255

renaming, debounce input

Browse files
frontend/src/lib/App.svelte CHANGED
@@ -2,13 +2,13 @@
2
  import Cursor from '$lib/Cursor.svelte';
3
  import Frame from '$lib/Frame.svelte';
4
  import PaintFrame from '$lib/PaintFrame.svelte';
5
- import Canvas from '$lib/Canvas.svelte';
6
  import Menu from '$lib/Menu.svelte';
7
  import PromptModal from '$lib/PromptModal.svelte';
8
  import { COLORS, EMOJIS } from '$lib/constants';
9
  import { PUBLIC_WS_INPAINTING } from '$env/static/public';
10
  import type { PromptImgObject, PromptImgKey, Presence } from '$lib/types';
11
- import { loadingState, currZoomTransform, showFrames } from '$lib/store';
12
 
13
  import { useMyPresence, useObject, useOthers } from '$lib/liveblocks';
14
 
@@ -30,7 +30,6 @@
30
  frame: null,
31
  isPrompting: false,
32
  isLoading: false,
33
- isMoving: true,
34
  currentPrompt: ''
35
  };
36
  myPresence.update(initialPresence);
@@ -41,18 +40,10 @@
41
 
42
  const promptImgStorage = useObject('promptImgStorage');
43
 
44
- function getpromptImgList(promptImgList: PromptImgObject[]): PromptImgObject[] {
45
- if (promptImgList) {
46
- const list: PromptImgObject[] = Object.values(promptImgList);
47
- return list.sort((a, b) => a.date - b.date);
48
- }
49
- return [];
50
- }
51
  let showModal = false;
52
- let promptImgList: PromptImgObject[] = [];
53
- $: promptImgList = getpromptImgList($promptImgStorage?.toObject());
54
 
55
  $: isPrompting = $myPresence?.isPrompting || false;
 
56
 
57
  let canvasEl: HTMLCanvasElement;
58
 
@@ -69,7 +60,8 @@
69
  showModal = false;
70
  }
71
 
72
- function onPrompt(e: CustomEvent) {
 
73
  generateImage();
74
  showModal = false;
75
  }
@@ -94,7 +86,7 @@
94
  return base64Crop;
95
  }
96
  async function generateImage() {
97
- if (isPrompting) return;
98
  $loadingState = 'Pending';
99
  const prompt = $myPresence.currentPrompt;
100
  const position = $myPresence.frame;
@@ -106,7 +98,7 @@
106
  const sessionHash = crypto.randomUUID();
107
  const payload = {
108
  fn_index: 0,
109
- data: [getImageCrop(position), prompt, 0.75, 7.5, 30, 'patchmatch'],
110
  session_hash: sessionHash
111
  };
112
  console.log('payload', payload);
@@ -137,7 +129,8 @@
137
  $loadingState = 'Queue full';
138
  websocket.close();
139
  myPresence.update({
140
- isPrompting: false
 
141
  });
142
  return;
143
  case 'estimation':
@@ -167,13 +160,17 @@
167
  $promptImgStorage.set(key, promptImg);
168
  console.log(imgURL);
169
  $loadingState = data.success ? 'Complete' : 'Error';
 
 
 
170
  } catch (err) {
171
  const tError = err as Error;
172
  $loadingState = tError?.message;
173
  }
174
  websocket.close();
175
  myPresence.update({
176
- isPrompting: false
 
177
  });
178
  return;
179
  case 'process_starts':
@@ -196,7 +193,7 @@
196
  <PromptModal on:prompt={onPrompt} on:close={onClose} />
197
  {/if}
198
  <div class="fixed top-0 left-0 z-0 w-screen h-screen">
199
- <Canvas bind:value={canvasEl} />
200
 
201
  <main class="z-10 relative">
202
  <PaintFrame transform={$currZoomTransform} interactive={!isPrompting} />
 
2
  import Cursor from '$lib/Cursor.svelte';
3
  import Frame from '$lib/Frame.svelte';
4
  import PaintFrame from '$lib/PaintFrame.svelte';
5
+ import PaintCanvas from '$lib/PaintCanvas.svelte';
6
  import Menu from '$lib/Menu.svelte';
7
  import PromptModal from '$lib/PromptModal.svelte';
8
  import { COLORS, EMOJIS } from '$lib/constants';
9
  import { PUBLIC_WS_INPAINTING } from '$env/static/public';
10
  import type { PromptImgObject, PromptImgKey, Presence } from '$lib/types';
11
+ import { loadingState, currZoomTransform } from '$lib/store';
12
 
13
  import { useMyPresence, useObject, useOthers } from '$lib/liveblocks';
14
 
 
30
  frame: null,
31
  isPrompting: false,
32
  isLoading: false,
 
33
  currentPrompt: ''
34
  };
35
  myPresence.update(initialPresence);
 
40
 
41
  const promptImgStorage = useObject('promptImgStorage');
42
 
 
 
 
 
 
 
 
43
  let showModal = false;
 
 
44
 
45
  $: isPrompting = $myPresence?.isPrompting || false;
46
+ $: isLoading = $myPresence?.isLoading || false;
47
 
48
  let canvasEl: HTMLCanvasElement;
49
 
 
60
  showModal = false;
61
  }
62
 
63
+ function onPrompt() {
64
+ console.log('onPrompt');
65
  generateImage();
66
  showModal = false;
67
  }
 
86
  return base64Crop;
87
  }
88
  async function generateImage() {
89
+ if (isLoading) return;
90
  $loadingState = 'Pending';
91
  const prompt = $myPresence.currentPrompt;
92
  const position = $myPresence.frame;
 
98
  const sessionHash = crypto.randomUUID();
99
  const payload = {
100
  fn_index: 0,
101
+ data: [getImageCrop(position), prompt, 0.75, 7.5, 40, 'patchmatch'],
102
  session_hash: sessionHash
103
  };
104
  console.log('payload', payload);
 
129
  $loadingState = 'Queue full';
130
  websocket.close();
131
  myPresence.update({
132
+ isPrompting: false,
133
+ isLoading: false
134
  });
135
  return;
136
  case 'estimation':
 
160
  $promptImgStorage.set(key, promptImg);
161
  console.log(imgURL);
162
  $loadingState = data.success ? 'Complete' : 'Error';
163
+ setTimeout(() => {
164
+ $loadingState = '';
165
+ }, 2000);
166
  } catch (err) {
167
  const tError = err as Error;
168
  $loadingState = tError?.message;
169
  }
170
  websocket.close();
171
  myPresence.update({
172
+ isPrompting: false,
173
+ isLoading: false
174
  });
175
  return;
176
  case 'process_starts':
 
193
  <PromptModal on:prompt={onPrompt} on:close={onClose} />
194
  {/if}
195
  <div class="fixed top-0 left-0 z-0 w-screen h-screen">
196
+ <PaintCanvas bind:canvasEl />
197
 
198
  <main class="z-10 relative">
199
  <PaintFrame transform={$currZoomTransform} interactive={!isPrompting} />
frontend/src/lib/Frame.svelte CHANGED
@@ -7,6 +7,7 @@
7
  export let color = '';
8
  export let position = { x: 0, y: 0 };
9
  export let prompt = '';
 
10
  export let interactive = false;
11
  export let isDragging = false;
12
  $: coord = {
@@ -19,11 +20,11 @@
19
  class="frame z-0 flex relative
20
  {!interactive ? 'pointer-events-none touch-none' : ''}
21
  {isDragging ? 'cursor-grabbing' : 'cursor-grab'}"
22
- style={`transform: translateX(${coord.x}px) translateY(${coord.y}px) scale(${transform.k});
23
- background-image: linear-gradient(${color}, rgba(255,255,255,0));
24
- color: ${color};
25
- `}
26
  >
 
 
 
27
  <div class="small-frame z-0 flex relative" />
28
  <LoadingIcon />
29
  <h2 class="text-lg">Click to paint</h2>
@@ -37,7 +38,7 @@
37
  transform-origin: 0 0;
38
  }
39
  .small-frame {
40
- @apply pointer-events-none touch-none absolute top-1/2 left-1/2 border-2 border-spacing-3 border-sky-500 w-[256px] h-[256px];
41
  transform: translateX(-50%) translateY(-50%);
42
  }
43
  </style>
 
7
  export let color = '';
8
  export let position = { x: 0, y: 0 };
9
  export let prompt = '';
10
+ export let loadingState = '';
11
  export let interactive = false;
12
  export let isDragging = false;
13
  $: coord = {
 
20
  class="frame z-0 flex relative
21
  {!interactive ? 'pointer-events-none touch-none' : ''}
22
  {isDragging ? 'cursor-grabbing' : 'cursor-grab'}"
23
+ style={`transform: translateX(${coord.x}px) translateY(${coord.y}px) scale(${transform.k}); border-color: ${color};`}
 
 
 
24
  >
25
+ {#if loadingState}
26
+ <span class="text-white drop-shadow-lg">{loadingState}</span>
27
+ {/if}
28
  <div class="small-frame z-0 flex relative" />
29
  <LoadingIcon />
30
  <h2 class="text-lg">Click to paint</h2>
 
38
  transform-origin: 0 0;
39
  }
40
  .small-frame {
41
+ @apply pointer-events-none touch-none absolute top-1/2 left-1/2 border-2 border-spacing-3 w-[256px] h-[256px];
42
  transform: translateX(-50%) translateY(-50%);
43
  }
44
  </style>
frontend/src/lib/Menu.svelte CHANGED
@@ -4,7 +4,6 @@
4
  const dispatch = createEventDispatcher();
5
 
6
  const onKeyup = (e: KeyboardEvent) => {
7
- e.preventDefault();
8
  if (e.key === 'Enter') {
9
  dispatch('paintMode', { mode: 'paint' });
10
  }
 
4
  const dispatch = createEventDispatcher();
5
 
6
  const onKeyup = (e: KeyboardEvent) => {
 
7
  if (e.key === 'Enter') {
8
  dispatch('paintMode', { mode: 'paint' });
9
  }
frontend/src/lib/{Canvas.svelte → PaintCanvas.svelte} RENAMED
@@ -15,8 +15,7 @@
15
  const height = 512 * 4;
16
  const width = 512 * 4;
17
 
18
- let canvasEl: HTMLCanvasElement;
19
- export { canvasEl as value };
20
 
21
  let containerEl: HTMLDivElement;
22
  let canvasCtx: CanvasRenderingContext2D;
 
15
  const height = 512 * 4;
16
  const width = 512 * 4;
17
 
18
+ export let canvasEl: HTMLCanvasElement = undefined;
 
19
 
20
  let containerEl: HTMLDivElement;
21
  let canvasCtx: CanvasRenderingContext2D;
frontend/src/lib/PaintFrame.svelte CHANGED
@@ -1,5 +1,4 @@
1
  <script lang="ts">
2
- import LoadingIcon from '$lib/LoadingIcon.svelte';
3
  import Frame from '$lib/Frame.svelte';
4
  import { drag } from 'd3-drag';
5
  import { select } from 'd3-selection';
@@ -8,9 +7,8 @@
8
  import type { ZoomTransform } from 'd3-zoom';
9
  import { onMount } from 'svelte';
10
 
11
- import { loadingState } from '$lib/store';
12
  import { useMyPresence } from '$lib/liveblocks';
13
-
14
  const myPresence = useMyPresence();
15
 
16
  export let transform: ZoomTransform;
@@ -27,7 +25,7 @@
27
  $: prompt = $myPresence?.currentPrompt;
28
 
29
  onMount(() => {
30
- function dragstarted(event: Event) {
31
  isDragging = true;
32
  }
33
 
@@ -59,5 +57,5 @@
59
  </script>
60
 
61
  <div bind:this={frameElement}>
62
- <Frame {color} {position} {prompt} {transform} {isDragging} {interactive} />
63
  </div>
 
1
  <script lang="ts">
 
2
  import Frame from '$lib/Frame.svelte';
3
  import { drag } from 'd3-drag';
4
  import { select } from 'd3-selection';
 
7
  import type { ZoomTransform } from 'd3-zoom';
8
  import { onMount } from 'svelte';
9
 
 
10
  import { useMyPresence } from '$lib/liveblocks';
11
+ import { loadingState } from '$lib/store';
12
  const myPresence = useMyPresence();
13
 
14
  export let transform: ZoomTransform;
 
25
  $: prompt = $myPresence?.currentPrompt;
26
 
27
  onMount(() => {
28
+ function dragstarted() {
29
  isDragging = true;
30
  }
31
 
 
57
  </script>
58
 
59
  <div bind:this={frameElement}>
60
+ <Frame {color} {position} loadingState={$loadingState} {prompt} {transform} {isDragging} {interactive} />
61
  </div>
frontend/src/lib/PromptModal.svelte CHANGED
@@ -3,39 +3,49 @@
3
  import { useMyPresence } from '$lib/liveblocks';
4
 
5
  const dispatch = createEventDispatcher();
6
- let prompt: string;
7
  let inputEl: HTMLInputElement;
8
  const myPresence = useMyPresence();
9
 
10
- $: {
11
- myPresence.update({
12
- currentPrompt: prompt,
13
- isPrompting: true
14
- });
15
- }
16
-
17
  const onKeyup = (e: KeyboardEvent) => {
18
  if (e.key === 'Escape') {
19
- dispatch('close');
20
  myPresence.update({
21
  currentPrompt: '',
22
  isPrompting: false
23
  });
 
24
  }
25
  };
26
  onMount(() => {
27
  inputEl.focus();
 
28
  window.addEventListener('keyup', onKeyup);
29
  return () => {
30
  window.removeEventListener('keyup', onKeyup);
31
  };
32
  });
33
 
 
 
 
 
 
 
 
 
 
 
 
34
  function onPrompt() {
35
  if (prompt.trim() !== '') {
36
- dispatch('prompt', prompt);
 
37
  }
38
  }
 
 
 
 
39
  </script>
40
 
41
  <form
@@ -45,8 +55,8 @@
45
  >
46
  <input
47
  bind:this={inputEl}
48
- bind:value={prompt}
49
  on:click|stopPropagation
 
50
  class="input"
51
  placeholder="Type a prompt..."
52
  title="Input prompt to generate image and obtain palette"
 
3
  import { useMyPresence } from '$lib/liveblocks';
4
 
5
  const dispatch = createEventDispatcher();
6
+ let prompt = '';
7
  let inputEl: HTMLInputElement;
8
  const myPresence = useMyPresence();
9
 
 
 
 
 
 
 
 
10
  const onKeyup = (e: KeyboardEvent) => {
11
  if (e.key === 'Escape') {
 
12
  myPresence.update({
13
  currentPrompt: '',
14
  isPrompting: false
15
  });
16
+ dispatch('close');
17
  }
18
  };
19
  onMount(() => {
20
  inputEl.focus();
21
+ prompt = '';
22
  window.addEventListener('keyup', onKeyup);
23
  return () => {
24
  window.removeEventListener('keyup', onKeyup);
25
  };
26
  });
27
 
28
+ let timer: NodeJS.Timeout;
29
+ function debouce(newPrompt: string) {
30
+ clearTimeout(timer);
31
+ timer = setTimeout(() => {
32
+ prompt = newPrompt;
33
+ myPresence.update({
34
+ currentPrompt: prompt,
35
+ isPrompting: true
36
+ });
37
+ }, 100);
38
+ }
39
  function onPrompt() {
40
  if (prompt.trim() !== '') {
41
+ console.log('Prompting with: ', prompt);
42
+ dispatch('prompt');
43
  }
44
  }
45
+ function onInput(event: Event) {
46
+ const target = event.target as HTMLInputElement;
47
+ debouce(target.value);
48
+ }
49
  </script>
50
 
51
  <form
 
55
  >
56
  <input
57
  bind:this={inputEl}
 
58
  on:click|stopPropagation
59
+ on:input={onInput}
60
  class="input"
61
  placeholder="Type a prompt..."
62
  title="Input prompt to generate image and obtain palette"
frontend/src/lib/store.ts CHANGED
@@ -1,13 +1,6 @@
1
  import { writable } from 'svelte/store';
2
  import { type ZoomTransform, zoomIdentity } from 'd3-zoom';
3
 
4
-
5
  export const loadingState = writable<string>('');
6
- export const isLoading = writable<boolean>(false);
7
- export const isPrompting = writable<boolean>(false);
8
- export const clickedPosition = writable<{ x: number; y: number }>();
9
- export const showFrames = writable<boolean>(false);
10
-
11
-
12
  export const currZoomTransform = writable<ZoomTransform>(zoomIdentity);
13
 
 
1
  import { writable } from 'svelte/store';
2
  import { type ZoomTransform, zoomIdentity } from 'd3-zoom';
3
 
 
4
  export const loadingState = writable<string>('');
 
 
 
 
 
 
5
  export const currZoomTransform = writable<ZoomTransform>(zoomIdentity);
6
 
frontend/src/lib/types.ts CHANGED
@@ -9,7 +9,6 @@ export type Presence = {
9
  } | null;
10
  isPrompting: boolean;
11
  isLoading: boolean;
12
- isMoving: boolean;
13
  currentPrompt: string
14
  }
15
 
 
9
  } | null;
10
  isPrompting: boolean;
11
  isLoading: boolean;
 
12
  currentPrompt: string
13
  }
14