@nethesis/phone-island 1.0.0-dev.10 → 1.0.0-dev.11
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/dist/App.js +1 -1
- package/dist/App.js.map +1 -1
- package/dist/components/AudioPlayerView/index.js +1 -1
- package/dist/components/AudioPlayerView/index.js.map +1 -1
- package/dist/components/CallView/Avatar.js +1 -1
- package/dist/components/CallView/Avatar.js.map +1 -1
- package/dist/components/CallView/DisplayName.js +1 -1
- package/dist/components/CallView/DisplayName.js.map +1 -1
- package/dist/components/CallView/Number.js +1 -1
- package/dist/components/CallView/Number.js.map +1 -1
- package/dist/components/CallView/Timer.js +1 -1
- package/dist/components/CallView/Timer.js.map +1 -1
- package/dist/components/CallView/index.js +1 -1
- package/dist/components/CallView/index.js.map +1 -1
- package/dist/components/IslandDrag.js +1 -1
- package/dist/components/IslandDrag.js.map +1 -1
- package/dist/components/RecorderView/index.js +1 -1
- package/dist/components/RecorderView/index.js.map +1 -1
- package/dist/components/Socket.js +1 -1
- package/dist/components/Socket.js.map +1 -1
- package/dist/components/TranscriptionView/TranscriptionView.js +1 -1
- package/dist/components/TranscriptionView/TranscriptionView.js.map +1 -1
- package/dist/components/WebRTC.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/lib/phone/conversation.js +1 -1
- package/dist/lib/phone/conversation.js.map +1 -1
- package/dist/models/currentCall.js +1 -1
- package/dist/models/currentCall.js.map +1 -1
- package/dist/node_modules/webrtc-adapter/src/js/utils.js +1 -1
- package/dist/node_modules/webrtc-adapter/src/js/utils.js.map +1 -1
- package/dist/package.json.js +1 -1
- package/dist/services/user.js +1 -1
- package/dist/services/user.js.map +1 -1
- package/dist/styles/CustomRange.styles.js +1 -1
- package/dist/styles/CustomRange.styles.js.map +1 -1
- package/dist/styles/Island.styles.js +1 -1
- package/dist/styles/Island.styles.js.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Avatar.js","sources":["../../../src/components/CallView/Avatar.tsx"],"sourcesContent":["// Copyright (C) 2025 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type FC, useMemo } from 'react'\nimport {
|
|
1
|
+
{"version":3,"file":"Avatar.js","sources":["../../../src/components/CallView/Avatar.tsx"],"sourcesContent":["// Copyright (C) 2025 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type FC, useMemo } from 'react'\nimport { useSelector } from 'react-redux'\nimport { RootState } from '../../store'\nimport { GenericAvatar } from '../GenericAvatar'\nimport { resolveUsernameByNumber } from '../../lib/phone/conversation'\n\nconst Avatar: FC = () => {\n const { isOpen } = useSelector((state: RootState) => state.island)\n const { avatars } = useSelector((state: RootState) => state.avatars)\n const { extensions } = useSelector((state: RootState) => state.users)\n const {\n username,\n number,\n incoming,\n outgoing,\n accepted,\n transferring,\n } = useSelector((state: RootState) => state.currentCall)\n\n const resolvedUsername = useMemo(\n () => username || resolveUsernameByNumber(number, extensions),\n [username, number, extensions],\n )\n\n const avatarUrl = useMemo(() => {\n if (transferring && number) {\n const transferringUsername = resolveUsernameByNumber(number, extensions)\n return transferringUsername ? avatars?.[transferringUsername] : undefined\n }\n\n return resolvedUsername ? avatars?.[resolvedUsername] : undefined\n }, [avatars, resolvedUsername, transferring, number, extensions])\n\n const showPulseEffect = incoming || (outgoing && !accepted)\n\n return (\n <GenericAvatar\n avatarUrl={avatarUrl}\n size={isOpen ? 'open' : 'closed'}\n showPulseEffect={showPulseEffect}\n pulseColor='pi-bg-gray-600'\n backgroundColorClass='pi-bg-secondaryNeutral dark:pi-bg-secondaryNeutralDark'\n borderRadius='pi-rounded-xl'\n className={isOpen ? 'pi--mt-1' : ''}\n />\n )\n}\n\nexport default Avatar\n"],"names":["isOpen","useSelector","state","island","avatars","extensions","users","_a","currentCall","username","number","incoming","outgoing","accepted","transferring","resolvedUsername","useMemo","resolveUsernameByNumber","avatarUrl","transferringUsername","undefined","showPulseEffect","React","GenericAvatar","size","pulseColor","backgroundColorClass","borderRadius","className"],"mappings":"0YASmB,WACT,IAAAA,EAAWC,eAAY,SAACC,GAAqB,OAAAA,EAAMC,iBACnDC,EAAYH,eAAY,SAACC,GAAqB,OAAAA,EAAME,mBACpDC,EAAeJ,eAAY,SAACC,GAAqB,OAAAA,EAAMI,oBACzDC,EAOFN,EAAWA,aAAC,SAACC,GAAqB,OAAAA,EAAMM,WAAN,IANpCC,EAAQF,EAAAE,SACRC,EAAMH,EAAAG,OACNC,aACAC,EAAQL,EAAAK,SACRC,EAAQN,EAAAM,SACRC,iBAGIC,EAAmBC,EAAOA,SAC9B,WAAM,OAAAP,GAAYQ,EAAAA,wBAAwBP,EAAQL,EAAW,GAC7D,CAACI,EAAUC,EAAQL,IAGfa,EAAYF,EAAAA,SAAQ,WACxB,GAAIF,GAAgBJ,EAAQ,CAC1B,IAAMS,EAAuBF,EAAAA,wBAAwBP,EAAQL,GAC7D,OAAOc,EAAuBf,aAAO,EAAPA,EAAUe,QAAwBC,CACjE,CAED,OAAOL,EAAmBX,aAAO,EAAPA,EAAUW,QAAoBK,CAC1D,GAAG,CAAChB,EAASW,EAAkBD,EAAcJ,EAAQL,IAE/CgB,EAAkBV,GAAaC,IAAaC,EAElD,OACES,wBAACC,EAAaA,cAAA,CACZL,UAAWA,EACXM,KAAMxB,EAAS,OAAS,SACxBqB,gBAAiBA,EACjBI,WAAW,iBACXC,qBAAqB,yDACrBC,aAAa,gBACbC,UAAW5B,EAAS,WAAa,IAGvC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("../../styles/Island.styles.js");require("../../node_modules/react-redux/es/index.js"),require("../../node_modules/@babel/runtime/helpers/defineProperty.js"),require("../../node_modules/@babel/runtime/helpers/objectWithoutProperties.js"),require("../../node_modules/@babel/runtime/helpers/typeof.js"),require("../../node_modules/html-parse-stringify/dist/html-parse-stringify.js"),require("../../node_modules/react-i18next/dist/es/context.js");var r=require("../../node_modules/react-i18next/dist/es/useTranslation.js");require("../../node_modules/@babel/runtime/helpers/slicedToArray.js");var i=require("./DisplayNameUtils.js"),n=require("../../node_modules/framer-motion/dist/es/render/components/motion/proxy.mjs.js"),l=require("../../node_modules/react-redux/es/hooks/useSelector.js");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=o(e),u=function(e){var t,r;return{displayName:null===(t=null==e?void 0:e.currentCall)||void 0===t?void 0:t.displayName,incoming:null===(r=null==e?void 0:e.currentCall)||void 0===r?void 0:r.incoming}},a=function(e){return e.listen},d=e.memo((function(){var o=e.useState(!1),d=o[0],c=o[1],m=e.useRef(null),p=e.useRef(null),f=n.motion(t.StyledName),v=l.useSelector(u),y=v.displayName,j=v.incoming,h=l.useSelector(a),x=r.useTranslation().t;e.useLayoutEffect((function(){var e,t;(null==m?void 0:m.current)&&(null==p?void 0:p.current)&&(null===(e=null==p?void 0:p.current)||void 0===e?void 0:e.clientWidth)-(null===(t=null==m?void 0:m.current)||void 0===t?void 0:t.clientWidth)>5&&c(!0)}),[m,p]);var b=e.useMemo((function(){return i.getTextClassName({intrudeListenStatus:h,animateText:d})}),[h,d]),g=e.useMemo((function(){return i.getDisplayText({intrudeListenStatus:h,displayName:y,incoming:j,t:x})}),[h,y,j,x]);return s.default.createElement(
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("../../styles/Island.styles.js");require("../../node_modules/react-redux/es/index.js"),require("../../node_modules/@babel/runtime/helpers/defineProperty.js"),require("../../node_modules/@babel/runtime/helpers/objectWithoutProperties.js"),require("../../node_modules/@babel/runtime/helpers/typeof.js"),require("../../node_modules/html-parse-stringify/dist/html-parse-stringify.js"),require("../../node_modules/react-i18next/dist/es/context.js");var r=require("../../node_modules/react-i18next/dist/es/useTranslation.js");require("../../node_modules/@babel/runtime/helpers/slicedToArray.js");var i=require("./DisplayNameUtils.js"),n=require("../../node_modules/framer-motion/dist/es/render/components/motion/proxy.mjs.js"),l=require("../../node_modules/react-redux/es/hooks/useSelector.js");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=o(e),u=function(e){var t,r;return{displayName:null===(t=null==e?void 0:e.currentCall)||void 0===t?void 0:t.displayName,incoming:null===(r=null==e?void 0:e.currentCall)||void 0===r?void 0:r.incoming}},a=function(e){return e.listen},d=e.memo((function(){var o=e.useState(!1),d=o[0],c=o[1],m=e.useRef(null),p=e.useRef(null),f=n.motion(t.StyledName),v=l.useSelector(u),y=v.displayName,j=v.incoming,h=l.useSelector(a),x=r.useTranslation().t;e.useLayoutEffect((function(){var e,t;(null==m?void 0:m.current)&&(null==p?void 0:p.current)&&(null===(e=null==p?void 0:p.current)||void 0===e?void 0:e.clientWidth)-(null===(t=null==m?void 0:m.current)||void 0===t?void 0:t.clientWidth)>5&&c(!0)}),[m,p]);var b=e.useMemo((function(){return i.getTextClassName({intrudeListenStatus:h,animateText:d})}),[h,d]),g=e.useMemo((function(){return i.getDisplayText({intrudeListenStatus:h,displayName:y,incoming:j,t:x})}),[h,y,j,x]);return s.default.createElement("div",{ref:m,className:"pi-whitespace-nowrap pi-relative pi-overflow-hidden"},s.default.createElement(f,null,s.default.createElement("div",{className:b,ref:p},"scroll"===g.type?s.default.createElement(i.MemoizedTextScroll,{text:g.content}):g.content),s.default.createElement("div",{className:"pi-w-6 pi-absolute pi-right-0 pi-top-0 pi-h-full pi-bg-gradient-to-r pi-from-transparent dark:pi-to-gray-950 pi-to-gray-50"})))}));exports.default=d;
|
|
2
2
|
//# sourceMappingURL=DisplayName.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DisplayName.js","sources":["../../../src/components/CallView/DisplayName.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { useState, useRef, useLayoutEffect, useMemo, memo } from 'react'\nimport { StyledName } from '../../styles/Island.styles'\nimport { motion } from 'framer-motion'\nimport { RootState } from '../../store'\nimport { useSelector } from 'react-redux'\nimport { useTranslation } from 'react-i18next'\nimport {\n getDisplayText,\n getTextClassName,\n MemoizedTextScroll,\n
|
|
1
|
+
{"version":3,"file":"DisplayName.js","sources":["../../../src/components/CallView/DisplayName.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { useState, useRef, useLayoutEffect, useMemo, memo } from 'react'\nimport { StyledName } from '../../styles/Island.styles'\nimport { motion } from 'framer-motion'\nimport { RootState } from '../../store'\nimport { useSelector } from 'react-redux'\nimport { useTranslation } from 'react-i18next'\nimport {\n getDisplayText,\n getTextClassName,\n MemoizedTextScroll,\n} from './DisplayNameUtils'\n\nconst selectDisplayNameAndIncoming = (state: RootState) => ({\n displayName: state?.currentCall?.displayName,\n incoming: state?.currentCall?.incoming,\n})\n\nconst selectIntrudeListenStatus = (state: RootState) => state.listen\n\nconst DisplayName: React.FC<DisplayNameProps> = () => {\n const [animateText, setAnimateText] = useState<boolean>(false)\n const nameContainer = useRef<null | HTMLDivElement>(null)\n const nameText = useRef<null | HTMLDivElement>(null)\n const NameMotion = motion(StyledName)\n\n const { displayName, incoming } = useSelector(selectDisplayNameAndIncoming)\n const intrudeListenStatus = useSelector(selectIntrudeListenStatus)\n\n const { t } = useTranslation()\n\n useLayoutEffect(() => {\n if (\n nameContainer?.current &&\n nameText?.current &&\n nameText?.current?.clientWidth - nameContainer?.current?.clientWidth > 5\n ) {\n setAnimateText(true)\n }\n }, [nameContainer, nameText])\n\n const textClassName = useMemo(\n () => getTextClassName({ intrudeListenStatus, animateText }),\n [intrudeListenStatus, animateText],\n )\n\n const displayTextResult = useMemo(\n () => getDisplayText({ intrudeListenStatus, displayName, incoming, t }),\n [intrudeListenStatus, displayName, incoming, t],\n )\n\n const renderDisplayContent = () => {\n if (displayTextResult.type === 'scroll') {\n return <MemoizedTextScroll text={displayTextResult.content} />\n }\n return displayTextResult.content\n }\n\n return (\n <div ref={nameContainer} className='pi-whitespace-nowrap pi-relative pi-overflow-hidden'>\n <NameMotion>\n <div className={textClassName} ref={nameText}>\n {renderDisplayContent()}\n </div>\n <div className='pi-w-6 pi-absolute pi-right-0 pi-top-0 pi-h-full pi-bg-gradient-to-r pi-from-transparent dark:pi-to-gray-950 pi-to-gray-50' />\n </NameMotion>\n </div>\n )\n}\n\nexport default memo(DisplayName)\n\nexport interface DisplayNameProps {}\n"],"names":["selectDisplayNameAndIncoming","state","displayName","_a","currentCall","incoming","_b","selectIntrudeListenStatus","listen","memo","useState","animateText","setAnimateText","nameContainer","useRef","nameText","NameMotion","motion","StyledName","useSelector","intrudeListenStatus","t","useTranslation","useLayoutEffect","current","clientWidth","textClassName","useMemo","getTextClassName","displayTextResult","getDisplayText","React","ref","className","createElement","type","MemoizedTextScroll","text","content"],"mappings":"68BAeMA,EAA+B,SAACC,WAAqB,MAAC,CAC1DC,YAA+B,QAAlBC,EAAAF,eAAAA,EAAOG,mBAAW,IAAAD,OAAA,EAAAA,EAAED,YACjCG,SAA4B,QAAlBC,EAAAL,eAAAA,EAAOG,mBAAW,IAAAE,OAAA,EAAAA,EAAED,WAG1BE,EAA4B,SAACN,GAAqB,OAAAA,EAAMO,MAAN,EAoDzCC,EAAAA,EAAAA,MAlDiC,WACxC,IAAAN,EAAgCO,EAAAA,UAAkB,GAAjDC,EAAWR,EAAA,GAAES,EAAcT,EAAA,GAC5BU,EAAgBC,SAA8B,MAC9CC,EAAWD,SAA8B,MACzCE,EAAaC,SAAOC,EAAAA,YAEpBZ,EAA4Ba,cAAYnB,GAAtCE,EAAWI,EAAAJ,YAAEG,EAAQC,EAAAD,SACvBe,EAAsBD,cAAYZ,GAEhCc,EAAMC,qBAEdC,EAAAA,iBAAgB,oBAEZV,aAAA,EAAAA,EAAeW,WACfT,aAAQ,EAARA,EAAUS,WACS,QAAnBrB,EAAAY,aAAQ,EAARA,EAAUS,eAAS,IAAArB,OAAA,EAAAA,EAAAsB,sBAAcnB,EAAAO,aAAA,EAAAA,EAAeW,8BAASC,aAAc,GAEvEb,GAAe,EAEnB,GAAG,CAACC,EAAeE,IAEnB,IAAMW,EAAgBC,EAAAA,SACpB,WAAM,OAAAC,EAAgBA,iBAAC,CAAER,oBAAmBA,EAAET,YAAWA,GAAG,GAC5D,CAACS,EAAqBT,IAGlBkB,EAAoBF,WACxB,WAAM,OAAAG,EAAAA,eAAe,CAAEV,oBAAmBA,EAAElB,YAAWA,EAAEG,SAAQA,EAAEgB,KAAI,GACvE,CAACD,EAAqBlB,EAAaG,EAAUgB,IAU/C,OACEU,EAAAA,6BAAKC,IAAKnB,EAAeoB,UAAU,uDACjCF,UAAAG,cAAClB,EAAU,KACTe,UAAKG,cAAA,MAAA,CAAAD,UAAWP,EAAeM,IAAKjB,GATT,WAA3Bc,EAAkBM,KACbJ,EAAAA,QAAAG,cAACE,EAAkBA,mBAAC,CAAAC,KAAMR,EAAkBS,UAE9CT,EAAkBS,SASrBP,EAAA,QAAAG,cAAA,MAAA,CAAKD,UAAU,gIAIvB"}
|
|
@@ -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")
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");require("../../node_modules/react-redux/es/index.js");var r=require("../../styles/Island.styles.js");require("../../node_modules/@babel/runtime/helpers/defineProperty.js"),require("../../node_modules/@babel/runtime/helpers/objectWithoutProperties.js"),require("../../node_modules/@babel/runtime/helpers/typeof.js"),require("../../node_modules/html-parse-stringify/dist/html-parse-stringify.js"),require("../../node_modules/react-i18next/dist/es/context.js");var t=require("../../node_modules/react-i18next/dist/es/useTranslation.js");require("../../node_modules/@babel/runtime/helpers/slicedToArray.js");var s=require("../../node_modules/react-redux/es/hooks/useSelector.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=n(e);exports.default=function(){var e=s.useSelector((function(e){return e.currentCall})).number,n=s.useSelector((function(e){return e.island})).isOpen,o=t.useTranslation().t,l="unknown"===e?o("TextScroll.unknown"):e||o("Call.In progress...")||"-";return u.default.createElement(r.StyledNumber,{isOpen:n,className:"dark:pi-text-gray-50 pi-text-gray-600"},l)};
|
|
2
2
|
//# sourceMappingURL=Number.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Number.js","sources":["../../../src/components/CallView/Number.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type FC } from 'react'\nimport { useSelector } from 'react-redux'\nimport { RootState } from '../../store'\nimport { useTranslation } from 'react-i18next'\n\nconst Number: FC = () => {\n const { number } = useSelector((state: RootState) => state.currentCall)\n const { isOpen } = useSelector((state: RootState) => state.island)\n const { t } = useTranslation()\n\n const displayNumber =\n number === 'unknown' ? t('TextScroll.unknown') : number || t('Call.In progress...') || '-'\n\n return (\n <
|
|
1
|
+
{"version":3,"file":"Number.js","sources":["../../../src/components/CallView/Number.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type FC } from 'react'\nimport { useSelector } from 'react-redux'\nimport { RootState } from '../../store'\nimport { StyledNumber } from '../../styles/Island.styles'\nimport { useTranslation } from 'react-i18next'\n\nconst Number: FC = () => {\n const { number } = useSelector((state: RootState) => state.currentCall)\n const { isOpen } = useSelector((state: RootState) => state.island)\n const { t } = useTranslation()\n\n const displayNumber =\n number === 'unknown' ? t('TextScroll.unknown') : number || t('Call.In progress...') || '-'\n\n return (\n <StyledNumber isOpen={isOpen} className='dark:pi-text-gray-50 pi-text-gray-600'>\n {displayNumber}\n </StyledNumber>\n )\n}\n\nexport default Number\n"],"names":["number","useSelector","state","currentCall","isOpen","island","t","useTranslation","displayNumber","React","createElement","StyledNumber","className"],"mappings":"k2BASmB,WACT,IAAAA,EAAWC,eAAY,SAACC,GAAqB,OAAAA,EAAMC,sBACnDC,EAAWH,eAAY,SAACC,GAAqB,OAAAA,EAAMG,iBACnDC,EAAMC,qBAERC,EACO,YAAXR,EAAuBM,EAAE,sBAAwBN,GAAUM,EAAE,wBAA0B,IAEzF,OACEG,EAAA,QAAAC,cAACC,EAAAA,aAAY,CAACP,OAAQA,EAAQQ,UAAU,yCACrCJ,EAGP"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react")
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");require("../../node_modules/react-redux/es/index.js");var t=require("../../styles/Island.styles.js"),r=require("../../node_modules/react-moment/dist/index.js"),a=require("../../lib/user/default_device.js"),i=require("../../node_modules/react-redux/es/hooks/useSelector.js");function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=s(e);exports.default=function(e){var s=e.size,u=void 0===s?"large":s,l=e.startTime,d=e.isNotAlwaysWhite,o=e.isInsideConference,c=i.useSelector((function(e){return e.island})).isOpen;return n.default.createElement(n.default.Fragment,null,null!=l&&!a.isPhysical()&&n.default.createElement(t.StyledTimer,{isOpen:c,size:u},n.default.createElement(r.default,{date:Number(l),interval:1e3,format:"hh:mm:ss",trim:!1,unix:!0,durationFromNow:!0,className:"".concat(void 0!==d&&d?"pi-text-gray-950 dark:pi-text-gray-50":"pi-text-gray-50 dark:pi-text-gray-50"," ").concat(o?"pi-font-mono":"")})))};
|
|
2
2
|
//# sourceMappingURL=Timer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Timer.js","sources":["../../../src/components/CallView/Timer.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { FC } from 'react'\nimport Moment from 'react-moment'\nimport { isPhysical } from '../../lib/user/default_device'\n\nconst Timer: FC<TimerProps> = ({\n size = 'large',\n startTime,\n isNotAlwaysWhite,\n isInsideConference,\n}) => {\n return (\n <>\n {startTime != null && !isPhysical() && (\n <
|
|
1
|
+
{"version":3,"file":"Timer.js","sources":["../../../src/components/CallView/Timer.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { FC } from 'react'\nimport { useSelector } from 'react-redux'\nimport { RootState } from '../../store'\nimport { StyledTimer } from '../../styles/Island.styles'\nimport Moment from 'react-moment'\nimport { isPhysical } from '../../lib/user/default_device'\n\nconst Timer: FC<TimerProps> = ({\n size = 'large',\n startTime,\n isNotAlwaysWhite,\n isInsideConference,\n}) => {\n // Get isOpen from the island store\n const { isOpen } = useSelector((state: RootState) => state.island)\n return (\n <>\n {startTime != null && !isPhysical() && (\n <StyledTimer isOpen={isOpen} size={size}>\n <Moment\n date={Number(startTime)}\n interval={1000}\n format='hh:mm:ss'\n trim={false}\n unix\n durationFromNow\n className={`${\n isNotAlwaysWhite !== undefined && isNotAlwaysWhite\n ? 'pi-text-gray-950 dark:pi-text-gray-50'\n : 'pi-text-gray-50 dark:pi-text-gray-50'\n } ${isInsideConference ? 'pi-font-mono' : ''}`}\n />\n </StyledTimer>\n )}\n </>\n )\n}\n\nexport default Timer\n\nexport interface TimerProps {\n size?: 'small' | 'large'\n startTime: string\n // when the timer is used in the home view or in the pill view\n // TODO rename prop: it is used also in video view\n isNotAlwaysWhite?: boolean\n isInsideConference?: boolean\n}\n"],"names":["_a","_b","size","startTime","isNotAlwaysWhite","isInsideConference","isOpen","useSelector","state","island","React","isPhysical","createElement","StyledTimer","Moment","date","Number","interval","format","trim","unix","durationFromNow","className","concat","undefined"],"mappings":"gdAU8B,SAACA,GAC7B,IAAAC,EAAAD,EAAAE,KAAAA,OAAO,IAAAD,EAAA,QAAOA,EACdE,EAASH,EAAAG,UACTC,EAAgBJ,EAAAI,iBAChBC,EAAkBL,EAAAK,mBAGVC,EAAWC,eAAY,SAACC,GAAqB,OAAAA,EAAMC,iBAC3D,OACEC,EAAAA,8CACgB,MAAbP,IAAsBQ,EAAUA,cAC/BD,EAAAA,QAACE,cAAAC,EAAWA,aAACP,OAAQA,EAAQJ,KAAMA,GACjCQ,EAAAA,QAAAE,cAACE,UAAM,CACLC,KAAMC,OAAOb,GACbc,SAAU,IACVC,OAAO,WACPC,MAAM,EACNC,QACAC,iBAAe,EACfC,UAAW,GACTC,YAAqBC,IAArBpB,GAAkCA,EAC9B,wCACA,uCAAsC,KAAAmB,OACxClB,EAAqB,eAAiB,OAMtD"}
|
|
@@ -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 t=require("../../node_modules/@fortawesome/react-fontawesome/index.es.js"),i=require("../../node_modules/@fortawesome/free-solid-svg-icons/index.mjs.js"),n=require("../../utils/streaming/streamingUtils.js"),a=require("../../lib/phone/call.js");require("../../node_modules/tslib/tslib.es6.js"),require("../../store/index.js"),require("../../node_modules/socket.io-client/build/esm/index.js");var r=require("../../lib/user/default_device.js");require("../../node_modules/mic-check/lib/index.js"),require("../../lib/webrtc/janus.js"),require("../../node_modules/webrtc-adapter/src/js/adapter_core.js"),require("../Island.js");var l=require("../Button.js"),s=require("../AudioBars.js");require("../../node_modules/i18next/dist/esm/i18next.js");var o=require("../CustomThemedTooltip.js");require("../TranscriptionView/TranscriptionView.js");var u=require("./Timer.js"),c=require("./Number.js"),d=require("./DisplayName.js"),p=require("./Avatar.js"),m=require("./Actions.js"),f=require("../Hangup.js");require("../../node_modules/@babel/runtime/helpers/defineProperty.js"),require("../../node_modules/@babel/runtime/helpers/objectWithoutProperties.js"),require("../../node_modules/@babel/runtime/helpers/typeof.js"),require("../../node_modules/html-parse-stringify/dist/html-parse-stringify.js"),require("../../node_modules/react-i18next/dist/es/context.js");var g=require("../../node_modules/react-i18next/dist/es/useTranslation.js");require("../../node_modules/@babel/runtime/helpers/slicedToArray.js");var v=require("../../node_modules/@nethesis/nethesis-solid-svg-icons/index.mjs.js"),x=require("../StreamingImage/index.js"),E=require("../VideoStreamingSkeleton/index.js"),j=require("../VideoStreamingEmptyState/index.js"),w=require("../../node_modules/react-redux/es/hooks/useDispatch.js"),h=require("../../node_modules/react-redux/es/hooks/useSelector.js");function b(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var q=b(e);function N(e,t){return!e&&!t}var y=e.memo((function(e){var t=e.children;return q.default.createElement("div",{className:"pi-grid pi-self-center pi-gap-1 pi-grid-cols-1 pi-grid-rows-2"},t)}));y.displayName="Details";var _=e.memo((function(){var b,_=g.useTranslation().t,T=w.useDispatch(),A=h.useSelector((function(e){return e.currentCall})),k=A.incoming,C=A.accepted,S=A.outgoing,I=A.startTime,F=A.paused,P=A.number,O=A.isRecording,M=A.username,U=A.streamingSourceNumber,B=h.useSelector((function(e){return e.island})),L=B.isOpen,V=B.isFromStreaming,W=h.useSelector((function(e){return e.webrtc})).remoteAudioStream,z=h.useSelector((function(e){return e.listen})),D=z.isListen,H=z.isIntrude,R=z.isListenExtension,G=z.isIntrudeExtension,J=h.useSelector((function(e){return e.alerts})).data,K=h.useSelector((function(e){return e.currentUser})),Q=h.useSelector((function(e){return e.streaming})),X=Q.videoSources,Y=Q.sourceImages,Z=e.useMemo((function(){return Object.values(J).filter((function(e){return e.active}))}),[J]),$=e.useMemo((function(){return Z.length>0?Z[Z.length-1]:null}),[Z]),ee=e.useMemo((function(){return V&&U&&!C}),[V,U,C]),te=e.useMemo((function(){if(!U||!X)return{canUnlock:!1,tooltipText:""};var e=Object.values(X).find((function(e){return(null==e?void 0:e.extension)===U})),t=Boolean((null==e?void 0:e.cmdOpen)&&""!==(null==e?void 0:e.cmdOpen.trim()));return{canUnlock:t,tooltipText:t&&e?"".concat(_("VideoStreaming.Open"),": ").concat(null==e?void 0:e.description):""}}),[U,X,_]),ie=e.useMemo((function(){return""!==M&&"undefined"!==M}),[M]),ne=e.useCallback((function(){var e;return q.default.createElement("div",{className:"pi-text-gray-600 dark:pi-text-gray-300 pi-font-normal pi-text-sm pi-flex pi-items-center pi-truncate"},q.default.createElement(t.FontAwesomeIcon,{size:"sm",icon:v.faOfficePhone,className:"pi-mr-1"}),q.default.createElement("span",{className:"pi-max-w-16 pi-truncate"},(null===(e=null==K?void 0:K.default_device)||void 0===e?void 0:e.description)||_("Common.Physical phone")))}),[null===(b=null==K?void 0:K.default_device)||void 0===b?void 0:b.description,_]),ae=e.useCallback((function(e){var n=L?"pi-h-12 pi-w-12":"pi-h-6 pi-w-6",a=L?"pi-h-8":"pi-h-4 pi-w-4 pi-rounded-full",r=L?"pi-w-8 pi-h-8":"pi-h-6 pi-w-6",l="red"===e?"pi-bg-red-400":"pi-bg-green-400",s="red"===e?"pi-text-red-500":"pi-text-green-500";return q.default.createElement("div",{className:"".concat(n," pi-flex pi-justify-center pi-items-center")},q.default.createElement("div",{className:"".concat(a," pi-w-fit pi-flex pi-justify-center pi-items-center pi-gap-1 pi-overflow-hidden")},q.default.createElement("span",{className:"".concat(r," pi-animate-ping pi-absolute pi-inline-flex pi-rounded-full ").concat(l," pi-opacity-75")}),q.default.createElement(t.FontAwesomeIcon,{className:"pi-w-4 pi-h-6 pi-rotate-45 ".concat(s),icon:i.faCircle})))}),[L]),re=e.useMemo((function(){var e="pi-grid pi-items-center";return L&&(e="pi-grid pi-items-start",C?e+=" pi-grid-rows-[72px_1fr]":k?e+=" pi-grid-cols-[256px_114px]":S&&(e+=" pi-grid-cols-[1fr_84px]")),ee?"pi-flex pi-flex-col":e}),[L,C,k,S,ee]),le=e.useMemo((function(){return"pi-grid ".concat(L&&!C&&S?"pi-grid-cols-[48px_1fr]":L&&!C&&k?"pi-grid-cols-[48px_1fr_1px]":L&&C?"pi-grid-cols-[48px_164px_48px]":L||C?"pi-grid-cols-[24px_66px_24px]":"pi-grid-cols-[24px_102px]"," pi-gap-").concat(L?"5":"3"," pi-items-").concat(L?"start":"center"," pi-justify-center pi-w-full")}),[L,C,k,S]),se=e.useMemo((function(){return ee?"pi-grid-cols-3":N(S,C)?"pi-grid-cols-2":C?"pi-grid-cols-1 pi-justify-items-center":"pi-grid-cols-1 pi-justify-items-end"}),[ee,S,C]),oe=e.useCallback((function(){var e=L?"pi-relative pi-z-30 pi-h-12 pi-w-12 pi-rounded-sm pi-bg-cover":"pi-relative pi-z-30 pi-h-6 pi-w-6 pi-rounded-sm pi-bg-cover";return D?q.default.createElement(t.FontAwesomeIcon,{className:e,icon:i.faEarListen}):H?q.default.createElement(t.FontAwesomeIcon,{className:e,icon:i.faHandPointUp}):""!==P&&ie?q.default.createElement(p.default,null):k&&!ie?q.default.createElement(t.FontAwesomeIcon,{className:"".concat(e," pi--rotate-45"),icon:i.faArrowLeft}):!C||S||ie?S&&!ie?q.default.createElement(t.FontAwesomeIcon,{className:"".concat(e," pi-rotate-[135deg]"),icon:i.faArrowLeft}):null:q.default.createElement(t.FontAwesomeIcon,{className:"".concat(e," pi--rotate-45"),icon:i.faArrowLeft})}),[L,D,H,P,ie,k,S,C]),ue=e.useCallback((function(){return L?H?q.default.createElement(y,null,q.default.createElement("span",{className:"pi-justify-center pi-w-fit pi-relative pi-inline-block pi-font-bold pi-text-base"},_("Common.Intrude"),G?" - ".concat(G):""),C?r.isPhysical()?ne():q.default.createElement(u.default,{startTime:I,isNotAlwaysWhite:!0}):G?"".concat(G):""):D?q.default.createElement(y,null,q.default.createElement("span",{className:"pi-justify-center pi-w-fit pi-relative pi-inline-block pi-font-bold pi-text-base"},_("Common.Listen"),R?" - ".concat(R):""),C?r.isPhysical()?ne():q.default.createElement(u.default,{startTime:I,isNotAlwaysWhite:!0}):R?"".concat(R):""):q.default.createElement(y,null,q.default.createElement(d.default,null),C?r.isPhysical()?ne():q.default.createElement(u.default,{startTime:I,isNotAlwaysWhite:!0}):q.default.createElement(c.default,null)):null}),[L,H,D,C,I,G,R,_,ne]),ce=e.useCallback((function(){return C&&O?ae("red"):C&&W&&!r.isPhysical()?q.default.createElement(s.AudioBars,{audioStream:W,paused:F,size:L?"large":"small"}):C&&r.isPhysical()?ae("green"):null}),[C,O,W,L,F,ae]),de=e.useCallback((function(){if(!X||0===Object.keys(X).length||!U)return q.default.createElement(E.default,{className:"pi-w-full pi-h-40 pi-mt-4"});var e=Object.values(X).find((function(e){return e.extension===U}));return e&&(Y[e.id]||e.image)?q.default.createElement(x.default,null):q.default.createElement(j.default,{className:"pi-w-full pi-h-40 pi-mt-4"})}),[U,X,Y]);if(null!==$)return null;return q.default.createElement("div",{className:"pi-bg-red pi-content-center pi-justify-center"},q.default.createElement("div",{className:re},ee?q.default.createElement(q.default.Fragment,null,q.default.createElement("div",{className:"pi-flex pi-items-center pi-justify-between"},q.default.createElement("div",{className:"pi-flex pi-items-center pi-gap-4"},oe(),q.default.createElement("div",{className:"pi-flex pi-flex-col pi-justify-center pi-space-y-2"},q.default.createElement(d.default,null),q.default.createElement(c.default,null))),q.default.createElement("div",{className:"pi-flex pi-gap-2"},q.default.createElement(f.default,{description:_("Tooltip.Hangup")}),!S&&q.default.createElement(l.Button,{onClick:function(){return a.answerIncomingCall(),void setTimeout((function(){T.island.setIslandView("streamingAnswer")}),200)},variant:"green","data-tooltip-id":"tooltip-answer","data-tooltip-content":_("Tooltip.Answer")||""},q.default.createElement(t.FontAwesomeIcon,{className:"pi-w-5 pi-h-5",icon:i.faPhone})),(null==te?void 0:te.canUnlock)&&q.default.createElement(l.Button,{variant:"default",onClick:n.handleStreamingUnlock,"data-tooltip-id":"tooltip-unlock","data-tooltip-content":null==te?void 0:te.tooltipText},q.default.createElement(t.FontAwesomeIcon,{className:"pi-w-5 pi-h-5",icon:i.faUnlock})))),de()):q.default.createElement(q.default.Fragment,null,q.default.createElement("div",{className:le},oe(),ue(),!L&&!C&&q.default.createElement(d.default,null),!L&&C&&q.default.createElement(u.default,{startTime:I,isNotAlwaysWhite:!0}),ce()),L&&q.default.createElement(q.default.Fragment,null,q.default.createElement("div",{className:"".concat(D||H?"":"pi-grid pi-gap-y-5")},C&&q.default.createElement(m.default,null),q.default.createElement("div",{className:"pi-grid ".concat(se," pi-gap-3.5")},q.default.createElement(f.default,{description:_("Tooltip.Hangup and transfer")}),N(S,C)&&q.default.createElement(l.Button,{onClick:a.answerIncomingCall,variant:"green","data-tooltip-id":"tooltip-answer-left","data-tooltip-content":_("Tooltip.Answer")||""},q.default.createElement(t.FontAwesomeIcon,{className:"pi-w-6 pi-h-6",icon:i.faPhone}))))))),q.default.createElement(o.CustomThemedTooltip,{id:"tooltip-answer-left",place:"left"}),q.default.createElement(o.CustomThemedTooltip,{id:"tooltip-answer",place:"left"}),q.default.createElement(o.CustomThemedTooltip,{id:"tooltip-unlock",place:"left"}))}));exports.default=_;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");require("../../node_modules/react-redux/es/index.js");var t=require("../../node_modules/@fortawesome/react-fontawesome/index.es.js"),i=require("../../node_modules/@fortawesome/free-solid-svg-icons/index.mjs.js"),n=require("../../utils/streaming/streamingUtils.js"),r=require("../../lib/phone/call.js");require("../../node_modules/tslib/tslib.es6.js"),require("../../store/index.js"),require("../../node_modules/socket.io-client/build/esm/index.js");var a=require("../../lib/phone/conversation.js"),l=require("../../lib/user/default_device.js");require("../../node_modules/mic-check/lib/index.js"),require("../../lib/webrtc/janus.js"),require("../../node_modules/webrtc-adapter/src/js/adapter_core.js"),require("../Island.js");var s=require("../Button.js"),o=require("../AudioBars.js");require("../../node_modules/i18next/dist/esm/i18next.js");var u=require("../CustomThemedTooltip.js");require("../TranscriptionView/TranscriptionView.js");var c=require("./Timer.js"),d=require("./Number.js"),p=require("./DisplayName.js"),m=require("./Avatar.js"),f=require("./Actions.js"),g=require("../Hangup.js");require("../../node_modules/@babel/runtime/helpers/defineProperty.js"),require("../../node_modules/@babel/runtime/helpers/objectWithoutProperties.js"),require("../../node_modules/@babel/runtime/helpers/typeof.js"),require("../../node_modules/html-parse-stringify/dist/html-parse-stringify.js"),require("../../node_modules/react-i18next/dist/es/context.js");var v=require("../../node_modules/react-i18next/dist/es/useTranslation.js");require("../../node_modules/@babel/runtime/helpers/slicedToArray.js");var x=require("../../node_modules/@nethesis/nethesis-solid-svg-icons/index.mjs.js"),E=require("../StreamingImage/index.js"),j=require("../VideoStreamingSkeleton/index.js"),w=require("../VideoStreamingEmptyState/index.js"),h=require("../../node_modules/react-redux/es/hooks/useDispatch.js"),b=require("../../node_modules/react-redux/es/hooks/useSelector.js");function q(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var N=q(e);function y(e,t){return!e&&!t}var _=e.memo((function(e){var t=e.children;return N.default.createElement("div",{className:"pi-grid pi-self-center pi-gap-1 pi-grid-cols-1 pi-grid-rows-2"},t)}));_.displayName="Details";var T=e.memo((function(){var q,T=v.useTranslation().t,A=h.useDispatch(),k=b.useSelector((function(e){return e.currentCall})),S=k.incoming,C=k.accepted,I=k.outgoing,F=k.startTime,P=k.paused,M=k.number,O=k.isRecording,U=k.username,B=k.streamingSourceNumber,L=b.useSelector((function(e){return e.island})),V=L.isOpen,W=L.isFromStreaming,z=b.useSelector((function(e){return e.webrtc})).remoteAudioStream,D=b.useSelector((function(e){return e.listen})),H=D.isListen,R=D.isIntrude,G=D.isListenExtension,J=D.isIntrudeExtension,K=b.useSelector((function(e){return e.alerts})).data,Q=b.useSelector((function(e){return e.currentUser})),X=b.useSelector((function(e){return e.users})).extensions,Y=b.useSelector((function(e){return e.streaming})),Z=Y.videoSources,$=Y.sourceImages,ee=e.useMemo((function(){return Object.values(K).filter((function(e){return e.active}))}),[K]),te=e.useMemo((function(){return ee.length>0?ee[ee.length-1]:null}),[ee]),ie=e.useMemo((function(){return W&&B&&!C}),[W,B,C]),ne=e.useMemo((function(){if(!B||!Z)return{canUnlock:!1,tooltipText:""};var e=Object.values(Z).find((function(e){return(null==e?void 0:e.extension)===B})),t=Boolean((null==e?void 0:e.cmdOpen)&&""!==(null==e?void 0:e.cmdOpen.trim()));return{canUnlock:t,tooltipText:t&&e?"".concat(T("VideoStreaming.Open"),": ").concat(null==e?void 0:e.description):""}}),[B,Z,T]),re=e.useMemo((function(){return U&&"undefined"!==U?U:a.resolveUsernameByNumber(M,X)}),[U,M,X]),ae=e.useMemo((function(){return""!==re}),[re]),le=e.useCallback((function(){var e;return N.default.createElement("div",{className:"pi-text-gray-600 dark:pi-text-gray-300 pi-font-normal pi-text-sm pi-flex pi-items-center pi-truncate"},N.default.createElement(t.FontAwesomeIcon,{size:"sm",icon:x.faOfficePhone,className:"pi-mr-1"}),N.default.createElement("span",{className:"pi-max-w-16 pi-truncate"},(null===(e=null==Q?void 0:Q.default_device)||void 0===e?void 0:e.description)||T("Common.Physical phone")))}),[null===(q=null==Q?void 0:Q.default_device)||void 0===q?void 0:q.description,T]),se=e.useCallback((function(e){var n=V?"pi-h-12 pi-w-12":"pi-h-6 pi-w-6",r=V?"pi-h-8":"pi-h-4 pi-w-4 pi-rounded-full",a=V?"pi-w-8 pi-h-8":"pi-h-6 pi-w-6",l="red"===e?"pi-bg-red-400":"pi-bg-green-400",s="red"===e?"pi-text-red-500":"pi-text-green-500";return N.default.createElement("div",{className:"".concat(n," pi-flex pi-justify-center pi-items-center")},N.default.createElement("div",{className:"".concat(r," pi-w-fit pi-flex pi-justify-center pi-items-center pi-gap-1 pi-overflow-hidden")},N.default.createElement("span",{className:"".concat(a," pi-animate-ping pi-absolute pi-inline-flex pi-rounded-full ").concat(l," pi-opacity-75")}),N.default.createElement(t.FontAwesomeIcon,{className:"pi-w-4 pi-h-6 pi-rotate-45 ".concat(s),icon:i.faCircle})))}),[V]),oe=e.useMemo((function(){var e="pi-grid pi-items-center";return V&&(e="pi-grid pi-items-start",C?e+=" pi-grid-rows-[72px_1fr]":S?e+=" pi-grid-cols-[256px_114px]":I&&(e+=" pi-grid-cols-[1fr_84px]")),ie?"pi-flex pi-flex-col":e}),[V,C,S,I,ie]),ue=e.useMemo((function(){return"pi-grid ".concat(V&&!C&&I?"pi-grid-cols-[48px_1fr]":V&&!C&&S?"pi-grid-cols-[48px_1fr_1px]":V&&C?"pi-grid-cols-[48px_164px_48px]":V||C?"pi-grid-cols-[24px_66px_24px]":"pi-grid-cols-[24px_102px]"," pi-gap-").concat(V?"5":"3"," pi-items-").concat(V?"start":"center"," pi-justify-center pi-w-full")}),[V,C,S,I]),ce=e.useMemo((function(){return ie?"pi-grid-cols-3":y(I,C)?"pi-grid-cols-2":C?"pi-grid-cols-1 pi-justify-items-center":"pi-grid-cols-1 pi-justify-items-end"}),[ie,I,C]),de=e.useCallback((function(){var e=V?"pi-relative pi-z-30 pi-h-12 pi-w-12 pi-rounded-sm pi-bg-cover":"pi-relative pi-z-30 pi-h-6 pi-w-6 pi-rounded-sm pi-bg-cover";return H?N.default.createElement(t.FontAwesomeIcon,{className:e,icon:i.faEarListen}):R?N.default.createElement(t.FontAwesomeIcon,{className:e,icon:i.faHandPointUp}):""!==M&&ae?N.default.createElement(m.default,null):S&&!ae?N.default.createElement(t.FontAwesomeIcon,{className:"".concat(e," pi--rotate-45"),icon:i.faArrowLeft}):!C||I||ae?I&&!ae?N.default.createElement(t.FontAwesomeIcon,{className:"".concat(e," pi-rotate-[135deg]"),icon:i.faArrowLeft}):null:N.default.createElement(t.FontAwesomeIcon,{className:"".concat(e," pi--rotate-45"),icon:i.faArrowLeft})}),[V,H,R,M,ae,S,I,C]),pe=e.useCallback((function(){return V?R?N.default.createElement(_,null,N.default.createElement("span",{className:"pi-justify-center pi-w-fit pi-relative pi-inline-block pi-font-bold pi-text-base"},T("Common.Intrude"),J?" - ".concat(J):""),C?l.isPhysical()?le():N.default.createElement(c.default,{startTime:F,isNotAlwaysWhite:!0}):J?"".concat(J):""):H?N.default.createElement(_,null,N.default.createElement("span",{className:"pi-justify-center pi-w-fit pi-relative pi-inline-block pi-font-bold pi-text-base"},T("Common.Listen"),G?" - ".concat(G):""),C?l.isPhysical()?le():N.default.createElement(c.default,{startTime:F,isNotAlwaysWhite:!0}):G?"".concat(G):""):N.default.createElement(_,null,N.default.createElement(p.default,null),C?l.isPhysical()?le():N.default.createElement(c.default,{startTime:F,isNotAlwaysWhite:!0}):N.default.createElement(d.default,null)):null}),[V,R,H,C,F,J,G,T,le]),me=e.useCallback((function(){return C&&O?se("red"):C&&z&&!l.isPhysical()?N.default.createElement(o.AudioBars,{audioStream:z,paused:P,size:V?"large":"small"}):C&&l.isPhysical()?se("green"):null}),[C,O,z,V,P,se]),fe=e.useCallback((function(){if(!Z||0===Object.keys(Z).length||!B)return N.default.createElement(j.default,{className:"pi-w-full pi-h-40 pi-mt-4"});var e=Object.values(Z).find((function(e){return e.extension===B}));return e&&($[e.id]||e.image)?N.default.createElement(E.default,null):N.default.createElement(w.default,{className:"pi-w-full pi-h-40 pi-mt-4"})}),[B,Z,$]);if(null!==te)return null;return N.default.createElement("div",{className:"pi-bg-red pi-content-center pi-justify-center"},N.default.createElement("div",{className:oe},ie?N.default.createElement(N.default.Fragment,null,N.default.createElement("div",{className:"pi-flex pi-items-center pi-justify-between"},N.default.createElement("div",{className:"pi-flex pi-items-center pi-gap-4"},de(),N.default.createElement("div",{className:"pi-flex pi-flex-col pi-justify-center pi-space-y-2"},N.default.createElement(p.default,null),N.default.createElement(d.default,null))),N.default.createElement("div",{className:"pi-flex pi-gap-2"},N.default.createElement(g.default,{description:T("Tooltip.Hangup")}),!I&&N.default.createElement(s.Button,{onClick:function(){return r.answerIncomingCall(),void setTimeout((function(){A.island.setIslandView("streamingAnswer")}),200)},variant:"green","data-tooltip-id":"tooltip-answer","data-tooltip-content":T("Tooltip.Answer")||""},N.default.createElement(t.FontAwesomeIcon,{className:"pi-w-5 pi-h-5",icon:i.faPhone})),(null==ne?void 0:ne.canUnlock)&&N.default.createElement(s.Button,{variant:"default",onClick:n.handleStreamingUnlock,"data-tooltip-id":"tooltip-unlock","data-tooltip-content":null==ne?void 0:ne.tooltipText},N.default.createElement(t.FontAwesomeIcon,{className:"pi-w-5 pi-h-5",icon:i.faUnlock})))),fe()):N.default.createElement(N.default.Fragment,null,N.default.createElement("div",{className:ue},de(),pe(),!V&&!C&&N.default.createElement(p.default,null),!V&&C&&N.default.createElement(c.default,{startTime:F,isNotAlwaysWhite:!0}),me()),V&&N.default.createElement(N.default.Fragment,null,N.default.createElement("div",{className:"".concat(H||R?"":"pi-grid pi-gap-y-5")},C&&N.default.createElement(f.default,null),N.default.createElement("div",{className:"pi-grid ".concat(ce," pi-gap-3.5")},N.default.createElement(g.default,{description:T("Tooltip.Hangup and transfer")}),y(I,C)&&N.default.createElement(s.Button,{onClick:r.answerIncomingCall,variant:"green","data-tooltip-id":"tooltip-answer-left","data-tooltip-content":T("Tooltip.Answer")||""},N.default.createElement(t.FontAwesomeIcon,{className:"pi-w-6 pi-h-6",icon:i.faPhone}))))))),N.default.createElement(u.CustomThemedTooltip,{id:"tooltip-answer-left",place:"left"}),N.default.createElement(u.CustomThemedTooltip,{id:"tooltip-answer",place:"left"}),N.default.createElement(u.CustomThemedTooltip,{id:"tooltip-unlock",place:"left"}))}));exports.default=T;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/CallView/index.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type FC, useMemo, useCallback, memo } from 'react'\nimport { useSelector } from 'react-redux'\nimport { RootState, Dispatch } from '../../store'\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport {\n faPhone,\n faEarListen,\n faHandPointUp,\n faArrowLeft,\n faCircle,\n faUnlock,\n} from '@fortawesome/free-solid-svg-icons'\nimport { Button } from '../'\nimport Timer from './Timer'\nimport Number from './Number'\nimport DisplayName from './DisplayName'\nimport { AudioBars } from '../'\nimport { answerIncomingCall } from '../../lib/phone/call'\nimport Avatar from './Avatar'\nimport Actions from './Actions'\nimport Hangup from '../Hangup'\nimport { useTranslation } from 'react-i18next'\nimport { faOfficePhone } from '@nethesis/nethesis-solid-svg-icons'\nimport { isPhysical } from '../../lib/user/default_device'\nimport { CustomThemedTooltip } from '../CustomThemedTooltip'\nimport StreamingImage from '../StreamingImage'\nimport VideoStreamingSkeleton from '../VideoStreamingSkeleton'\nimport VideoStreamingEmptyState from '../VideoStreamingEmptyState'\nimport { handleStreamingUnlock } from '../../utils'\nimport { useDispatch } from 'react-redux'\n\nfunction isAnswerVisible(outgoing: boolean, accepted: boolean): boolean {\n return !outgoing && !accepted\n}\n\nconst Details = memo(({ children }: { children: React.ReactNode }) => (\n <div className='pi-grid pi-self-center pi-gap-1 pi-grid-cols-1 pi-grid-rows-2'>{children}</div>\n))\nDetails.displayName = 'Details'\n\n/**\n * The main view to manage calls, the starting point for calls actions flows\n */\nconst CallView: FC<CallViewProps> = () => {\n const { t } = useTranslation()\n const dispatch = useDispatch<Dispatch>()\n\n const currentCall = useSelector((state: RootState) => state.currentCall)\n const {\n incoming,\n accepted,\n outgoing,\n startTime,\n paused,\n number,\n isRecording,\n username,\n streamingSourceNumber,\n } = currentCall\n\n const { isOpen, isFromStreaming } = useSelector((state: RootState) => state.island)\n const { remoteAudioStream } = useSelector((state: RootState) => state.webrtc)\n const listenState = useSelector((state: RootState) => state.listen)\n const { isListen, isIntrude, isListenExtension, isIntrudeExtension } = listenState\n const { data: alertsData } = useSelector((state: RootState) => state.alerts)\n const currentUser = useSelector((state: RootState) => state.currentUser)\n const { videoSources, sourceImages } = useSelector((state: RootState) => state.streaming)\n\n const activeAlerts = useMemo(\n () => Object.values(alertsData).filter((alert: any) => alert.active),\n [alertsData],\n )\n\n const latestAlert = useMemo(\n () => (activeAlerts.length > 0 ? activeAlerts[activeAlerts.length - 1] : null),\n [activeAlerts],\n )\n\n const shouldShowStreamingImage = useMemo(\n () => isFromStreaming && streamingSourceNumber && !accepted,\n [isFromStreaming, streamingSourceNumber, accepted],\n )\n\n // Check if unlock button should be shown and get tooltip text\n const unlockData = useMemo(() => {\n if (!streamingSourceNumber || !videoSources) return { canUnlock: false, tooltipText: '' }\n\n const source = Object.values(videoSources).find(\n (source) => source?.extension === streamingSourceNumber,\n )\n\n const canUnlock = Boolean(source?.cmdOpen && source?.cmdOpen.trim() !== '')\n const tooltipText = canUnlock && source ? `${t('VideoStreaming.Open')}: ${source?.description}` : ''\n\n return { canUnlock, tooltipText }\n }, [streamingSourceNumber, videoSources, t])\n\n const hasValidUsername = useMemo(() => username !== '' && username !== 'undefined', [username])\n\n const renderLandlinePhoneDiv = useCallback(\n () => (\n <div className='pi-text-gray-600 dark:pi-text-gray-300 pi-font-normal pi-text-sm pi-flex pi-items-center pi-truncate'>\n <FontAwesomeIcon size='sm' icon={faOfficePhone} className='pi-mr-1' />\n <span className='pi-max-w-16 pi-truncate'>\n {currentUser?.default_device?.description || t('Common.Physical phone')}\n </span>\n </div>\n ),\n [currentUser?.default_device?.description, t],\n )\n\n const renderPulseIcon = useCallback(\n (color: string) => {\n const sizeClasses = !isOpen ? 'pi-h-6 pi-w-6' : 'pi-h-12 pi-w-12'\n const innerSizeClasses = !isOpen ? 'pi-h-4 pi-w-4 pi-rounded-full' : 'pi-h-8'\n const animationSizeClasses = !isOpen ? 'pi-h-6 pi-w-6' : 'pi-w-8 pi-h-8'\n const colorClasses = color === 'red' ? 'pi-bg-red-400' : 'pi-bg-green-400'\n const textColorClasses = color === 'red' ? 'pi-text-red-500' : 'pi-text-green-500'\n\n return (\n <div className={`${sizeClasses} pi-flex pi-justify-center pi-items-center`}>\n <div\n className={`${innerSizeClasses} pi-w-fit pi-flex pi-justify-center pi-items-center pi-gap-1 pi-overflow-hidden`}\n >\n <span\n className={`${animationSizeClasses} pi-animate-ping pi-absolute pi-inline-flex pi-rounded-full ${colorClasses} pi-opacity-75`}\n ></span>\n <FontAwesomeIcon\n className={`pi-w-4 pi-h-6 pi-rotate-45 ${textColorClasses}`}\n icon={faCircle}\n />\n </div>\n </div>\n )\n },\n [isOpen],\n )\n\n const callViewClasses = useMemo(() => {\n let baseClasses = 'pi-grid pi-items-center'\n\n if (isOpen) {\n baseClasses = 'pi-grid pi-items-start'\n\n if (accepted) {\n baseClasses += ' pi-grid-rows-[72px_1fr]'\n } else if (incoming) {\n baseClasses += ' pi-grid-cols-[256px_114px]'\n } else if (outgoing) {\n baseClasses += ' pi-grid-cols-[1fr_84px]'\n }\n }\n\n return shouldShowStreamingImage ? 'pi-flex pi-flex-col' : baseClasses\n }, [isOpen, accepted, incoming, outgoing, shouldShowStreamingImage])\n\n const topContentClasses = useMemo(() => {\n let columns = ''\n\n if (isOpen && !accepted && outgoing) {\n columns = 'pi-grid-cols-[48px_1fr]'\n } else if (isOpen && !accepted && incoming) {\n columns = 'pi-grid-cols-[48px_1fr_1px]'\n } else if (isOpen && accepted) {\n columns = 'pi-grid-cols-[48px_164px_48px]'\n } else if (!isOpen && !accepted) {\n columns = 'pi-grid-cols-[24px_102px]'\n } else {\n columns = 'pi-grid-cols-[24px_66px_24px]'\n }\n\n return `pi-grid ${columns} pi-gap-${isOpen ? '5' : '3'} pi-items-${isOpen ? 'start' : 'center'\n } pi-justify-center pi-w-full`\n }, [isOpen, accepted, incoming, outgoing])\n\n const getGridClasses = useMemo(() => {\n if (shouldShowStreamingImage) return 'pi-grid-cols-3'\n if (isAnswerVisible(outgoing, accepted)) return 'pi-grid-cols-2'\n if (accepted) return 'pi-grid-cols-1 pi-justify-items-center'\n return 'pi-grid-cols-1 pi-justify-items-end'\n }, [shouldShowStreamingImage, outgoing, accepted])\n\n const renderStatusIcon = useCallback(() => {\n const iconSizeClass = isOpen\n ? 'pi-relative pi-z-30 pi-h-12 pi-w-12 pi-rounded-sm pi-bg-cover'\n : 'pi-relative pi-z-30 pi-h-6 pi-w-6 pi-rounded-sm pi-bg-cover'\n\n if (isListen) {\n return <FontAwesomeIcon className={iconSizeClass} icon={faEarListen} />\n }\n\n if (isIntrude) {\n return <FontAwesomeIcon className={iconSizeClass} icon={faHandPointUp} />\n }\n\n if (number !== '' && hasValidUsername) {\n return <Avatar />\n }\n\n if (incoming && !hasValidUsername) {\n return <FontAwesomeIcon className={`${iconSizeClass} pi--rotate-45`} icon={faArrowLeft} />\n }\n\n if (accepted && !outgoing && !hasValidUsername) {\n return <FontAwesomeIcon className={`${iconSizeClass} pi--rotate-45`} icon={faArrowLeft} />\n }\n\n if (outgoing && !hasValidUsername) {\n return (\n <FontAwesomeIcon className={`${iconSizeClass} pi-rotate-[135deg]`} icon={faArrowLeft} />\n )\n }\n\n return null\n }, [isOpen, isListen, isIntrude, number, hasValidUsername, incoming, outgoing, accepted])\n\n const renderDetails = useCallback(() => {\n if (!isOpen) return null\n\n if (isIntrude) {\n return (\n <Details>\n <span className='pi-justify-center pi-w-fit pi-relative pi-inline-block pi-font-bold pi-text-base'>\n {t('Common.Intrude')}\n {isIntrudeExtension ? ` - ${isIntrudeExtension}` : ''}\n </span>\n {accepted ? (\n !isPhysical() ? (\n <Timer startTime={startTime} isNotAlwaysWhite />\n ) : (\n renderLandlinePhoneDiv()\n )\n ) : isIntrudeExtension ? (\n `${isIntrudeExtension}`\n ) : (\n ''\n )}\n </Details>\n )\n }\n\n if (isListen) {\n return (\n <Details>\n <span className='pi-justify-center pi-w-fit pi-relative pi-inline-block pi-font-bold pi-text-base'>\n {t('Common.Listen')}\n {isListenExtension ? ` - ${isListenExtension}` : ''}\n </span>\n {accepted ? (\n !isPhysical() ? (\n <Timer startTime={startTime} isNotAlwaysWhite />\n ) : (\n renderLandlinePhoneDiv()\n )\n ) : isListenExtension ? (\n `${isListenExtension}`\n ) : (\n ''\n )}\n </Details>\n )\n }\n\n return (\n <Details>\n <DisplayName />\n {accepted ? (\n !isPhysical() ? (\n <Timer startTime={startTime} isNotAlwaysWhite />\n ) : (\n renderLandlinePhoneDiv()\n )\n ) : (\n <Number />\n )}\n </Details>\n )\n }, [\n isOpen,\n isIntrude,\n isListen,\n accepted,\n startTime,\n isIntrudeExtension,\n isListenExtension,\n t,\n renderLandlinePhoneDiv,\n ])\n\n const renderAudioIndicator = useCallback(() => {\n if (accepted && isRecording) {\n return renderPulseIcon('red')\n }\n\n if (accepted && remoteAudioStream && !isPhysical()) {\n return (\n <AudioBars\n audioStream={remoteAudioStream}\n paused={paused}\n size={isOpen ? 'large' : 'small'}\n />\n )\n }\n\n if (accepted && isPhysical()) {\n return renderPulseIcon('green')\n }\n\n return null\n }, [accepted, isRecording, remoteAudioStream, isOpen, paused, renderPulseIcon])\n\n const renderStreamingContent = useCallback(() => {\n // Show skeleton while videoSources are loading or if streaming source number is not set yet\n if (!videoSources || Object.keys(videoSources).length === 0 || !streamingSourceNumber) {\n return <VideoStreamingSkeleton className=\"pi-w-full pi-h-40 pi-mt-4\" />\n }\n\n // Find the streaming source\n const source = Object.values(videoSources).find(\n (source) => source.extension === streamingSourceNumber,\n )\n\n // If source doesn't exist, show empty state\n if (!source) {\n return <VideoStreamingEmptyState className=\"pi-w-full pi-h-40 pi-mt-4\" />\n }\n\n // Check if image is available\n const hasImage = sourceImages[source.id] || source.image\n\n // If no image available, show empty state\n if (!hasImage) {\n return <VideoStreamingEmptyState className=\"pi-w-full pi-h-40 pi-mt-4\" />\n }\n\n // If we have an image, show StreamingImage component\n return <StreamingImage />\n }, [streamingSourceNumber, videoSources, sourceImages])\n\n // Early return AFTER all hooks have been called\n if (latestAlert !== null) {\n return null\n }\n\n const setVideoStreamingAnswer = () => {\n answerIncomingCall()\n // Set view as video streaming answer with a small delay\n setTimeout(() => {\n dispatch.island.setIslandView('streamingAnswer')\n }, 200)\n }\n\n return (\n <div className='pi-bg-red pi-content-center pi-justify-center'>\n <div className={callViewClasses}>\n {shouldShowStreamingImage ? (\n <>\n <div className='pi-flex pi-items-center pi-justify-between'>\n <div className='pi-flex pi-items-center pi-gap-4'>\n {renderStatusIcon()}\n <div className='pi-flex pi-flex-col pi-justify-center pi-space-y-2'>\n <DisplayName />\n <Number />\n </div>\n </div>\n\n <div className='pi-flex pi-gap-2'>\n <Hangup description={t('Tooltip.Hangup')} />\n {!outgoing && (\n <Button\n onClick={() => setVideoStreamingAnswer()}\n variant='green'\n data-tooltip-id='tooltip-answer'\n data-tooltip-content={t('Tooltip.Answer') || ''}\n >\n <FontAwesomeIcon className='pi-w-5 pi-h-5' icon={faPhone} />\n </Button>\n )}\n {/* Open door button - only show if cmdOpen is valid */}\n {unlockData?.canUnlock && (\n <Button\n variant='default'\n onClick={handleStreamingUnlock}\n data-tooltip-id='tooltip-unlock'\n data-tooltip-content={unlockData?.tooltipText}\n >\n <FontAwesomeIcon className='pi-w-5 pi-h-5' icon={faUnlock} />\n </Button>\n )}\n </div>\n </div>\n\n {renderStreamingContent()}\n </>\n ) : (\n <>\n <div className={topContentClasses}>\n {renderStatusIcon()}\n {renderDetails()}\n\n {!isOpen && !accepted && <DisplayName />}\n {!isOpen && accepted && <Timer startTime={startTime} isNotAlwaysWhite />}\n\n {renderAudioIndicator()}\n </div>\n\n {isOpen && (\n <>\n <div className={`${!(isListen || isIntrude) ? 'pi-grid pi-gap-y-5' : ''}`}>\n {accepted && <Actions />}\n <div className={`pi-grid ${getGridClasses} pi-gap-3.5`}>\n <Hangup description={t('Tooltip.Hangup and transfer')} />\n\n {isAnswerVisible(outgoing, accepted) && (\n <Button\n onClick={answerIncomingCall}\n variant='green'\n data-tooltip-id='tooltip-answer-left'\n data-tooltip-content={t('Tooltip.Answer') || ''}\n >\n <FontAwesomeIcon className='pi-w-6 pi-h-6' icon={faPhone} />\n </Button>\n )}\n </div>\n </div>\n </>\n )}\n </>\n )}\n </div>\n <CustomThemedTooltip id='tooltip-answer-left' place='left' />\n <CustomThemedTooltip id='tooltip-answer' place='left' />\n <CustomThemedTooltip id='tooltip-unlock' place='left' />\n </div>\n )\n}\n\nexport default memo(CallView)\n\nexport interface CallViewProps { }\n"],"names":["isAnswerVisible","outgoing","accepted","Details","memo","_a","children","React","className","displayName","t","useTranslation","dispatch","useDispatch","currentCall","useSelector","state","incoming","startTime","paused","number","isRecording","username","streamingSourceNumber","_b","island","isOpen","isFromStreaming","remoteAudioStream","webrtc","listenState","listen","isListen","isIntrude","isListenExtension","isIntrudeExtension","alertsData","alerts","currentUser","_c","streaming","videoSources","sourceImages","activeAlerts","useMemo","Object","values","filter","alert","active","latestAlert","length","shouldShowStreamingImage","unlockData","canUnlock","tooltipText","source","find","extension","Boolean","cmdOpen","trim","concat","description","hasValidUsername","renderLandlinePhoneDiv","useCallback","createElement","FontAwesomeIcon","size","icon","faOfficePhone","default_device","renderPulseIcon","color","sizeClasses","innerSizeClasses","animationSizeClasses","colorClasses","textColorClasses","faCircle","callViewClasses","baseClasses","topContentClasses","getGridClasses","renderStatusIcon","iconSizeClass","faEarListen","faHandPointUp","Avatar","faArrowLeft","renderDetails","isPhysical","Timer","isNotAlwaysWhite","DisplayName","Number","renderAudioIndicator","AudioBars","audioStream","renderStreamingContent","keys","VideoStreamingSkeleton","id","image","StreamingImage","VideoStreamingEmptyState","Fragment","Hangup","Button","onClick","answerIncomingCall","setTimeout","setIslandView","variant","faPhone","handleStreamingUnlock","faUnlock","Actions","CustomThemedTooltip","place"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/CallView/index.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type FC, useMemo, useCallback, memo } from 'react'\nimport { useSelector } from 'react-redux'\nimport { RootState, Dispatch } from '../../store'\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport {\n faPhone,\n faEarListen,\n faHandPointUp,\n faArrowLeft,\n faCircle,\n faUnlock,\n} from '@fortawesome/free-solid-svg-icons'\nimport { Button } from '../'\nimport Timer from './Timer'\nimport Number from './Number'\nimport DisplayName from './DisplayName'\nimport { AudioBars } from '../'\nimport { answerIncomingCall } from '../../lib/phone/call'\nimport Avatar from './Avatar'\nimport Actions from './Actions'\nimport Hangup from '../Hangup'\nimport { useTranslation } from 'react-i18next'\nimport { faOfficePhone } from '@nethesis/nethesis-solid-svg-icons'\nimport { isPhysical } from '../../lib/user/default_device'\nimport { CustomThemedTooltip } from '../CustomThemedTooltip'\nimport StreamingImage from '../StreamingImage'\nimport VideoStreamingSkeleton from '../VideoStreamingSkeleton'\nimport VideoStreamingEmptyState from '../VideoStreamingEmptyState'\nimport { handleStreamingUnlock } from '../../utils'\nimport { useDispatch } from 'react-redux'\nimport { resolveUsernameByNumber } from '../../lib/phone/conversation'\n\nfunction isAnswerVisible(outgoing: boolean, accepted: boolean): boolean {\n return !outgoing && !accepted\n}\n\nconst Details = memo(({ children }: { children: React.ReactNode }) => (\n <div className='pi-grid pi-self-center pi-gap-1 pi-grid-cols-1 pi-grid-rows-2'>{children}</div>\n))\nDetails.displayName = 'Details'\n\n/**\n * The main view to manage calls, the starting point for calls actions flows\n */\nconst CallView: FC<CallViewProps> = () => {\n const { t } = useTranslation()\n const dispatch = useDispatch<Dispatch>()\n\n const currentCall = useSelector((state: RootState) => state.currentCall)\n const {\n incoming,\n accepted,\n outgoing,\n startTime,\n paused,\n number,\n isRecording,\n username,\n streamingSourceNumber,\n } = currentCall\n\n const { isOpen, isFromStreaming } = useSelector((state: RootState) => state.island)\n const { remoteAudioStream } = useSelector((state: RootState) => state.webrtc)\n const listenState = useSelector((state: RootState) => state.listen)\n const { isListen, isIntrude, isListenExtension, isIntrudeExtension } = listenState\n const { data: alertsData } = useSelector((state: RootState) => state.alerts)\n const currentUser = useSelector((state: RootState) => state.currentUser)\n const { extensions } = useSelector((state: RootState) => state.users)\n const { videoSources, sourceImages } = useSelector((state: RootState) => state.streaming)\n\n const activeAlerts = useMemo(\n () => Object.values(alertsData).filter((alert: any) => alert.active),\n [alertsData],\n )\n\n const latestAlert = useMemo(\n () => (activeAlerts.length > 0 ? activeAlerts[activeAlerts.length - 1] : null),\n [activeAlerts],\n )\n\n const shouldShowStreamingImage = useMemo(\n () => isFromStreaming && streamingSourceNumber && !accepted,\n [isFromStreaming, streamingSourceNumber, accepted],\n )\n\n // Check if unlock button should be shown and get tooltip text\n const unlockData = useMemo(() => {\n if (!streamingSourceNumber || !videoSources) return { canUnlock: false, tooltipText: '' }\n\n const source = Object.values(videoSources).find(\n (source) => source?.extension === streamingSourceNumber,\n )\n\n const canUnlock = Boolean(source?.cmdOpen && source?.cmdOpen.trim() !== '')\n const tooltipText = canUnlock && source ? `${t('VideoStreaming.Open')}: ${source?.description}` : ''\n\n return { canUnlock, tooltipText }\n }, [streamingSourceNumber, videoSources, t])\n\n const resolvedCallUsername = useMemo(() => {\n if (username && username !== 'undefined') {\n return username\n }\n\n return resolveUsernameByNumber(number, extensions)\n }, [username, number, extensions])\n\n const hasResolvedCallIdentity = useMemo(() => resolvedCallUsername !== '', [resolvedCallUsername])\n\n const renderLandlinePhoneDiv = useCallback(\n () => (\n <div className='pi-text-gray-600 dark:pi-text-gray-300 pi-font-normal pi-text-sm pi-flex pi-items-center pi-truncate'>\n <FontAwesomeIcon size='sm' icon={faOfficePhone} className='pi-mr-1' />\n <span className='pi-max-w-16 pi-truncate'>\n {currentUser?.default_device?.description || t('Common.Physical phone')}\n </span>\n </div>\n ),\n [currentUser?.default_device?.description, t],\n )\n\n const renderPulseIcon = useCallback(\n (color: string) => {\n const sizeClasses = !isOpen ? 'pi-h-6 pi-w-6' : 'pi-h-12 pi-w-12'\n const innerSizeClasses = !isOpen ? 'pi-h-4 pi-w-4 pi-rounded-full' : 'pi-h-8'\n const animationSizeClasses = !isOpen ? 'pi-h-6 pi-w-6' : 'pi-w-8 pi-h-8'\n const colorClasses = color === 'red' ? 'pi-bg-red-400' : 'pi-bg-green-400'\n const textColorClasses = color === 'red' ? 'pi-text-red-500' : 'pi-text-green-500'\n\n return (\n <div className={`${sizeClasses} pi-flex pi-justify-center pi-items-center`}>\n <div\n className={`${innerSizeClasses} pi-w-fit pi-flex pi-justify-center pi-items-center pi-gap-1 pi-overflow-hidden`}\n >\n <span\n className={`${animationSizeClasses} pi-animate-ping pi-absolute pi-inline-flex pi-rounded-full ${colorClasses} pi-opacity-75`}\n ></span>\n <FontAwesomeIcon\n className={`pi-w-4 pi-h-6 pi-rotate-45 ${textColorClasses}`}\n icon={faCircle}\n />\n </div>\n </div>\n )\n },\n [isOpen],\n )\n\n const callViewClasses = useMemo(() => {\n let baseClasses = 'pi-grid pi-items-center'\n\n if (isOpen) {\n baseClasses = 'pi-grid pi-items-start'\n\n if (accepted) {\n baseClasses += ' pi-grid-rows-[72px_1fr]'\n } else if (incoming) {\n baseClasses += ' pi-grid-cols-[256px_114px]'\n } else if (outgoing) {\n baseClasses += ' pi-grid-cols-[1fr_84px]'\n }\n }\n\n return shouldShowStreamingImage ? 'pi-flex pi-flex-col' : baseClasses\n }, [isOpen, accepted, incoming, outgoing, shouldShowStreamingImage])\n\n const topContentClasses = useMemo(() => {\n let columns = ''\n\n if (isOpen && !accepted && outgoing) {\n columns = 'pi-grid-cols-[48px_1fr]'\n } else if (isOpen && !accepted && incoming) {\n columns = 'pi-grid-cols-[48px_1fr_1px]'\n } else if (isOpen && accepted) {\n columns = 'pi-grid-cols-[48px_164px_48px]'\n } else if (!isOpen && !accepted) {\n columns = 'pi-grid-cols-[24px_102px]'\n } else {\n columns = 'pi-grid-cols-[24px_66px_24px]'\n }\n\n return `pi-grid ${columns} pi-gap-${isOpen ? '5' : '3'} pi-items-${isOpen ? 'start' : 'center'\n } pi-justify-center pi-w-full`\n }, [isOpen, accepted, incoming, outgoing])\n\n const getGridClasses = useMemo(() => {\n if (shouldShowStreamingImage) return 'pi-grid-cols-3'\n if (isAnswerVisible(outgoing, accepted)) return 'pi-grid-cols-2'\n if (accepted) return 'pi-grid-cols-1 pi-justify-items-center'\n return 'pi-grid-cols-1 pi-justify-items-end'\n }, [shouldShowStreamingImage, outgoing, accepted])\n\n const renderStatusIcon = useCallback(() => {\n const iconSizeClass = isOpen\n ? 'pi-relative pi-z-30 pi-h-12 pi-w-12 pi-rounded-sm pi-bg-cover'\n : 'pi-relative pi-z-30 pi-h-6 pi-w-6 pi-rounded-sm pi-bg-cover'\n\n if (isListen) {\n return <FontAwesomeIcon className={iconSizeClass} icon={faEarListen} />\n }\n\n if (isIntrude) {\n return <FontAwesomeIcon className={iconSizeClass} icon={faHandPointUp} />\n }\n\n if (number !== '' && hasResolvedCallIdentity) {\n return <Avatar />\n }\n\n if (incoming && !hasResolvedCallIdentity) {\n return <FontAwesomeIcon className={`${iconSizeClass} pi--rotate-45`} icon={faArrowLeft} />\n }\n\n if (accepted && !outgoing && !hasResolvedCallIdentity) {\n return <FontAwesomeIcon className={`${iconSizeClass} pi--rotate-45`} icon={faArrowLeft} />\n }\n\n if (outgoing && !hasResolvedCallIdentity) {\n return (\n <FontAwesomeIcon className={`${iconSizeClass} pi-rotate-[135deg]`} icon={faArrowLeft} />\n )\n }\n\n return null\n }, [isOpen, isListen, isIntrude, number, hasResolvedCallIdentity, incoming, outgoing, accepted])\n\n const renderDetails = useCallback(() => {\n if (!isOpen) return null\n\n if (isIntrude) {\n return (\n <Details>\n <span className='pi-justify-center pi-w-fit pi-relative pi-inline-block pi-font-bold pi-text-base'>\n {t('Common.Intrude')}\n {isIntrudeExtension ? ` - ${isIntrudeExtension}` : ''}\n </span>\n {accepted ? (\n !isPhysical() ? (\n <Timer startTime={startTime} isNotAlwaysWhite />\n ) : (\n renderLandlinePhoneDiv()\n )\n ) : isIntrudeExtension ? (\n `${isIntrudeExtension}`\n ) : (\n ''\n )}\n </Details>\n )\n }\n\n if (isListen) {\n return (\n <Details>\n <span className='pi-justify-center pi-w-fit pi-relative pi-inline-block pi-font-bold pi-text-base'>\n {t('Common.Listen')}\n {isListenExtension ? ` - ${isListenExtension}` : ''}\n </span>\n {accepted ? (\n !isPhysical() ? (\n <Timer startTime={startTime} isNotAlwaysWhite />\n ) : (\n renderLandlinePhoneDiv()\n )\n ) : isListenExtension ? (\n `${isListenExtension}`\n ) : (\n ''\n )}\n </Details>\n )\n }\n\n return (\n <Details>\n <DisplayName />\n {accepted ? (\n !isPhysical() ? (\n <Timer startTime={startTime} isNotAlwaysWhite />\n ) : (\n renderLandlinePhoneDiv()\n )\n ) : (\n <Number />\n )}\n </Details>\n )\n }, [\n isOpen,\n isIntrude,\n isListen,\n accepted,\n startTime,\n isIntrudeExtension,\n isListenExtension,\n t,\n renderLandlinePhoneDiv,\n ])\n\n const renderAudioIndicator = useCallback(() => {\n if (accepted && isRecording) {\n return renderPulseIcon('red')\n }\n\n if (accepted && remoteAudioStream && !isPhysical()) {\n return (\n <AudioBars\n audioStream={remoteAudioStream}\n paused={paused}\n size={isOpen ? 'large' : 'small'}\n />\n )\n }\n\n if (accepted && isPhysical()) {\n return renderPulseIcon('green')\n }\n\n return null\n }, [accepted, isRecording, remoteAudioStream, isOpen, paused, renderPulseIcon])\n\n const renderStreamingContent = useCallback(() => {\n // Show skeleton while videoSources are loading or if streaming source number is not set yet\n if (!videoSources || Object.keys(videoSources).length === 0 || !streamingSourceNumber) {\n return <VideoStreamingSkeleton className=\"pi-w-full pi-h-40 pi-mt-4\" />\n }\n\n // Find the streaming source\n const source = Object.values(videoSources).find(\n (source) => source.extension === streamingSourceNumber,\n )\n\n // If source doesn't exist, show empty state\n if (!source) {\n return <VideoStreamingEmptyState className=\"pi-w-full pi-h-40 pi-mt-4\" />\n }\n\n // Check if image is available\n const hasImage = sourceImages[source.id] || source.image\n\n // If no image available, show empty state\n if (!hasImage) {\n return <VideoStreamingEmptyState className=\"pi-w-full pi-h-40 pi-mt-4\" />\n }\n\n // If we have an image, show StreamingImage component\n return <StreamingImage />\n }, [streamingSourceNumber, videoSources, sourceImages])\n\n // Early return AFTER all hooks have been called\n if (latestAlert !== null) {\n return null\n }\n\n const setVideoStreamingAnswer = () => {\n answerIncomingCall()\n // Set view as video streaming answer with a small delay\n setTimeout(() => {\n dispatch.island.setIslandView('streamingAnswer')\n }, 200)\n }\n\n return (\n <div className='pi-bg-red pi-content-center pi-justify-center'>\n <div className={callViewClasses}>\n {shouldShowStreamingImage ? (\n <>\n <div className='pi-flex pi-items-center pi-justify-between'>\n <div className='pi-flex pi-items-center pi-gap-4'>\n {renderStatusIcon()}\n <div className='pi-flex pi-flex-col pi-justify-center pi-space-y-2'>\n <DisplayName />\n <Number />\n </div>\n </div>\n\n <div className='pi-flex pi-gap-2'>\n <Hangup description={t('Tooltip.Hangup')} />\n {!outgoing && (\n <Button\n onClick={() => setVideoStreamingAnswer()}\n variant='green'\n data-tooltip-id='tooltip-answer'\n data-tooltip-content={t('Tooltip.Answer') || ''}\n >\n <FontAwesomeIcon className='pi-w-5 pi-h-5' icon={faPhone} />\n </Button>\n )}\n {/* Open door button - only show if cmdOpen is valid */}\n {unlockData?.canUnlock && (\n <Button\n variant='default'\n onClick={handleStreamingUnlock}\n data-tooltip-id='tooltip-unlock'\n data-tooltip-content={unlockData?.tooltipText}\n >\n <FontAwesomeIcon className='pi-w-5 pi-h-5' icon={faUnlock} />\n </Button>\n )}\n </div>\n </div>\n\n {renderStreamingContent()}\n </>\n ) : (\n <>\n <div className={topContentClasses}>\n {renderStatusIcon()}\n {renderDetails()}\n\n {!isOpen && !accepted && <DisplayName />}\n {!isOpen && accepted && <Timer startTime={startTime} isNotAlwaysWhite />}\n\n {renderAudioIndicator()}\n </div>\n\n {isOpen && (\n <>\n <div className={`${!(isListen || isIntrude) ? 'pi-grid pi-gap-y-5' : ''}`}>\n {accepted && <Actions />}\n <div className={`pi-grid ${getGridClasses} pi-gap-3.5`}>\n <Hangup description={t('Tooltip.Hangup and transfer')} />\n\n {isAnswerVisible(outgoing, accepted) && (\n <Button\n onClick={answerIncomingCall}\n variant='green'\n data-tooltip-id='tooltip-answer-left'\n data-tooltip-content={t('Tooltip.Answer') || ''}\n >\n <FontAwesomeIcon className='pi-w-6 pi-h-6' icon={faPhone} />\n </Button>\n )}\n </div>\n </div>\n </>\n )}\n </>\n )}\n </div>\n <CustomThemedTooltip id='tooltip-answer-left' place='left' />\n <CustomThemedTooltip id='tooltip-answer' place='left' />\n <CustomThemedTooltip id='tooltip-unlock' place='left' />\n </div>\n )\n}\n\nexport default memo(CallView)\n\nexport interface CallViewProps { }\n"],"names":["isAnswerVisible","outgoing","accepted","Details","memo","_a","children","React","className","displayName","t","useTranslation","dispatch","useDispatch","currentCall","useSelector","state","incoming","startTime","paused","number","isRecording","username","streamingSourceNumber","_b","island","isOpen","isFromStreaming","remoteAudioStream","webrtc","listenState","listen","isListen","isIntrude","isListenExtension","isIntrudeExtension","alertsData","alerts","currentUser","extensions","users","_c","streaming","videoSources","sourceImages","activeAlerts","useMemo","Object","values","filter","alert","active","latestAlert","length","shouldShowStreamingImage","unlockData","canUnlock","tooltipText","source","find","extension","Boolean","cmdOpen","trim","concat","description","resolvedCallUsername","resolveUsernameByNumber","hasResolvedCallIdentity","renderLandlinePhoneDiv","useCallback","createElement","FontAwesomeIcon","size","icon","faOfficePhone","default_device","renderPulseIcon","color","sizeClasses","innerSizeClasses","animationSizeClasses","colorClasses","textColorClasses","faCircle","callViewClasses","baseClasses","topContentClasses","getGridClasses","renderStatusIcon","iconSizeClass","faEarListen","faHandPointUp","Avatar","faArrowLeft","renderDetails","isPhysical","Timer","isNotAlwaysWhite","DisplayName","Number","renderAudioIndicator","AudioBars","audioStream","renderStreamingContent","keys","VideoStreamingSkeleton","id","image","StreamingImage","VideoStreamingEmptyState","Fragment","Hangup","Button","onClick","answerIncomingCall","setTimeout","setIslandView","variant","faPhone","handleStreamingUnlock","faUnlock","Actions","CustomThemedTooltip","place"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../node_modules/tslib/tslib.es6.js"),t=require("react"),r=require("../store/index.js");require("../node_modules/react-redux/es/index.js");var o=require("../utils/customHooks/useEventListener.js"),s=require("../utils/customHooks/useLocalStorage.js"),n=require("../utils/customHooks/useLongPress.js"),i=require("../utils/genericFunctions/styleTransformValues.js"),a=require("../lib/island/island.js"),u=require("../node_modules/framer-motion/dist/es/gestures/drag/use-drag-controls.mjs.js"),l=require("../node_modules/framer-motion/dist/es/animation/hooks/use-animation.mjs.js"),d=require("../node_modules/framer-motion/dist/es/render/components/motion/proxy.mjs.js"),c=require("../node_modules/react-redux/es/hooks/useSelector.js"),m=require("../node_modules/react-redux/es/hooks/useDispatch.js");function p(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../node_modules/tslib/tslib.es6.js"),t=require("react"),r=require("../store/index.js");require("../node_modules/react-redux/es/index.js");var o=require("../utils/customHooks/useEventListener.js"),s=require("../utils/customHooks/useLocalStorage.js"),n=require("../utils/customHooks/useLongPress.js"),i=require("../utils/genericFunctions/styleTransformValues.js"),a=require("../lib/island/island.js"),u=require("../node_modules/framer-motion/dist/es/gestures/drag/use-drag-controls.mjs.js"),l=require("../node_modules/framer-motion/dist/es/animation/hooks/use-animation.mjs.js"),d=require("../node_modules/framer-motion/dist/es/render/components/motion/proxy.mjs.js"),c=require("../node_modules/react-redux/es/hooks/useSelector.js"),m=require("../node_modules/react-redux/es/hooks/useDispatch.js");function p(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var g=p(t),f=function(p){var f=p.children,v=p.islandContainerRef,j=c.useSelector((function(e){return e.island})).startPosition,x=t.useState(!1),h=x[0],y=x[1],_=m.useDispatch(),q=u.useDragControls(),b=l.useAnimation(),S=s.useLocalStorage("phone-island",null),D=S[0],P=S[1],L=t.useRef(null),k=t.useState(D&&D.position?D.position:null),C=k[0],w=k[1];o.useEventListener("phone-island-reset-position",(function(){return e.__awaiter(void 0,void 0,void 0,(function(){return e.__generator(this,(function(e){switch(e.label){case 0:return localStorage.removeItem("phone-island"),w(null),[4,b.start({x:j.x,y:j.y,transition:{duration:.3,ease:"easeOut"}})];case 1:return e.sent(),[2]}}))}))}));var E=n.useLongPress((function(){}),(function(e){var t,o;if(e&&e.target){var s=e.target;if(s.closest('[data-stop-propagation="true"]')||s.hasAttribute("data-stop-propagation"))return}!(null===(o=null===(t=null===r.store||void 0===r.store?void 0:r.store.getState())||void 0===t?void 0:t.island)||void 0===o?void 0:o.isOpen)&&_.island.handleToggleIsOpen()}),h,(function(){return y(!1)}),{shouldPreventDefault:!0,delay:250});return g.default.createElement(d.motion.div,e.__assign({drag:!0,onPointerDown:function(e){var t=e.target;t.closest('[data-stop-propagation="true"]')||t.hasAttribute("data-stop-propagation")||q.start(e)},onDragStart:function(){y(!0)},dragTransition:{power:0,timeConstant:300},initial:{x:(null==C?void 0:C.x)||j.x,y:(null==C?void 0:C.y)||j.y},animate:b,dragControls:q,dragListener:!1,dragConstraints:v,onDragEnd:function(){var e=i.styleTransformValues(L.current),t=e.x,r=e.y;t=a.xPosition(Math.round(t),L.current,v.current),r=a.yPosition(Math.round(r),L.current,v.current),P({position:{x:t,y:r}}),w({x:t,y:r})},ref:L},E,{className:"pi-absolute"}),f&&f)};exports.IslandDrag=f,exports.default=f;
|
|
2
2
|
//# sourceMappingURL=IslandDrag.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IslandDrag.js","sources":["../../src/components/IslandDrag.tsx"],"sourcesContent":["// Copyright (C) 2025 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type ReactNode, FC, useState, useRef, MutableRefObject } from 'react'\nimport { RootState, Dispatch, store } from '../store'\nimport { useSelector, useDispatch } from 'react-redux'\nimport { motion, useDragControls, useAnimation } from 'framer-motion'\nimport { useLongPress, useLocalStorage, styleTransformValues, useEventListener } from '../utils'\nimport { xPosition, yPosition } from '../lib/island/island'\n\nexport const IslandDrag: FC<IslandDragProps> = ({ children, islandContainerRef }) => {\n const { startPosition } = useSelector((state: RootState) => state.island)\n\n // Initialize the moved property\n const [moved, setMoved] = useState<boolean>(false)\n\n // Initialize dispatch\n const dispatch = useDispatch<Dispatch>()\n\n // Initialize Island drag controls\n const controls = useDragControls()\n\n // Initialize animation controls for reset functionality\n const animationControls = useAnimation()\n\n // Initialize Island storage\n const [phoneIslandStorage, setPhoneIslandStorage] =\n useLocalStorage<PhoneIslandStorageTypes | null>('phone-island', null)\n\n // The Island reference\n const islandRef = useRef<any>(null)\n\n // Initialize position or get from storage\n const [position, setPosition] = useState<PositionTypes | null>(\n phoneIslandStorage && phoneIslandStorage.position ? phoneIslandStorage.position : null,\n )\n\n // Handles reset position to default\n const handleResetPosition = async () => {\n // Clear localStorage\n localStorage.removeItem('phone-island')\n \n // Reset position state\n setPosition(null)\n \n // Animate back to default position\n await animationControls.start({\n x: startPosition.x,\n y: startPosition.y,\n transition: {\n duration: 0.3,\n ease: 'easeOut',\n },\n })\n }\n\n // Listen for reset position event\n useEventListener('phone-island-reset-position', handleResetPosition)\n\n // Handles the drag started event\n function handleStartDrag(event: React.PointerEvent<Element>) {\n const target = event.target as HTMLElement\n if (\n target.closest('[data-stop-propagation=\"true\"]') ||\n target.hasAttribute('data-stop-propagation')\n ) {\n return\n }\n\n controls.start(event)\n }\n\n // Handles log press event\n const handleLongPress = () => {}\n\n const handleIslandClick = (event?: React.MouseEvent<Element> | any) => {\n if (event && event.target) {\n const target = event.target as HTMLElement\n if (\n target.closest('[data-stop-propagation=\"true\"]') ||\n target.hasAttribute('data-stop-propagation')\n ) {\n return\n }\n }\n\n // Only if phone island is close is possible to open it trough the click\n const isPhoneIslandAlreadyOpen = store?.getState()?.island?.isOpen\n !isPhoneIslandAlreadyOpen && dispatch.island.handleToggleIsOpen()\n }\n\n // Handles drag end event\n const handleDragEnd = () => {\n
|
|
1
|
+
{"version":3,"file":"IslandDrag.js","sources":["../../src/components/IslandDrag.tsx"],"sourcesContent":["// Copyright (C) 2025 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type ReactNode, FC, useState, useRef, MutableRefObject } from 'react'\nimport { RootState, Dispatch, store } from '../store'\nimport { useSelector, useDispatch } from 'react-redux'\nimport { motion, useDragControls, useAnimation } from 'framer-motion'\nimport { useLongPress, useLocalStorage, styleTransformValues, useEventListener } from '../utils'\nimport { xPosition, yPosition } from '../lib/island/island'\n\nexport const IslandDrag: FC<IslandDragProps> = ({ children, islandContainerRef }) => {\n const { startPosition } = useSelector((state: RootState) => state.island)\n\n // Initialize the moved property\n const [moved, setMoved] = useState<boolean>(false)\n\n // Initialize dispatch\n const dispatch = useDispatch<Dispatch>()\n\n // Initialize Island drag controls\n const controls = useDragControls()\n\n // Initialize animation controls for reset functionality\n const animationControls = useAnimation()\n\n // Initialize Island storage\n const [phoneIslandStorage, setPhoneIslandStorage] =\n useLocalStorage<PhoneIslandStorageTypes | null>('phone-island', null)\n\n // The Island reference\n const islandRef = useRef<any>(null)\n\n // Initialize position or get from storage\n const [position, setPosition] = useState<PositionTypes | null>(\n phoneIslandStorage && phoneIslandStorage.position ? phoneIslandStorage.position : null,\n )\n\n // Handles reset position to default\n const handleResetPosition = async () => {\n // Clear localStorage\n localStorage.removeItem('phone-island')\n \n // Reset position state\n setPosition(null)\n \n // Animate back to default position\n await animationControls.start({\n x: startPosition.x,\n y: startPosition.y,\n transition: {\n duration: 0.3,\n ease: 'easeOut',\n },\n })\n }\n\n // Listen for reset position event\n useEventListener('phone-island-reset-position', handleResetPosition)\n\n // Handles the drag started event\n function handleStartDrag(event: React.PointerEvent<Element>) {\n const target = event.target as HTMLElement\n if (\n target.closest('[data-stop-propagation=\"true\"]') ||\n target.hasAttribute('data-stop-propagation')\n ) {\n return\n }\n\n controls.start(event)\n }\n\n // Handles log press event\n const handleLongPress = () => {}\n\n const handleIslandClick = (event?: React.MouseEvent<Element> | any) => {\n if (event && event.target) {\n const target = event.target as HTMLElement\n if (\n target.closest('[data-stop-propagation=\"true\"]') ||\n target.hasAttribute('data-stop-propagation')\n ) {\n return\n }\n }\n\n // Only if phone island is close is possible to open it trough the click\n const isPhoneIslandAlreadyOpen = store?.getState()?.island?.isOpen\n !isPhoneIslandAlreadyOpen && dispatch.island.handleToggleIsOpen()\n }\n\n // Handles drag end event\n const handleDragEnd = () => {\n // Get initial transform values\n let { x, y }: any = styleTransformValues(islandRef.current)\n // Round position\n x = xPosition(Math.round(x), islandRef.current, islandContainerRef.current)\n y = yPosition(Math.round(y), islandRef.current, islandContainerRef.current)\n // Save the new position to localstorage\n setPhoneIslandStorage({\n position: {\n x,\n y,\n },\n })\n // Set position to variable\n setPosition({\n x,\n y,\n })\n }\n\n // Handles drag started event\n function handleDragStarted() {\n setMoved(true)\n }\n\n // Initialize the longPressEvent object\n const longPressEvent = useLongPress(\n handleLongPress,\n handleIslandClick,\n moved,\n () => setMoved(false),\n {\n shouldPreventDefault: true,\n delay: 250,\n },\n )\n\n return (\n <motion.div\n drag\n onPointerDown={handleStartDrag}\n onDragStart={handleDragStarted}\n dragTransition={{ \n power: 0,\n timeConstant: 300\n }}\n initial={{\n x: position?.x || startPosition.x,\n y: position?.y || startPosition.y,\n }}\n animate={animationControls}\n dragControls={controls}\n dragListener={false}\n dragConstraints={islandContainerRef}\n onDragEnd={handleDragEnd}\n ref={islandRef}\n {...longPressEvent}\n className='pi-absolute'\n >\n {children && children}\n </motion.div>\n )\n}\n\nexport default IslandDrag\n\nexport interface IslandDragProps {\n children: ReactNode\n islandContainerRef: MutableRefObject<HTMLDivElement>\n}\n\ninterface PhoneIslandStorageTypes {\n position: PositionTypes\n}\n\ninterface PositionTypes {\n x: number\n y: number\n}\n"],"names":["IslandDrag","_a","children","islandContainerRef","startPosition","useSelector","state","island","_b","useState","moved","setMoved","dispatch","useDispatch","controls","useDragControls","animationControls","useAnimation","_c","useLocalStorage","phoneIslandStorage","setPhoneIslandStorage","islandRef","useRef","_d","position","setPosition","useEventListener","__awaiter","localStorage","removeItem","start","x","y","transition","duration","ease","sent","longPressEvent","useLongPress","event","target","closest","hasAttribute","store","getState","isOpen","handleToggleIsOpen","shouldPreventDefault","delay","React","createElement","motion","div","drag","onPointerDown","onDragStart","dragTransition","power","timeConstant","initial","animate","dragControls","dragListener","dragConstraints","onDragEnd","styleTransformValues","current","xPosition","Math","round","yPosition","ref","className"],"mappings":"k8BAUaA,EAAkC,SAACC,OAAEC,EAAQD,EAAAC,SAAEC,EAAkBF,EAAAE,mBACpEC,EAAkBC,eAAY,SAACC,GAAqB,OAAAA,EAAMC,wBAG5DC,EAAoBC,EAAAA,UAAkB,GAArCC,EAAKF,EAAA,GAAEG,EAAQH,EAAA,GAGhBI,EAAWC,EAAAA,cAGXC,EAAWC,EAAAA,kBAGXC,EAAoBC,EAAAA,eAGpBC,EACJC,EAAAA,gBAAgD,eAAgB,MAD3DC,EAAkBF,EAAA,GAAEG,OAIrBC,EAAYC,SAAY,MAGxBC,EAA0Bf,EAAAA,SAC9BW,GAAsBA,EAAmBK,SAAWL,EAAmBK,SAAW,MAD7EA,EAAQD,EAAA,GAAEE,EAAWF,EAAA,GAwB5BG,mBAAiB,+BAnBW,WAAA,OAAAC,EAAAA,eAAA,OAAA,OAAA,GAAA,yEAQ1B,OANAC,aAAaC,WAAW,gBAGxBJ,EAAY,MAGN,CAAA,EAAAV,EAAkBe,MAAM,CAC5BC,EAAG5B,EAAc4B,EACjBC,EAAG7B,EAAc6B,EACjBC,WAAY,CACVC,SAAU,GACVC,KAAM,4BALVnC,EAAAoC,qBAwEF,IAAMC,EAAiBC,EAAAA,cA7CC,eAEE,SAACC,WACzB,GAAIA,GAASA,EAAMC,OAAQ,CACzB,IAAMA,EAASD,EAAMC,OACrB,GACEA,EAAOC,QAAQ,mCACfD,EAAOE,aAAa,yBAEpB,MAEH,GAGyD,QAAzBnC,EAAiB,QAAjBP,SAAA2C,EAAAA,YAAK,IAALA,EAAKA,WAAA,EAALA,EAAAA,MAAOC,kBAAU,IAAA5C,OAAA,EAAAA,EAAEM,cAAM,IAAAC,OAAA,EAAAA,EAAEsC,SAC/BlC,EAASL,OAAOwC,oBAC/C,GAgCErC,GACA,WAAM,OAAAC,GAAS,KACf,CACEqC,sBAAsB,EACtBC,MAAO,MAIX,OACEC,EAAC,QAAAC,cAAAC,SAAOC,gBACNC,MAAI,EACJC,cAxEJ,SAAyBf,GACvB,IAAMC,EAASD,EAAMC,OAEnBA,EAAOC,QAAQ,mCACfD,EAAOE,aAAa,0BAKtB7B,EAASiB,MAAMS,EAChB,EA+DGgB,YApBJ,WACE7C,GAAS,EACV,EAmBG8C,eAAgB,CACdC,MAAO,EACPC,aAAc,KAEhBC,QAAS,CACP5B,GAAGP,aAAQ,EAARA,EAAUO,IAAK5B,EAAc4B,EAChCC,GAAGR,aAAQ,EAARA,EAAUQ,IAAK7B,EAAc6B,GAElC4B,QAAS7C,EACT8C,aAAchD,EACdiD,cAAc,EACdC,gBAAiB7D,EACjB8D,UAtDkB,WAEhB,IAAAhE,EAAgBiE,EAAAA,qBAAqB5C,EAAU6C,SAA7CnC,EAAC/B,EAAA+B,EAAEC,MAETD,EAAIoC,EAAAA,UAAUC,KAAKC,MAAMtC,GAAIV,EAAU6C,QAAShE,EAAmBgE,SACnElC,EAAIsC,EAAAA,UAAUF,KAAKC,MAAMrC,GAAIX,EAAU6C,QAAShE,EAAmBgE,SAEnE9C,EAAsB,CACpBI,SAAU,CACRO,EAACA,EACDC,EAACA,KAILP,EAAY,CACVM,EAACA,EACDC,EAACA,GAEL,EAqCIuC,IAAKlD,GACDgB,EACJ,CAAAmC,UAAU,gBAETvE,GAAYA,EAGnB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../node_modules/tslib/tslib.es6.js"),t=require("react");require("../../node_modules/react-redux/es/index.js");var r=require("./Actions.js"),i=require("./BarsGroup.js"),a=require("../AudioPlayerView/Progress.js"),n=require("../../lib/phone/audio.js"),s=require("../../node_modules/webm-duration-fix/lib/index.js"),l=require("./Timer.js");require("../../node_modules/@babel/runtime/helpers/defineProperty.js"),require("../../node_modules/@babel/runtime/helpers/objectWithoutProperties.js"),require("../../node_modules/@babel/runtime/helpers/typeof.js"),require("../../node_modules/html-parse-stringify/dist/html-parse-stringify.js"),require("../../node_modules/react-i18next/dist/es/context.js");var o=require("../../node_modules/react-i18next/dist/es/useTranslation.js");require("../../node_modules/@babel/runtime/helpers/slicedToArray.js");var u=require("../Button.js"),d=require("../../node_modules/@fortawesome/react-fontawesome/index.es.js"),c=require("../../node_modules/@fortawesome/free-solid-svg-icons/index.mjs.js")
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../node_modules/tslib/tslib.es6.js"),t=require("react");require("../../node_modules/react-redux/es/index.js");var r=require("./Actions.js"),i=require("./BarsGroup.js"),a=require("../AudioPlayerView/Progress.js"),n=require("../../lib/phone/audio.js"),s=require("../../node_modules/webm-duration-fix/lib/index.js"),l=require("./Timer.js");require("../../node_modules/@babel/runtime/helpers/defineProperty.js"),require("../../node_modules/@babel/runtime/helpers/objectWithoutProperties.js"),require("../../node_modules/@babel/runtime/helpers/typeof.js"),require("../../node_modules/html-parse-stringify/dist/html-parse-stringify.js"),require("../../node_modules/react-i18next/dist/es/context.js");var o=require("../../node_modules/react-i18next/dist/es/useTranslation.js");require("../../node_modules/@babel/runtime/helpers/slicedToArray.js");var u=require("../Button.js"),d=require("../../node_modules/@fortawesome/react-fontawesome/index.es.js"),c=require("../../node_modules/@fortawesome/free-solid-svg-icons/index.mjs.js");require("../../store/index.js");var f=require("../../node_modules/react-redux/es/hooks/useSelector.js"),m=require("../../node_modules/react-redux/es/hooks/useDispatch.js"),p=require("../../node_modules/react-redux/es/utils/shallowEqual.js");function x(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var v=x(t),w="audio/webm";exports.RecorderView=function(){var x=f.useSelector((function(e){return e.island})).isOpen,b=f.useSelector((function(e){return e.player})).audioPlayerPlaying,h=t.useRef(null),g=t.useRef(null),j=t.useRef([]),y=m.useDispatch(),E=f.useSelector((function(e){return e.webrtc.localAudioStream})),q=f.useSelector((function(e){return{recording:e.recorder.recording,recorded:e.recorder.recorded,waiting:e.recorder.waiting}}),p.default),_=q.recording,N=q.recorded,k=q.waiting;function A(e){j.current.push(e.data)}function P(){return e.__awaiter(this,void 0,void 0,(function(){var t,r;return e.__generator(this,(function(e){switch(e.label){case 0:return[4,s.default(new Blob(j.current,{type:w}))];case 1:return t=e.sent(),r=URL.createObjectURL(t),n.updateAudioPlayerSource(r),[2]}}))}))}t.useEffect((function(){(null==E?void 0:E.active)&&_&&(g.current=new MediaRecorder(E,{mimeType:w}),g.current.ondataavailable=A,g.current.onstop=P,g.current.start())}),[null==E?void 0:E.active,_]),t.useEffect((function(){var e;N&&(j.current=[],null===(e=g.current)||void 0===e||e.stop())}),[N]),t.useEffect((function(){return y.recorder.setVisibleContainerRef(h),function(){y.recorder.reset()}}),[]);var S=o.useTranslation().t;return v.default.createElement(v.default.Fragment,null,x?v.default.createElement(v.default.Fragment,null," ",v.default.createElement("div",{className:"pi-flex pi-items-center pi-justify-between pi-text-gray-900 dark:pi-text-gray-50"},v.default.createElement("h1",{className:"pi-text-lg pi-font-medium pi-leading-7"},S("Common.Record message")),v.default.createElement(u.Button,{onClick:function(){y.island.resetPlayerClose()},variant:"transparentSettings","data-tooltip-id":"tooltip-close-settings","data-tooltip-content":S("Common.Close")||""},v.default.createElement(d.FontAwesomeIcon,{icon:c.faXmark,className:"pi-w-5 pi-h-5"}))),v.default.createElement("div",{className:"pi-pt-4"},v.default.createElement("div",{className:"".concat(!_||k||b?"pi-mb-3":""," pi-flex pi-w-full pi-justify-center pi-items-center")},v.default.createElement("div",{className:"pi-font-medium pi-text-4xl pi-w-fit pi-h-fit dark:pi-text-white"},v.default.createElement(l.default,null))),v.default.createElement("div",{className:"pi-relative pi-w-full pi-justify-center pi-overflow-hidden pi-flex pi-items-center",ref:h},N?v.default.createElement(a.Progress,null):_&&!k?v.default.createElement("div",{className:"pi-flex pi-items-center pi-justify-between pi-w-full pi-pb-3 pi-overflow-hidden"},v.default.createElement(u.Button,{variant:"transparent",disabled:!0,className:"pi-flex pi-flex-none"},v.default.createElement(d.FontAwesomeIcon,{icon:c.faPlay,className:"pi-h-4 pi-w-4 pi-text-gray-700 dark:pi-text-gray-200"})),v.default.createElement("div",{className:"pi-relative pi-overflow-hidden pi-flex pi-flex-grow pi-justify-center pi-h-4"},Array.from({length:2}).map((function(e,t){return v.default.createElement(i.BarsGroup,{key:t,index:t,startAnimation:_,audioStream:E})}))),v.default.createElement(u.Button,{variant:"transparent",disabled:!0,className:"pi-flex pi-flex-none"},v.default.createElement(d.FontAwesomeIcon,{icon:c.faTrash,className:"pi-h-4 pi-w-4 pi-text-gray-700 dark:pi-text-gray-200"}))):_&&k?v.default.createElement("div",{className:"pi-sans pi-text-sm pi-w-fit pi-h-fit dark:pi-text-white pi-pb-7"},S("Common.Start recording message after")):v.default.createElement("div",{className:"pi-sans pi-text-sm pi-w-fit pi-h-fit dark:pi-text-white pi-pb-7"},S("Common.Start recording message before")))),v.default.createElement(r.Actions,null)):v.default.createElement("div",{className:"pi-font-medium pi-text-base"},"Recorder"))};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/components/RecorderView/index.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type FC, useRef, useEffect } from 'react'\nimport { useDispatch, useSelector, shallowEqual } from 'react-redux'\nimport { Dispatch, RootState } from '../../store'\nimport { Actions } from './Actions'\nimport { BarsGroup } from './BarsGroup'\nimport Progress from '../AudioPlayerView/Progress'\nimport { updateAudioPlayerSource } from '../../lib/phone/audio'\nimport fixWebmDuration from 'webm-duration-fix'\nimport Timer from './Timer'\nimport { useTranslation } from 'react-i18next'\nimport { Button } from '../Button'\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport { faTrash, faXmark, faPlay } from '@fortawesome/free-solid-svg-icons'\n\n// The number of groups to be created\n// ...the minimun to have this effect is 2\nconst BAR_GROUPS_COUNT = 2\n\n// The mime type of the recorded audio\nconst MIME_TYPE = 'audio/webm'\n\nexport const RecorderView: FC<RecorderViewProps> = () => {\n const { isOpen } = useSelector((state: RootState) => state.island)\n const { audioPlayerPlaying } = useSelector((state: RootState) => state.player)\n const visibleContainerRef = useRef<HTMLDivElement>(null)\n const recorderRef = useRef<MediaRecorder | null>(null)\n const mediaChunks = useRef<BlobPart[]>([])\n\n // Initialize state dispatch\n const dispatch = useDispatch<Dispatch>()\n\n // Retrieve the local audio stream from webrtc state\n const localAudioStream = useSelector((state: RootState) => state.webrtc.localAudioStream)\n\n // Retrieve the local audio stream from recorder state\n const { recording, recorded, waiting } = useSelector(\n (state: RootState) => ({\n recording: state.recorder.recording,\n recorded: state.recorder.recorded,\n waiting: state.recorder.waiting,\n }),\n shallowEqual,\n )\n\n function handleRecordedMedia(event: BlobEvent) {\n mediaChunks.current.push(event.data)\n }\n\n async function handleRecordingStopped() {\n const blob = await fixWebmDuration(new Blob(mediaChunks.current, { type: MIME_TYPE }))\n const audioURL = URL.createObjectURL(blob)\n // The next function is async\n updateAudioPlayerSource(audioURL)\n }\n\n // Handle and manage audio recording start\n useEffect(() => {\n // @ts-ignore\n if (localAudioStream?.active && recording) {\n recorderRef.current = new MediaRecorder(localAudioStream, {\n mimeType: MIME_TYPE,\n })\n recorderRef.current.ondataavailable = handleRecordedMedia\n recorderRef.current.onstop = handleRecordingStopped\n // Start the media recording\n recorderRef.current.start()\n }\n // @ts-ignore\n }, [localAudioStream?.active, recording])\n\n // Handle and manage audio recorded\n useEffect(() => {\n if (recorded) {\n mediaChunks.current = []\n recorderRef.current?.stop()\n }\n }, [recorded])\n\n // Handle view close and reset state\n useEffect(() => {\n // Set visible container reference to recorder state\n dispatch.recorder.setVisibleContainerRef(visibleContainerRef)\n\n return () => {\n dispatch.recorder.reset()\n }\n }, [])\n\n const { t } = useTranslation()\n\n function close() {\n dispatch.island.resetPlayerClose()\n }\n\n return (\n <>\n {isOpen ? (\n <>\n {' '}\n <div className='pi-flex pi-items-center pi-justify-between pi-text-gray-900 dark:pi-text-gray-50'>\n <h1 className='pi-text-lg pi-font-medium pi-leading-7'>{t('Common.Record message')}</h1>\n <Button\n onClick={() => close()}\n variant='transparentSettings'\n data-tooltip-id='tooltip-close-settings'\n data-tooltip-content={t('Common.Close') || ''}\n >\n <FontAwesomeIcon icon={faXmark} className='pi-w-5 pi-h-5' />\n </Button>\n </div>\n <div className='pi-pt-4'>\n <div\n className={`${\n !recording || waiting || audioPlayerPlaying ? 'pi-mb-3' : ''\n } pi-flex pi-w-full pi-justify-center pi-items-center`}\n >\n <div className='pi-font-medium pi-text-4xl pi-w-fit pi-h-fit dark:pi-text-white'>\n <Timer />\n </div>\n </div>\n {/* Bars animation section */}\n <div\n className={`pi-relative pi-w-full pi-justify-center pi-overflow-hidden pi-flex pi-items-center`}\n ref={visibleContainerRef}\n >\n {recorded ? (\n <Progress />\n ) : recording && !waiting ? (\n <div className='pi-flex pi-items-center pi-justify-between pi-w-full pi-pb-3 pi-overflow-hidden'>\n {/* Play button (disabled) on left */}\n <Button variant='transparent' disabled className='pi-flex pi-flex-none'>\n <FontAwesomeIcon\n icon={faPlay}\n className='pi-h-4 pi-w-4 pi-text-gray-700 dark:pi-text-gray-200'\n />\n </Button>\n\n {/* Audio visualization in the middle */}\n <div className='pi-relative pi-overflow-hidden pi-flex pi-flex-grow pi-justify-center pi-h-4'>\n {/* Create a custom numbers of bars groups */}\n {Array.from({ length: BAR_GROUPS_COUNT }).map((_, i) => (\n <BarsGroup\n key={i}\n index={i}\n startAnimation={recording}\n audioStream={localAudioStream}\n />\n ))}\n </div>\n\n {/* Trash button (disabled) on right */}\n <Button variant='transparent' disabled className='pi-flex pi-flex-none'>\n <FontAwesomeIcon\n icon={faTrash}\n className='pi-h-4 pi-w-4 pi-text-gray-700 dark:pi-text-gray-200'\n />\n </Button>\n </div>\n ) : recording && waiting ? (\n <div className='pi-sans pi-text-sm pi-w-fit pi-h-fit dark:pi-text-white pi-pb-7'>\n {t('Common.Start recording message after')}\n </div>\n ) : (\n <div className='pi-sans pi-text-sm pi-w-fit pi-h-fit dark:pi-text-white pi-pb-7'>\n {t('Common.Start recording message before')}\n </div>\n )}\n </div>\n </div>\n {/* Actions section */}\n <Actions />\n </>\n ) : (\n <div className='pi-font-medium pi-text-base'>Recorder</div>\n )}\n </>\n )\n}\n\nexport interface RecorderViewProps {}\n"],"names":["MIME_TYPE","isOpen","useSelector","state","island","audioPlayerPlaying","player","visibleContainerRef","useRef","recorderRef","mediaChunks","dispatch","useDispatch","localAudioStream","webrtc","_a","recording","recorder","recorded","waiting","shallowEqual","handleRecordedMedia","event","current","push","data","handleRecordingStopped","fixWebmDuration","Blob","type","blob","sent","audioURL","URL","createObjectURL","updateAudioPlayerSource","useEffect","active","MediaRecorder","mimeType","ondataavailable","onstop","start","stop","setVisibleContainerRef","reset","t","useTranslation","React","createElement","Fragment","className","Button","onClick","resetPlayerClose","variant","FontAwesomeIcon","icon","faXmark","concat","Timer","ref","Progress","disabled","faPlay","Array","from","length","map","_","i","BarsGroup","key","index","startAnimation","audioStream","faTrash","Actions"],"mappings":"s3CAsBMA,EAAY,kCAEiC,WACzC,IAAAC,EAAWC,eAAY,SAACC,GAAqB,OAAAA,EAAMC,iBACnDC,EAAuBH,eAAY,SAACC,GAAqB,OAAAA,EAAMG,6BACjEC,EAAsBC,SAAuB,MAC7CC,EAAcD,SAA6B,MAC3CE,EAAcF,SAAmB,IAGjCG,EAAWC,EAAAA,cAGXC,EAAmBX,eAAY,SAACC,GAAqB,OAAAA,EAAMW,OAAOD,gBAAb,IAGrDE,EAAmCb,EAAAA,aACvC,SAACC,GAAqB,MAAC,CACrBa,UAAWb,EAAMc,SAASD,UAC1BE,SAAUf,EAAMc,SAASC,SACzBC,QAAShB,EAAMc,SAASE,WAE1BC,EAAAA,SANMJ,EAASD,EAAAC,UAAEE,EAAQH,EAAAG,SAAEC,YAS7B,SAASE,EAAoBC,GAC3BZ,EAAYa,QAAQC,KAAKF,EAAMG,KAChC,CAED,SAAeC,qHACA,KAAA,EAAA,MAAA,CAAA,EAAMC,EAAAA,QAAgB,IAAIC,KAAKlB,EAAYa,QAAS,CAAEM,KAAM7B,oBAAnE8B,EAAOf,EAAyEgB,OAChFC,EAAWC,IAAIC,gBAAgBJ,GAErCK,EAAuBA,wBAACH,aACzB,CAGDI,EAAAA,WAAU,YAEJvB,aAAgB,EAAhBA,EAAkBwB,SAAUrB,IAC9BP,EAAYc,QAAU,IAAIe,cAAczB,EAAkB,CACxD0B,SAAUvC,IAEZS,EAAYc,QAAQiB,gBAAkBnB,EACtCZ,EAAYc,QAAQkB,OAASf,EAE7BjB,EAAYc,QAAQmB,QAGvB,GAAE,CAAC7B,aAAgB,EAAhBA,EAAkBwB,OAAQrB,IAG9BoB,EAAAA,WAAU,iBACJlB,IACFR,EAAYa,QAAU,GACD,QAArBR,EAAAN,EAAYc,eAAS,IAAAR,GAAAA,EAAA4B,OAEzB,GAAG,CAACzB,IAGJkB,EAAAA,WAAU,WAIR,OAFAzB,EAASM,SAAS2B,uBAAuBrC,GAElC,WACLI,EAASM,SAAS4B,OACpB,CACD,GAAE,IAEK,IAAAC,EAAMC,qBAMd,OACEC,UACGC,cAAAD,EAAA,QAAAE,SAAA,KAAAjD,EACC+C,UAAAC,cAAAD,EAAA,QAAAE,SAAA,KACG,IACDF,EAAAA,QAAKC,cAAA,MAAA,CAAAE,UAAU,oFACbH,UAAIC,cAAA,KAAA,CAAAE,UAAU,0CAA0CL,EAAE,0BAC1DE,EAAC,QAAAC,cAAAG,UACCC,QAAS,WAXnB1C,EAASP,OAAOkD,kBAWgB,EACtBC,QAAQ,wCACQ,yBAAwB,uBAClBT,EAAE,iBAAmB,IAE3CE,UAACC,cAAAO,EAAAA,gBAAgB,CAAAC,KAAMC,EAAAA,QAASP,UAAU,oBAG9CH,EAAAA,QAAKC,cAAA,MAAA,CAAAE,UAAU,WACbH,EAAAA,QAAAC,cAAA,MAAA,CACEE,UAAW,GAAAQ,QACR3C,GAAaG,GAAWd,EAAqB,UAAY,GACN,yDAEtD2C,EAAAA,QAAKC,cAAA,MAAA,CAAAE,UAAU,mEACbH,EAAAA,QAACC,cAAAW,UAAQ,QAIbZ,UAAAC,cAAA,MAAA,CACEE,UAAW,qFACXU,IAAKtD,GAEJW,EACC8B,UAACC,cAAAa,EAAAA,SAAW,MACV9C,IAAcG,EAChB6B,UAAKC,cAAA,MAAA,CAAAE,UAAU,mFAEbH,UAACC,cAAAG,EAAMA,OAAC,CAAAG,QAAQ,cAAcQ,UAAQ,EAACZ,UAAU,wBAC/CH,UAACC,cAAAO,EAAAA,gBACC,CAAAC,KAAMO,EAAAA,OACNb,UAAU,0DAKdH,EAAAA,QAAKC,cAAA,MAAA,CAAAE,UAAU,gFAEZc,MAAMC,KAAK,CAAEC,OA5HT,IA4HqCC,KAAI,SAACC,EAAGC,GAAM,OACtDtB,EAAAA,QAACC,cAAAsB,EAAAA,WACCC,IAAKF,EACLG,MAAOH,EACPI,eAAgB1D,EAChB2D,YAAa9D,GAEhB,KAIHmC,UAACC,cAAAG,EAAMA,OAAC,CAAAG,QAAQ,cAAcQ,UAAQ,EAACZ,UAAU,wBAC/CH,EAAC,QAAAC,cAAAO,EAAeA,iBACdC,KAAMmB,EAAAA,QACNzB,UAAU,2DAIdnC,GAAaG,EACf6B,EAAAA,QAAKC,cAAA,MAAA,CAAAE,UAAU,mEACZL,EAAE,yCAGLE,EAAAA,6BAAKG,UAAU,mEACZL,EAAE,4CAMXE,EAAAA,QAAAC,cAAC4B,EAAAA,QAAU,OAGb7B,EAAAA,QAAKC,cAAA,MAAA,CAAAE,UAAU,+BAA6B,YAIpD"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/RecorderView/index.tsx"],"sourcesContent":["// Copyright (C) 2024 Nethesis S.r.l.\n// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport React, { type FC, useState, useRef, useEffect, useCallback, memo } from 'react'\nimport { useDispatch, useSelector, shallowEqual } from 'react-redux'\nimport { Dispatch, RootState } from '../../store'\nimport { Actions } from './Actions'\nimport { BarsGroup } from './BarsGroup'\nimport Progress from '../AudioPlayerView/Progress'\nimport { updateAudioPlayerSource } from '../../lib/phone/audio'\nimport fixWebmDuration from 'webm-duration-fix'\nimport Timer from './Timer'\nimport { useTranslation } from 'react-i18next'\nimport { Button } from '../Button'\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport { faTrash, faXmark, faPlay } from '@fortawesome/free-solid-svg-icons'\nimport { eventDispatch } from '../../utils'\n\n// The number of groups to be created\n// ...the minimun to have this effect is 2\nconst BAR_GROUPS_COUNT = 2\n\n// The mime type of the recorded audio\nconst MIME_TYPE = 'audio/webm'\n\nexport const RecorderView: FC<RecorderViewProps> = () => {\n const { isOpen } = useSelector((state: RootState) => state.island)\n const { audioPlayerPlaying } = useSelector((state: RootState) => state.player)\n const visibleContainerRef = useRef<HTMLDivElement>(null)\n const recorderRef = useRef<MediaRecorder | null>(null)\n const mediaChunks = useRef<BlobPart[]>([])\n\n // Initialize state dispatch\n const dispatch = useDispatch<Dispatch>()\n\n // Retrieve the local audio stream from webrtc state\n const localAudioStream = useSelector((state: RootState) => state.webrtc.localAudioStream)\n\n // Retrieve the local audio stream from recorder state\n const { recording, recorded, waiting } = useSelector(\n (state: RootState) => ({\n recording: state.recorder.recording,\n recorded: state.recorder.recorded,\n waiting: state.recorder.waiting,\n }),\n shallowEqual,\n )\n\n function handleRecordedMedia(event: BlobEvent) {\n mediaChunks.current.push(event.data)\n }\n\n async function handleRecordingStopped() {\n const blob = await fixWebmDuration(new Blob(mediaChunks.current, { type: MIME_TYPE }))\n const audioURL = URL.createObjectURL(blob)\n // The next function is async\n updateAudioPlayerSource(audioURL)\n }\n\n // Handle and manage audio recording start\n useEffect(() => {\n // @ts-ignore\n if (localAudioStream?.active && recording) {\n recorderRef.current = new MediaRecorder(localAudioStream, {\n mimeType: MIME_TYPE,\n })\n recorderRef.current.ondataavailable = handleRecordedMedia\n recorderRef.current.onstop = handleRecordingStopped\n // Start the media recording\n recorderRef.current.start()\n }\n // @ts-ignore\n }, [localAudioStream?.active, recording])\n\n // Handle and manage audio recorded\n useEffect(() => {\n if (recorded) {\n mediaChunks.current = []\n recorderRef.current?.stop()\n }\n }, [recorded])\n\n // Handle view close and reset state\n useEffect(() => {\n // Set visible container reference to recorder state\n dispatch.recorder.setVisibleContainerRef(visibleContainerRef)\n\n return () => {\n dispatch.recorder.reset()\n }\n }, [])\n\n const { t } = useTranslation()\n\n function playerClose() {\n if (audioPlayerPlaying) {\n dispatch.player.stopAudioPlayer()\n eventDispatch('phone-island-audio-player-close', {})\n }\n dispatch.island.resetPlayerClose()\n }\n\n function close() {\n dispatch.island.resetPlayerClose()\n }\n\n return (\n <>\n {isOpen ? (\n <>\n {' '}\n <div className='pi-flex pi-items-center pi-justify-between pi-text-gray-900 dark:pi-text-gray-50'>\n <h1 className='pi-text-lg pi-font-medium pi-leading-7'>{t('Common.Record message')}</h1>\n <Button\n onClick={() => close()}\n variant='transparentSettings'\n data-tooltip-id='tooltip-close-settings'\n data-tooltip-content={t('Common.Close') || ''}\n >\n <FontAwesomeIcon icon={faXmark} className='pi-w-5 pi-h-5' />\n </Button>\n </div>\n <div className='pi-pt-4'>\n <div\n className={`${\n !recording || waiting || audioPlayerPlaying ? 'pi-mb-3' : ''\n } pi-flex pi-w-full pi-justify-center pi-items-center`}\n >\n <div className='pi-font-medium pi-text-4xl pi-w-fit pi-h-fit dark:pi-text-white'>\n <Timer />\n </div>\n </div>\n {/* Bars animation section */}\n <div\n className={`pi-relative pi-w-full pi-justify-center pi-overflow-hidden pi-flex pi-items-center`}\n ref={visibleContainerRef}\n >\n {recorded ? (\n <Progress />\n ) : recording && !waiting ? (\n <div className='pi-flex pi-items-center pi-justify-between pi-w-full pi-pb-3 pi-overflow-hidden'>\n {/* Play button (disabled) on left */}\n <Button variant='transparent' disabled className='pi-flex pi-flex-none'>\n <FontAwesomeIcon\n icon={faPlay}\n className='pi-h-4 pi-w-4 pi-text-gray-700 dark:pi-text-gray-200'\n />\n </Button>\n\n {/* Audio visualization in the middle */}\n <div className='pi-relative pi-overflow-hidden pi-flex pi-flex-grow pi-justify-center pi-h-4'>\n {/* Create a custom numbers of bars groups */}\n {Array.from({ length: BAR_GROUPS_COUNT }).map((_, i) => (\n <BarsGroup\n key={i}\n index={i}\n startAnimation={recording}\n audioStream={localAudioStream}\n />\n ))}\n </div>\n\n {/* Trash button (disabled) on right */}\n <Button variant='transparent' disabled className='pi-flex pi-flex-none'>\n <FontAwesomeIcon\n icon={faTrash}\n className='pi-h-4 pi-w-4 pi-text-gray-700 dark:pi-text-gray-200'\n />\n </Button>\n </div>\n ) : recording && waiting ? (\n <div className='pi-sans pi-text-sm pi-w-fit pi-h-fit dark:pi-text-white pi-pb-7'>\n {t('Common.Start recording message after')}\n </div>\n ) : (\n <div className='pi-sans pi-text-sm pi-w-fit pi-h-fit dark:pi-text-white pi-pb-7'>\n {t('Common.Start recording message before')}\n </div>\n )}\n </div>\n </div>\n {/* Actions section */}\n <Actions />\n </>\n ) : (\n <div className='pi-font-medium pi-text-base'>Recorder</div>\n )}\n </>\n )\n}\n\nexport interface RecorderViewProps {}\n"],"names":["MIME_TYPE","isOpen","useSelector","state","island","audioPlayerPlaying","player","visibleContainerRef","useRef","recorderRef","mediaChunks","dispatch","useDispatch","localAudioStream","webrtc","_a","recording","recorder","recorded","waiting","shallowEqual","handleRecordedMedia","event","current","push","data","handleRecordingStopped","fixWebmDuration","Blob","type","blob","sent","audioURL","URL","createObjectURL","updateAudioPlayerSource","useEffect","active","MediaRecorder","mimeType","ondataavailable","onstop","start","stop","setVisibleContainerRef","reset","t","useTranslation","React","createElement","Fragment","className","Button","onClick","resetPlayerClose","variant","FontAwesomeIcon","icon","faXmark","concat","Timer","ref","Progress","disabled","faPlay","Array","from","length","map","_","i","BarsGroup","key","index","startAnimation","audioStream","faTrash","Actions"],"mappings":"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"}
|