1
1
import {
2
+ Accordion ,
3
+ AccordionButton ,
4
+ AccordionIcon ,
5
+ AccordionItem ,
6
+ AccordionPanel ,
2
7
Box , Button , CircularProgress , CircularProgressLabel , FormControl , FormLabel , Heading , Input , SimpleGrid ,
3
8
Slider ,
4
9
SliderFilledTrack ,
5
10
SliderMark ,
6
11
SliderThumb ,
7
12
SliderTrack ,
8
13
Switch ,
14
+ Text ,
9
15
useToast ,
10
16
} from '@chakra-ui/react' ;
11
17
import CytoGraph from '@deep-foundation/deepcase/imports/cyto/graph' ;
@@ -16,19 +22,20 @@ import {
16
22
DeviceProvider ,
17
23
useDevice
18
24
} from '@deep-foundation/deepmemo-imports/imports/device' ;
19
- import {
20
- VoiceProvider ,
21
- useVoice
22
- } from '@deep-foundation/deepmemo-imports/imports/voice' ;
23
25
import {
24
26
GeolocationProvider ,
25
27
useGeolocation
26
28
} 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' ;
27
35
import React , { useEffect , useRef , useState } from 'react' ;
28
36
import { Connection } from '../src/connection' ;
29
37
import { 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' ;
32
39
33
40
const Loading = React . memo ( function Loading ( { factor, interval } : { factor : any , interval : number } ) {
34
41
const [ value , setValue ] = useState ( 0 ) ;
@@ -76,7 +83,7 @@ const Interval = React.memo(function Loading({ value, onChange }: { value: any,
76
83
</ Slider > </ Box > ;
77
84
} ) ;
78
85
79
- const Graph = React . memo ( function Graph ( { linkId } : { linkId : Id } ) {
86
+ const Graph = React . memo ( function Graph ( { linkId, query = { } } : { linkId : Id ; query ?: any } ) {
80
87
const deep = useDeep ( ) ;
81
88
const cyRef = useRef ( ) ;
82
89
const cytoViewportRef = useRefstarter < { pan : { x : number ; y : number ; } ; zoom : number } > ( ) ;
@@ -89,6 +96,7 @@ const Graph = React.memo(function Graph({ linkId }: { linkId: Id }) {
89
96
deep . idLocal ( '@deep-foundation/core' , 'Rejected' ) ,
90
97
deep . idLocal ( '@deep-foundation/core' , 'PromiseResult' ) ,
91
98
] } } ,
99
+ ...( query )
92
100
} ) ;
93
101
return < >
94
102
{ ! ! linkId && < Box w = { 500 } h = { 500 } border = { '1px' } rounded = 'md' position = "relative" >
@@ -122,29 +130,91 @@ const GeolocationView = React.memo(function GeolocationView({ interval }: { inte
122
130
</ > ;
123
131
} ) ;
124
132
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
+
125
207
const VoiceView = React . memo ( function VoiceView ( ) {
126
208
const deep = useDeep ( ) ;
127
209
const voice = useVoice ( ) ;
128
- const [ voices , setVoices ] = useState ( [ ] ) ;
129
- const [ active , setActive ] = useState ( - 1 ) ;
210
+ const device = useDevice ( ) ;
130
211
return < >
131
212
< 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 /> }
143
214
{ voice . status ? (
144
215
voice . recording ? ( < >
145
216
< Button onClick = { async ( ) => {
146
217
const record = await voice . stop ( ) ;
147
- setVoices ( v => [ ...v , record ] ) ;
148
218
} } > stop</ Button >
149
219
{ voice . paused ? (
150
220
< Button onClick = { ( ) => voice . pause ( ) } > pause</ Button >
0 commit comments