Skip to content

Commit 616e37a

Browse files
committed
update chat visualization
1 parent 3d1f0ef commit 616e37a

File tree

2 files changed

+95
-30
lines changed

2 files changed

+95
-30
lines changed

src/routes/visualizations-chat/+page.svelte

Lines changed: 91 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import InnerGlowVisualizer from '$lib/realtime/visualizations/InnerGlowVisualizer.svelte';
99
import CircleCirclesVisualizer from '$lib/realtime/visualizations/CircleCirclesVisualizer.svelte';
1010
import BarVisualizer from '$lib/realtime/visualizations/BarVisualizer.svelte';
11+
import type { ItemType } from '@openai/realtime-api-beta/dist/lib/client';
1112
1213
export let wavRecorder: WavRecorder;
1314
let wavStreamPlayer: WavStreamPlayer;
@@ -21,10 +22,40 @@
2122
let current = 0;
2223
2324
$: shownVisualizer = visualizations[current];
25+
26+
let items: ItemType[] = [];
27+
28+
let lastAssistantText = '';
29+
let lastUserText = '';
30+
31+
$: if (items && items.length > 0) {
32+
// last item with role "assistant"
33+
34+
const lastAssistant = items
35+
.slice()
36+
.reverse()
37+
.find((item) => item.role === 'assistant');
38+
39+
if (
40+
lastAssistant?.formatted.transcript &&
41+
lastAssistant.formatted.transcript !== lastAssistantText
42+
) {
43+
lastAssistantText = lastAssistant.formatted.transcript;
44+
}
45+
46+
const lastUser = items
47+
.slice()
48+
.reverse()
49+
.find((item) => item.role === 'user');
50+
51+
if (lastUser?.formatted.transcript && lastUser.formatted.transcript !== lastUserText) {
52+
lastUserText = lastUser.formatted.transcript;
53+
}
54+
}
2455
</script>
2556

2657
<button
27-
class="absolute inset-0 h-[100dvh] w-screen z-10 text-white flex items-end justify-center p-8 text-sm font-semibold"
58+
class="absolute inset-0 h-[100dvh] w-screen z-10 text-white flex items-end justify-center p-4 text-sm font-semibold"
2859
on:click={() => {
2960
current = (current + 1) % visualizations.length;
3061
}}
@@ -33,52 +64,69 @@
3364
</button>
3465

