@@ -245,24 +245,6 @@ export const COMPONENTS = {
245245    return  ( 
246246      < Container  componentName = "AudioVisualizer" > 
247247        < div  className = "flex items-center gap-2" > 
248-           < div  className = "flex-1" > 
249-             < label  className = "font-mono text-xs uppercase"  htmlFor = "state" > 
250-               State
251-             </ label > 
252-             < Select  value = { state }  onValueChange = { ( value )  =>  setState ( value  as  AgentState ) } > 
253-               < SelectTrigger  id = "state"  className = "w-full" > 
254-                 < SelectValue  placeholder = "Select a state"  /> 
255-               </ SelectTrigger > 
256-               < SelectContent > 
257-                 { states . map ( ( state )  =>  ( 
258-                   < SelectItem  key = { state }  value = { state } > 
259-                     { state } 
260-                   </ SelectItem > 
261-                 ) ) } 
262-               </ SelectContent > 
263-             </ Select > 
264-           </ div > 
265- 
266248          < div  className = "flex-1" > 
267249            < label  className = "font-mono text-xs uppercase"  htmlFor = "size" > 
268250              Size
@@ -313,16 +295,34 @@ export const COMPONENTS = {
313295              className = "mx-auto" 
314296            /> 
315297          </ div > 
316-           < div  className = "text-center" > Original BarVisualizer</ div > 
317-           < div  className = "border-border grid place-items-center rounded-xl border p-4 py-8" > 
318-             < BarVisualizer 
319-               size = { size  as  audioBarVisualizerVariantsSizeType } 
320-               state = { state } 
321-               audioTrack = { micTrackRef ! } 
322-               barCount = { parseInt ( barCount )  ||  undefined } 
323-               className = "mx-auto" 
324-             /> 
325-           </ div > 
298+           < details > 
299+             < summary  className = "text-muted-foreground font-mono text-xs uppercase" > 
300+               < span  className = "inline-block cursor-pointer p-1" > Original BarVisualizer</ span > 
301+             </ summary > 
302+             < div  className = "border-border grid place-items-center rounded-xl border p-4 py-8" > 
303+               < BarVisualizer 
304+                 size = { size  as  audioBarVisualizerVariantsSizeType } 
305+                 state = { state } 
306+                 audioTrack = { micTrackRef ! } 
307+                 barCount = { parseInt ( barCount )  ||  undefined } 
308+                 className = "mx-auto" 
309+               /> 
310+             </ div > 
311+           </ details > 
312+         </ div > 
313+ 
314+         < div  className = "flex flex-wrap gap-4" > 
315+           { states . map ( ( stateType )  =>  ( 
316+             < Button 
317+               key = { stateType } 
318+               size = "sm" 
319+               variant = { state  ===  stateType  ? 'primary'  : 'default' } 
320+               onClick = { ( )  =>  setState ( stateType ) } 
321+               className = { 'flex-1' } 
322+             > 
323+               { stateType } 
324+             </ Button > 
325+           ) ) } 
326326        </ div > 
327327      </ Container > 
328328    ) ; 
@@ -363,24 +363,6 @@ export const COMPONENTS = {
363363    return  ( 
364364      < Container  componentName = "AudioVisualizer" > 
365365        < div  className = "flex items-center gap-2" > 
366-           < div  className = "flex-1" > 
367-             < label  className = "font-mono text-xs uppercase"  htmlFor = "state" > 
368-               State
369-             </ label > 
370-             < Select  value = { state }  onValueChange = { ( value )  =>  setState ( value  as  AgentState ) } > 
371-               < SelectTrigger  id = "state"  className = "w-full" > 
372-                 < SelectValue  placeholder = "Select a state"  /> 
373-               </ SelectTrigger > 
374-               < SelectContent > 
375-                 { states . map ( ( state )  =>  ( 
376-                   < SelectItem  key = { state }  value = { state } > 
377-                     { state } 
378-                   </ SelectItem > 
379-                 ) ) } 
380-               </ SelectContent > 
381-             </ Select > 
382-           </ div > 
383- 
384366          < div  className = "flex-1" > 
385367            < label  className = "font-mono text-xs uppercase"  htmlFor = "size" > 
386368              Size
@@ -432,6 +414,20 @@ export const COMPONENTS = {
432414            /> 
433415          </ div > 
434416        </ div > 
417+ 
418+         < div  className = "flex flex-wrap gap-4" > 
419+           { states . map ( ( stateType )  =>  ( 
420+             < Button 
421+               key = { stateType } 
422+               size = "sm" 
423+               variant = { state  ===  stateType  ? 'primary'  : 'default' } 
424+               onClick = { ( )  =>  setState ( stateType ) } 
425+               className = { 'flex-1' } 
426+             > 
427+               { stateType } 
428+             </ Button > 
429+           ) ) } 
430+         </ div > 
435431      </ Container > 
436432    ) ; 
437433  } , 
@@ -476,24 +472,6 @@ export const COMPONENTS = {
476472    return  ( 
477473      < Container  componentName = "AudioVisualizer" > 
478474        < div  className = "flex items-center gap-2" > 
479-           < div  className = "flex-1" > 
480-             < label  className = "font-mono text-xs uppercase"  htmlFor = "state" > 
481-               State
482-             </ label > 
483-             < Select  value = { state }  onValueChange = { ( value )  =>  setState ( value  as  AgentState ) } > 
484-               < SelectTrigger  id = "state"  className = "w-full" > 
485-                 < SelectValue  placeholder = "Select a state"  /> 
486-               </ SelectTrigger > 
487-               < SelectContent > 
488-                 { states . map ( ( state )  =>  ( 
489-                   < SelectItem  key = { state }  value = { state } > 
490-                     { state } 
491-                   </ SelectItem > 
492-                 ) ) } 
493-               </ SelectContent > 
494-             </ Select > 
495-           </ div > 
496- 
497475          < div  className = "flex-1" > 
498476            < label  className = "font-mono text-xs uppercase"  htmlFor = "rowCount" > 
499477              Row count
@@ -560,19 +538,34 @@ export const COMPONENTS = {
560538            options = { demoOptions } 
561539          /> 
562540        </ div > 
563-         < div  className = "border-border bg-muted overflow-x-auto rounded-xl border p-8" > 
564-           < pre  className = "text-muted-foreground text-sm" > 
565-             < code > { JSON . stringify ( demoOptions ,  null ,  2 ) } </ code > 
566-           </ pre > 
541+ 
542+         < div  className = "flex flex-wrap gap-4" > 
543+           { states . map ( ( stateType )  =>  ( 
544+             < Button 
545+               key = { stateType } 
546+               size = "sm" 
547+               variant = { state  ===  stateType  ? 'primary'  : 'default' } 
548+               onClick = { ( )  =>  setState ( stateType ) } 
549+               className = { 'flex-1' } 
550+             > 
551+               { stateType } 
552+             </ Button > 
553+           ) ) } 
554+         </ div > 
555+ 
556+         < div > 
557+           < StoryTitle > Demo options</ StoryTitle > 
558+           < div  className = "border-border bg-muted overflow-x-auto rounded-xl border p-8" > 
559+             < pre  className = "text-muted-foreground text-sm" > 
560+               < code > { JSON . stringify ( demoOptions ,  null ,  2 ) } </ code > 
561+             </ pre > 
562+           </ div > 
567563        </ div > 
568564      </ Container > 
569565    ) ; 
570566  } , 
571567
572568  AudioShaderVisualizer : ( )  =>  { 
573-     const  {  startSession,  endSession }  =  useSession ( ) ; 
574-     const  {  localParticipant }  =  useLocalParticipant ( ) ; 
575- 
576569    // shape 
577570    const  [ shape ,  setShape ]  =  useState ( 1.0 ) ; 
578571    // color scale 
@@ -593,20 +586,18 @@ export const COMPONENTS = {
593586    const  [ size ,  setSize ]  =  useState < audioShaderVisualizerVariantsSizeType > ( 'lg' ) ; 
594587    const  [ state ,  setState ]  =  useState < AgentState > ( states [ 0 ] ) ; 
595588
596-     const  { 
597-       // state, 
598-       audioTrack, 
599-     }  =  useVoiceAssistant ( ) ; 
600- 
601-     useEffect ( ( )  =>  { 
602-       if  ( state  ===  'speaking' )  { 
603-         startSession ( ) ; 
604-         localParticipant . setMicrophoneEnabled ( true ,  undefined ) ; 
605-       }  else  { 
606-         endSession ( ) ; 
607-         localParticipant . setMicrophoneEnabled ( false ,  undefined ) ; 
608-       } 
609-     } ,  [ startSession ,  endSession ,  state ,  localParticipant ] ) ; 
589+     const  {  microphoneTrack,  localParticipant }  =  useLocalParticipant ( ) ; 
590+     const  micTrackRef  =  useMemo < TrackReferenceOrPlaceholder  |  undefined > ( ( )  =>  { 
591+       return  state  ===  'speaking' 
592+         ? ( { 
593+             participant : localParticipant , 
594+             source : Track . Source . Microphone , 
595+             publication : microphoneTrack , 
596+           }  as  TrackReference ) 
597+         : undefined ; 
598+     } ,  [ state ,  localParticipant ,  microphoneTrack ] ) ; 
599+ 
600+     useMicrophone ( ) ; 
610601
611602    const  fields  =  [ 
612603      [ 'color position' ,  colorPosition ,  setColorPosition ,  0 ,  1 ,  0.01 ] , 
@@ -615,28 +606,7 @@ export const COMPONENTS = {
615606
616607    return  ( 
617608      < Container  componentName = "AudioShaderVisualizer" > 
618-         < StartAudio  label = "Start Audio"  /> 
619-         < RoomAudioRenderer  /> 
620- 
621609        < div  className = "flex gap-4" > 
622-           < div  className = "flex-1" > 
623-             < label  className = "font-mono text-xs uppercase"  htmlFor = "state" > 
624-               State
625-             </ label > 
626-             < Select  value = { state }  onValueChange = { ( value )  =>  setState ( value  as  AgentState ) } > 
627-               < SelectTrigger  id = "state"  className = "w-full" > 
628-                 < SelectValue  placeholder = "Select a state"  /> 
629-               </ SelectTrigger > 
630-               < SelectContent > 
631-                 { states . map ( ( state )  =>  ( 
632-                   < SelectItem  key = { state }  value = { state } > 
633-                     { state } 
634-                   </ SelectItem > 
635-                 ) ) } 
636-               </ SelectContent > 
637-             </ Select > 
638-           </ div > 
639- 
640610          < div  className = "flex-1" > 
641611            < label  className = "font-mono text-xs uppercase"  htmlFor = "size" > 
642612              Size
@@ -681,11 +651,25 @@ export const COMPONENTS = {
681651            shape = { shape } 
682652            colorScale = { colorScale } 
683653            colorPosition = { colorPosition } 
684-             audioTrack = { audioTrack   as   TrackReferenceOrPlaceholder } 
654+             audioTrack = { micTrackRef ! } 
685655            className = "mx-auto bg-black" 
686656          /> 
687657        </ div > 
688658
659+         < div  className = "flex flex-wrap gap-4" > 
660+           { states . map ( ( stateType )  =>  ( 
661+             < Button 
662+               key = { stateType } 
663+               size = "sm" 
664+               variant = { state  ===  stateType  ? 'primary'  : 'default' } 
665+               onClick = { ( )  =>  setState ( stateType ) } 
666+               className = { 'flex-1' } 
667+             > 
668+               { stateType } 
669+             </ Button > 
670+           ) ) } 
671+         </ div > 
672+ 
689673        < div  className = "grid grid-cols-2 gap-4" > 
690674          { fields . map ( ( [ name ,  value ,  setValue ,  min  =  0.1 ,  max  =  10 ,  step  =  0.1 ] )  =>  { 
691675            return  ( 
0 commit comments