radames commited on
Commit
35d6c3b
1 Parent(s): 446d1c3

better cancel click handler

Browse files
.devcontainer/devcontainer.json CHANGED
@@ -14,7 +14,10 @@
14
  "customizations": {
15
  "vscode": {
16
  "extensions": [
17
- "GitHub.vscode-pull-request-github"
 
 
 
18
  ]
19
  }
20
  },
 
14
  "customizations": {
15
  "vscode": {
16
  "extensions": [
17
+ "GitHub.vscode-pull-request-github",
18
+ "bradlc.vscode-tailwindcss",
19
+ "svelte.svelte-vscode",
20
+ "csstools.postcss"
21
  ]
22
  }
23
  },
frontend/src/lib/App.svelte CHANGED
@@ -7,7 +7,7 @@
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 { Status } from '$lib/types';
12
  import { loadingState, currZoomTransform, maskEl } from '$lib/store';
13
  import { useMyPresence, useObject, useOthers } from '$lib/liveblocks';
@@ -51,11 +51,9 @@
51
  }
52
  function onClose() {
53
  showModal = false;
54
- console.log('close Modal');
55
  }
56
 
57
  function onPaint() {
58
- console.log('onPaint');
59
  generateImage();
60
  showModal = false;
61
  }
@@ -74,10 +72,9 @@
74
 
75
  const payload = {
76
  fn_index: 0,
77
- data: [base64Crop, prompt, 0.75, 7.5, 40, 'patchmatch'],
78
  session_hash: sessionHash
79
  };
80
- console.log('payload', payload);
81
 
82
  const websocket = new WebSocket(PUBLIC_WS_INPAINTING);
83
  // websocket.onopen = async function (event) {
@@ -137,15 +134,18 @@
137
  setTimeout(() => {
138
  $loadingState = '';
139
  }, 2000);
 
 
 
 
140
  } catch (err) {
141
  const tError = err as Error;
142
  $loadingState = tError?.message;
 
 
 
143
  }
144
  websocket.close();
145
- myPresence.update({
146
- status: Status.ready,
147
- currentPrompt: ''
148
- });
149
  return;
150
  case 'process_starts':
151
  $loadingState = 'Processing';
 
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 { PromptImgKey, Presence } from '$lib/types';
11
  import { Status } from '$lib/types';
12
  import { loadingState, currZoomTransform, maskEl } from '$lib/store';
13
  import { useMyPresence, useObject, useOthers } from '$lib/liveblocks';
 
51
  }
52
  function onClose() {
53
  showModal = false;
 
54
  }
55
 
56
  function onPaint() {
 
57
  generateImage();
58
  showModal = false;
59
  }
 
72
 
73
  const payload = {
74
  fn_index: 0,
75
+ data: [base64Crop, prompt, 0.75, 7.5, 35, 'patchmatch'],
76
  session_hash: sessionHash
77
  };
 
78
 
79
  const websocket = new WebSocket(PUBLIC_WS_INPAINTING);
80
  // websocket.onopen = async function (event) {
 
134
  setTimeout(() => {
135
  $loadingState = '';
136
  }, 2000);
137
+ myPresence.update({
138
+ status: Status.ready,
139
+ currentPrompt: ''
140
+ });
141
  } catch (err) {
142
  const tError = err as Error;
143
  $loadingState = tError?.message;
144
+ myPresence.update({
145
+ status: Status.ready
146
+ });
147
  }
148
  websocket.close();
 
 
 
 
149
  return;
150
  case 'process_starts':
151
  $loadingState = 'Processing';
frontend/src/lib/Buttons/PPButton.svelte CHANGED
@@ -5,7 +5,7 @@
5
  <button
6
  on:click
7
  disabled={isLoading}
8
- class="button-paint"
9
  title="New Paint Frame"
10
  >
11
  {#if isLoading}
@@ -24,6 +24,6 @@
24
  @apply disabled:opacity-50 dark:bg-white dark:text-black bg-black text-white rounded-2xl text-xs shadow-sm focus:outline-none focus:border-gray-400;
25
  } */
26
  .button-paint {
27
- @apply text-sm font-mono bg-violet-100 text-violet-900 min-w-[25ch] flex justify-center items-center disabled:opacity-50 dark:bg-white dark:text-black rounded-2xl px-3 py-1 shadow-sm focus:outline-none focus:border-gray-400;
28
  }
29
  </style>
 
5
  <button
6
  on:click
7
  disabled={isLoading}
8
+ class="button-paint {isLoading ? 'cursor-wait' : 'cursor-pointer'}"
9
  title="New Paint Frame"
10
  >
11
  {#if isLoading}
 
24
  @apply disabled:opacity-50 dark:bg-white dark:text-black bg-black text-white rounded-2xl text-xs shadow-sm focus:outline-none focus:border-gray-400;
25
  } */