3566
{#if apiKey}
36-
<Realtime bind:startConversation bind:wavRecorder bind:wavStreamPlayer {apiKey} />
67+
<Realtime bind:startConversation bind:items bind:wavRecorder bind:wavStreamPlayer {apiKey} />
3768
{/if}
3869

3970
{#if shownVisualizer === 'circle-bars'}
40-
<div
41-
class="absolute flex flex-col md:flex-row items-center justify-center h-[100dvh] w-screen gap-16"
42-
>
43-
<div class="h-64 w-96">
44-
<CircleBarVisualizer detail={128} wavInput={wavStreamPlayer} startHue={150} endHue={220} />
71+
<div class="absolute flex items-center justify-center h-[100dvh] w-screen">
72+
<div class="h-96 w-96">
73+
<CircleBarVisualizer
74+
detail={128}
75+
wavInput={wavRecorder}
76+
startHue={0}
77+
endHue={50}
78+
varyBrightness
79+
/>
4580
</div>
81+
</div>
4682

47-
<div class="h-64 w-96">
48-
<CircleBarVisualizer detail={128} wavInput={wavRecorder} startHue={0} endHue={50} />
83+
<div class="absolute flex items-center justify-center h-[100dvh] w-screen">
84+
<div class="h-96 w-96">
85+
<CircleBarVisualizer
86+
detail={128}
87+
wavInput={wavStreamPlayer}
88+
startHue={150}
89+
endHue={220}
90+
varyBrightness
91+
/>
4992
</div>
5093
</div>
5194
{:else if shownVisualizer === 'bars'}
52-
<div
53-
class="absolute flex flex-col md:flex-row items-center justify-center h-[100dvh] w-screen gap-16"
54-
>
55-
<div class="h-64 w-96 -scale-y-100 md:scale-y-100">
56-
<BarVisualizer barSpacing={8} wavInput={wavStreamPlayer} startHue={150} endHue={220} />
57-
</div>
95+
<div class="absolute flex items-center justify-center h-[100dvh] w-screen">
5896
<div class="h-64 w-96">
5997
<BarVisualizer barSpacing={8} wavInput={wavRecorder} startHue={0} endHue={50} />
6098
</div>
6199
</div>
100+
<div class="absolute flex items-center justify-center h-[100dvh] w-screen">
101+
<div class="h-64 w-96 -scale-y-100 md:scale-y-100">
102+
<BarVisualizer barSpacing={8} wavInput={wavStreamPlayer} startHue={150} endHue={220} />
103+
</div>
104+
</div>
62105
{:else if shownVisualizer === 'circle-circles'}
63-
<div
64-
class="absolute flex flex-col md:flex-row items-center justify-center h-[100dvh] w-screen gap-16"
65-
>
66-
<div class="h-64 w-96">
67-
<CircleCirclesVisualizer wavInput={wavStreamPlayer} startHue={150} endHue={220} />
106+
<div class="absolute flex items-center justify-center h-[100dvh] w-screen">
107+
<div class="h-96 w-96">
108+
<CircleCirclesVisualizer wavInput={wavRecorder} startHue={0} endHue={50} varyBrightness />
68109
</div>
69-
<div class="h-64 w-96">
70-
<CircleCirclesVisualizer wavInput={wavRecorder} startHue={0} endHue={50} />
110+
</div>
111+
<div class="absolute flex items-center justify-center h-[100dvh] w-screen">
112+
<div class="h-96 w-96">
113+
<CircleCirclesVisualizer
114+
wavInput={wavStreamPlayer}
115+
startHue={150}
116+
endHue={220}
117+
varyBrightness
118+
/>
71119
</div>
72120
</div>
73121
{:else if shownVisualizer === 'deformed-circle'}
74-
<div
75-
class="absolute flex flex-col md:flex-row items-center justify-center h-[100dvh] w-screen gap-16"
76-
>
122+
<div class="absolute flex items-center justify-center h-[100dvh] w-screen">
77123
<div class="h-96 w-96">
78-
<DeformedCircleVisualizer wavInput={wavStreamPlayer} startHue={150} endHue={220} />
124+
<DeformedCircleVisualizer wavInput={wavRecorder} startHue={0} endHue={50} />
79125
</div>
126+
</div>
127+
<div class="absolute flex items-center justify-center h-[100dvh] w-screen">
80128
<div class="h-96 w-96">
81-
<DeformedCircleVisualizer wavInput={wavRecorder} startHue={0} endHue={50} />
129+
<DeformedCircleVisualizer wavInput={wavStreamPlayer} startHue={150} endHue={220} />
82130
</div>
83131
</div>
84132
{:else if shownVisualizer === 'innerglow'}
@@ -103,6 +151,22 @@
103151
</div>
104152
{/if}
105153

154+
<div
155+
class="absolute flex flex-col items-center justify-between h-[100dvh] w-screen py-16 px-4 text-center"
156+
>
157+
<div
158+
class="bg-gradient-to-r from-blue-400 via-cyan-400 to-green-400 inline-block text-transparent bg-clip-text font-semibold text-xl max-w-xl"
159+
>
160+
{lastAssistantText}
161+
</div>
162+
<div class="h-96 w-96"></div>
163+
<div
164+
class="bg-gradient-to-r from-red-400 to-amber-400 inline-block text-transparent bg-clip-text font-semibold text-xl max-w-xl"
165+
>
166+
{lastUserText}
167+
</div>
168+
</div>
169+
106170
<Modal
107171
onStart={() => {
108172
startConversation();

src/routes/visualizations-input/+page.svelte

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121

2222
recording = true;
2323
}}
24-
class="rounded-full px-5 py-3 text-base font-semibold focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500 text-amber-500 bg-amber-500/10 border border-amber-500/20 hover:bg-amber-500/20 {recording ? 'cursor-not-allowed opacity-50' : ''}"
25-
>start microphone</button
24+
class="rounded-full px-5 py-3 text-base font-semibold focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-500 text-amber-500 bg-amber-500/10 border border-amber-500/20 hover:bg-amber-500/20 {recording
25+
? 'cursor-not-allowed opacity-50'
26+
: ''}">start microphone</button
2627
>
2728

2829
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4 mt-8">
@@ -39,7 +40,7 @@
3940
<DeformedCircleVisualizer wavInput={wavRecorder} startHue={0} endHue={50} />
4041
</div>
4142
<div class="h-64 w-full rounded-xl border border-white/15 overflow-hidden">
42-
<InnerGlowVisualizer wavInput={wavRecorder} startHue={0} endHue={50}/>
43+
<InnerGlowVisualizer wavInput={wavRecorder} startHue={0} endHue={50} />
4344
</div>
4445
</div>
4546
</div>

0 commit comments

Comments
 (0)