@nethesis/phone-island 0.7.76 → 0.7.78
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/README.md
CHANGED
|
@@ -73,6 +73,18 @@ touch .env.development.local
|
|
|
73
73
|
echo "CONFIG_TOKEN=$(echo -n "<cti_host>:<cti_username>:<cti_token>:<sip_ext>:<sip_secret>" | base64 -w0)" > .env.development.local
|
|
74
74
|
npm run dev
|
|
75
75
|
```
|
|
76
|
+
**Other environment variables can be specified inside the file above:**
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
# The destination number to be called
|
|
80
|
+
DEST_NUMBER=<call_destination_number>
|
|
81
|
+
|
|
82
|
+
# The announcement id to be reproduced as announcement and base64 audio file
|
|
83
|
+
ANNOUNCEMENT_ID=<announcement_id>
|
|
84
|
+
|
|
85
|
+
# The call recording id to be reproduced
|
|
86
|
+
CALL_RECORDING_ID=<call_recording_id>
|
|
87
|
+
```
|
|
76
88
|
|
|
77
89
|
The main component can be developed using Storybook. Inside the story is rendered the component exported by the final component library.
|
|
78
90
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");require("../node_modules/react-redux/es/index.js");var r=require("../store/index.js"),t=require("../node_modules/react-redux/es/hooks/useDispatch.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=n(e),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");require("../node_modules/react-redux/es/index.js");var r=require("../store/index.js"),t=require("../node_modules/react-redux/es/hooks/useDispatch.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=n(e),c={0:4,1:3,2:2,3:1,4:1,5:2,6:3,7:4},i={0:2,1:1,2:1,3:2};exports.AudioBars=function(n){var a=n.audioStream,o=void 0===a?null:a,s=n.audioElement,l=void 0===s?null:s,d=n.paused,f=n.size,m=e.useRef(null),p=e.useRef(null),v="large"===f?c:i,y=e.useRef(null),h=e.useRef(null),A=e.useRef(null),E=t.useDispatch();function x(){var e,r=requestAnimationFrame(j);(e=r)&&(p.current=e)}function j(){var e;if(h&&h.current){var r=new Uint8Array(h.current.frequencyBinCount);h.current.getByteFrequencyData(r);var t=Object.values(r),n=null===(e=m.current)||void 0===e?void 0:e.children;if(n&&(null==n?void 0:n.length)>0){for(var u=0;u<Object.keys(v).length;++u){var c=t[v[u]]/255,i=n&&n[u]&&n[u].style;i&&c>0&&(i.height="".concat(100*c,"%"))}x()}}}return e.useEffect((function(){var e=r.store.getState().audioBars,t=e.audioElementContext,n=e.audioElementAnalyser,u=e.audioElementSource,c=e.isReady;return l&&c?(y.current=t,h.current=n,A.current=u):(y.current=new AudioContext,h.current=y.current.createAnalyser(),h.current.smoothingTimeConstant=.8,h.current.fftSize=32,o?A.current=y.current.createMediaStreamSource(o):l&&(A.current=y.current.createMediaElementSource(l),E.audioBars.setAudioElementContext(y.current),E.audioBars.setAudioElementAnalyser(h.current),E.audioBars.setAudioElementSource(A.current),E.audioBars.setIsReady(!0))),h.current&&A.current&&A.current.connect(h.current),l&&y.current&&h.current&&h.current.connect(y.current.destination),x(),function(){var e;p.current&&cancelAnimationFrame(p.current),null===(e=A.current)||void 0===e||e.disconnect()}}),[]),e.useEffect((function(){p.current&&(d?cancelAnimationFrame(p.current):(cancelAnimationFrame(p.current),x()))}),[f,d]),u.default.createElement("div",{className:"".concat("small"===f?"pi-h-6 pi-w-6":"pi-h-12 pi-w-12"," pi-flex pi-justify-center pi-items-center")},u.default.createElement("div",{className:"".concat("small"===f?"pi-h-6":"pi-h-8"," pi-w-fit pi-flex pi-justify-center pi-items-center pi-gap-1 pi-overflow-hidden"),ref:m},(o||l)&&Object.keys(v).map((function(e){return u.default.createElement("span",{key:e,className:"pi-bg-emerald-600 pi-w-0.5 pi-rounded-sm"})}))))};
|
|
2
2
|
//# sourceMappingURL=AudioBars.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudioBars.js","sources":["../../src/components/AudioBars.tsx"],"sourcesContent":["// Copyright (C) 2022 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type FC, useEffect, useRef } from 'react'\nimport { ContextSourceType } from '../models/audioBars'\nimport { useDispatch } from 'react-redux'\nimport { store } from '../store'\nimport { Dispatch } from '../store'\n\nconst large = {\n 0: 4,\n 1: 3,\n 2: 2,\n 3: 1,\n 4: 1,\n 5: 2,\n 6: 3,\n 7: 4,\n}\n\nconst small = {\n 0: 2,\n 1: 1,\n 2: 1,\n 3: 2,\n}\n\n/**\n * This component shows a dynamic audio spectrum given an audio stream\n *\n * @param audioStream An audio stream to analyse\n * @param audioElement An audio element to analyse\n */\nexport const AudioBars: FC<AudioBarsProps> = ({\n audioStream = null,\n audioElement = null,\n paused,\n size,\n}) => {\n // Initialize the main elements\n const containerElement = useRef<HTMLDivElement | null>(null)\n const animationRequest = useRef<number | null>(null)\n const barsMap: BarsMapType = size === 'large' ? large : small\n const context = useRef<AudioContext | null>(null)\n const analyser = useRef<AnalyserNode | null>(null)\n const source = useRef<ContextSourceType>(null)\n const dispatch = useDispatch<Dispatch>()\n\n function saveAnimationRequest(requestId: number) {\n if (requestId) {\n animationRequest.current = requestId\n }\n }\n\n function startAnimation() {\n const animationRequestId: number = requestAnimationFrame(animationFrame)\n saveAnimationRequest(animationRequestId)\n }\n\n // The function that renders the frames of animation\n function animationFrame() {\n if (analyser && analyser.current) {\n const frequencyData = new Uint8Array(analyser.current.frequencyBinCount)\n analyser.current.getByteFrequencyData(frequencyData)\n const values = Object.values(frequencyData)\n\n const bars = containerElement.current?.children\n if (bars && bars?.length > 0) {\n // Change styles to every bar\n for (let i = 0; i < Object.keys(barsMap).length; ++i) {\n const value = values[barsMap[i]] / 255\n // @ts-ignore\n const barStyles = bars && bars[i] && bars[i].style\n if (barStyles && value > 0) {\n barStyles.height = `${100 * value}%`\n }\n }\n startAnimation()\n }\n }\n }\n\n useEffect(() => {\n const { audioElementContext, audioElementAnalyser, audioElementSource, isReady } =\n store.getState().audioBars\n // Initialize audio context and analyser once\n if (audioElement && isReady) {\n // The source is an audio element\n context.current = audioElementContext\n analyser.current = audioElementAnalyser\n source.current = audioElementSource\n } else {\n // The source is an audio stream\n context.current = new AudioContext()\n analyser.current = context.current.createAnalyser()\n analyser.current.smoothingTimeConstant = 0.8\n analyser.current.fftSize = 32\n // Create the media source stream\n if (audioStream) {\n source.current = context.current.createMediaStreamSource(audioStream)\n } else if (audioElement) {\n source.current = context.current.createMediaElementSource(audioElement)\n // Save the audio elements to stores\n dispatch.audioBars.setAudioElementContext(context.current)\n dispatch.audioBars.setAudioElementAnalyser(analyser.current)\n dispatch.audioBars.setAudioElementSource(source.current)\n dispatch.audioBars.setIsReady(true)\n }\n }\n\n // Connect the audio source to the analyser\n analyser.current && source.current && source.current.connect(analyser.current)\n startAnimation()\n\n // Cleanup bars animation\n return () => {\n animationRequest.current && cancelAnimationFrame(animationRequest.current)\n source.current?.disconnect()\n }\n }, [])\n\n useEffect(() => {\n if (animationRequest.current) {\n if (!paused) {\n cancelAnimationFrame(animationRequest.current)\n startAnimation()\n } else {\n cancelAnimationFrame(animationRequest.current)\n }\n }\n }, [size, paused])\n\n return (\n <div\n className={`${\n size === 'small' ? 'pi-h-6 pi-w-6' : 'pi-h-12 pi-w-12'\n } pi-flex pi-justify-center pi-items-center`}\n >\n {/* The bars container */}\n <div\n className={`${\n size === 'small' ? 'pi-h-6' : 'pi-h-8'\n } pi-w-fit pi-flex pi-justify-center pi-items-center pi-gap-1 pi-overflow-hidden`}\n ref={containerElement}\n >\n {/* Every single bar */}\n {(audioStream || audioElement) &&\n Object.keys(barsMap).map((key) => (\n <span key={key} className='pi-bg-emerald-600 pi-w-0.5 pi-rounded-sm'></span>\n ))}\n </div>\n </div>\n )\n}\n\ninterface AudioBarsProps {\n audioStream?: MediaStream | null\n audioElement?: HTMLAudioElement | null\n size?: 'large' | 'small'\n paused?: boolean\n}\n\ninterface BarsMapType {\n [key: number]: number\n}\n"],"names":["large","small","_a","_b","audioStream","_c","audioElement","paused","size","containerElement","useRef","animationRequest","barsMap","context","analyser","source","dispatch","useDispatch","startAnimation","requestId","animationRequestId","requestAnimationFrame","animationFrame","current","frequencyData","Uint8Array","frequencyBinCount","getByteFrequencyData","values","Object","bars","children","length","i","keys","value","barStyles","style","height","concat","useEffect","store","getState","audioBars","audioElementContext","audioElementAnalyser","audioElementSource","isReady","AudioContext","createAnalyser","smoothingTimeConstant","fftSize","createMediaStreamSource","createMediaElementSource","setAudioElementContext","setAudioElementAnalyser","setAudioElementSource","setIsReady","connect","cancelAnimationFrame","disconnect","React","createElement","className","ref","map","key"],"mappings":"qUASMA,EAAQ,CACZ,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,GAGCC,EAAQ,CACZ,EAAG,EACH,EAAG,EACH,EAAG,EACH,EAAG,qBASwC,SAACC,GAC5C,IAAAC,EAAAD,EAAAE,YAAAA,OAAW,IAAAD,EAAG,KAAIA,EAClBE,EAAmBH,EAAAI,aAAnBA,OAAY,IAAAD,EAAG,KAAIA,EACnBE,EAAML,EAAAK,OACNC,EAAIN,EAAAM,KAGEC,EAAmBC,SAA8B,MACjDC,EAAmBD,SAAsB,MACzCE,EAAgC,UAATJ,EAAmBR,EAAQC,EAClDY,EAAUH,SAA4B,MACtCI,EAAWJ,SAA4B,MACvCK,EAASL,SAA0B,MACnCM,EAAWC,EAAAA,cAQjB,SAASC,IACP,IAP4BC,EAOtBC,EAA6BC,sBAAsBC,IAP7BH,EAQPC,KANnBT,EAAiBY,QAAUJ,EAO9B,CAGD,SAASG,UACP,GAAIR,GAAYA,EAASS,QAAS,CAChC,IAAMC,EAAgB,IAAIC,WAAWX,EAASS,QAAQG,mBACtDZ,EAASS,QAAQI,qBAAqBH,GACtC,IAAMI,EAASC,OAAOD,OAAOJ,GAEvBM,EAA+B,QAAxB5B,EAAAO,EAAiBc,eAAO,IAAArB,OAAA,EAAAA,EAAE6B,SACvC,GAAID,IAAQA,aAAA,EAAAA,EAAME,QAAS,EAAG,CAE5B,IAAK,IAAIC,EAAI,EAAGA,EAAIJ,OAAOK,KAAKtB,GAASoB,SAAUC,EAAG,CACpD,IAAME,EAAQP,EAAOhB,EAAQqB,IAAM,IAE7BG,EAAYN,GAAQA,EAAKG,IAAMH,EAAKG,GAAGI,MACzCD,GAAaD,EAAQ,IACvBC,EAAUE,OAAS,GAAAC,OAAG,IAAMJ,OAE/B,CACDjB,GACD,CACF,CACF,
|
|
1
|
+
{"version":3,"file":"AudioBars.js","sources":["../../src/components/AudioBars.tsx"],"sourcesContent":["// Copyright (C) 2022 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type FC, useEffect, useRef } from 'react'\nimport { ContextSourceType } from '../models/audioBars'\nimport { useDispatch } from 'react-redux'\nimport { store } from '../store'\nimport { Dispatch } from '../store'\n\nconst large = {\n 0: 4,\n 1: 3,\n 2: 2,\n 3: 1,\n 4: 1,\n 5: 2,\n 6: 3,\n 7: 4,\n}\n\nconst small = {\n 0: 2,\n 1: 1,\n 2: 1,\n 3: 2,\n}\n\n/**\n * This component shows a dynamic audio spectrum given an audio stream\n *\n * @param audioStream An audio stream to analyse\n * @param audioElement An audio element to analyse\n */\nexport const AudioBars: FC<AudioBarsProps> = ({\n audioStream = null,\n audioElement = null,\n paused,\n size,\n}) => {\n // Initialize the main elements\n const containerElement = useRef<HTMLDivElement | null>(null)\n const animationRequest = useRef<number | null>(null)\n const barsMap: BarsMapType = size === 'large' ? large : small\n const context = useRef<AudioContext | null>(null)\n const analyser = useRef<AnalyserNode | null>(null)\n const source = useRef<ContextSourceType>(null)\n const dispatch = useDispatch<Dispatch>()\n\n function saveAnimationRequest(requestId: number) {\n if (requestId) {\n animationRequest.current = requestId\n }\n }\n\n function startAnimation() {\n const animationRequestId: number = requestAnimationFrame(animationFrame)\n saveAnimationRequest(animationRequestId)\n }\n\n // The function that renders the frames of animation\n function animationFrame() {\n if (analyser && analyser.current) {\n const frequencyData = new Uint8Array(analyser.current.frequencyBinCount)\n analyser.current.getByteFrequencyData(frequencyData)\n const values = Object.values(frequencyData)\n\n const bars = containerElement.current?.children\n if (bars && bars?.length > 0) {\n // Change styles to every bar\n for (let i = 0; i < Object.keys(barsMap).length; ++i) {\n const value = values[barsMap[i]] / 255\n // @ts-ignore\n const barStyles = bars && bars[i] && bars[i].style\n if (barStyles && value > 0) {\n barStyles.height = `${100 * value}%`\n }\n }\n startAnimation()\n }\n }\n }\n\n useEffect(() => {\n const { audioElementContext, audioElementAnalyser, audioElementSource, isReady } =\n store.getState().audioBars\n // Initialize audio context and analyser once\n if (audioElement && isReady) {\n // The source is an audio element\n context.current = audioElementContext\n analyser.current = audioElementAnalyser\n source.current = audioElementSource\n } else {\n // The source is an audio stream\n context.current = new AudioContext()\n analyser.current = context.current.createAnalyser()\n analyser.current.smoothingTimeConstant = 0.8\n analyser.current.fftSize = 32\n // Create the media source stream\n if (audioStream) {\n source.current = context.current.createMediaStreamSource(audioStream)\n } else if (audioElement) {\n source.current = context.current.createMediaElementSource(audioElement)\n // Save the audio elements to stores\n dispatch.audioBars.setAudioElementContext(context.current)\n dispatch.audioBars.setAudioElementAnalyser(analyser.current)\n dispatch.audioBars.setAudioElementSource(source.current)\n dispatch.audioBars.setIsReady(true)\n }\n }\n\n // Connect the audio source to the analyser\n analyser.current && source.current && source.current.connect(analyser.current)\n if (audioElement) {\n context.current && analyser.current && analyser.current.connect(context.current.destination)\n }\n startAnimation()\n\n // Cleanup bars animation\n return () => {\n animationRequest.current && cancelAnimationFrame(animationRequest.current)\n source.current?.disconnect()\n }\n }, [])\n\n useEffect(() => {\n if (animationRequest.current) {\n if (!paused) {\n cancelAnimationFrame(animationRequest.current)\n startAnimation()\n } else {\n cancelAnimationFrame(animationRequest.current)\n }\n }\n }, [size, paused])\n\n return (\n <div\n className={`${\n size === 'small' ? 'pi-h-6 pi-w-6' : 'pi-h-12 pi-w-12'\n } pi-flex pi-justify-center pi-items-center`}\n >\n {/* The bars container */}\n <div\n className={`${\n size === 'small' ? 'pi-h-6' : 'pi-h-8'\n } pi-w-fit pi-flex pi-justify-center pi-items-center pi-gap-1 pi-overflow-hidden`}\n ref={containerElement}\n >\n {/* Every single bar */}\n {(audioStream || audioElement) &&\n Object.keys(barsMap).map((key) => (\n <span key={key} className='pi-bg-emerald-600 pi-w-0.5 pi-rounded-sm'></span>\n ))}\n </div>\n </div>\n )\n}\n\ninterface AudioBarsProps {\n audioStream?: MediaStream | null\n audioElement?: HTMLAudioElement | null\n size?: 'large' | 'small'\n paused?: boolean\n}\n\ninterface BarsMapType {\n [key: number]: number\n}\n"],"names":["large","small","_a","_b","audioStream","_c","audioElement","paused","size","containerElement","useRef","animationRequest","barsMap","context","analyser","source","dispatch","useDispatch","startAnimation","requestId","animationRequestId","requestAnimationFrame","animationFrame","current","frequencyData","Uint8Array","frequencyBinCount","getByteFrequencyData","values","Object","bars","children","length","i","keys","value","barStyles","style","height","concat","useEffect","store","getState","audioBars","audioElementContext","audioElementAnalyser","audioElementSource","isReady","AudioContext","createAnalyser","smoothingTimeConstant","fftSize","createMediaStreamSource","createMediaElementSource","setAudioElementContext","setAudioElementAnalyser","setAudioElementSource","setIsReady","connect","destination","cancelAnimationFrame","disconnect","React","createElement","className","ref","map","key"],"mappings":"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"}
|