File size: 3,421 Bytes
1123781
246efdb
 
d1f4c77
246efdb
 
 
 
 
 
 
 
 
 
 
 
 
ff9325e
0835cd8
246efdb
d1f4c77
246efdb
 
 
 
d1f4c77
0835cd8
 
cb60b56
 
246efdb
 
cb60b56
 
 
 
 
 
 
 
1123781
 
d1f4c77
 
 
9a8789a
 
bea2d0b
246efdb
 
 
bea2d0b
9a8789a
 
cb60b56
9a8789a
246efdb
cb60b56
 
 
246efdb
 
 
9a8789a
 
 
 
 
cb60b56
 
d1f4c77
cb60b56
246efdb
 
 
cb60b56
246efdb
cb60b56
d1f4c77
246efdb
d1f4c77
246efdb
 
d1f4c77
246efdb
d1f4c77
0835cd8
9a8789a
 
bea2d0b
 
 
 
9a8789a
d1f4c77
246efdb
d1f4c77
 
 
 
 
1123781
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<script lang="ts">
  import { lcmLiveStatus, LCMLiveStatus, streamId } from "$lib/lcmLive";
  import { getPipelineValues } from "$lib/store";

  import Button from "$lib/components/Button.svelte";
  import Floppy from "$lib/icons/floppy.svelte";
  import Expand from "$lib/icons/expand.svelte";
  import { snapImage, expandWindow } from "$lib/utils";

  let isLCMRunning = $derived(
    $lcmLiveStatus !== LCMLiveStatus.DISCONNECTED &&
      $lcmLiveStatus !== LCMLiveStatus.ERROR,
  );

  let imageEl: HTMLImageElement | undefined = $state();
  let expandedWindow: Window | undefined = $state();
  let isExpanded = $state(false);

  async function takeSnapshot() {
    if (isLCMRunning && imageEl) {
      await snapImage(imageEl, {
        prompt: getPipelineValues()?.prompt as string,
        negative_prompt: getPipelineValues()?.negative_prompt as string,
        seed: getPipelineValues()?.seed as number,
        guidance_scale: getPipelineValues()?.guidance_scale as number,
      });
    }
  }
  async function toggleFullscreen() {
    if (isLCMRunning && !isExpanded) {
      expandedWindow = expandWindow("/api/stream/" + $streamId);
      expandedWindow.addEventListener("beforeunload", () => {
        isExpanded = false;
      });
      isExpanded = true;
    } else {
      expandedWindow?.close();
      isExpanded = false;
    }
  }
</script>

<div
  class="relative mx-auto aspect-square max-w-lg self-center overflow-hidden rounded-lg border border-slate-300"
>
  {#if $lcmLiveStatus === LCMLiveStatus.CONNECTING}
    <!-- Show connecting spinner -->
    <div class="flex h-full w-full items-center justify-center">
      <div
        class="h-16 w-16 animate-spin rounded-full border-b-2 border-white"
      ></div>
      <p class="ml-2 text-white">Connecting...</p>
    </div>
  {:else if isLCMRunning}
    {#if !isExpanded}
      <!-- Handle image error by adding onerror event -->
      <!-- svelte-ignore a11y_missing_attribute -->
      <img
        bind:this={imageEl}
        class="aspect-square w-full rounded-lg"
        src={"/api/stream/" + $streamId}
        onerror={(e) => {
          console.error("Image stream error:", e);
          // If stream fails to load, set status to error
          if ($lcmLiveStatus !== LCMLiveStatus.ERROR) {
            lcmLiveStatus.set(LCMLiveStatus.ERROR);
          }
        }}
      />
    {/if}
    <div class="absolute bottom-1 right-1">
      <Button
        onclick={toggleFullscreen}
        title="Expand Fullscreen"
        class="ml-auto rounded-lg p-1 text-sm text-white opacity-50 shadow-lg"
      >
        <Expand />
      </Button>
      <Button
        onclick={takeSnapshot}
        disabled={!isLCMRunning}
        title="Take Snapshot"
        class="ml-auto rounded-lg p-1 text-sm text-white opacity-50 shadow-lg"
      >
        <Floppy />
      </Button>
    </div>
  {:else if $lcmLiveStatus === LCMLiveStatus.ERROR}
    <!-- Show error state with red border -->
    <div
      class="flex h-full w-full items-center justify-center rounded-lg border-2 border-red-500 bg-gray-900"
    >
      <p class="p-4 text-center text-white">Connection error</p>
    </div>
  {:else}
    <!-- svelte-ignore a11y_missing_attribute -->
    <img
      class="aspect-square w-full rounded-lg"
      src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="
    />
  {/if}
</div>