26
  .button-paint {
27
+ @apply text-sm font-mono bg-violet-100 text-violet-900 min-w-[25ch] flex justify-center items-center disabled:opacity-50 rounded-xl px-3 py-1 shadow-sm focus:outline-none focus:border-gray-400;
28
  }
29
  </style>
frontend/src/lib/Buttons/RoomsSelector.svelte CHANGED
@@ -2,8 +2,10 @@
2
  import Room from '$lib/Icons/Room.svelte';
3
  import Pin from '$lib/Icons/Pin.svelte';
4
  import People from '$lib/Icons/People.svelte';
 
5
 
6
  export let isLoading = false;
 
7
 
8
  let rooms = [
9
  { label: 'room 1', total: 11, capacity: 20 },
@@ -13,39 +15,77 @@
13
  { label: 'room 5', total: 11, capacity: 20 }
14
  ];
15
 
16
- let selectedRoom = 0;
17
- </script>
 
18
 
19
- <button on:click disabled={isLoading} class="button-paint" title="New Paint Frame" />
 
 
 
 
 
 
 
 
 
 
 
20
 
21
- <ul class="font-mono font-medium tracking-tight bg-violet-100">
22
- <li class="grid-row gap-2">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  <Room />
24
- <span> room </span>
25
  <People />
