11import {
2+ Accordion ,
3+ AccordionButton ,
4+ AccordionIcon ,
5+ AccordionItem ,
6+ AccordionPanel ,
27 Box , Button , CircularProgress , CircularProgressLabel , FormControl , FormLabel , Heading , Input , SimpleGrid ,
38 Slider ,
49 SliderFilledTrack ,
510 SliderMark ,
611 SliderThumb ,
712 SliderTrack ,
813 Switch ,
14+ Text ,
915 useToast ,
1016} from '@chakra-ui/react' ;
1117import CytoGraph from '@deep-foundation/deepcase/imports/cyto/graph' ;
@@ -16,19 +22,20 @@ import {
1622 DeviceProvider ,
1723 useDevice
1824} from '@deep-foundation/deepmemo-imports/imports/device' ;
19- import {
20- VoiceProvider ,
21- useVoice
22- } from '@deep-foundation/deepmemo-imports/imports/voice' ;
2325import {
2426 GeolocationProvider ,
2527 useGeolocation
2628} from '@deep-foundation/deepmemo-imports/imports/geolocation' ;
29+ import { SaverProvider } from '@deep-foundation/deepmemo-imports/imports/saver' ;
30+ import {
31+ VoiceProvider ,
32+ useVoice
33+ } from '@deep-foundation/deepmemo-imports/imports/voice' ;
34+ import { useLocalStore } from '@deep-foundation/store/local' ;
2735import React , { useEffect , useRef , useState } from 'react' ;
2836import { Connection } from '../src/connection' ;
2937import { i18nGetStaticProps } from '../src/i18n' ;
30- import { SaverProvider } from '@deep-foundation/deepmemo-imports/imports/saver' ;
31- import { useLocalStore } from '@deep-foundation/store/local' ;
38+ import useAxios from 'axios-hooks' ;
3239
3340const Loading = React . memo ( function Loading ( { factor, interval } : { factor : any , interval : number } ) {
3441 const [ value , setValue ] = useState ( 0 ) ;
@@ -76,7 +83,7 @@ const Interval = React.memo(function Loading({ value, onChange }: { value: any,
7683 </ Slider > </ Box > ;
7784} ) ;
7885
79- const Graph = React . memo ( function Graph ( { linkId } : { linkId : Id } ) {
86+ const Graph = React . memo ( function Graph ( { linkId, query = { } } : { linkId : Id ; query ?: any } ) {
8087 const deep = useDeep ( ) ;
8188 const cyRef = useRef ( ) ;
8289 const cytoViewportRef = useRefstarter < { pan : { x : number ; y : number ; } ; zoom : number } > ( ) ;
@@ -89,6 +96,7 @@ const Graph = React.memo(function Graph({ linkId }: { linkId: Id }) {
8996 deep . idLocal ( '@deep-foundation/core' , 'Rejected' ) ,
9097 deep . idLocal ( '@deep-foundation/core' , 'PromiseResult' ) ,
9198 ] } } ,
99+ ...( query )
92100 } ) ;
93101 return < >
94102 { ! ! linkId && < Box w = { 500 } h = { 500 } border = { '1px' } rounded = 'md' position = "relative" >
@@ -122,29 +130,91 @@ const GeolocationView = React.memo(function GeolocationView({ interval }: { inte
122130 </ > ;
123131} ) ;
124132
133+ const VoicesVoiceView = React . memo ( function VoicesVoiceView ( { voice, i } : { voice : any , i : number } ) {
134+ const deep = useDeep ( ) ;
135+
136+ const ssl = deep . apolloClient . ssl ;
137+ const path = deep . apolloClient . path . slice ( 0 , - 4 ) ;
138+ const url = `${ ssl ? "https://" : "http://" } ${ path } /file?linkId=${ voice . id } ` ;
139+
140+ const [ { data, loading, error } , refetch ] = useAxios ( {
141+ method : 'get' , url : `${ ssl ? "https://" : "http://" } ${ path } /file?linkId=${ voice . id } ` ,
142+ headers : { 'Authorization' : `Bearer ${ deep . token } ` } ,
143+ responseType : "blob" ,
144+ } ) ;
145+ const [ src , setSrc ] = useState < any > ( ) ;
146+ useEffect ( ( ) => {
147+ if ( ! loading && data ) {
148+ const reader = new window . FileReader ( ) ;
149+ reader . onload = ( ) => {
150+ setSrc ( reader . result ) ;
151+ }
152+ reader . readAsDataURL ( data ) ;
153+ }
154+ } , [ data , loading ] ) ;
155+
156+ const [ text ] = deep . useMinilinksSubscription ( {
157+ type_id : deep . idLocal ( '@deep-foundation/core' , 'SyncTextFile' ) ,
158+ in : { type_id : deep . idLocal ( '@deep-foundation/core' , 'Contain' ) , from_id : voice . id } ,
159+ } ) ;
160+
161+ return < >
162+ < AccordionItem > { ( { isExpanded } ) => ( < >
163+ < h2 >
164+ < AccordionButton >
165+ < Box >
166+ < Text noOfLines = { 1 } >
167+ { voice ?. id || i } { text ?. value ?. value || '' }
168+ </ Text >
169+ </ Box >
170+ < AccordionIcon />
171+ </ AccordionButton >
172+ </ h2 >
173+ < AccordionPanel pb = { 4 } >
174+ { ! ! isExpanded && ! ! src && < audio src = { src } controls > Your browser does not support the audio element.</ audio > }
175+ { ! ! text && < Box > { text ?. value ?. value } </ Box > }
176+ </ AccordionPanel >
177+ </ > ) } </ AccordionItem >
178+ </ > ;
179+ } ) ;
180+
181+ const VoicesView = React . memo ( function VoiceView ( ) {
182+ const deep = useDeep ( ) ;
183+ const device = useDevice ( ) ;
184+ const voice = useVoice ( ) ;
185+ // const [voices, setVoices] = useState([]);
186+ const voices = deep . useMinilinksSubscription ( {
187+ type_id : deep . idLocal ( '@deep-foundation/core' , 'AsyncFile' ) ,
188+ in : { type_id : deep . idLocal ( '@deep-foundation/core' , 'Contain' ) , from_id : device ?. id || 0 } ,
189+ order_by : { id : 'asc' } ,
190+ } ) ;
191+ return < >
192+ < SimpleGrid columns = { { sm : 1 , md : 2 } } >
193+ < Box >
194+ < Accordion allowToggle >
195+ { voices . map ( ( v , i ) => < >
196+ < VoicesVoiceView key = { v . id } voice = { v } i = { i } />
197+ </ > ) }
198+ </ Accordion >
199+ </ Box >
200+ { deep ?. linkId && device ?. id && < Graph linkId = { device . id } query = { {
201+ up : { parent : { type_id : deep . idLocal ( '@deep-foundation/core' , 'AsyncFile' ) } }
202+ } } /> }
203+ </ SimpleGrid >
204+ </ > ;
205+ } ) ;
206+
125207const VoiceView = React . memo ( function VoiceView ( ) {
126208 const deep = useDeep ( ) ;
127209 const voice = useVoice ( ) ;
128- const [ voices , setVoices ] = useState ( [ ] ) ;
129- const [ active , setActive ] = useState ( - 1 ) ;
210+ const device = useDevice ( ) ;
130211 return < >
131212 < Heading > Voice</ Heading >
132- < Box >
133- { voices . map ( ( v , i ) => < Button key = { i }
134- onClick = { ( ) => setActive ( id => i === id ? - 1 : i ) }
135- variant = { active === i ? 'solid' : 'outline' }
136- > { v ?. id || i } </ Button > ) }
137- < Box >
138- </ Box >
139- { active >= 0 && < audio controls >
140- < source src = { `data:audio/mpeg;base64,${ voices [ active ] ?. record } ` } type = "audio/mpeg" > </ source >
141- </ audio > }
142- </ Box >
213+ { ! ! deep && ! ! device ?. id && < VoicesView /> }
143214 { voice . status ? (
144215 voice . recording ? ( < >
145216 < Button onClick = { async ( ) => {
146217 const record = await voice . stop ( ) ;
147- setVoices ( v => [ ...v , record ] ) ;
148218 } } > stop</ Button >
149219 { voice . paused ? (
150220 < Button onClick = { ( ) => voice . pause ( ) } > pause</ Button >
0 commit comments