@ghchinoy/lit-audio-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +148 -0
- package/dist/favicon.png +0 -0
- package/dist/scream-audio-ui.es.js +2121 -0
- package/dist/scream-audio-ui.umd.js +1217 -0
- package/package.json +54 -0
|
@@ -0,0 +1,1217 @@
|
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`lit`),require(`lit/decorators.js`),require(`@material/web/button/filled-button.js`),require(`@material/web/icon/icon.js`),require(`lit/directives/class-map.js`),require(`@material/web/button/outlined-button.js`),require(`@material/web/iconbutton/filled-icon-button.js`),require(`@material/web/progress/circular-progress.js`),require(`@material/web/slider/slider.js`),require(`@material/web/menu/menu.js`),require(`@material/web/menu/menu-item.js`),require(`@material/web/divider/divider.js`),require(`@material/web/button/text-button.js`),require(`@material/web/button/filled-tonal-button.js`),require(`@material/web/textfield/outlined-text-field.js`),require(`three`),require(`@material/web/iconbutton/icon-button.js`)):typeof define==`function`&&define.amd?define([`exports`,`lit`,`lit/decorators.js`,`@material/web/button/filled-button.js`,`@material/web/icon/icon.js`,`lit/directives/class-map.js`,`@material/web/button/outlined-button.js`,`@material/web/iconbutton/filled-icon-button.js`,`@material/web/progress/circular-progress.js`,`@material/web/slider/slider.js`,`@material/web/menu/menu.js`,`@material/web/menu/menu-item.js`,`@material/web/divider/divider.js`,`@material/web/button/text-button.js`,`@material/web/button/filled-tonal-button.js`,`@material/web/textfield/outlined-text-field.js`,`three`,`@material/web/iconbutton/icon-button.js`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ScreamAudioUI={},e.Lit,e.Lit,e.MaterialWeb,e.MaterialWeb,e.Lit,e.MaterialWeb,e.MaterialWeb,e.MaterialWeb,e.MaterialWeb,e.MaterialWeb,e.MaterialWeb,e.MaterialWeb,e.MaterialWeb,e.MaterialWeb,e.MaterialWeb,e.THREE,e.MaterialWeb))})(this,function(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h,g,_){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var v=Object.create,y=Object.defineProperty,b=Object.getOwnPropertyDescriptor,x=Object.getOwnPropertyNames,S=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty,w=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=x(t),a=0,o=i.length,s;a<o;a++)s=i[a],!C.call(e,s)&&s!==n&&y(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=b(t,s))||r.enumerable});return e};g=((e,t,n)=>(n=e==null?{}:v(S(e)),w(t||!e||!e.__esModule?y(n,`default`,{value:e,enumerable:!0}):n,e)))(g);function T(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var E=class extends t.LitElement{constructor(...e){super(...e),this.state=`idle`}static{this.styles=t.css`
|
|
2
|
+
:host {
|
|
3
|
+
display: inline-block;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
md-filled-button {
|
|
7
|
+
--md-filled-button-container-shape: 999px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
md-filled-button.recording {
|
|
11
|
+
--md-filled-button-container-color: var(--md-sys-color-error, #ba1a1a);
|
|
12
|
+
--md-filled-button-label-text-color: var(
|
|
13
|
+
--md-sys-color-on-error,
|
|
14
|
+
#ffffff
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
`}render(){return t.html`
|
|
18
|
+
<md-filled-button class="${this.state}" @click="${this._handleClick}">
|
|
19
|
+
<md-icon slot="icon">
|
|
20
|
+
${this.state===`recording`?`stop`:`mic`}
|
|
21
|
+
</md-icon>
|
|
22
|
+
|
|
23
|
+
${this.state===`recording`?`Recording...`:`Speak`}
|
|
24
|
+
</md-filled-button>
|
|
25
|
+
`}_handleClick(){this.state=this.state===`idle`?`recording`:`idle`,this.dispatchEvent(new CustomEvent(`voice-toggle`,{bubbles:!0,composed:!0,detail:{state:this.state}}))}};T([(0,n.property)({type:String})],E.prototype,`state`,void 0),E=T([(0,n.customElement)(`scream-voice-button`)],E);function D(e,t){e.getByteFrequencyData(t);let n=[];for(let e=0;e<t.length;e++)n.push(t[e]/255);return n}function O(e,t,n,r){if(r<=0||t<=0)return;let i=e.createLinearGradient(0,0,t,0),a=Math.min(.2,r/t);i.addColorStop(0,`rgba(0,0,0,0)`),i.addColorStop(a,`rgba(0,0,0,1)`),i.addColorStop(1-a,`rgba(0,0,0,1)`),i.addColorStop(1,`rgba(0,0,0,0)`),e.globalCompositeOperation=`destination-in`,e.fillStyle=i,e.fillRect(0,0,t,n),e.globalCompositeOperation=`source-over`}var k=class extends t.LitElement{constructor(...e){super(...e),this.active=!1,this.processing=!1,this.barWidth=3,this.barHeight=4,this.barGap=1,this.barRadius=1.5,this.fadeEdges=!0,this.fadeWidth=24,this.height=64,this.sensitivity=1,this.updateRate=30,this._animationFrameId=0,this._lastUpdateTime=0,this._currentBars=[],this._processingTime=0,this._transitionProgress=0,this._lastActiveData=[]}static{this.styles=t.css`
|
|
26
|
+
:host {
|
|
27
|
+
display: block;
|
|
28
|
+
width: 100%;
|
|
29
|
+
}
|
|
30
|
+
.container {
|
|
31
|
+
position: relative;
|
|
32
|
+
width: 100%;
|
|
33
|
+
}
|
|
34
|
+
canvas {
|
|
35
|
+
position: absolute;
|
|
36
|
+
top: 0;
|
|
37
|
+
left: 0;
|
|
38
|
+
display: block;
|
|
39
|
+
height: 100%;
|
|
40
|
+
width: 100%;
|
|
41
|
+
}
|
|
42
|
+
`}render(){return t.html`
|
|
43
|
+
<div class="container" style="height: ${this.height}px;">
|
|
44
|
+
<canvas></canvas>
|
|
45
|
+
</div>
|
|
46
|
+
`}firstUpdated(){this._resizeObserver=new ResizeObserver(()=>{this._handleResize()}),this._resizeObserver.observe(this._container),this._startAnimationLoop()}updated(e){super.updated(e),e.has(`analyserNode`)&&this.analyserNode&&(this._dataArray=new Uint8Array(this.analyserNode.frequencyBinCount)),e.has(`processing`)&&this.processing&&!this.active&&(this._processingTime=0,this._transitionProgress=0)}disconnectedCallback(){super.disconnectedCallback(),this._resizeObserver&&this._resizeObserver.disconnect(),this._animationFrameId&&cancelAnimationFrame(this._animationFrameId)}_handleResize(){if(!this._canvas||!this._container)return;let e=this._container.getBoundingClientRect(),t=window.devicePixelRatio||1;this._canvas.width=e.width*t,this._canvas.height=e.height*t,this._canvas.style.width=`${e.width}px`,this._canvas.style.height=`${e.height}px`;let n=this._canvas.getContext(`2d`);n&&n.scale(t,t),this._renderFrame()}_startAnimationLoop(){let e=t=>{this._updateData(t),this._renderFrame(),this._animationFrameId=requestAnimationFrame(e)};this._animationFrameId=requestAnimationFrame(e)}_updateData(e){if(!this._canvas)return;let t=this._canvas.getBoundingClientRect(),n=Math.floor(t.width/(this.barWidth+this.barGap));if(this.active&&this.analyserNode&&this._dataArray){if(e-this._lastUpdateTime>this.updateRate){this._lastUpdateTime=e;let t=D(this.analyserNode,this._dataArray),r=Math.floor(t.length*.05),i=Math.floor(t.length*.4),a=t.slice(r,i),o=Math.floor(n/2),s=Array(n).fill(.05),c=a.length-1;for(let e=0;e<=o;e++){let t=e/o,r=a[Math.floor(t*c)]||0;t>.8&&(r*=1-(t-.8)*5);let i=Math.max(.05,Math.min(1,r*this.sensitivity)),l=o+e,u=o-e;l<n&&(s[l]=i),u>=0&&(s[u]=i)}this._currentBars=s,this._lastActiveData=[...s]}}else if(this.processing&&!this.active){this._processingTime+=.03,this._transitionProgress=Math.min(1,this._transitionProgress+.02);let e=Array(n).fill(.05),t=Math.floor(n/2);for(let r=0;r<n;r++){let n=(r-t)/t,i=1-Math.abs(n)*.4,a=Math.sin(this._processingTime*1.5+n*3)*.25,o=Math.sin(this._processingTime*.8-n*2)*.2,s=Math.cos(this._processingTime*2+n)*.15,c=(.2+(a+o+s))*i,l=c;if(this._lastActiveData.length>0&&this._transitionProgress<1){let e=Math.min(r,this._lastActiveData.length-1);l=(this._lastActiveData[e]||0)*(1-this._transitionProgress)+c*this._transitionProgress}e[r]=Math.max(.05,Math.min(1,l))}this._currentBars=e}else if(this._currentBars.length>0){let e=!0;for(let t=0;t<this._currentBars.length;t++)this._currentBars[t]=Math.max(.05,this._currentBars[t]*.85),this._currentBars[t]>.06&&(e=!1);e&&(this._currentBars=[])}}_renderFrame(){if(!this._canvas)return;let e=this._canvas.getContext(`2d`);if(!e)return;let t=this._canvas.getBoundingClientRect();e.clearRect(0,0,t.width,t.height);let n=getComputedStyle(this),r=this.barColor;if(!r){let e=n.getPropertyValue(`--md-sys-color-primary`).trim(),t=n.getPropertyValue(`color`).trim();r=e||t||`#0066cc`}let i=this.barWidth+this.barGap,a=Math.floor(t.width/i),o=t.height/2;for(let n=0;n<a&&n<this._currentBars.length;n++){let a=this._currentBars[n]||.05,s=n*i,c=Math.max(this.barHeight,a*t.height*.8),l=o-c/2;e.fillStyle=r,e.globalAlpha=.4+a*.6,this.barRadius>0?(e.beginPath(),e.roundRect(s,l,this.barWidth,c,this.barRadius),e.fill()):e.fillRect(s,l,this.barWidth,c)}this.fadeEdges&&O(e,t.width,t.height,this.fadeWidth),e.globalAlpha=1}};T([(0,n.property)({type:Boolean})],k.prototype,`active`,void 0),T([(0,n.property)({type:Boolean})],k.prototype,`processing`,void 0),T([(0,n.property)({attribute:!1})],k.prototype,`analyserNode`,void 0),T([(0,n.property)({type:Number})],k.prototype,`barWidth`,void 0),T([(0,n.property)({type:Number})],k.prototype,`barHeight`,void 0),T([(0,n.property)({type:Number})],k.prototype,`barGap`,void 0),T([(0,n.property)({type:Number})],k.prototype,`barRadius`,void 0),T([(0,n.property)({type:String})],k.prototype,`barColor`,void 0),T([(0,n.property)({type:Boolean})],k.prototype,`fadeEdges`,void 0),T([(0,n.property)({type:Number})],k.prototype,`fadeWidth`,void 0),T([(0,n.property)({type:Number})],k.prototype,`height`,void 0),T([(0,n.property)({type:Number})],k.prototype,`sensitivity`,void 0),T([(0,n.property)({type:Number})],k.prototype,`updateRate`,void 0),T([(0,n.query)(`canvas`)],k.prototype,`_canvas`,void 0),T([(0,n.query)(`.container`)],k.prototype,`_container`,void 0),k=T([(0,n.customElement)(`ui-live-waveform`)],k);var A=class extends t.LitElement{constructor(...e){super(...e),this.state=`idle`,this.disabled=!1,this._showFeedback=!1}static{this.styles=t.css`
|
|
47
|
+
:host {
|
|
48
|
+
display: inline-block;
|
|
49
|
+
--ui-waveform-height: 24px;
|
|
50
|
+
--ui-waveform-width: 96px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.wrapper {
|
|
54
|
+
display: flex;
|
|
55
|
+
align-items: center;
|
|
56
|
+
gap: 12px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
md-filled-button,
|
|
60
|
+
md-outlined-button {
|
|
61
|
+
transition: all 0.2s ease-in-out;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* Customize the button depending on the state */
|
|
65
|
+
md-filled-button.recording {
|
|
66
|
+
--md-filled-button-container-color: var(
|
|
67
|
+
--md-sys-color-error-container,
|
|
68
|
+
#ffdad6
|
|
69
|
+
);
|
|
70
|
+
--md-filled-button-label-text-color: var(
|
|
71
|
+
--md-sys-color-on-error-container,
|
|
72
|
+
#410002
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
md-filled-button.processing {
|
|
77
|
+
--md-filled-button-container-color: var(
|
|
78
|
+
--md-sys-color-secondary-container,
|
|
79
|
+
#cce5ff
|
|
80
|
+
);
|
|
81
|
+
--md-filled-button-label-text-color: var(
|
|
82
|
+
--md-sys-color-on-secondary-container,
|
|
83
|
+
#001d36
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
md-filled-button.success {
|
|
88
|
+
--md-filled-button-container-color: var(
|
|
89
|
+
--md-sys-color-primary-container,
|
|
90
|
+
#d1e4ff
|
|
91
|
+
);
|
|
92
|
+
--md-filled-button-label-text-color: var(
|
|
93
|
+
--md-sys-color-on-primary-container,
|
|
94
|
+
#001d36
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.waveform-slot {
|
|
99
|
+
position: relative;
|
|
100
|
+
width: var(--ui-waveform-width);
|
|
101
|
+
height: var(--ui-waveform-height);
|
|
102
|
+
border-radius: 4px;
|
|
103
|
+
overflow: hidden;
|
|
104
|
+
display: flex;
|
|
105
|
+
align-items: center;
|
|
106
|
+
justify-content: center;
|
|
107
|
+
background: var(--md-sys-color-surface-container-highest, #e3e3e3);
|
|
108
|
+
border: 1px solid var(--md-sys-color-outline-variant, #c4c7c5);
|
|
109
|
+
transition: background-color 0.3s ease;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.waveform-slot.recording {
|
|
113
|
+
background: var(--md-sys-color-error-container, #ffdad6);
|
|
114
|
+
border-color: transparent;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.waveform-slot.processing {
|
|
118
|
+
background: var(--md-sys-color-secondary-container, #cce5ff);
|
|
119
|
+
border-color: transparent;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.trailing-text {
|
|
123
|
+
font-family: monospace;
|
|
124
|
+
font-size: 11px;
|
|
125
|
+
color: var(--md-sys-color-on-surface-variant, #444);
|
|
126
|
+
font-weight: 500;
|
|
127
|
+
user-select: none;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.feedback-overlay {
|
|
131
|
+
position: absolute;
|
|
132
|
+
inset: 0;
|
|
133
|
+
display: flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
justify-content: center;
|
|
136
|
+
background: var(--md-sys-color-surface, #fff);
|
|
137
|
+
animation: fadeIn 0.3s ease forwards;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.feedback-icon {
|
|
141
|
+
font-size: 16px;
|
|
142
|
+
}
|
|
143
|
+
.feedback-icon.success {
|
|
144
|
+
color: var(--md-sys-color-primary, #0066cc);
|
|
145
|
+
}
|
|
146
|
+
.feedback-icon.error {
|
|
147
|
+
color: var(--md-sys-color-error, #ba1a1a);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@keyframes fadeIn {
|
|
151
|
+
from {
|
|
152
|
+
opacity: 0;
|
|
153
|
+
}
|
|
154
|
+
to {
|
|
155
|
+
opacity: 0.9;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
`}updated(e){super.updated(e),e.has(`state`)&&(this.state===`success`||this.state===`error`?(this._showFeedback=!0,this._feedbackTimeout&&clearTimeout(this._feedbackTimeout),this._feedbackTimeout=setTimeout(()=>{this._showFeedback=!1,(this.state===`success`||this.state===`error`)&&(this.state=`idle`)},1500)):this._showFeedback=!1)}render(){let e=this.state===`recording`,n=this.state===`processing`,r=this.state===`success`,i=this.state===`error`,o=this.disabled||n,s=e||n,c=!s&&!this._showFeedback&&this.trailing,l={recording:e,processing:n,success:r&&this._showFeedback,error:i&&this._showFeedback},u={"waveform-slot":!0,recording:e,processing:n};return t.html`
|
|
159
|
+
<md-filled-button
|
|
160
|
+
class=${(0,a.classMap)(l)}
|
|
161
|
+
?disabled=${o}
|
|
162
|
+
@click=${this._handleClick}
|
|
163
|
+
>
|
|
164
|
+
<div class="wrapper">
|
|
165
|
+
${this.label?t.html`<span>${this.label}</span>`:``}
|
|
166
|
+
|
|
167
|
+
<div class=${(0,a.classMap)(u)}>
|
|
168
|
+
${s?t.html`
|
|
169
|
+
<ui-live-waveform
|
|
170
|
+
.active=${e}
|
|
171
|
+
.processing=${n}
|
|
172
|
+
.analyserNode=${this.analyserNode}
|
|
173
|
+
.barWidth=${2}
|
|
174
|
+
.barGap=${1}
|
|
175
|
+
.barRadius=${4}
|
|
176
|
+
.fadeEdges=${!1}
|
|
177
|
+
.sensitivity=${1.8}
|
|
178
|
+
height="20"
|
|
179
|
+
style="position: absolute; inset: 0;"
|
|
180
|
+
></ui-live-waveform>
|
|
181
|
+
`:``}
|
|
182
|
+
${c?t.html` <span class="trailing-text">${this.trailing}</span> `:``}
|
|
183
|
+
${this._showFeedback&&r?t.html`
|
|
184
|
+
<div class="feedback-overlay">
|
|
185
|
+
<md-icon class="feedback-icon success">check</md-icon>
|
|
186
|
+
</div>
|
|
187
|
+
`:``}
|
|
188
|
+
${this._showFeedback&&i?t.html`
|
|
189
|
+
<div class="feedback-overlay">
|
|
190
|
+
<md-icon class="feedback-icon error">close</md-icon>
|
|
191
|
+
</div>
|
|
192
|
+
`:``}
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
</md-filled-button>
|
|
196
|
+
`}_handleClick(e){this.dispatchEvent(new CustomEvent(`voice-button-click`,{bubbles:!0,composed:!0,detail:{state:this.state}}))}};T([(0,n.property)({type:String})],A.prototype,`state`,void 0),T([(0,n.property)({type:String})],A.prototype,`label`,void 0),T([(0,n.property)({type:String})],A.prototype,`trailing`,void 0),T([(0,n.property)({type:Boolean})],A.prototype,`disabled`,void 0),T([(0,n.property)({attribute:!1})],A.prototype,`analyserNode`,void 0),T([(0,n.state)()],A.prototype,`_showFeedback`,void 0),A=T([(0,n.customElement)(`ui-voice-button`)],A);var j=class extends t.LitElement{constructor(...e){super(...e),this.data=[],this.barWidth=4,this.barHeight=4,this.barGap=2,this.barRadius=2,this.fadeEdges=!0,this.fadeWidth=24,this.height=128}static{this.styles=t.css`
|
|
197
|
+
:host {
|
|
198
|
+
display: block;
|
|
199
|
+
width: 100%;
|
|
200
|
+
}
|
|
201
|
+
.container {
|
|
202
|
+
position: relative;
|
|
203
|
+
width: 100%;
|
|
204
|
+
}
|
|
205
|
+
canvas {
|
|
206
|
+
position: absolute;
|
|
207
|
+
top: 0;
|
|
208
|
+
left: 0;
|
|
209
|
+
display: block;
|
|
210
|
+
height: 100%;
|
|
211
|
+
width: 100%;
|
|
212
|
+
}
|
|
213
|
+
`}render(){return t.html`
|
|
214
|
+
<div class="container" style="height: ${this.height}px;">
|
|
215
|
+
<canvas></canvas>
|
|
216
|
+
</div>
|
|
217
|
+
`}firstUpdated(){this._resizeObserver=new ResizeObserver(()=>{this._handleResize()}),this._resizeObserver.observe(this._container)}updated(e){super.updated(e),(e.has(`data`)||e.has(`barColor`))&&this._renderWaveform()}disconnectedCallback(){super.disconnectedCallback(),this._resizeObserver&&this._resizeObserver.disconnect()}_handleResize(){if(!this._canvas||!this._container)return;let e=this._container.getBoundingClientRect(),t=window.devicePixelRatio||1;this._canvas.width=e.width*t,this._canvas.height=e.height*t,this._canvas.style.width=`${e.width}px`,this._canvas.style.height=`${e.height}px`;let n=this._canvas.getContext(`2d`);n&&(n.scale(t,t),this._renderWaveform())}_renderWaveform(){if(!this._canvas)return;let e=this._canvas.getContext(`2d`);if(!e)return;let t=this._canvas.getBoundingClientRect();e.clearRect(0,0,t.width,t.height);let n=getComputedStyle(this),r=this.barColor;if(!r){let e=n.getPropertyValue(`--md-sys-color-primary`).trim(),t=n.getPropertyValue(`color`).trim();r=e||t||`#0066cc`}let i=Math.floor(t.width/(this.barWidth+this.barGap)),a=t.height/2;for(let n=0;n<i;n++){let o=Math.floor(n/i*this.data.length),s=this.data[o]||0,c=Math.max(this.barHeight,s*t.height*.8),l=n*(this.barWidth+this.barGap),u=a-c/2;e.fillStyle=r,e.globalAlpha=.3+s*.7,this.barRadius>0?(e.beginPath(),e.roundRect(l,u,this.barWidth,c,this.barRadius),e.fill()):e.fillRect(l,u,this.barWidth,c)}this.fadeEdges&&O(e,t.width,t.height,this.fadeWidth),e.globalAlpha=1}};T([(0,n.property)({type:Array})],j.prototype,`data`,void 0),T([(0,n.property)({type:Number})],j.prototype,`barWidth`,void 0),T([(0,n.property)({type:Number})],j.prototype,`barHeight`,void 0),T([(0,n.property)({type:Number})],j.prototype,`barGap`,void 0),T([(0,n.property)({type:Number})],j.prototype,`barRadius`,void 0),T([(0,n.property)({type:String})],j.prototype,`barColor`,void 0),T([(0,n.property)({type:Boolean})],j.prototype,`fadeEdges`,void 0),T([(0,n.property)({type:Number})],j.prototype,`fadeWidth`,void 0),T([(0,n.property)({type:Number})],j.prototype,`height`,void 0),T([(0,n.query)(`canvas`)],j.prototype,`_canvas`,void 0),T([(0,n.query)(`.container`)],j.prototype,`_container`,void 0),j=T([(0,n.customElement)(`ui-waveform`)],j);var M=class extends Event{constructor(e,t,n,r){super(`context-request`,{bubbles:!0,composed:!0}),this.context=e,this.contextTarget=t,this.callback=n,this.subscribe=r??!1}};function N(e){return e}var P=class{constructor(e,t,n,r){if(this.subscribe=!1,this.provided=!1,this.value=void 0,this.t=(e,t)=>{this.unsubscribe&&(this.unsubscribe!==t&&(this.provided=!1,this.unsubscribe()),this.subscribe||this.unsubscribe()),this.value=e,this.host.requestUpdate(),this.provided&&!this.subscribe||(this.provided=!0,this.callback&&this.callback(e,t)),this.unsubscribe=t},this.host=e,t.context!==void 0){let e=t;this.context=e.context,this.callback=e.callback,this.subscribe=e.subscribe??!1}else this.context=t,this.callback=n,this.subscribe=r??!1;this.host.addController(this)}hostConnected(){this.dispatchRequest()}hostDisconnected(){this.unsubscribe&&=(this.unsubscribe(),void 0)}dispatchRequest(){this.host.dispatchEvent(new M(this.context,this.host,this.t,this.subscribe))}},F=class{get value(){return this.o}set value(e){this.setValue(e)}setValue(e,t=!1){let n=t||!Object.is(e,this.o);this.o=e,n&&this.updateObservers()}constructor(e){this.subscriptions=new Map,this.updateObservers=()=>{for(let[e,{disposer:t}]of this.subscriptions)e(this.o,t)},e!==void 0&&(this.value=e)}addCallback(e,t,n){if(!n)return void e(this.value);this.subscriptions.has(e)||this.subscriptions.set(e,{disposer:()=>{this.subscriptions.delete(e)},consumerHost:t});let{disposer:r}=this.subscriptions.get(e);e(this.value,r)}clearCallbacks(){this.subscriptions.clear()}},I=class extends Event{constructor(e,t){super(`context-provider`,{bubbles:!0,composed:!0}),this.context=e,this.contextTarget=t}},L=class extends F{constructor(e,t,n){super(t.context===void 0?n:t.initialValue),this.onContextRequest=e=>{if(e.context!==this.context)return;let t=e.contextTarget??e.composedPath()[0];t!==this.host&&(e.stopPropagation(),this.addCallback(e.callback,t,e.subscribe))},this.onProviderRequest=e=>{if(e.context!==this.context||(e.contextTarget??e.composedPath()[0])===this.host)return;let t=new Set;for(let[e,{consumerHost:n}]of this.subscriptions)t.has(e)||(t.add(e),n.dispatchEvent(new M(this.context,n,e,!0)));e.stopPropagation()},this.host=e,t.context===void 0?this.context=t:this.context=t.context,this.attachListeners(),this.host.addController?.(this)}attachListeners(){this.host.addEventListener(`context-request`,this.onContextRequest),this.host.addEventListener(`context-provider`,this.onProviderRequest)}hostConnected(){this.host.dispatchEvent(new I(this.context,this.host))}};function R({context:e}){return(t,n)=>{let r=new WeakMap;if(typeof n==`object`)return{get(){return t.get.call(this)},set(e){return r.get(this).setValue(e),t.set.call(this,e)},init(t){return r.set(this,new L(this,{context:e,initialValue:t})),t}};{t.constructor.addInitializer((t=>{r.set(t,new L(t,{context:e}))}));let i=Object.getOwnPropertyDescriptor(t,n),a;if(i===void 0){let e=new WeakMap;a={get(){return e.get(this)},set(t){r.get(this).setValue(t),e.set(this,t)},configurable:!0,enumerable:!0}}else{let e=i.set;a={...i,set(t){r.get(this).setValue(t),e?.call(this,t)}}}Object.defineProperty(t,n,a);return}}}function z({context:e,subscribe:t}){return(n,r)=>{typeof r==`object`?r.addInitializer((function(){new P(this,{context:e,callback:e=>{n.set.call(this,e)},subscribe:t})})):n.constructor.addInitializer((n=>{new P(n,{context:e,callback:e=>{n[r]=e},subscribe:t})}))}}let B=N(`ui-audio-player-context`);var V=class extends t.LitElement{constructor(...e){super(...e),this.src=``,this._animationFrameId=0,this.state={src:``,isPlaying:!1,isBuffering:!1,currentTime:0,duration:0,volume:1,muted:!1,analyserNode:void 0,play:()=>this.play(),pause:()=>this.pause(),togglePlay:()=>this._togglePlay(),seek:e=>this._seek(e),setVolume:e=>this._setVolume(e),toggleMute:()=>this._toggleMute()}}static{this.styles=t.css`
|
|
218
|
+
:host {
|
|
219
|
+
display: contents; /* We are completely invisible, just wrapping children */
|
|
220
|
+
}
|
|
221
|
+
audio {
|
|
222
|
+
display: none;
|
|
223
|
+
}
|
|
224
|
+
`}render(){return t.html`
|
|
225
|
+
<audio
|
|
226
|
+
crossorigin="anonymous"
|
|
227
|
+
src="${this.src}"
|
|
228
|
+
preload="metadata"
|
|
229
|
+
@loadedmetadata="${this._handleLoadedMetadata}"
|
|
230
|
+
@ended="${this._handleEnded}"
|
|
231
|
+
@playing="${this._handlePlaying}"
|
|
232
|
+
@pause="${this._handlePause}"
|
|
233
|
+
@waiting="${()=>this._updateState({isBuffering:!0})}"
|
|
234
|
+
@canplay="${()=>this._updateState({isBuffering:!1})}"
|
|
235
|
+
@error="${this._handleError}"
|
|
236
|
+
></audio>
|
|
237
|
+
<slot></slot>
|
|
238
|
+
`}willUpdate(e){e.has(`src`)&&this._updateState({src:this.src,isPlaying:!1,currentTime:0,error:void 0})}updated(e){e.has(`src`)&&this._audioEl&&this._audioEl.load()}disconnectedCallback(){super.disconnectedCallback(),this._animationFrameId&&cancelAnimationFrame(this._animationFrameId),this._audioContext&&this._audioContext.state!==`closed`&&this._audioContext.close()}_updateState(e){this.state={...this.state,...e},this.dispatchEvent(new CustomEvent(`state-change`,{detail:this.state,bubbles:!0,composed:!0}))}_setupAudioContext(){if(!(this._audioContext||!this._audioEl))try{this._audioContext=new(window.AudioContext||window.webkitAudioContext),this._analyserNode=this._audioContext.createAnalyser(),this._analyserNode.fftSize=256,this._analyserNode.smoothingTimeConstant=.8,this._mediaSource=this._audioContext.createMediaElementSource(this._audioEl),this._mediaSource.connect(this._analyserNode),this._analyserNode.connect(this._audioContext.destination),this._updateState({analyserNode:this._analyserNode})}catch(e){console.warn(`Failed to set up AudioContext for visualizer:`,e)}}play(){this._audioEl.src&&(this._setupAudioContext(),this._audioContext?.state===`suspended`&&this._audioContext.resume(),this._audioEl.play().catch(e=>{console.error(`Error playing audio`,e),this._updateState({error:`Playback failed`})}))}pause(){this._audioEl&&this._audioEl.pause()}_togglePlay(){this.state.isPlaying?this.pause():this.play()}_seek(e){this._audioEl&&(this._audioEl.currentTime=e,this._updateState({currentTime:e}))}_setVolume(e){this._audioEl&&(this._audioEl.volume=e,this._updateState({volume:e,muted:e===0}))}_toggleMute(){this._audioEl&&(this._audioEl.muted=!this._audioEl.muted,this._updateState({muted:this._audioEl.muted}))}_handleLoadedMetadata(){this._updateState({duration:this._audioEl.duration})}_handleEnded(){this._updateState({isPlaying:!1,currentTime:0}),this._audioEl.currentTime=0}_handlePlaying(){this._updateState({isPlaying:!0,isBuffering:!1,error:void 0}),this._startTrackingTime()}_handlePause(){this._updateState({isPlaying:!1}),this._animationFrameId&&cancelAnimationFrame(this._animationFrameId)}_handleError(){this._updateState({error:`Error loading audio`,isPlaying:!1,isBuffering:!1})}_startTrackingTime(){let e=()=>{this._audioEl&&this.state.isPlaying&&(Math.abs(this.state.currentTime-this._audioEl.currentTime)>.05&&this._updateState({currentTime:this._audioEl.currentTime}),this._animationFrameId=requestAnimationFrame(e))};this._animationFrameId=requestAnimationFrame(e)}};T([(0,n.property)({type:String})],V.prototype,`src`,void 0),T([(0,n.query)(`audio`)],V.prototype,`_audioEl`,void 0),T([R({context:B}),(0,n.state)()],V.prototype,`state`,void 0),V=T([(0,n.customElement)(`ui-audio-provider`)],V);var H=class extends t.LitElement{static{this.styles=t.css`
|
|
239
|
+
:host {
|
|
240
|
+
display: inline-flex;
|
|
241
|
+
position: relative;
|
|
242
|
+
align-items: center;
|
|
243
|
+
justify-content: center;
|
|
244
|
+
font-family: inherit;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
md-filled-icon-button {
|
|
248
|
+
--md-filled-icon-button-container-color: var(
|
|
249
|
+
--md-sys-color-primary,
|
|
250
|
+
#0066cc
|
|
251
|
+
);
|
|
252
|
+
--md-filled-icon-button-icon-color: var(
|
|
253
|
+
--md-sys-color-on-primary,
|
|
254
|
+
#ffffff
|
|
255
|
+
);
|
|
256
|
+
--md-filled-icon-button-hover-icon-color: var(
|
|
257
|
+
--md-sys-color-on-primary,
|
|
258
|
+
#ffffff
|
|
259
|
+
);
|
|
260
|
+
--md-filled-icon-button-focus-icon-color: var(
|
|
261
|
+
--md-sys-color-on-primary,
|
|
262
|
+
#ffffff
|
|
263
|
+
);
|
|
264
|
+
--md-filled-icon-button-pressed-icon-color: var(
|
|
265
|
+
--md-sys-color-on-primary,
|
|
266
|
+
#ffffff
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
--md-filled-icon-button-toggle-icon-color: var(
|
|
270
|
+
--md-sys-color-on-primary,
|
|
271
|
+
#ffffff
|
|
272
|
+
);
|
|
273
|
+
--md-filled-icon-button-selected-container-color: var(
|
|
274
|
+
--md-sys-color-primary,
|
|
275
|
+
#0066cc
|
|
276
|
+
);
|
|
277
|
+
--md-filled-icon-button-selected-icon-color: var(
|
|
278
|
+
--md-sys-color-on-primary,
|
|
279
|
+
#ffffff
|
|
280
|
+
);
|
|
281
|
+
color: var(--md-sys-color-on-primary, #ffffff);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
md-circular-progress {
|
|
285
|
+
position: absolute;
|
|
286
|
+
--md-circular-progress-size: 48px;
|
|
287
|
+
}
|
|
288
|
+
`}render(){let e=this.playerState?.isPlaying??!1,n=this.playerState?.isBuffering??!1;return t.html`
|
|
289
|
+
<md-filled-icon-button
|
|
290
|
+
part="button"
|
|
291
|
+
@click="${this._handleClick}"
|
|
292
|
+
?disabled="${!this.playerState?.src}"
|
|
293
|
+
>
|
|
294
|
+
<md-icon>${e?`pause`:`play_arrow`}</md-icon>
|
|
295
|
+
</md-filled-icon-button>
|
|
296
|
+
${n&&e?t.html`<md-circular-progress indeterminate></md-circular-progress>`:``}
|
|
297
|
+
`}_handleClick(){this.playerState&&this.playerState.togglePlay()}};T([z({context:B,subscribe:!0}),(0,n.property)({attribute:!1})],H.prototype,`playerState`,void 0),H=T([(0,n.customElement)(`ui-audio-play-button`)],H);var U=class extends t.LitElement{constructor(...e){super(...e),this._isDragging=!1,this._dragValue=0}static{this.styles=t.css`
|
|
298
|
+
:host {
|
|
299
|
+
display: flex;
|
|
300
|
+
width: 100%;
|
|
301
|
+
align-items: center;
|
|
302
|
+
min-width: 100px;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
md-slider {
|
|
306
|
+
width: 100%;
|
|
307
|
+
/* Give the slider track better contrast against backgrounds */
|
|
308
|
+
--md-slider-inactive-track-color: var(--md-sys-color-outline, #79747e);
|
|
309
|
+
}
|
|
310
|
+
`}render(){let e=this.playerState?.duration||0,n=e===0||!this.playerState?.src,r=this._isDragging?this._dragValue:this.playerState?.currentTime||0;return t.html`
|
|
311
|
+
<md-slider
|
|
312
|
+
min="0"
|
|
313
|
+
max="${e||100}"
|
|
314
|
+
value="${r}"
|
|
315
|
+
step="0.1"
|
|
316
|
+
?disabled="${n}"
|
|
317
|
+
@input="${this._handleInput}"
|
|
318
|
+
@change="${this._handleChange}"
|
|
319
|
+
></md-slider>
|
|
320
|
+
`}_handleInput(e){this._isDragging=!0,this._dragValue=e.target.value}_handleChange(e){this._dragValue=e.target.value,this.playerState&&this.playerState.seek(this._dragValue),this._isDragging=!1}};T([z({context:B,subscribe:!0}),(0,n.property)({attribute:!1})],U.prototype,`playerState`,void 0),U=T([(0,n.customElement)(`ui-audio-progress-slider`)],U);var W=class extends t.LitElement{constructor(...e){super(...e),this.format=`full`}static{this.styles=t.css`
|
|
321
|
+
:host {
|
|
322
|
+
display: inline-block;
|
|
323
|
+
font-variant-numeric: tabular-nums;
|
|
324
|
+
font-size: 14px;
|
|
325
|
+
color: var(--md-sys-color-on-surface-variant, #444);
|
|
326
|
+
font-family: inherit;
|
|
327
|
+
}
|
|
328
|
+
`}render(){let e=this.playerState?.currentTime||0,n=this.playerState?.duration||0;if(this.format===`elapsed`)return t.html`${this._formatTime(e)}`;if(this.format===`remaining`){let r=Math.max(0,n-e);return t.html`-${this._formatTime(r)}`}else return t.html`${this._formatTime(e)} /
|
|
329
|
+
${n?this._formatTime(n):`--:--`}`}_formatTime(e){if(!e||isNaN(e))return`0:00`;let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=Math.floor(e%60),i=``;return t>0&&(i+=``+t+`:`+(n<10?`0`:``)),i+=``+n+`:`+(r<10?`0`:``),i+=``+r,i}};T([z({context:B,subscribe:!0}),(0,n.property)({attribute:!1})],W.prototype,`playerState`,void 0),T([(0,n.property)({type:String})],W.prototype,`format`,void 0),W=T([(0,n.customElement)(`ui-audio-time-display`)],W);var G=class extends t.LitElement{static{this.styles=t.css`
|
|
330
|
+
:host {
|
|
331
|
+
display: inline-block;
|
|
332
|
+
width: 100%;
|
|
333
|
+
max-width: 400px;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.player-pill {
|
|
337
|
+
display: flex;
|
|
338
|
+
align-items: center;
|
|
339
|
+
gap: 16px;
|
|
340
|
+
padding: 12px 24px;
|
|
341
|
+
background: var(--md-sys-color-surface-container-high, #e2e2e2);
|
|
342
|
+
border-radius: 999px; /* Pill shape */
|
|
343
|
+
width: fit-content;
|
|
344
|
+
font-family: inherit;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.time-container {
|
|
348
|
+
min-width: 85px; /* prevent jitter when times change */
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
.slider-container {
|
|
352
|
+
width: 200px;
|
|
353
|
+
display: flex;
|
|
354
|
+
align-items: center;
|
|
355
|
+
}
|
|
356
|
+
`}render(){return t.html`
|
|
357
|
+
<ui-audio-provider .src="${this.item?.src||``}">
|
|
358
|
+
<div class="player-pill" part="container">
|
|
359
|
+
<!-- Atomic Play/Pause Button -->
|
|
360
|
+
<ui-audio-play-button></ui-audio-play-button>
|
|
361
|
+
|
|
362
|
+
<!-- Atomic Time Display (Full format: 0:00 / 0:00) -->
|
|
363
|
+
<div class="time-container">
|
|
364
|
+
<ui-audio-time-display format="full"></ui-audio-time-display>
|
|
365
|
+
</div>
|
|
366
|
+
|
|
367
|
+
<!-- Atomic Slider -->
|
|
368
|
+
<div class="slider-container">
|
|
369
|
+
<ui-audio-progress-slider></ui-audio-progress-slider>
|
|
370
|
+
</div>
|
|
371
|
+
</div>
|
|
372
|
+
</ui-audio-provider>
|
|
373
|
+
`}};T([(0,n.property)({type:Object})],G.prototype,`item`,void 0),G=T([(0,n.customElement)(`ui-audio-player`)],G);var K=class extends t.LitElement{constructor(...e){super(...e),this.muted=!1,this.disabled=!1,this._devices=[],this._loading=!0,this._error=null,this._hasPermission=!1,this._isMenuOpen=!1,this._handleDeviceChange=()=>{this._hasPermission?this._loadDevicesWithPermission():this._loadDevicesWithoutPermission()}}static{this.styles=t.css`
|
|
374
|
+
:host {
|
|
375
|
+
display: inline-block;
|
|
376
|
+
position: relative;
|
|
377
|
+
font-family: inherit;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.anchor-button {
|
|
381
|
+
display: flex;
|
|
382
|
+
align-items: center;
|
|
383
|
+
gap: 8px;
|
|
384
|
+
padding: 8px 16px;
|
|
385
|
+
background: var(--md-sys-color-surface-container-high, #e2e2e2);
|
|
386
|
+
color: var(--md-sys-color-on-surface, #1e1e1e);
|
|
387
|
+
border-radius: 999px;
|
|
388
|
+
cursor: pointer;
|
|
389
|
+
border: none;
|
|
390
|
+
font-family: inherit;
|
|
391
|
+
font-size: 14px;
|
|
392
|
+
font-weight: 500;
|
|
393
|
+
transition: background-color 0.2s;
|
|
394
|
+
max-width: 250px;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.anchor-button:hover:not(:disabled) {
|
|
398
|
+
background: var(--md-sys-color-surface-container-highest, #e3e3e3);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.anchor-button:disabled {
|
|
402
|
+
opacity: 0.5;
|
|
403
|
+
cursor: not-allowed;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.label-text {
|
|
407
|
+
flex: 1;
|
|
408
|
+
white-space: nowrap;
|
|
409
|
+
overflow: hidden;
|
|
410
|
+
text-overflow: ellipsis;
|
|
411
|
+
text-align: left;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
md-menu {
|
|
415
|
+
--md-menu-container-color: var(
|
|
416
|
+
--md-sys-color-surface-container,
|
|
417
|
+
var(--md-sys-color-surface, #ffffff)
|
|
418
|
+
);
|
|
419
|
+
--md-menu-container-shape: 12px;
|
|
420
|
+
min-width: 280px;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
.menu-footer {
|
|
424
|
+
display: flex;
|
|
425
|
+
align-items: center;
|
|
426
|
+
justify-content: space-between;
|
|
427
|
+
padding: 8px 12px;
|
|
428
|
+
gap: 12px;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.preview-waveform {
|
|
432
|
+
flex: 1;
|
|
433
|
+
height: 24px;
|
|
434
|
+
background: var(
|
|
435
|
+
--md-sys-color-surface-variant,
|
|
436
|
+
var(--md-sys-color-surface-container-highest, #e1e2e1)
|
|
437
|
+
);
|
|
438
|
+
border-radius: 6px;
|
|
439
|
+
overflow: hidden;
|
|
440
|
+
display: flex;
|
|
441
|
+
align-items: center;
|
|
442
|
+
padding: 0 4px;
|
|
443
|
+
}
|
|
444
|
+
`}connectedCallback(){super.connectedCallback(),this._loadDevicesWithoutPermission(),navigator.mediaDevices.addEventListener(`devicechange`,this._handleDeviceChange)}disconnectedCallback(){super.disconnectedCallback(),navigator.mediaDevices.removeEventListener(`devicechange`,this._handleDeviceChange),this._stopPreview()}updated(e){super.updated(e),e.has(`_isMenuOpen`)&&this._isMenuOpen&&(!this._hasPermission&&!this._loading?this._loadDevicesWithPermission():this._hasPermission&&!this.muted&&this._startPreview()),(e.has(`_isMenuOpen`)&&!this._isMenuOpen||e.has(`muted`)&&this.muted)&&this._stopPreview(),e.has(`muted`)&&!this.muted&&this._isMenuOpen&&this._hasPermission&&this._startPreview()}render(){let e=this._devices.find(e=>e.deviceId===this.value)||this._devices[0]||{label:this._loading?`Loading...`:`No microphone`};return t.html`
|
|
445
|
+
<!-- Anchor Button -->
|
|
446
|
+
<button
|
|
447
|
+
id="anchor-button"
|
|
448
|
+
class="anchor-button"
|
|
449
|
+
?disabled=${this._loading||this.disabled}
|
|
450
|
+
@click=${this._toggleMenu}
|
|
451
|
+
>
|
|
452
|
+
<md-icon>${this.muted?`mic_off`:`mic`}</md-icon>
|
|
453
|
+
<span class="label-text">${e.label}</span>
|
|
454
|
+
<md-icon style="font-size: 18px;">unfold_more</md-icon>
|
|
455
|
+
</button>
|
|
456
|
+
|
|
457
|
+
<!-- Dropdown Menu -->
|
|
458
|
+
<md-menu
|
|
459
|
+
id="device-menu"
|
|
460
|
+
anchor="anchor-button"
|
|
461
|
+
positioning="popover"
|
|
462
|
+
@closed=${()=>this._isMenuOpen=!1}
|
|
463
|
+
@opened=${()=>this._isMenuOpen=!0}
|
|
464
|
+
>
|
|
465
|
+
${this._loading?t.html`<md-menu-item disabled
|
|
466
|
+
><div slot="headline">Loading devices...</div></md-menu-item
|
|
467
|
+
>`:this._error?t.html`<md-menu-item disabled
|
|
468
|
+
><div slot="headline" style="color: var(--md-sys-color-error)">
|
|
469
|
+
${this._error}
|
|
470
|
+
</div></md-menu-item
|
|
471
|
+
>`:this._devices.map(e=>t.html`
|
|
472
|
+
<md-menu-item
|
|
473
|
+
@click=${()=>this._selectDevice(e.deviceId)}
|
|
474
|
+
?selected=${this.value===e.deviceId||!this.value&&this._devices[0]?.deviceId===e.deviceId}
|
|
475
|
+
>
|
|
476
|
+
<div slot="headline">${e.label}</div>
|
|
477
|
+
${this.value===e.deviceId||!this.value&&this._devices[0]?.deviceId===e.deviceId?t.html`<md-icon slot="end">check</md-icon>`:``}
|
|
478
|
+
</md-menu-item>
|
|
479
|
+
`)}
|
|
480
|
+
${this._devices.length>0?t.html`
|
|
481
|
+
<md-divider></md-divider>
|
|
482
|
+
<div class="menu-footer">
|
|
483
|
+
<md-text-button @click=${this._toggleMute}>
|
|
484
|
+
<md-icon slot="icon"
|
|
485
|
+
>${this.muted?`mic_off`:`mic`}</md-icon
|
|
486
|
+
>
|
|
487
|
+
${this.muted?`Unmute`:`Mute`}
|
|
488
|
+
</md-text-button>
|
|
489
|
+
|
|
490
|
+
<div class="preview-waveform">
|
|
491
|
+
<ui-live-waveform
|
|
492
|
+
.active=${this._isMenuOpen&&!this.muted&&this._hasPermission}
|
|
493
|
+
.processing=${!1}
|
|
494
|
+
.analyserNode=${this._previewAnalyser}
|
|
495
|
+
.barWidth=${3}
|
|
496
|
+
.barGap=${1}
|
|
497
|
+
.fadeEdges=${!1}
|
|
498
|
+
height="16"
|
|
499
|
+
></ui-live-waveform>
|
|
500
|
+
</div>
|
|
501
|
+
</div>
|
|
502
|
+
`:``}
|
|
503
|
+
</md-menu>
|
|
504
|
+
`}_toggleMenu(){this._menuEl&&(this._menuEl.open=!this._menuEl.open,this._isMenuOpen=this._menuEl.open)}_selectDevice(e){this.value=e,this.dispatchEvent(new CustomEvent(`device-change`,{detail:{deviceId:e},bubbles:!0,composed:!0})),this._isMenuOpen&&!this.muted&&this._hasPermission&&this._startPreview()}_toggleMute(e){e.stopPropagation(),this.muted=!this.muted,this.dispatchEvent(new CustomEvent(`mute-change`,{detail:{muted:this.muted},bubbles:!0,composed:!0}))}async _loadDevicesWithoutPermission(){try{this._loading=!0,this._error=null;let e=await navigator.mediaDevices.enumerateDevices();this._parseDeviceList(e)}catch(e){this._error=e instanceof Error?e.message:`Failed to get audio devices`}finally{this._loading=!1}}async _loadDevicesWithPermission(){if(!this._loading)try{this._loading=!0,this._error=null,(await navigator.mediaDevices.getUserMedia({audio:!0})).getTracks().forEach(e=>e.stop());let e=await navigator.mediaDevices.enumerateDevices();this._parseDeviceList(e),this._hasPermission=!0,this._isMenuOpen&&!this.muted&&this._startPreview()}catch(e){this._error=e instanceof Error?e.message:`Permission denied`}finally{this._loading=!1}}_parseDeviceList(e){let t=e.filter(e=>e.kind===`audioinput`).map(e=>{let t=e.label||"Microphone ${device.deviceId.slice(0, 8)}";return t=t.replace(/\s*\([^)]*\)/g,``).trim(),{deviceId:e.deviceId,label:t,groupId:e.groupId}});this._devices=t,!this.value&&t.length>0&&(this.value=t[0].deviceId,this.dispatchEvent(new CustomEvent(`device-change`,{detail:{deviceId:this.value},bubbles:!0,composed:!0})))}async _startPreview(){if(this._stopPreview(),this.value)try{this._previewStream=await navigator.mediaDevices.getUserMedia({audio:{deviceId:{exact:this.value}}}),this._previewAudioContext=new(window.AudioContext||window.webkitAudioContext),this._previewAnalyser=this._previewAudioContext.createAnalyser(),this._previewAnalyser.fftSize=256,this._previewAnalyser.smoothingTimeConstant=.8,this._previewAudioContext.createMediaStreamSource(this._previewStream).connect(this._previewAnalyser)}catch(e){console.warn(`Failed to start preview stream`,e)}}_stopPreview(){this._previewStream&&=(this._previewStream.getTracks().forEach(e=>e.stop()),void 0),this._previewAudioContext&&this._previewAudioContext.state!==`closed`&&(this._previewAudioContext.close(),this._previewAudioContext=void 0),this._previewAnalyser=void 0}};T([(0,n.property)({type:String})],K.prototype,`value`,void 0),T([(0,n.property)({type:Boolean})],K.prototype,`muted`,void 0),T([(0,n.property)({type:Boolean})],K.prototype,`disabled`,void 0),T([(0,n.state)()],K.prototype,`_devices`,void 0),T([(0,n.state)()],K.prototype,`_loading`,void 0),T([(0,n.state)()],K.prototype,`_error`,void 0),T([(0,n.state)()],K.prototype,`_hasPermission`,void 0),T([(0,n.state)()],K.prototype,`_isMenuOpen`,void 0),T([(0,n.state)()],K.prototype,`_previewAnalyser`,void 0),T([(0,n.query)(`md-menu`)],K.prototype,`_menuEl`,void 0),K=T([(0,n.customElement)(`ui-mic-selector`)],K);var q=class extends t.LitElement{constructor(...e){super(...e),this.voices=[],this.placeholder=`Select a voice...`,this.idKey=`voiceId`,this.titleKey=`name`,this.subtitleKey=`category`,this.previewUrlKey=`previewUrl`,this.useOrbs=!1,this.colorKey=`colors`,this._searchQuery=``}static{this.styles=t.css`
|
|
505
|
+
:host {
|
|
506
|
+
display: inline-block;
|
|
507
|
+
width: 100%;
|
|
508
|
+
font-family: inherit;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
.anchor-button {
|
|
512
|
+
display: flex;
|
|
513
|
+
align-items: center;
|
|
514
|
+
justify-content: space-between;
|
|
515
|
+
width: 100%;
|
|
516
|
+
padding: 8px 16px;
|
|
517
|
+
background: transparent;
|
|
518
|
+
border: 1px solid var(--md-sys-color-outline, #79747e);
|
|
519
|
+
border-radius: 8px;
|
|
520
|
+
color: var(--md-sys-color-on-surface, #1e1e1e);
|
|
521
|
+
cursor: pointer;
|
|
522
|
+
font-family: inherit;
|
|
523
|
+
font-size: 14px;
|
|
524
|
+
min-height: 48px;
|
|
525
|
+
transition:
|
|
526
|
+
background-color 0.2s,
|
|
527
|
+
border-color 0.2s;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
.anchor-button:hover {
|
|
531
|
+
background: var(--md-sys-color-surface-container-highest, #e3e3e3);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
.anchor-button:focus-visible {
|
|
535
|
+
outline: none;
|
|
536
|
+
border-color: var(--md-sys-color-primary, #0066cc);
|
|
537
|
+
box-shadow: 0 0 0 1px var(--md-sys-color-primary, #0066cc);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.trigger-content {
|
|
541
|
+
display: flex;
|
|
542
|
+
align-items: center;
|
|
543
|
+
justify-content: space-between;
|
|
544
|
+
width: 100%;
|
|
545
|
+
min-width: 100%;
|
|
546
|
+
padding: 4px 0;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
.trigger-left {
|
|
550
|
+
display: flex;
|
|
551
|
+
align-items: center;
|
|
552
|
+
gap: 12px;
|
|
553
|
+
overflow: hidden;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
.trigger-icon {
|
|
557
|
+
width: 24px;
|
|
558
|
+
height: 24px;
|
|
559
|
+
border-radius: 50%;
|
|
560
|
+
background: var(--md-sys-color-primary-container);
|
|
561
|
+
color: var(--md-sys-color-on-primary-container);
|
|
562
|
+
display: flex;
|
|
563
|
+
align-items: center;
|
|
564
|
+
justify-content: center;
|
|
565
|
+
flex-shrink: 0;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
.trigger-text {
|
|
569
|
+
white-space: nowrap;
|
|
570
|
+
overflow: hidden;
|
|
571
|
+
text-overflow: ellipsis;
|
|
572
|
+
color: var(--md-sys-color-on-surface);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
md-menu {
|
|
576
|
+
--md-menu-container-shape: 12px;
|
|
577
|
+
--md-menu-container-color: var(--md-sys-color-surface-container, #f3f3f3);
|
|
578
|
+
max-width: 400px;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
.search-container {
|
|
582
|
+
padding: 8px 12px;
|
|
583
|
+
background: var(--md-sys-color-surface-container, #f3f3f3);
|
|
584
|
+
border-bottom: 1px solid var(--md-sys-color-outline-variant);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
md-outlined-text-field {
|
|
588
|
+
width: 100%;
|
|
589
|
+
--md-outlined-text-field-container-shape: 8px;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
md-menu-item {
|
|
593
|
+
--md-menu-item-hover-state-layer-color: var(
|
|
594
|
+
--md-sys-color-on-surface-variant
|
|
595
|
+
);
|
|
596
|
+
--md-menu-item-focus-state-layer-color: var(
|
|
597
|
+
--md-sys-color-on-surface-variant
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
.voice-item-content {
|
|
602
|
+
display: flex;
|
|
603
|
+
align-items: center;
|
|
604
|
+
gap: 16px;
|
|
605
|
+
width: 100%;
|
|
606
|
+
padding: 8px 0;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.voice-avatar {
|
|
610
|
+
position: relative;
|
|
611
|
+
width: 32px;
|
|
612
|
+
height: 32px;
|
|
613
|
+
border-radius: 50%;
|
|
614
|
+
background: var(--md-sys-color-surface-variant);
|
|
615
|
+
display: flex;
|
|
616
|
+
align-items: center;
|
|
617
|
+
justify-content: center;
|
|
618
|
+
flex-shrink: 0;
|
|
619
|
+
cursor: pointer;
|
|
620
|
+
overflow: hidden;
|
|
621
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
622
|
+
z-index: 2; /* Keep above the menu item ripple */
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
.voice-avatar:hover .play-overlay {
|
|
626
|
+
opacity: 1;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
.play-overlay {
|
|
630
|
+
position: absolute;
|
|
631
|
+
inset: 0;
|
|
632
|
+
background: rgba(0, 0, 0, 0.4);
|
|
633
|
+
display: flex;
|
|
634
|
+
align-items: center;
|
|
635
|
+
justify-content: center;
|
|
636
|
+
color: white;
|
|
637
|
+
opacity: 0;
|
|
638
|
+
transition: opacity 0.2s;
|
|
639
|
+
border-radius: 50%;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
.play-overlay.active {
|
|
643
|
+
opacity: 1;
|
|
644
|
+
background: rgba(0, 0, 0, 0.6);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
.voice-info {
|
|
648
|
+
display: flex;
|
|
649
|
+
flex-direction: column;
|
|
650
|
+
gap: 2px;
|
|
651
|
+
flex: 1;
|
|
652
|
+
overflow: hidden;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
.voice-name {
|
|
656
|
+
font-weight: 500;
|
|
657
|
+
font-size: 14px;
|
|
658
|
+
white-space: nowrap;
|
|
659
|
+
overflow: hidden;
|
|
660
|
+
text-overflow: ellipsis;
|
|
661
|
+
color: var(--md-sys-color-on-surface);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
.voice-labels {
|
|
665
|
+
display: flex;
|
|
666
|
+
align-items: center;
|
|
667
|
+
gap: 6px;
|
|
668
|
+
font-size: 12px;
|
|
669
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
670
|
+
white-space: nowrap;
|
|
671
|
+
overflow: hidden;
|
|
672
|
+
text-overflow: ellipsis;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
.label-dot {
|
|
676
|
+
font-size: 8px;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
.empty-state {
|
|
680
|
+
padding: 24px;
|
|
681
|
+
text-align: center;
|
|
682
|
+
color: var(--md-sys-color-on-surface-variant);
|
|
683
|
+
font-size: 14px;
|
|
684
|
+
}
|
|
685
|
+
`}render(){let e=this.voices.find(e=>e[this.idKey]===this.value),n=this.voices.filter(e=>{if(!this._searchQuery)return!0;let t=this._searchQuery.toLowerCase();return e[this.titleKey].toLowerCase().includes(t)||e.labels?.accent?.toLowerCase().includes(t)||e.labels?.gender?.toLowerCase().includes(t)||e.labels?.age?.toLowerCase().includes(t)});return t.html`
|
|
686
|
+
<!-- Hidden audio player for previews -->
|
|
687
|
+
<audio
|
|
688
|
+
crossorigin="anonymous"
|
|
689
|
+
@ended=${()=>this._previewingVoiceId=void 0}
|
|
690
|
+
@pause=${()=>this._previewingVoiceId=void 0}
|
|
691
|
+
></audio>
|
|
692
|
+
|
|
693
|
+
<!-- Anchor Button -->
|
|
694
|
+
<button
|
|
695
|
+
class="anchor-button"
|
|
696
|
+
part="button"
|
|
697
|
+
id="voice-anchor"
|
|
698
|
+
@click=${this._toggleMenu}
|
|
699
|
+
>
|
|
700
|
+
<div class="trigger-content">
|
|
701
|
+
<div class="trigger-left">
|
|
702
|
+
${e?t.html`
|
|
703
|
+
<div
|
|
704
|
+
class="trigger-icon"
|
|
705
|
+
style="${this.useOrbs?`overflow: hidden;`:``}"
|
|
706
|
+
>
|
|
707
|
+
${this.useOrbs?t.html`<ui-orb
|
|
708
|
+
agentState="listening"
|
|
709
|
+
.colors="${e[this.colorKey]||[`#CADCFC`,`#A0B9D1`]}"
|
|
710
|
+
></ui-orb>`:t.html`<md-icon style="font-size: 16px;"
|
|
711
|
+
>record_voice_over</md-icon
|
|
712
|
+
>`}
|
|
713
|
+
</div>
|
|
714
|
+
<span class="trigger-text"
|
|
715
|
+
>${e[this.titleKey]||e.name}</span
|
|
716
|
+
>
|
|
717
|
+
`:t.html`
|
|
718
|
+
<span
|
|
719
|
+
class="trigger-text"
|
|
720
|
+
style="color: var(--md-sys-color-on-surface-variant)"
|
|
721
|
+
>${this.placeholder}</span
|
|
722
|
+
>
|
|
723
|
+
`}
|
|
724
|
+
</div>
|
|
725
|
+
<md-icon style="color: var(--md-sys-color-on-surface-variant);"
|
|
726
|
+
>unfold_more</md-icon
|
|
727
|
+
>
|
|
728
|
+
</div>
|
|
729
|
+
</button>
|
|
730
|
+
|
|
731
|
+
<!-- Dropdown Menu -->
|
|
732
|
+
<md-menu
|
|
733
|
+
id="voice-menu"
|
|
734
|
+
anchor="voice-anchor"
|
|
735
|
+
positioning="popover"
|
|
736
|
+
@closed=${this._handleMenuClosed}
|
|
737
|
+
>
|
|
738
|
+
<!-- The click.stop modifier stops the menu from closing when searching -->
|
|
739
|
+
<div
|
|
740
|
+
class="search-container"
|
|
741
|
+
@click=${e=>e.stopPropagation()}
|
|
742
|
+
>
|
|
743
|
+
<md-outlined-text-field
|
|
744
|
+
placeholder="Search voices..."
|
|
745
|
+
.value=${this._searchQuery}
|
|
746
|
+
@input=${e=>this._searchQuery=e.target.value}
|
|
747
|
+
>
|
|
748
|
+
<md-icon slot="leading-icon">search</md-icon>
|
|
749
|
+
</md-outlined-text-field>
|
|
750
|
+
</div>
|
|
751
|
+
|
|
752
|
+
${n.length===0?t.html` <div class="empty-state">No voice found.</div> `:n.map(e=>t.html`
|
|
753
|
+
<md-menu-item
|
|
754
|
+
@click=${()=>this._selectVoice(e[this.idKey])}
|
|
755
|
+
?selected=${this.value===e[this.idKey]}
|
|
756
|
+
>
|
|
757
|
+
<div slot="headline" class="voice-item-content">
|
|
758
|
+
<!-- Avatar / Preview Button -->
|
|
759
|
+
<div
|
|
760
|
+
class="voice-avatar"
|
|
761
|
+
@click=${t=>this._togglePreview(t,e)}
|
|
762
|
+
>
|
|
763
|
+
${this.useOrbs?t.html`<ui-orb
|
|
764
|
+
agentState="${this._previewingVoiceId===e[this.idKey]?`talking`:`listening`}"
|
|
765
|
+
.colors="${e[this.colorKey]||[`#CADCFC`,`#A0B9D1`]}"
|
|
766
|
+
></ui-orb>`:t.html`<md-icon style="font-size: 18px;"
|
|
767
|
+
>face</md-icon
|
|
768
|
+
>`}
|
|
769
|
+
${e[this.previewUrlKey]?t.html`
|
|
770
|
+
<div
|
|
771
|
+
class="play-overlay ${this._previewingVoiceId===e[this.idKey]?`active`:``}"
|
|
772
|
+
>
|
|
773
|
+
<md-icon style="font-size: 16px;">
|
|
774
|
+
${this._previewingVoiceId===e[this.idKey]?`pause`:`play_arrow`}
|
|
775
|
+
</md-icon>
|
|
776
|
+
</div>
|
|
777
|
+
`:``}
|
|
778
|
+
</div>
|
|
779
|
+
|
|
780
|
+
<!-- Voice Info -->
|
|
781
|
+
<div class="voice-info">
|
|
782
|
+
<span class="voice-name">${e[this.titleKey]}</span>
|
|
783
|
+
${e[this.subtitleKey]||e.labels?t.html`
|
|
784
|
+
<div class="voice-labels">
|
|
785
|
+
${e[this.subtitleKey]?t.html`<span class="voice-badge"
|
|
786
|
+
>${e[this.subtitleKey]}</span
|
|
787
|
+
>`:Object.values(e.labels||{}).filter(Boolean).map(e=>t.html`<span class="voice-badge"
|
|
788
|
+
>${e}</span
|
|
789
|
+
>`)}
|
|
790
|
+
</div>
|
|
791
|
+
`:``}
|
|
792
|
+
</div>
|
|
793
|
+
</div>
|
|
794
|
+
|
|
795
|
+
${this.value===e[this.idKey]?t.html`<md-icon slot="end">check</md-icon>`:``}
|
|
796
|
+
</md-menu-item>
|
|
797
|
+
`)}
|
|
798
|
+
</md-menu>
|
|
799
|
+
`}_toggleMenu(){this._menuEl&&(this._menuEl.open=!this._menuEl.open)}_handleMenuClosed(){this._stopPreview()}_selectVoice(e){this.value=e,this.dispatchEvent(new CustomEvent(`voice-change`,{detail:{voiceId:e},bubbles:!0,composed:!0}))}_togglePreview(e,t){e.stopPropagation(),e.preventDefault(),!(!t[this.previewUrlKey]||!this._audioEl)&&(this._previewingVoiceId===t[this.idKey]?this._stopPreview():(this._audioEl.src=t[this.previewUrlKey],this._audioEl.play().catch(console.error),this._previewingVoiceId=t[this.idKey]))}_stopPreview(){this._audioEl&&(this._audioEl.pause(),this._audioEl.currentTime=0),this._previewingVoiceId=void 0}};T([(0,n.property)({type:Array})],q.prototype,`voices`,void 0),T([(0,n.property)({type:String})],q.prototype,`value`,void 0),T([(0,n.property)({type:String})],q.prototype,`placeholder`,void 0),T([(0,n.property)({type:String})],q.prototype,`idKey`,void 0),T([(0,n.property)({type:String})],q.prototype,`titleKey`,void 0),T([(0,n.property)({type:String})],q.prototype,`subtitleKey`,void 0),T([(0,n.property)({type:String})],q.prototype,`previewUrlKey`,void 0),T([(0,n.property)({type:Boolean})],q.prototype,`useOrbs`,void 0),T([(0,n.property)({type:String})],q.prototype,`colorKey`,void 0),T([(0,n.state)()],q.prototype,`_searchQuery`,void 0),T([(0,n.state)()],q.prototype,`_previewingVoiceId`,void 0),T([(0,n.query)(`md-menu`)],q.prototype,`_menuEl`,void 0),T([(0,n.query)(`audio`)],q.prototype,`_audioEl`,void 0),q=T([(0,n.customElement)(`ui-voice-picker`)],q);var J=class extends t.LitElement{constructor(...e){super(...e),this.speed=50,this.barCount=60,this.barWidth=4,this.barHeight=4,this.barGap=2,this.barRadius=2,this.fadeEdges=!0,this.fadeWidth=24,this.height=128,this.active=!0,this._animationFrameId=0,this._lastTime=0,this._bars=[],this._seed=Math.random(),this._dataIndex=0}static{this.styles=t.css`
|
|
800
|
+
:host {
|
|
801
|
+
display: block;
|
|
802
|
+
width: 100%;
|
|
803
|
+
}
|
|
804
|
+
.container {
|
|
805
|
+
position: relative;
|
|
806
|
+
width: 100%;
|
|
807
|
+
overflow: hidden;
|
|
808
|
+
}
|
|
809
|
+
canvas {
|
|
810
|
+
position: absolute;
|
|
811
|
+
top: 0;
|
|
812
|
+
left: 0;
|
|
813
|
+
display: block;
|
|
814
|
+
height: 100%;
|
|
815
|
+
width: 100%;
|
|
816
|
+
}
|
|
817
|
+
`}render(){return t.html`
|
|
818
|
+
<div class="container" style="height: ${this.height}px;">
|
|
819
|
+
<canvas></canvas>
|
|
820
|
+
</div>
|
|
821
|
+
`}firstUpdated(){this._resizeObserver=new ResizeObserver(()=>{this._handleResize()}),this._resizeObserver.observe(this._container),this._canvas&&this._container&&this._populateInitialBars(),this._startAnimation()}disconnectedCallback(){super.disconnectedCallback(),this._resizeObserver&&this._resizeObserver.disconnect(),this._animationFrameId&&cancelAnimationFrame(this._animationFrameId)}_handleResize(){if(!this._canvas||!this._container)return;let e=this._container.getBoundingClientRect(),t=window.devicePixelRatio||1;this._canvas.width=e.width*t,this._canvas.height=e.height*t,this._canvas.style.width=`${e.width}px`,this._canvas.style.height=`${e.height}px`;let n=this._canvas.getContext(`2d`);n&&n.scale(t,t)}_seededRandom(e){let t=Math.sin(this._seed*1e4+e*137.5)*1e4;return t-Math.floor(t)}_populateInitialBars(){let e=this._container.getBoundingClientRect(),t=this.barWidth+this.barGap,n=e.width,r=0;for(this._bars=[];n>-t;)this._bars.push({x:n,height:.2+this._seededRandom(r++)*.6}),n-=t;this._bars.reverse()}_startAnimation(){this._lastTime=performance.now();let e=t=>{if(!this._canvas)return;let n=this._canvas.getContext(`2d`);if(!n)return;let r=this._lastTime?(t-this._lastTime)/1e3:0;this._lastTime=t;let i=this._canvas.getBoundingClientRect();n.clearRect(0,0,i.width,i.height);let a=this.barColor;a||=getComputedStyle(this).getPropertyValue(`--md-sys-color-primary`).trim()||`#0066cc`;let o=this.barWidth+this.barGap,s=this.active?this.speed:0;for(let e=0;e<this._bars.length;e++)this._bars[e].x-=s*r,this.active||(this._bars[e].height+=(.05-this._bars[e].height)*.15);for(this._bars=this._bars.filter(e=>e.x+this.barWidth>-o);this._bars.length===0||this._bars[this._bars.length-1].x<i.width;){let e=this._bars[this._bars.length-1],t=e?e.x+o:i.width,n;if(this.data&&this.data.length>0)n=this.data[this._dataIndex%this.data.length]||.1,this._dataIndex=(this._dataIndex+1)%this.data.length;else if(this.analyserNode){(!this._dataArray||this._dataArray.length!==this.analyserNode.frequencyBinCount)&&(this._dataArray=new Uint8Array(this.analyserNode.frequencyBinCount)),this.analyserNode.getByteFrequencyData(this._dataArray);let e=0,t=Math.min(this._dataArray.length,50);for(let n=0;n<t;n++)e+=this._dataArray[n];let r=e/t/255;n=Math.max(.1,r**1.5*1.5)}else{let e=Date.now()/1e3,t=this._bars.length+e*.01,r=Math.sin(t*.1)*.2,i=Math.cos(t*.05)*.15,a=this._seededRandom(t)*.4;n=Math.max(.1,Math.min(.9,.3+r+i+a))}if(this._bars.push({x:t,height:n}),this._bars.length>this.barCount*2)break}let c=i.height/2;for(let e of this._bars)if(e.x<i.width&&e.x+this.barWidth>0){let t=Math.max(this.barHeight,e.height*i.height*.8),r=c-t/2;n.fillStyle=a,n.globalAlpha=.3+e.height*.7,this.barRadius>0?(n.beginPath(),n.roundRect(e.x,r,this.barWidth,t,this.barRadius),n.fill()):n.fillRect(e.x,r,this.barWidth,t)}n.globalAlpha=1,this.fadeEdges&&this.fadeWidth>0&&O(n,i.width,i.height,this.fadeWidth),this._animationFrameId=requestAnimationFrame(e)};this._animationFrameId=requestAnimationFrame(e)}};T([(0,n.property)({type:Number})],J.prototype,`speed`,void 0),T([(0,n.property)({type:Number})],J.prototype,`barCount`,void 0),T([(0,n.property)({type:Number})],J.prototype,`barWidth`,void 0),T([(0,n.property)({type:Number})],J.prototype,`barHeight`,void 0),T([(0,n.property)({type:Number})],J.prototype,`barGap`,void 0),T([(0,n.property)({type:Number})],J.prototype,`barRadius`,void 0),T([(0,n.property)({type:String})],J.prototype,`barColor`,void 0),T([(0,n.property)({type:Boolean})],J.prototype,`fadeEdges`,void 0),T([(0,n.property)({type:Number})],J.prototype,`fadeWidth`,void 0),T([(0,n.property)({type:Number})],J.prototype,`height`,void 0),T([(0,n.property)({type:Array})],J.prototype,`data`,void 0),T([(0,n.property)({attribute:!1})],J.prototype,`analyserNode`,void 0),T([(0,n.property)({type:Boolean})],J.prototype,`active`,void 0),T([(0,n.query)(`canvas`)],J.prototype,`_canvas`,void 0),T([(0,n.query)(`.container`)],J.prototype,`_container`,void 0),J=T([(0,n.customElement)(`ui-scrolling-waveform`)],J);var Y=class extends t.LitElement{constructor(...e){super(...e),this.title=`Component`,this.description=``,this.mode=`preview`}static{this.styles=t.css`
|
|
822
|
+
:host {
|
|
823
|
+
display: block;
|
|
824
|
+
background: var(--md-sys-color-surface, #ffffff);
|
|
825
|
+
color: var(--md-sys-color-on-surface, #1e1e1e);
|
|
826
|
+
border-radius: 12px;
|
|
827
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
828
|
+
transition:
|
|
829
|
+
background-color 0.3s,
|
|
830
|
+
color 0.3s;
|
|
831
|
+
overflow: hidden;
|
|
832
|
+
font-family: inherit;
|
|
833
|
+
border: 1px solid var(--md-sys-color-outline-variant, #c4c7c5);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
.header {
|
|
837
|
+
padding: 1.5rem 2rem 1rem 2rem;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
.title {
|
|
841
|
+
margin-top: 0;
|
|
842
|
+
margin-bottom: 0.5rem;
|
|
843
|
+
font-size: 1.4rem;
|
|
844
|
+
font-weight: 600;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
.description {
|
|
848
|
+
margin: 0;
|
|
849
|
+
font-size: 0.95rem;
|
|
850
|
+
color: var(--md-sys-color-on-surface-variant, #444444);
|
|
851
|
+
line-height: 1.5;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
.tabs {
|
|
855
|
+
display: flex;
|
|
856
|
+
gap: 8px;
|
|
857
|
+
padding: 0 2rem;
|
|
858
|
+
border-bottom: 1px solid var(--md-sys-color-outline-variant, #c4c7c5);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
.tab-btn {
|
|
862
|
+
padding: 8px 16px;
|
|
863
|
+
background: transparent;
|
|
864
|
+
border: none;
|
|
865
|
+
border-bottom: 2px solid transparent;
|
|
866
|
+
color: var(--md-sys-color-on-surface-variant, #444444);
|
|
867
|
+
font-family: inherit;
|
|
868
|
+
font-weight: 600;
|
|
869
|
+
font-size: 0.9rem;
|
|
870
|
+
cursor: pointer;
|
|
871
|
+
transition: all 0.2s;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
.tab-btn:hover {
|
|
875
|
+
color: var(--md-sys-color-primary, #0066cc);
|
|
876
|
+
background: var(--md-sys-color-surface-container-highest, #e3e3e3);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
.tab-btn.active {
|
|
880
|
+
color: var(--md-sys-color-primary, #0066cc);
|
|
881
|
+
border-bottom-color: var(--md-sys-color-primary, #0066cc);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
.content-area {
|
|
885
|
+
padding: 2rem;
|
|
886
|
+
position: relative;
|
|
887
|
+
background: var(--md-sys-color-surface, #ffffff);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
.preview-panel {
|
|
891
|
+
display: none;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
.preview-panel.active {
|
|
895
|
+
display: block;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
.code-panel {
|
|
899
|
+
display: none;
|
|
900
|
+
background: #1e1e1e; /* Standard terminal color */
|
|
901
|
+
color: #e3e3e3;
|
|
902
|
+
padding: 1.5rem;
|
|
903
|
+
border-radius: 8px;
|
|
904
|
+
overflow-x: auto;
|
|
905
|
+
font-family: 'Courier New', Courier, monospace;
|
|
906
|
+
font-size: 0.85rem;
|
|
907
|
+
line-height: 1.5;
|
|
908
|
+
margin: 0;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
.code-panel.active {
|
|
912
|
+
display: block;
|
|
913
|
+
}
|
|
914
|
+
`}render(){return t.html`
|
|
915
|
+
<div class="header">
|
|
916
|
+
<h2 class="title">${this.title}</h2>
|
|
917
|
+
${this.description?t.html`<p class="description">${this.description}</p>`:``}
|
|
918
|
+
</div>
|
|
919
|
+
|
|
920
|
+
<div class="tabs">
|
|
921
|
+
<button
|
|
922
|
+
class="tab-btn ${this.mode===`preview`?`active`:``}"
|
|
923
|
+
@click="${()=>this.mode=`preview`}"
|
|
924
|
+
>
|
|
925
|
+
Preview
|
|
926
|
+
</button>
|
|
927
|
+
<button
|
|
928
|
+
class="tab-btn ${this.mode===`code`?`active`:``}"
|
|
929
|
+
@click="${()=>this.mode=`code`}"
|
|
930
|
+
>
|
|
931
|
+
Code
|
|
932
|
+
</button>
|
|
933
|
+
</div>
|
|
934
|
+
|
|
935
|
+
<div class="content-area">
|
|
936
|
+
<div class="preview-panel ${this.mode===`preview`?`active`:``}">
|
|
937
|
+
<slot></slot>
|
|
938
|
+
</div>
|
|
939
|
+
|
|
940
|
+
<pre
|
|
941
|
+
class="code-panel ${this.mode===`code`?`active`:``}"
|
|
942
|
+
><code><slot name="code"></slot></code></pre>
|
|
943
|
+
</div>
|
|
944
|
+
`}};T([(0,n.property)({type:String})],Y.prototype,`title`,void 0),T([(0,n.property)({type:String})],Y.prototype,`description`,void 0),T([(0,n.property)({type:String})],Y.prototype,`mode`,void 0),Y=T([(0,n.customElement)(`ui-showcase-card`)],Y);var X=class extends t.LitElement{constructor(...e){super(...e),this.text=``,this.duration=2,this.delay=0,this.repeat=!0,this.repeatDelay=.5,this.startOnView=!0,this.once=!1,this.spread=2,this._isInView=!1}static{this.styles=t.css`
|
|
945
|
+
:host {
|
|
946
|
+
display: inline-block;
|
|
947
|
+
font-family: inherit;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
span {
|
|
951
|
+
position: relative;
|
|
952
|
+
display: inline-block;
|
|
953
|
+
|
|
954
|
+
/* Default colors fallback to MD3 tokens if available */
|
|
955
|
+
/* Use a highly transparent base color for maximum contrast against the shimmer */
|
|
956
|
+
--base-color: color-mix(
|
|
957
|
+
in srgb,
|
|
958
|
+
var(--md-sys-color-on-surface, #1e1e1e) 20%,
|
|
959
|
+
transparent
|
|
960
|
+
);
|
|
961
|
+
--shimmer-color: var(--md-sys-color-on-surface, #1e1e1e);
|
|
962
|
+
|
|
963
|
+
--shimmer-bg: linear-gradient(
|
|
964
|
+
90deg,
|
|
965
|
+
transparent calc(50% - var(--spread)),
|
|
966
|
+
var(--shimmer-color) 50%,
|
|
967
|
+
transparent calc(50% + var(--spread))
|
|
968
|
+
);
|
|
969
|
+
|
|
970
|
+
background-image:
|
|
971
|
+
var(--shimmer-bg), linear-gradient(var(--base-color), var(--base-color));
|
|
972
|
+
background-size:
|
|
973
|
+
250% 100%,
|
|
974
|
+
auto; /* Important: this defines the size of the animated gradient */
|
|
975
|
+
background-position: 100% center;
|
|
976
|
+
background-repeat: no-repeat;
|
|
977
|
+
-webkit-background-clip: text;
|
|
978
|
+
background-clip: text;
|
|
979
|
+
color: transparent;
|
|
980
|
+
-webkit-text-fill-color: transparent;
|
|
981
|
+
opacity: 0;
|
|
982
|
+
transition: opacity 0.3s ease;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/* When active, trigger the keyframe animation */
|
|
986
|
+
span.active {
|
|
987
|
+
opacity: 1;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
@keyframes shimmer {
|
|
991
|
+
0% {
|
|
992
|
+
background-position: 100% center;
|
|
993
|
+
}
|
|
994
|
+
100% {
|
|
995
|
+
background-position: 0% center;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
`}firstUpdated(){this.startOnView?(this._intersectionObserver=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting?(this._isInView=!0,this.once&&this._intersectionObserver&&this._intersectionObserver.disconnect()):this.once||(this._isInView=!1)})}),this._intersectionObserver.observe(this)):this._isInView=!0}disconnectedCallback(){super.disconnectedCallback(),this._intersectionObserver&&this._intersectionObserver.disconnect()}render(){let e=!this.startOnView||this._isInView,n=`${this.text.length*this.spread}px`,r=this.duration+this.repeatDelay,i=this.repeat?`infinite`:`1`,a={"--spread":n,...this.color&&{"--base-color":this.color},...this.shimmerColor&&{"--shimmer-color":this.shimmerColor},"animation-name":e?`shimmer`:`none`,"animation-duration":`${r}s`,"animation-timing-function":`linear`,"animation-delay":`${this.delay}s`,"animation-iteration-count":i,"background-position":e&&!this.repeat?`0% center`:`100% center`},o=Object.entries(a).map(([e,t])=>`${e}: ${t}`).join(`; `);return t.html`
|
|
999
|
+
<span class="${e?`active`:``}" style="${o}">
|
|
1000
|
+
${this.text}
|
|
1001
|
+
</span>
|
|
1002
|
+
`}};T([(0,n.property)({type:String})],X.prototype,`text`,void 0),T([(0,n.property)({type:Number})],X.prototype,`duration`,void 0),T([(0,n.property)({type:Number})],X.prototype,`delay`,void 0),T([(0,n.property)({type:Boolean})],X.prototype,`repeat`,void 0),T([(0,n.property)({type:Number})],X.prototype,`repeatDelay`,void 0),T([(0,n.property)({type:Boolean})],X.prototype,`startOnView`,void 0),T([(0,n.property)({type:Boolean})],X.prototype,`once`,void 0),T([(0,n.property)({type:Number})],X.prototype,`spread`,void 0),T([(0,n.property)({type:String})],X.prototype,`color`,void 0),T([(0,n.property)({type:String})],X.prototype,`shimmerColor`,void 0),T([(0,n.state)()],X.prototype,`_isInView`,void 0),X=T([(0,n.customElement)(`ui-shimmering-text`)],X);var Z=class extends t.LitElement{constructor(...e){super(...e),this.agentState=null,this.inputVolume=0,this.outputVolume=0,this.volumeMode=`auto`,this.seed=Math.floor(Math.random()*2**32),this._animationFrameId=0,this._animSpeed=.1,this._curIn=0,this._curOut=0,this._textureLoader=new g.TextureLoader,this._lastTime=0,this._vertexShader=`
|
|
1003
|
+
uniform float uTime;
|
|
1004
|
+
uniform sampler2D uPerlinTexture;
|
|
1005
|
+
varying vec2 vUv;
|
|
1006
|
+
|
|
1007
|
+
void main() {
|
|
1008
|
+
vUv = uv;
|
|
1009
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
1010
|
+
}
|
|
1011
|
+
`,this._fragmentShader=`
|
|
1012
|
+
uniform float uTime;
|
|
1013
|
+
uniform float uAnimation;
|
|
1014
|
+
uniform float uInverted;
|
|
1015
|
+
uniform float uOffsets[7];
|
|
1016
|
+
uniform vec3 uColor1;
|
|
1017
|
+
uniform vec3 uColor2;
|
|
1018
|
+
uniform float uInputVolume;
|
|
1019
|
+
uniform float uOutputVolume;
|
|
1020
|
+
uniform float uOpacity;
|
|
1021
|
+
uniform sampler2D uPerlinTexture;
|
|
1022
|
+
varying vec2 vUv;
|
|
1023
|
+
|
|
1024
|
+
const float PI = 3.14159265358979323846;
|
|
1025
|
+
|
|
1026
|
+
bool drawOval(vec2 polarUv, vec2 polarCenter, float a, float b, bool reverseGradient, float softness, out vec4 color) {
|
|
1027
|
+
vec2 p = polarUv - polarCenter;
|
|
1028
|
+
float oval = (p.x * p.x) / (a * a) + (p.y * p.y) / (b * b);
|
|
1029
|
+
float edge = smoothstep(1.0, 1.0 - softness, oval);
|
|
1030
|
+
if (edge > 0.0) {
|
|
1031
|
+
float gradient = reverseGradient ? (1.0 - (p.x / a + 1.0) / 2.0) : ((p.x / a + 1.0) / 2.0);
|
|
1032
|
+
gradient = mix(0.5, gradient, 0.1);
|
|
1033
|
+
color = vec4(vec3(gradient), 0.85 * edge);
|
|
1034
|
+
return true;
|
|
1035
|
+
}
|
|
1036
|
+
return false;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
vec3 colorRamp(float grayscale, vec3 color1, vec3 color2, vec3 color3, vec3 color4) {
|
|
1040
|
+
if (grayscale < 0.33) {
|
|
1041
|
+
return mix(color1, color2, grayscale * 3.0);
|
|
1042
|
+
} else if (grayscale < 0.66) {
|
|
1043
|
+
return mix(color2, color3, (grayscale - 0.33) * 3.0);
|
|
1044
|
+
} else {
|
|
1045
|
+
return mix(color3, color4, (grayscale - 0.66) * 3.0);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
vec2 hash2(vec2 p) {
|
|
1050
|
+
return fract(sin(vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)))) * 43758.5453);
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
float noise2D(vec2 p) {
|
|
1054
|
+
vec2 i = floor(p);
|
|
1055
|
+
vec2 f = fract(p);
|
|
1056
|
+
vec2 u = f * f * (3.0 - 2.0 * f);
|
|
1057
|
+
float n = mix(
|
|
1058
|
+
mix(dot(hash2(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),
|
|
1059
|
+
dot(hash2(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)), u.x),
|
|
1060
|
+
mix(dot(hash2(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),
|
|
1061
|
+
dot(hash2(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)), u.x),
|
|
1062
|
+
u.y
|
|
1063
|
+
);
|
|
1064
|
+
return 0.5 + 0.5 * n;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
float sharpRing(vec3 decomposed, float time) {
|
|
1068
|
+
float ringStart = 1.0;
|
|
1069
|
+
float ringWidth = 0.3;
|
|
1070
|
+
float noiseScale = 5.0;
|
|
1071
|
+
float noise = mix(
|
|
1072
|
+
noise2D(vec2(decomposed.x, time) * noiseScale),
|
|
1073
|
+
noise2D(vec2(decomposed.y, time) * noiseScale),
|
|
1074
|
+
decomposed.z
|
|
1075
|
+
);
|
|
1076
|
+
noise = (noise - 0.5) * 2.5;
|
|
1077
|
+
return ringStart + noise * ringWidth * 1.5;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
float smoothRing(vec3 decomposed, float time) {
|
|
1081
|
+
float ringStart = 0.9;
|
|
1082
|
+
float ringWidth = 0.2;
|
|
1083
|
+
float noiseScale = 6.0;
|
|
1084
|
+
float noise = mix(
|
|
1085
|
+
noise2D(vec2(decomposed.x, time) * noiseScale),
|
|
1086
|
+
noise2D(vec2(decomposed.y, time) * noiseScale),
|
|
1087
|
+
decomposed.z
|
|
1088
|
+
);
|
|
1089
|
+
noise = (noise - 0.5) * 5.0;
|
|
1090
|
+
return ringStart + noise * ringWidth;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
float flow(vec3 decomposed, float time) {
|
|
1094
|
+
return mix(
|
|
1095
|
+
texture(uPerlinTexture, vec2(time, decomposed.x / 2.0)).r,
|
|
1096
|
+
texture(uPerlinTexture, vec2(time, decomposed.y / 2.0)).r,
|
|
1097
|
+
decomposed.z
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
void main() {
|
|
1102
|
+
vec2 uv = vUv * 2.0 - 1.0;
|
|
1103
|
+
float radius = length(uv);
|
|
1104
|
+
float theta = atan(uv.y, uv.x);
|
|
1105
|
+
if (theta < 0.0) theta += 2.0 * PI;
|
|
1106
|
+
|
|
1107
|
+
vec3 decomposed = vec3(
|
|
1108
|
+
theta / (2.0 * PI),
|
|
1109
|
+
mod(theta / (2.0 * PI) + 0.5, 1.0) + 1.0,
|
|
1110
|
+
abs(theta / PI - 1.0)
|
|
1111
|
+
);
|
|
1112
|
+
|
|
1113
|
+
float noise = flow(decomposed, radius * 0.03 - uAnimation * 0.2) - 0.5;
|
|
1114
|
+
theta += noise * mix(0.08, 0.25, uOutputVolume);
|
|
1115
|
+
|
|
1116
|
+
vec4 color = vec4(1.0, 1.0, 1.0, 1.0);
|
|
1117
|
+
float originalCenters[7] = float[7](0.0, 0.5 * PI, 1.0 * PI, 1.5 * PI, 2.0 * PI, 2.5 * PI, 3.0 * PI);
|
|
1118
|
+
float centers[7];
|
|
1119
|
+
for (int i = 0; i < 7; i++) {
|
|
1120
|
+
centers[i] = originalCenters[i] + 0.5 * sin(uTime / 20.0 + uOffsets[i]);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
float a, b;
|
|
1124
|
+
vec4 ovalColor;
|
|
1125
|
+
|
|
1126
|
+
for (int i = 0; i < 7; i++) {
|
|
1127
|
+
float noise = texture(uPerlinTexture, vec2(mod(centers[i] + uTime * 0.05, 1.0), 0.5)).r;
|
|
1128
|
+
a = 0.5 + noise * 0.3;
|
|
1129
|
+
b = noise * mix(3.5, 2.5, uInputVolume);
|
|
1130
|
+
bool reverseGradient = (i % 2 == 1);
|
|
1131
|
+
float distTheta = min(
|
|
1132
|
+
abs(theta - centers[i]),
|
|
1133
|
+
min(abs(theta + 2.0 * PI - centers[i]), abs(theta - 2.0 * PI - centers[i]))
|
|
1134
|
+
);
|
|
1135
|
+
if (drawOval(vec2(distTheta, radius), vec2(0.0, 0.0), a, b, reverseGradient, 0.6, ovalColor)) {
|
|
1136
|
+
color.rgb = mix(color.rgb, ovalColor.rgb, ovalColor.a);
|
|
1137
|
+
color.a = max(color.a, ovalColor.a);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
float ringRadius1 = sharpRing(decomposed, uTime * 0.1);
|
|
1142
|
+
float ringRadius2 = smoothRing(decomposed, uTime * 0.1);
|
|
1143
|
+
float inputRadius1 = radius + uInputVolume * 0.2;
|
|
1144
|
+
float inputRadius2 = radius + uInputVolume * 0.15;
|
|
1145
|
+
float opacity1 = mix(0.2, 0.6, uInputVolume);
|
|
1146
|
+
float opacity2 = mix(0.15, 0.45, uInputVolume);
|
|
1147
|
+
|
|
1148
|
+
float ringAlpha1 = (inputRadius2 >= ringRadius1) ? opacity1 : 0.0;
|
|
1149
|
+
float ringAlpha2 = smoothstep(ringRadius2 - 0.05, ringRadius2 + 0.05, inputRadius1) * opacity2;
|
|
1150
|
+
float totalRingAlpha = max(ringAlpha1, ringAlpha2);
|
|
1151
|
+
|
|
1152
|
+
vec3 ringColor = vec3(1.0);
|
|
1153
|
+
color.rgb = 1.0 - (1.0 - color.rgb) * (1.0 - ringColor * totalRingAlpha);
|
|
1154
|
+
|
|
1155
|
+
vec3 color1 = vec3(0.0, 0.0, 0.0);
|
|
1156
|
+
vec3 color2 = uColor1;
|
|
1157
|
+
vec3 color3 = uColor2;
|
|
1158
|
+
vec3 color4 = vec3(1.0, 1.0, 1.0);
|
|
1159
|
+
|
|
1160
|
+
float luminance = mix(color.r, 1.0 - color.r, uInverted);
|
|
1161
|
+
color.rgb = colorRamp(luminance, color1, color2, color3, color4);
|
|
1162
|
+
color.a *= uOpacity;
|
|
1163
|
+
|
|
1164
|
+
gl_FragColor = color;
|
|
1165
|
+
}
|
|
1166
|
+
`}static{this.styles=t.css`
|
|
1167
|
+
:host {
|
|
1168
|
+
display: block;
|
|
1169
|
+
width: 100%;
|
|
1170
|
+
height: 100%;
|
|
1171
|
+
position: relative;
|
|
1172
|
+
}
|
|
1173
|
+
.container {
|
|
1174
|
+
width: 100%;
|
|
1175
|
+
height: 100%;
|
|
1176
|
+
}
|
|
1177
|
+
canvas {
|
|
1178
|
+
display: block;
|
|
1179
|
+
width: 100%;
|
|
1180
|
+
height: 100%;
|
|
1181
|
+
}
|
|
1182
|
+
`}render(){return t.html`<div class="container"></div>`}firstUpdated(){this._initThree()}updated(e){e.has(`colors`)&&this._updateColors()}_updateColors(){if(!(!this._targetColor1||!this._targetColor2))if(this.colors&&this.colors.length===2)this._targetColor1.set(this.colors[0]),this._targetColor2.set(this.colors[1]);else{let e=getComputedStyle(this),t=e.getPropertyValue(`--md-sys-color-primary`).trim()||`#CADCFC`,n=e.getPropertyValue(`--md-sys-color-secondary`).trim()||`#A0B9D1`;this._targetColor1.set(t),this._targetColor2.set(n)}}disconnectedCallback(){super.disconnectedCallback(),this._animationFrameId&&cancelAnimationFrame(this._animationFrameId),this._resizeObserver&&this._resizeObserver.disconnect(),this._renderer&&this._renderer.dispose(),this._mesh&&(this._mesh.geometry.dispose(),this._mesh.material.dispose())}async _initThree(){if(!this._container)return;this._targetColor1=new g.Color,this._targetColor2=new g.Color,this._updateColors();try{this._perlinNoiseTexture=await this._textureLoader.loadAsync(`https://storage.googleapis.com/eleven-public-cdn/images/perlin-noise.png`),this._perlinNoiseTexture.wrapS=g.RepeatWrapping,this._perlinNoiseTexture.wrapT=g.RepeatWrapping}catch(e){console.warn(`Failed to load perlin noise texture for orb.`,e);return}let e=this._container.clientWidth,t=this._container.clientHeight;this._scene=new g.Scene,this._camera=new g.OrthographicCamera(-5,5,5,-5,.1,10),this._camera.position.z=1,this._renderer=new g.WebGLRenderer({alpha:!0,antialias:!0,premultipliedAlpha:!0}),this._renderer.setSize(e,t),this._renderer.setPixelRatio(window.devicePixelRatio),this._container.appendChild(this._renderer.domElement);let n=this._splitmix32(this.seed),r=new Float32Array(Array.from({length:7},()=>n()*Math.PI*2)),i=document.documentElement.classList.contains(`dark`)||window.matchMedia(`(prefers-color-scheme: dark)`).matches,a={uColor1:new g.Uniform(this._targetColor1),uColor2:new g.Uniform(this._targetColor2),uOffsets:{value:r},uPerlinTexture:new g.Uniform(this._perlinNoiseTexture),uTime:new g.Uniform(0),uAnimation:new g.Uniform(.1),uInverted:new g.Uniform(i?1:0),uInputVolume:new g.Uniform(0),uOutputVolume:new g.Uniform(0),uOpacity:new g.Uniform(0)},o=new g.CircleGeometry(3.5,64),s=new g.ShaderMaterial({uniforms:a,vertexShader:this._vertexShader,fragmentShader:this._fragmentShader,transparent:!0});this._mesh=new g.Mesh(o,s),this._scene.add(this._mesh),this._resizeObserver=new ResizeObserver(()=>{this._container&&this._renderer&&this._renderer.setSize(this._container.clientWidth,this._container.clientHeight)}),this._resizeObserver.observe(this._container),new MutationObserver(()=>{if(!this._mesh)return;let e=document.documentElement.classList.contains(`dark`);this._mesh.material.uniforms.uInverted.value=e?1:0,this._updateColors()}).observe(document.documentElement,{attributes:!0,attributeFilter:[`class`]}),this._lastTime=performance.now(),this._animate()}_animate(){if(this._animationFrameId=requestAnimationFrame(()=>this._animate()),!this._mesh||!this._renderer||!this._scene||!this._camera)return;let e=performance.now(),t=(e-this._lastTime)/1e3;this._lastTime=e;let n=this._mesh.material.uniforms;n.uTime.value+=t*.5,n.uOpacity.value<1&&(n.uOpacity.value=Math.min(1,n.uOpacity.value+t*2));let r=0,i=.3;if(this.volumeMode===`manual`)r=this._clamp01(this.inputVolume),i=this._clamp01(this.outputVolume);else{let e=n.uTime.value*2;if(this.agentState===null)r=0,i=.3;else if(this.agentState===`listening`)r=this._clamp01(.55+Math.sin(e*3.2)*.35),i=.45;else if(this.agentState===`talking`)r=this._clamp01(.65+Math.sin(e*4.8)*.22),i=this._clamp01(.75+Math.sin(e*3.6)*.22);else{let t=.38+.07*Math.sin(e*.7),n=.05*Math.sin(e*2.1)*Math.sin(e*.37+1.2);r=this._clamp01(t+n),i=this._clamp01(.48+.12*Math.sin(e*1.05+.6))}}this._curIn+=(r-this._curIn)*.2,this._curOut+=(i-this._curOut)*.2;let a=.1+(1-(this._curOut-1)**2)*.9;this._animSpeed+=(a-this._animSpeed)*.12,n.uAnimation.value+=t*this._animSpeed,n.uInputVolume.value=this._curIn,n.uOutputVolume.value=this._curOut,n.uColor1.value.lerp(this._targetColor1,.08),n.uColor2.value.lerp(this._targetColor2,.08),this._renderer.render(this._scene,this._camera)}_splitmix32(e){return function(){e|=0,e=e+2654435769|0;let t=e^e>>>16;return t=Math.imul(t,569420461),t^=t>>>15,t=Math.imul(t,1935289751),((t^=t>>>15)>>>0)/4294967296}}_clamp01(e){return Number.isFinite(e)?Math.min(1,Math.max(0,e)):0}};T([(0,n.property)({type:Array})],Z.prototype,`colors`,void 0),T([(0,n.property)({type:String})],Z.prototype,`agentState`,void 0),T([(0,n.property)({type:Number})],Z.prototype,`inputVolume`,void 0),T([(0,n.property)({type:Number})],Z.prototype,`outputVolume`,void 0),T([(0,n.property)({type:String})],Z.prototype,`volumeMode`,void 0),T([(0,n.property)({type:Number})],Z.prototype,`seed`,void 0),T([(0,n.query)(`.container`)],Z.prototype,`_container`,void 0),Z=T([(0,n.customElement)(`ui-orb`)],Z);var Q=class extends t.LitElement{static{this.styles=t.css`
|
|
1183
|
+
:host {
|
|
1184
|
+
display: flex;
|
|
1185
|
+
align-items: center;
|
|
1186
|
+
gap: 8px;
|
|
1187
|
+
width: 100%;
|
|
1188
|
+
box-sizing: border-box;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
md-slider {
|
|
1192
|
+
flex: 1;
|
|
1193
|
+
min-width: 0; /* Prevent flex overflow */
|
|
1194
|
+
width: 100%;
|
|
1195
|
+
--md-slider-inactive-track-color: var(
|
|
1196
|
+
--md-sys-color-outline-variant,
|
|
1197
|
+
#c4c7c5
|
|
1198
|
+
);
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
md-icon-button {
|
|
1202
|
+
color: var(--md-sys-color-on-surface-variant, #444);
|
|
1203
|
+
}
|
|
1204
|
+
`}render(){let e=this.playerState?.volume??1,n=this.playerState?.muted??!1,r=`volume_up`;return n||e===0?r=`volume_off`:e<.5&&(r=`volume_down`),t.html`
|
|
1205
|
+
<md-icon-button @click="${this._toggleMute}" part="button">
|
|
1206
|
+
<md-icon>${r}</md-icon>
|
|
1207
|
+
</md-icon-button>
|
|
1208
|
+
<md-slider
|
|
1209
|
+
part="slider"
|
|
1210
|
+
min="0"
|
|
1211
|
+
max="1"
|
|
1212
|
+
value="${n?0:e}"
|
|
1213
|
+
step="0.01"
|
|
1214
|
+
?disabled="${!this.playerState?.src}"
|
|
1215
|
+
@input="${this._handleInput}"
|
|
1216
|
+
></md-slider>
|
|
1217
|
+
`}_handleInput(e){let t=e.target;this.playerState&&this.playerState.setVolume(t.value)}_toggleMute(){this.playerState&&this.playerState.toggleMute()}};T([z({context:B,subscribe:!0}),(0,n.property)({attribute:!1})],Q.prototype,`playerState`,void 0),Q=T([(0,n.customElement)(`ui-audio-volume-slider`)],Q),Object.defineProperty(e,`ScreamVoiceButton`,{enumerable:!0,get:function(){return E}}),Object.defineProperty(e,`UiAudioPlayButton`,{enumerable:!0,get:function(){return H}}),Object.defineProperty(e,`UiAudioPlayer`,{enumerable:!0,get:function(){return G}}),Object.defineProperty(e,`UiAudioProgressSlider`,{enumerable:!0,get:function(){return U}}),Object.defineProperty(e,`UiAudioProvider`,{enumerable:!0,get:function(){return V}}),Object.defineProperty(e,`UiAudioTimeDisplay`,{enumerable:!0,get:function(){return W}}),Object.defineProperty(e,`UiAudioVolumeSlider`,{enumerable:!0,get:function(){return Q}}),Object.defineProperty(e,`UiLiveWaveform`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(e,`UiMicSelector`,{enumerable:!0,get:function(){return K}}),Object.defineProperty(e,`UiOrb`,{enumerable:!0,get:function(){return Z}}),Object.defineProperty(e,`UiScrollingWaveform`,{enumerable:!0,get:function(){return J}}),Object.defineProperty(e,`UiShimmeringText`,{enumerable:!0,get:function(){return X}}),Object.defineProperty(e,`UiShowcaseCard`,{enumerable:!0,get:function(){return Y}}),Object.defineProperty(e,`UiVoiceButton`,{enumerable:!0,get:function(){return A}}),Object.defineProperty(e,`UiVoicePicker`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(e,`UiWaveform`,{enumerable:!0,get:function(){return j}}),e.audioPlayerContext=B});
|