26
- <span> players </span>
27
- </li>
28
- {#each rooms as room, i}
29
- <li class="grid-row gap-2">
30
- <span>
31
- {#if i === selectedRoom}
32
- <Pin />
33
- {/if}
34
- </span>
35
- <span> {room.label} </span>
36
- <span />
37
- <span>{room.total} / {room.capacity}</span>
38
- </li>
39
- {/each}
40
- </ul>
41
 
42
  <style lang="postcss" scoped>
43
- /* .button {
44
- @apply disabled:opacity-50 dark:bg-white dark:text-black bg-black text-white rounded-2xl text-xs shadow-sm focus:outline-none focus:border-gray-400;
45
- } */
46
- .button-paint {
47
- @apply text-sm font-mono bg-violet-100 text-violet-900 min-w-[25ch] flex justify-center items-center disabled:opacity-50 dark:bg-white dark:text-black rounded-2xl px-3 py-1 shadow-sm focus:outline-none focus:border-gray-400;
48
- }
49
  .grid-row {
50
  display: grid;
51
  grid-template-columns: 0.5fr 2fr 0.5fr 2fr;
 
2
  import Room from '$lib/Icons/Room.svelte';
3
  import Pin from '$lib/Icons/Pin.svelte';
4
  import People from '$lib/Icons/People.svelte';
5
+ import { onMount } from 'svelte';
6
 
7
  export let isLoading = false;
8
+ let boxEl: HTMLElement;
9
 
10
  let rooms = [
11
  { label: 'room 1', total: 11, capacity: 20 },
 
15
  { label: 'room 5', total: 11, capacity: 20 }
16
  ];
17
 
18
+ let selectedRoomID = 0;
19
+ let collapsed = true;
20
+ $: selectedRoom = rooms[selectedRoomID];
21
 
22
+ function clickHandler(event: Event) {
23
+ if (!boxEl.contains(event.target as Node)) {
24
+ collapsed = true;
25
+ }
26
+ }
27
+ onMount(() => {
28
+ window.addEventListener('click', clickHandler, true);
29
+ return () => {
30
+ window.removeEventListener('click', clickHandler, true);
31
+ };
32
+ });
33
+ </script>
34
 
35
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
36
+ <div
37
+ class="bg-violet-100 text-violet-900 px-3 py-1 font-mono font-medium tracking-tight relative z-0
38
+ {isLoading ? 'opacity-50' : ''}
39
+ {collapsed ? 'rounded-xl' : 'rounded-b-xl'}"
40
+ bind:this={boxEl}
41
+ >
42
+ {#if !collapsed}
43
+ <div class="absolute z-10 left-0 right-0 bottom-full rounded-t-xl bg-violet-100 px-3 py-1">
44
+ <ul>
45
+ <li class="grid-row gap-2 pb-3">
46
+ <Room />
47
+ <span> room </span>
48
+ <People />
49
+ <span> players </span>
50
+ </li>
51
+ {#each rooms as room, i}
52
+ <li>
53
+ <!-- svelte-ignore a11y-invalid-attribute -->
54
+ <a
55
+ href="#"
56
+ on:click|preventDefault={() => (selectedRoomID = i)}
57
+ class="grid-row gap-2 hover:bg-gray-300
58
+ {i === selectedRoomID ? 'text-green-600' : ''}"
59
+ >
60
+ <span>
61
+ {#if i === selectedRoomID}
62
+ <Pin />
63
+ {/if}
64
+ </span>
65
+ <span> {room.label} </span>
66
+ <span />
67
+ <span>{room.total} / {room.capacity}</span>
68
+ </a>
69
+ </li>
70
+ {/each}
71
+ </ul>
72
+ <div class="border-t-2 border-t-gray-400 border-opacity-50" />
73
+ </div>
74
+ {/if}
75
+ <!-- svelte-ignore a11y-click-events-have-key-events -->
76
+ <div
77
+ class="grid-row gap-2 relative
78
+ {isLoading ? 'cursor-wait' : 'cursor-pointer'}"
79
+ on:click={() => (isLoading ? null : (collapsed = !collapsed))}
80
+ >
81
  <Room />
82
+ <span> {selectedRoom.label} </span>
83
  <People />
84
+ <span> {selectedRoom.total} / {selectedRoom.capacity} </span>
85
+ </div>
86
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  <style lang="postcss" scoped>
 
 
 
 
 
 
89
  .grid-row {
90
  display: grid;
91
  grid-template-columns: 0.5fr 2fr 0.5fr 2fr;
frontend/src/lib/PromptModal.svelte CHANGED
@@ -7,25 +7,29 @@
7
  export let initPrompt = '';
8
  let prompt: string;
9
  let inputEl: HTMLInputElement;
 
10
  const myPresence = useMyPresence();
11
 
12
  const onKeyup = (e: KeyboardEvent) => {
13
  if (e.key === 'Escape') {
14
- cancel(e);
 
 
 
15
  }
16
  };
17
 
18
  onMount(() => {
19
  inputEl.focus();
20
- inputEl.addEventListener('focusout', cancel);
21
  prompt = initPrompt;
22
  window.addEventListener('keyup', onKeyup);
 
 
23
  return () => {
24
  window.removeEventListener('keyup', onKeyup);
25
- inputEl.removeEventListener('focusout', cancel);
26
  };
27
  });
28
-
29
  let timer: NodeJS.Timeout;
30
  function debouce(newPrompt: string) {
31
  clearTimeout(timer);
@@ -39,7 +43,6 @@
39
  }
40
  function onPrompt() {
41
  if (prompt.trim() !== '') {
42
- console.log('Prompting with: ', prompt);
43
  dispatch('paint');
44
  dispatch('close');
45
  }
@@ -48,9 +51,10 @@
48
  const target = event.target as HTMLInputElement;
49
  debouce(target.value);
50
  }
51
- function cancel(event?: Event) {
52
- if (!(event instanceof KeyboardEvent) && event?.relatedTarget !== null) return;
53
-
 
54
  myPresence.update({
55
  status: Status.ready
56
  });
@@ -62,7 +66,7 @@
62
  class="fixed w-screen top-0 left-0 bottom-0 right-0 max-h-screen z-50 flex items-center justify-center bg-black bg-opacity-80 px-3"
63
  on:submit|preventDefault={onPrompt}
64
  >
65
- <div class="flex bg-white rounded-2xl px-2 w-full max-w-md">
66
  <input
67
  value={prompt}
68
  bind:this={inputEl}
 
7
  export let initPrompt = '';
8
  let prompt: string;
9
  let inputEl: HTMLInputElement;
10
+ let boxEl: HTMLDivElement;
11
  const myPresence = useMyPresence();
12
 
13
  const onKeyup = (e: KeyboardEvent) => {
14
  if (e.key === 'Escape') {
15
+ myPresence.update({
16
+ status: Status.ready
17
+ });
18
+ dispatch('close');
19
  }
20
  };
21
 
22
  onMount(() => {
23
  inputEl.focus();
 
24
  prompt = initPrompt;
25
  window.addEventListener('keyup', onKeyup);
26
+ window.addEventListener('click', cancelHandler, true);
27
+
28
  return () => {
29
  window.removeEventListener('keyup', onKeyup);
30
+ window.removeEventListener('click', cancelHandler, true);
31
  };
32
  });
 
33
  let timer: NodeJS.Timeout;
34
  function debouce(newPrompt: string) {
35
  clearTimeout(timer);
 
43
  }
44
  function onPrompt() {
45
  if (prompt.trim() !== '') {
 
46
  dispatch('paint');
47
  dispatch('close');
48
  }
 
51
  const target = event.target as HTMLInputElement;
52
  debouce(target.value);
53
  }
54
+ function cancelHandler(event: Event) {
55
+ if (boxEl.contains(event.target as Node)) {
56
+ return;
57
+ }
58
  myPresence.update({
59
  status: Status.ready
60
  });
 
66
  class="fixed w-screen top-0 left-0 bottom-0 right-0 max-h-screen z-50 flex items-center justify-center bg-black bg-opacity-80 px-3"
67
  on:submit|preventDefault={onPrompt}
68
  >
69
+ <div class="flex bg-white rounded-2xl px-2 w-full max-w-md" bind:this={boxEl}>
70
  <input
71
  value={prompt}
72
  bind:this={inputEl}