@davi-ai/retorik-framework 4.0.4 → 5.0.0

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.
Files changed (84) hide show
  1. package/README.md +13 -0
  2. package/dist/{AttachmentDetail.637ad44f.js → AttachmentDetail.3f9c113d.js} +15 -6
  3. package/dist/AttachmentDetail.3f9c113d.js.map +1 -0
  4. package/dist/{AttachmentDetail.83788045.js → AttachmentDetail.57c5579a.js} +15 -6
  5. package/dist/AttachmentDetail.57c5579a.js.map +1 -0
  6. package/dist/{CustomView.bf84bdf3.js → CustomView.6b96f53f.js} +8 -4
  7. package/dist/CustomView.6b96f53f.js.map +1 -0
  8. package/dist/{CustomView.9930c671.js → CustomView.b32a608f.js} +8 -4
  9. package/dist/CustomView.b32a608f.js.map +1 -0
  10. package/dist/{Emergency.1112c09f.js → Emergency.43605d14.js} +11 -2
  11. package/dist/Emergency.43605d14.js.map +1 -0
  12. package/dist/{Emergency.d5810ff2.js → Emergency.f1287bd5.js} +11 -2
  13. package/dist/Emergency.f1287bd5.js.map +1 -0
  14. package/dist/FullScreenImage.17df27bf.js.map +1 -1
  15. package/dist/FullScreenImage.99e19e10.js.map +1 -1
  16. package/dist/{HistoryList.3b4b1ffb.js → HistoryList.c19556a7.js} +8 -2
  17. package/dist/HistoryList.c19556a7.js.map +1 -0
  18. package/dist/{HistoryList.e5c01f21.js → HistoryList.e7262d62.js} +8 -2
  19. package/dist/HistoryList.e7262d62.js.map +1 -0
  20. package/dist/{LanguageChoice.1d866cfa.js → LanguageChoice.54fae1dc.js} +19 -8
  21. package/dist/LanguageChoice.54fae1dc.js.map +1 -0
  22. package/dist/{LanguageChoice.cce361a3.js → LanguageChoice.6e8b74f6.js} +19 -8
  23. package/dist/LanguageChoice.6e8b74f6.js.map +1 -0
  24. package/dist/LittleWeatherContainer.7e41105e.js.map +1 -1
  25. package/dist/LittleWeatherContainer.ee087e22.js.map +1 -1
  26. package/dist/{MapContainer.14c28128.js → MapContainer.25c8f4b4.js} +20 -5
  27. package/dist/MapContainer.25c8f4b4.js.map +1 -0
  28. package/dist/{MapContainer.f22ad81f.js → MapContainer.d00ab5b2.js} +20 -5
  29. package/dist/MapContainer.d00ab5b2.js.map +1 -0
  30. package/dist/{NewsContainer.d9de093c.js → NewsContainer.a39630c3.js} +33 -26
  31. package/dist/NewsContainer.a39630c3.js.map +1 -0
  32. package/dist/{NewsContainer.463e74de.js → NewsContainer.ec15c3bb.js} +33 -26
  33. package/dist/NewsContainer.ec15c3bb.js.map +1 -0
  34. package/dist/PrintingPreview.375e62b0.js.map +1 -1
  35. package/dist/PrintingPreview.c0ca7706.js.map +1 -1
  36. package/dist/RecognitionManager.c58b8a3d.js +298 -0
  37. package/dist/RecognitionManager.c58b8a3d.js.map +1 -0
  38. package/dist/RecognitionManager.cdfb39fc.js +314 -0
  39. package/dist/RecognitionManager.cdfb39fc.js.map +1 -0
  40. package/dist/SpiritEngineWrapper.21ea10d4.js.map +1 -1
  41. package/dist/SpiritEngineWrapper.39627300.js.map +1 -1
  42. package/dist/SynthesisPonyfillManager.10888d6d.js +888 -0
  43. package/dist/SynthesisPonyfillManager.10888d6d.js.map +1 -0
  44. package/dist/SynthesisPonyfillManager.f9f9a915.js +920 -0
  45. package/dist/SynthesisPonyfillManager.f9f9a915.js.map +1 -0
  46. package/dist/{ThreeJsWrapper.dd4906ff.js → ThreeJsWrapper.0285d280.js} +24 -12
  47. package/dist/ThreeJsWrapper.0285d280.js.map +1 -0
  48. package/dist/{ThreeJsWrapper.c02a077f.js → ThreeJsWrapper.ad746197.js} +24 -11
  49. package/dist/ThreeJsWrapper.ad746197.js.map +1 -0
  50. package/dist/{VeilleManager.f3bafdec.js → VeilleManager.0b3f2454.js} +11 -13
  51. package/dist/VeilleManager.0b3f2454.js.map +1 -0
  52. package/dist/{VeilleManager.85967e7c.js → VeilleManager.340a7825.js} +11 -13
  53. package/dist/VeilleManager.340a7825.js.map +1 -0
  54. package/dist/{Weather.7e945307.js → Weather.abc13d88.js} +9 -3
  55. package/dist/Weather.abc13d88.js.map +1 -0
  56. package/dist/{Weather.e81b7205.js → Weather.b9d9f82e.js} +9 -3
  57. package/dist/Weather.b9d9f82e.js.map +1 -0
  58. package/dist/index.d.ts +21 -951
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +52944 -33749
  61. package/dist/index.js.map +1 -1
  62. package/dist/index.modern.js +53461 -34269
  63. package/dist/index.modern.js.map +1 -1
  64. package/package.json +20 -21
  65. package/dist/AttachmentDetail.637ad44f.js.map +0 -1
  66. package/dist/AttachmentDetail.83788045.js.map +0 -1
  67. package/dist/CustomView.9930c671.js.map +0 -1
  68. package/dist/CustomView.bf84bdf3.js.map +0 -1
  69. package/dist/Emergency.1112c09f.js.map +0 -1
  70. package/dist/Emergency.d5810ff2.js.map +0 -1
  71. package/dist/HistoryList.3b4b1ffb.js.map +0 -1
  72. package/dist/HistoryList.e5c01f21.js.map +0 -1
  73. package/dist/LanguageChoice.1d866cfa.js.map +0 -1
  74. package/dist/LanguageChoice.cce361a3.js.map +0 -1
  75. package/dist/MapContainer.14c28128.js.map +0 -1
  76. package/dist/MapContainer.f22ad81f.js.map +0 -1
  77. package/dist/NewsContainer.463e74de.js.map +0 -1
  78. package/dist/NewsContainer.d9de093c.js.map +0 -1
  79. package/dist/ThreeJsWrapper.c02a077f.js.map +0 -1
  80. package/dist/ThreeJsWrapper.dd4906ff.js.map +0 -1
  81. package/dist/VeilleManager.85967e7c.js.map +0 -1
  82. package/dist/VeilleManager.f3bafdec.js.map +0 -1
  83. package/dist/Weather.7e945307.js.map +0 -1
  84. package/dist/Weather.e81b7205.js.map +0 -1
@@ -1 +0,0 @@
1
- {"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,MAAM,sCAAgB;AACtB,MAAM,4CAAsB;AAE5B,MAAM,mCAAa,CAAC,cAAE,UAAU,SAAE,KAAK,QAAE,IAAI,sBAAE,kBAAkB,WAAE,OAAO,6BAAE,yBAAyB,EAAmB;IACtH,MAAM,WAAW,CAAA,GAAA,kBAAU;IAC3B,MAAM,cAAc,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,mBAAmB;IAC7F,MAAM,SAAS,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,MAAM;IAE3E,MAAM,aAAa;QACjB,SACE,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;YAChC,MAAM;YACN,UAAU,IAAM,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;oBAAE,MAAM,QAAQ,CAAC,gBAAgB,EAAE,MAAM,OAAO,CAAC,OAAO,KAAK,GAAG;gBAAyB;QACtJ;QAEF,SAAS,CAAA,GAAA,mBAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA,GAAA,qBAAa,EAAE,IAAI;QACjE,0BAA0B;IAC5B;IAEA,MAAM,qBAAkC,CAAA,GAAA,cAAM,EAAE;QAC9C,IAAI,YAAY,QACd;YAAA,IAAI,oBAAoB;gBACtB,MAAM,YAAY,mBAAmB,IAAI,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;gBAC5D,IAAI,WAAW,WACb,OAAO,UAAU,SAAS;YAE9B;QAAA;QAEF,qBAAO;IACT,GAAG;QAAC;KAAW;IAEf,qBACE,iBAAC,CAAA,GAAA,cAAa;QAAE,SAAS;QAAS,SAAS;;0BAEzC,iBAAC;gBAAI,WAAU;;kCAEb,iBAAC;wBAAI,WAAU;;0CACb,gBAAC,CAAA,GAAA,iBAAS;gCAAE,OAAO,YAAY,MAAM,CAAC,IAAI;gCAAE,WAAU;gCAAa,YAAY;;0CAC/E,iBAAC;gCAAI,WAAU;;oCACZ,qBAAO,iBAAC;wCAAI,WAAW;;4CAAsB;4CAAK;;uDAAU;kDAC7D,gBAAC;wCAAI,WAAU;kDAA+C,QAAQ,CAAA,GAAA,4BAAoB,EAAE,OAAO,wBAAU;;;;;;kCAIjH,iBAAC;wBAAI,WAAU;;4BACZ,qBAAO,iBAAC;gCAAI,WAAW;;oCAAgB;oCAAK;;+CAAU;0CACvD,gBAAC;gCAAI,WAAU;0CAA8C,QAAQ,CAAA,GAAA,4BAAoB,EAAE,OAAO,wBAAU;;;;;;YAI/G;0BAGD,gBAAC,CAAA,GAAA,cAAyB;gBAAE,gBAAgB;gBAAC,iBAAiB;gBAAM,SAAS;;;;AAGnF;IAEA,2CAAe","sources":["src/components/Views/CustomView.tsx"],"sourcesContent":["import React, { useMemo } from 'react'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport { CurrentSubView } from '../../models/enums'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\nimport TemplateGlobal from '../Templates/TemplateGlobal'\r\nimport { BackButton } from '../Menu/Common'\r\nimport AbsoluteLargeClosingButton from '../Utils/SubView/AbsoluteLargeClosingButton'\r\n\r\ninterface CustomViewProps {\r\n customView?: string\r\n title?: string\r\n icon?: JSX.Element\r\n externalComponents?: Array<{ name: string; component: JSX.Element }>\r\n display?: boolean\r\n setDisplayCustomComponent: (value: boolean) => void\r\n}\r\n\r\nconst iconClassname = 'rf-h-16 rf-w-16 large-vertical:rf-h-24 large-vertical:rf-w-24'\r\nconst iconClassnameMobile = 'rf-h-8 rf-w-8'\r\n\r\nconst CustomView = ({ customView, title, icon, externalComponents, display, setDisplayCustomComponent }: CustomViewProps): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n\r\n const handleBack = (): void => {\r\n dispatch(\r\n storeActions.directline.sendEvent({\r\n name: 'Davi.CloseWindow',\r\n callback: () => dispatch(storeActions.directline.sendEvent({ name: title ? `Davi.CloseWindow${title.replace(/\\s/g, '')}` : 'Davi.CloseWindowCustom' }))\r\n })\r\n )\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n setDisplayCustomComponent(false)\r\n }\r\n\r\n const componentToDisplay: JSX.Element = useMemo(() => {\r\n if (customView?.length) {\r\n if (externalComponents) {\r\n const component = externalComponents.find((e) => e.name === customView)\r\n if (component?.component) {\r\n return component.component\r\n }\r\n }\r\n }\r\n return <></>\r\n }, [customView])\r\n\r\n return (\r\n <TemplateGlobal display={display} onClick={handleBack}>\r\n {/* title */}\r\n <div className='rf-absolute rf-z-[1] rf-w-full rf-top-0 rf-left-0'>\r\n {/* Mobile display */}\r\n <div className='large:rf-hidden rf-p-4 rf-flex rf-flex-col'>\r\n <BackButton title={translation.common.back} className='rf-text-sm' handleBack={handleBack} />\r\n <div className='large:rf-hidden rf-py-2 rf-flex rf-flex-row rf-items-end undefined'>\r\n {icon ? <div className={iconClassnameMobile}>{icon} </div> : <></>}\r\n <div className='rf-ml-2 rf-capitalize rf-subtitle-size-auto'>{title ? capitalizeFirstLetter(title, locale) : <></>}</div>\r\n </div>\r\n </div>\r\n\r\n <div className='rf-hidden large:rf-flex rf-w-full rf-pt-4 large-vertical:rf-pt-8 rf-pl-4 large-vertical:rf-pl-0 rf-flex-row rf-justify-start large-vertical:rf-justify-center rf-items-center'>\r\n {icon ? <div className={iconClassname}>{icon} </div> : <></>}\r\n <div className='rf-ml-2 rf-uppercase rf-subtitle-size-auto'>{title ? capitalizeFirstLetter(title, locale) : <></>}</div>\r\n </div>\r\n </div>\r\n\r\n {componentToDisplay}\r\n\r\n {/* Closing button in large mode */}\r\n <AbsoluteLargeClosingButton dashboardVisible customComponent={true} onClick={handleBack} />\r\n </TemplateGlobal>\r\n )\r\n}\r\n\r\nexport default CustomView\r\n"],"names":[],"version":3,"file":"CustomView.9930c671.js.map"}
@@ -1 +0,0 @@
1
- {"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,MAAM,sCAAgB;AACtB,MAAM,4CAAsB;AAE5B,MAAM,mCAAa,CAAC,cAAE,UAAU,SAAE,KAAK,QAAE,IAAI,sBAAE,kBAAkB,WAAE,OAAO,6BAAE,yBAAyB,EAAmB;IACtH,MAAM,WAAW,CAAA,GAAA,6BAAU;IAC3B,MAAM,cAAc,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,mBAAmB;IAC7F,MAAM,SAAS,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,MAAM;IAE3E,MAAM,aAAa;QACjB,SACE,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;YAChC,MAAM;YACN,UAAU,IAAM,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;oBAAE,MAAM,QAAQ,CAAC,gBAAgB,EAAE,MAAM,OAAO,CAAC,OAAO,KAAK,GAAG;gBAAyB;QACtJ;QAEF,SAAS,CAAA,GAAA,mBAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA,GAAA,qBAAa,EAAE,IAAI;QACjE,0BAA0B;IAC5B;IAEA,MAAM,qBAAkC,CAAA,GAAA,oBAAM,EAAE;QAC9C,IAAI,uBAAA,iCAAA,WAAY,MAAM,EACpB;YAAA,IAAI,oBAAoB;gBACtB,MAAM,YAAY,mBAAmB,IAAI,CAAC,CAAC,IAAM,EAAE,IAAI,KAAK;gBAC5D,IAAI,sBAAA,gCAAA,UAAW,SAAS,EACtB,OAAO,UAAU,SAAS;YAE9B;QAAA;QAEF,qBAAO;IACT,GAAG;QAAC;KAAW;IAEf,qBACE,iCAAC,CAAA,GAAA,cAAa;QAAE,SAAS;QAAS,SAAS;;0BAEzC,iCAAC;gBAAI,WAAU;;kCAEb,iCAAC;wBAAI,WAAU;;0CACb,gCAAC,CAAA,GAAA,iBAAS;gCAAE,OAAO,YAAY,MAAM,CAAC,IAAI;gCAAE,WAAU;gCAAa,YAAY;;0CAC/E,iCAAC;gCAAI,WAAU;;oCACZ,qBAAO,iCAAC;wCAAI,WAAW;;4CAAsB;4CAAK;;uDAAU;kDAC7D,gCAAC;wCAAI,WAAU;kDAA+C,QAAQ,CAAA,GAAA,4BAAoB,EAAE,OAAO,wBAAU;;;;;;kCAIjH,iCAAC;wBAAI,WAAU;;4BACZ,qBAAO,iCAAC;gCAAI,WAAW;;oCAAgB;oCAAK;;+CAAU;0CACvD,gCAAC;gCAAI,WAAU;0CAA8C,QAAQ,CAAA,GAAA,4BAAoB,EAAE,OAAO,wBAAU;;;;;;YAI/G;0BAGD,gCAAC,CAAA,GAAA,cAAyB;gBAAE,gBAAgB;gBAAC,iBAAiB;gBAAM,SAAS;;;;AAGnF;IAEA,2CAAe","sources":["src/components/Views/CustomView.tsx"],"sourcesContent":["import React, { useMemo } from 'react'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport { CurrentSubView } from '../../models/enums'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\nimport TemplateGlobal from '../Templates/TemplateGlobal'\r\nimport { BackButton } from '../Menu/Common'\r\nimport AbsoluteLargeClosingButton from '../Utils/SubView/AbsoluteLargeClosingButton'\r\n\r\ninterface CustomViewProps {\r\n customView?: string\r\n title?: string\r\n icon?: JSX.Element\r\n externalComponents?: Array<{ name: string; component: JSX.Element }>\r\n display?: boolean\r\n setDisplayCustomComponent: (value: boolean) => void\r\n}\r\n\r\nconst iconClassname = 'rf-h-16 rf-w-16 large-vertical:rf-h-24 large-vertical:rf-w-24'\r\nconst iconClassnameMobile = 'rf-h-8 rf-w-8'\r\n\r\nconst CustomView = ({ customView, title, icon, externalComponents, display, setDisplayCustomComponent }: CustomViewProps): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n\r\n const handleBack = (): void => {\r\n dispatch(\r\n storeActions.directline.sendEvent({\r\n name: 'Davi.CloseWindow',\r\n callback: () => dispatch(storeActions.directline.sendEvent({ name: title ? `Davi.CloseWindow${title.replace(/\\s/g, '')}` : 'Davi.CloseWindowCustom' }))\r\n })\r\n )\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n setDisplayCustomComponent(false)\r\n }\r\n\r\n const componentToDisplay: JSX.Element = useMemo(() => {\r\n if (customView?.length) {\r\n if (externalComponents) {\r\n const component = externalComponents.find((e) => e.name === customView)\r\n if (component?.component) {\r\n return component.component\r\n }\r\n }\r\n }\r\n return <></>\r\n }, [customView])\r\n\r\n return (\r\n <TemplateGlobal display={display} onClick={handleBack}>\r\n {/* title */}\r\n <div className='rf-absolute rf-z-[1] rf-w-full rf-top-0 rf-left-0'>\r\n {/* Mobile display */}\r\n <div className='large:rf-hidden rf-p-4 rf-flex rf-flex-col'>\r\n <BackButton title={translation.common.back} className='rf-text-sm' handleBack={handleBack} />\r\n <div className='large:rf-hidden rf-py-2 rf-flex rf-flex-row rf-items-end undefined'>\r\n {icon ? <div className={iconClassnameMobile}>{icon} </div> : <></>}\r\n <div className='rf-ml-2 rf-capitalize rf-subtitle-size-auto'>{title ? capitalizeFirstLetter(title, locale) : <></>}</div>\r\n </div>\r\n </div>\r\n\r\n <div className='rf-hidden large:rf-flex rf-w-full rf-pt-4 large-vertical:rf-pt-8 rf-pl-4 large-vertical:rf-pl-0 rf-flex-row rf-justify-start large-vertical:rf-justify-center rf-items-center'>\r\n {icon ? <div className={iconClassname}>{icon} </div> : <></>}\r\n <div className='rf-ml-2 rf-uppercase rf-subtitle-size-auto'>{title ? capitalizeFirstLetter(title, locale) : <></>}</div>\r\n </div>\r\n </div>\r\n\r\n {componentToDisplay}\r\n\r\n {/* Closing button in large mode */}\r\n <AbsoluteLargeClosingButton dashboardVisible customComponent={true} onClick={handleBack} />\r\n </TemplateGlobal>\r\n )\r\n}\r\n\r\nexport default CustomView\r\n"],"names":[],"version":3,"file":"CustomView.bf84bdf3.js.map","sourceRoot":"../"}
@@ -1 +0,0 @@
1
- {"mappings":"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","sources":["src/components/Emergency/Emergency.tsx","src/components/Emergency/EmergencyContent.tsx","src/utils/fetchEmergencyData.ts"],"sourcesContent":["import React from 'react'\r\nimport { useDispatch } from 'react-redux'\r\nimport { storeActions } from '../../store'\r\nimport { CurrentSubView, TemplateTarget } from '../../models/enums'\r\nimport TemplateGlobal from '../Templates/TemplateGlobal'\r\nimport AbsoluteLargeClosingButton from '../Utils/SubView/AbsoluteLargeClosingButton'\r\nimport { EmergencyContent } from './EmergencyContent'\r\n\r\nconst Emergency = (): JSX.Element => {\r\n const dispatch = useDispatch()\r\n\r\n const handleBack = (): void => {\r\n dispatch(\r\n storeActions.directline.sendEvent({\r\n name: 'Davi.CloseWindow',\r\n callback: () => {\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindowEmergency' }))\r\n }\r\n })\r\n )\r\n }\r\n\r\n return (\r\n <TemplateGlobal target={TemplateTarget.emergency} onClick={handleBack}>\r\n <div className='rf-h-full rf-w-full rf-flex rf-flex-col rf-items-center rf-justify-center rf-gap-12'>\r\n {/* Emergency data */}\r\n <EmergencyContent />\r\n </div>\r\n\r\n {/* Closing button */}\r\n <AbsoluteLargeClosingButton dashboardVisible={true} onClick={handleBack} />\r\n </TemplateGlobal>\r\n )\r\n}\r\n\r\nexport default Emergency\r\n","import React, { useEffect, useRef, useState } from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\nimport { fetchEmergencyData } from '../../utils/fetchEmergencyData'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\nimport { EmergencyTypes } from '../../models/emergencyTypes'\r\nimport * as Icons from '../Icons/ViewIcons'\r\nimport Animation2 from '../Loader/Animation2'\r\nimport preventEvents from '../../utils/preventEvents'\r\n\r\n\r\nconst EmergencyContent = (): JSX.Element => {\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const baseAddress = useSelector((state: RootState) => state.localeReducer.baseAddress)\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n const isWidget = useSelector((state: RootState) => state.viewReducer.isWidget)\r\n\r\n const [municipalPoliceNumber, setMunicipalPoliceNumber] = useState<string>('')\r\n const [localHospitalName, setLocalHospitalName] = useState<string>('')\r\n const [localHospitalNumber, setLocalHospitalNumber] = useState<string>('')\r\n const [poisonControlNumber, setPoisonControlNumber] = useState<string>('')\r\n const [loading, setLoading] = useState<boolean>(true)\r\n const divRef = useRef<HTMLDivElement>(null)\r\n\r\n useEffect(() => {\r\n if (divRef?.current) {\r\n isWidget && preventEvents(null, divRef)\r\n }\r\n }, [divRef?.current])\r\n\r\n useEffect(() => {\r\n const getData = async (): Promise<void> => {\r\n const data: EmergencyTypes = await fetchEmergencyData(baseAddress)\r\n if (data) {\r\n setMunicipalPoliceNumber(data.municipalPoliceNumber)\r\n setLocalHospitalName(data.localHospitalName)\r\n setLocalHospitalNumber(data.localHospitalNumber)\r\n setPoisonControlNumber(data.poisonControlNumber)\r\n }\r\n setLoading(false)\r\n }\r\n getData()\r\n }, [baseAddress])\r\n\r\n return (\r\n <>\r\n <div className={`rf-flex rf-flex-col rf-items-center ${isMobile ? 'rf-justify-center rf-gap-2' : 'rf-justify-end rf-flex-[2_1_0%] rf-gap-9'}`}>\r\n <Icons.EmergencyIcon className='rf-h-9 rf-w-9 large:rf-h-16 large:rf-w-16' />\r\n <h3 className='rf-text-verylarge-size-auto rf-font-bold rf-text-center'>{capitalizeFirstLetter(translation.emergency.shorttitle, locale)}</h3>\r\n </div>\r\n <div\r\n ref={divRef}\r\n className='rf-w-full rf-flex rf-flex-col rf-items-center rf-flex-[4_1_0%] rf-justify-evenly rf-h-full rf-pt-2 rf-overflow-y-scroll rf-scrollbar-hidden'\r\n style={{\r\n background: isMobile ? 'transparent' : 'transparent linear-gradient(291deg, #F2F3F6 0%, #E5E6EC 100%) 0% 0% no-repeat padding-box',\r\n boxShadow: isMobile ? '' : '#ffff -3px -3px 16px, rgb(0 0 0 / 25%) 0px 2px 10px 0px'\r\n }}\r\n >\r\n {loading ? (\r\n <>\r\n <div className='rf-w-6 rf-h-6 rf-mb-16'>\r\n <Animation2 color='gray' loaderColor='#1999b1' backgroundColor='transparent' />\r\n </div>\r\n </>\r\n ) : (\r\n <>\r\n <div className={`rf-w-full rf-grid ${isMobile ? 'rf-grid-cols-2 rf-gap-8 rf-mt-10 rf-mb-8' : 'rf-grid-cols-4 rf-divide-x'} `} style={{ padding: isMobile ? '' : '0 10%' }}>\r\n <div className='rf-flex rf-flex-col rf-items-center rf-gap-2'>\r\n <p className='rf-text-xl rf-font-bold rf-uppercase'>{translation.emergency.samu}</p>\r\n <p className='rf-text-5xl large:rf-text-6xl rf-font-bold'>15</p>\r\n </div>\r\n <div className={`rf-flex rf-flex-col rf-items-center ${isMobile ? '' : 'rf-border-l rf-border-[#C7C6C6]'} rf-gap-2`}>\r\n <p className='rf-text-xl rf-font-bold rf-uppercase'>{translation.emergency.police}</p>\r\n <p className='rf-text-5xl large:rf-text-6xl rf-font-bold'>17</p>\r\n </div>\r\n <div className={`rf-flex rf-flex-col rf-items-center ${isMobile ? '' : 'rf-border-l rf-border-[#C7C6C6]'} rf-gap-2`}>\r\n <p className='rf-text-xl rf-font-bold rf-uppercase'>{translation.emergency.firefighter}</p>\r\n <p className='rf-text-5xl large:rf-text-6xl rf-font-bold'>18</p>\r\n </div>\r\n <div className={`rf-flex rf-flex-col rf-items-center ${isMobile ? '' : 'rf-border-l rf-border-[#C7C6C6]'} rf-gap-2`}>\r\n <p className='rf-text-xl rf-font-bold rf-uppercase'>{translation.emergency.general}</p>\r\n <p className='rf-text-5xl large:rf-text-6xl rf-font-bold'>112</p>\r\n </div>\r\n </div>\r\n <div className={`rf-flex rf-items-start ${isMobile ? 'rf-flex-col' : 'rf-gap-12'} `}>\r\n <div>\r\n {municipalPoliceNumber?.length && (\r\n <p className='rf-text-xl rf-py-2'>\r\n {`${translation.emergency.citypolice} : `}\r\n <span className='rf-font-bold'>{municipalPoliceNumber}</span>\r\n </p>\r\n )}\r\n <p className='rf-text-xl rf-py-2'>\r\n {`${translation.emergency.homeless} : `}\r\n <span className='rf-font-bold'>115</span>\r\n </p>\r\n <p className='rf-text-xl rf-py-2'>\r\n {`${translation.emergency.emergency} : `}\r\n <span className='rf-font-bold'>118</span>\r\n </p>\r\n </div>\r\n <div>\r\n {localHospitalName?.length && (\r\n <p className='rf-text-xl rf-py-2'>\r\n {`${translation.emergency.hospital} ${localHospitalName} : `}\r\n <span className='rf-font-bold'>{localHospitalNumber}</span>\r\n </p>\r\n )}\r\n {poisonControlNumber?.length && (\r\n <p className='rf-text-xl rf-py-2'>\r\n {`${translation.emergency.poison} : `}\r\n <span className='rf-font-bold'>{poisonControlNumber}</span>\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n {!isMobile && <div className='rf-flex-1' />}\r\n </>\r\n )\r\n}\r\n\r\nexport { EmergencyContent }\r\n","import { hospitalityApiAddress } from '../models/constants'\r\nimport { EmergencyTypes } from '../models/emergencyTypes'\r\n\r\nasync function fetchEmergencyData(address: string): Promise<EmergencyTypes> {\r\n const res = await fetch(`${address}${hospitalityApiAddress}`)\r\n .then((emergencyData) => {\r\n return emergencyData.json()\r\n })\r\n .catch(() => {\r\n return null\r\n })\r\n\r\n return res\r\n}\r\n\r\nexport { fetchEmergencyData }\r\n"],"names":[],"version":3,"file":"Emergency.1112c09f.js.map"}
@@ -1 +0,0 @@
1
- {"mappings":"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","sources":["src/components/Emergency/Emergency.tsx","src/components/Emergency/EmergencyContent.tsx","src/utils/fetchEmergencyData.ts"],"sourcesContent":["import React from 'react'\r\nimport { useDispatch } from 'react-redux'\r\nimport { storeActions } from '../../store'\r\nimport { CurrentSubView, TemplateTarget } from '../../models/enums'\r\nimport TemplateGlobal from '../Templates/TemplateGlobal'\r\nimport AbsoluteLargeClosingButton from '../Utils/SubView/AbsoluteLargeClosingButton'\r\nimport { EmergencyContent } from './EmergencyContent'\r\n\r\nconst Emergency = (): JSX.Element => {\r\n const dispatch = useDispatch()\r\n\r\n const handleBack = (): void => {\r\n dispatch(\r\n storeActions.directline.sendEvent({\r\n name: 'Davi.CloseWindow',\r\n callback: () => {\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindowEmergency' }))\r\n }\r\n })\r\n )\r\n }\r\n\r\n return (\r\n <TemplateGlobal target={TemplateTarget.emergency} onClick={handleBack}>\r\n <div className='rf-h-full rf-w-full rf-flex rf-flex-col rf-items-center rf-justify-center rf-gap-12'>\r\n {/* Emergency data */}\r\n <EmergencyContent />\r\n </div>\r\n\r\n {/* Closing button */}\r\n <AbsoluteLargeClosingButton dashboardVisible={true} onClick={handleBack} />\r\n </TemplateGlobal>\r\n )\r\n}\r\n\r\nexport default Emergency\r\n","import React, { useEffect, useRef, useState } from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\nimport { fetchEmergencyData } from '../../utils/fetchEmergencyData'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\nimport { EmergencyTypes } from '../../models/emergencyTypes'\r\nimport * as Icons from '../Icons/ViewIcons'\r\nimport Animation2 from '../Loader/Animation2'\r\nimport preventEvents from '../../utils/preventEvents'\r\n\r\n\r\nconst EmergencyContent = (): JSX.Element => {\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const baseAddress = useSelector((state: RootState) => state.localeReducer.baseAddress)\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n const isWidget = useSelector((state: RootState) => state.viewReducer.isWidget)\r\n\r\n const [municipalPoliceNumber, setMunicipalPoliceNumber] = useState<string>('')\r\n const [localHospitalName, setLocalHospitalName] = useState<string>('')\r\n const [localHospitalNumber, setLocalHospitalNumber] = useState<string>('')\r\n const [poisonControlNumber, setPoisonControlNumber] = useState<string>('')\r\n const [loading, setLoading] = useState<boolean>(true)\r\n const divRef = useRef<HTMLDivElement>(null)\r\n\r\n useEffect(() => {\r\n if (divRef?.current) {\r\n isWidget && preventEvents(null, divRef)\r\n }\r\n }, [divRef?.current])\r\n\r\n useEffect(() => {\r\n const getData = async (): Promise<void> => {\r\n const data: EmergencyTypes = await fetchEmergencyData(baseAddress)\r\n if (data) {\r\n setMunicipalPoliceNumber(data.municipalPoliceNumber)\r\n setLocalHospitalName(data.localHospitalName)\r\n setLocalHospitalNumber(data.localHospitalNumber)\r\n setPoisonControlNumber(data.poisonControlNumber)\r\n }\r\n setLoading(false)\r\n }\r\n getData()\r\n }, [baseAddress])\r\n\r\n return (\r\n <>\r\n <div className={`rf-flex rf-flex-col rf-items-center ${isMobile ? 'rf-justify-center rf-gap-2' : 'rf-justify-end rf-flex-[2_1_0%] rf-gap-9'}`}>\r\n <Icons.EmergencyIcon className='rf-h-9 rf-w-9 large:rf-h-16 large:rf-w-16' />\r\n <h3 className='rf-text-verylarge-size-auto rf-font-bold rf-text-center'>{capitalizeFirstLetter(translation.emergency.shorttitle, locale)}</h3>\r\n </div>\r\n <div\r\n ref={divRef}\r\n className='rf-w-full rf-flex rf-flex-col rf-items-center rf-flex-[4_1_0%] rf-justify-evenly rf-h-full rf-pt-2 rf-overflow-y-scroll rf-scrollbar-hidden'\r\n style={{\r\n background: isMobile ? 'transparent' : 'transparent linear-gradient(291deg, #F2F3F6 0%, #E5E6EC 100%) 0% 0% no-repeat padding-box',\r\n boxShadow: isMobile ? '' : '#ffff -3px -3px 16px, rgb(0 0 0 / 25%) 0px 2px 10px 0px'\r\n }}\r\n >\r\n {loading ? (\r\n <>\r\n <div className='rf-w-6 rf-h-6 rf-mb-16'>\r\n <Animation2 color='gray' loaderColor='#1999b1' backgroundColor='transparent' />\r\n </div>\r\n </>\r\n ) : (\r\n <>\r\n <div className={`rf-w-full rf-grid ${isMobile ? 'rf-grid-cols-2 rf-gap-8 rf-mt-10 rf-mb-8' : 'rf-grid-cols-4 rf-divide-x'} `} style={{ padding: isMobile ? '' : '0 10%' }}>\r\n <div className='rf-flex rf-flex-col rf-items-center rf-gap-2'>\r\n <p className='rf-text-xl rf-font-bold rf-uppercase'>{translation.emergency.samu}</p>\r\n <p className='rf-text-5xl large:rf-text-6xl rf-font-bold'>15</p>\r\n </div>\r\n <div className={`rf-flex rf-flex-col rf-items-center ${isMobile ? '' : 'rf-border-l rf-border-[#C7C6C6]'} rf-gap-2`}>\r\n <p className='rf-text-xl rf-font-bold rf-uppercase'>{translation.emergency.police}</p>\r\n <p className='rf-text-5xl large:rf-text-6xl rf-font-bold'>17</p>\r\n </div>\r\n <div className={`rf-flex rf-flex-col rf-items-center ${isMobile ? '' : 'rf-border-l rf-border-[#C7C6C6]'} rf-gap-2`}>\r\n <p className='rf-text-xl rf-font-bold rf-uppercase'>{translation.emergency.firefighter}</p>\r\n <p className='rf-text-5xl large:rf-text-6xl rf-font-bold'>18</p>\r\n </div>\r\n <div className={`rf-flex rf-flex-col rf-items-center ${isMobile ? '' : 'rf-border-l rf-border-[#C7C6C6]'} rf-gap-2`}>\r\n <p className='rf-text-xl rf-font-bold rf-uppercase'>{translation.emergency.general}</p>\r\n <p className='rf-text-5xl large:rf-text-6xl rf-font-bold'>112</p>\r\n </div>\r\n </div>\r\n <div className={`rf-flex rf-items-start ${isMobile ? 'rf-flex-col' : 'rf-gap-12'} `}>\r\n <div>\r\n {municipalPoliceNumber?.length && (\r\n <p className='rf-text-xl rf-py-2'>\r\n {`${translation.emergency.citypolice} : `}\r\n <span className='rf-font-bold'>{municipalPoliceNumber}</span>\r\n </p>\r\n )}\r\n <p className='rf-text-xl rf-py-2'>\r\n {`${translation.emergency.homeless} : `}\r\n <span className='rf-font-bold'>115</span>\r\n </p>\r\n <p className='rf-text-xl rf-py-2'>\r\n {`${translation.emergency.emergency} : `}\r\n <span className='rf-font-bold'>118</span>\r\n </p>\r\n </div>\r\n <div>\r\n {localHospitalName?.length && (\r\n <p className='rf-text-xl rf-py-2'>\r\n {`${translation.emergency.hospital} ${localHospitalName} : `}\r\n <span className='rf-font-bold'>{localHospitalNumber}</span>\r\n </p>\r\n )}\r\n {poisonControlNumber?.length && (\r\n <p className='rf-text-xl rf-py-2'>\r\n {`${translation.emergency.poison} : `}\r\n <span className='rf-font-bold'>{poisonControlNumber}</span>\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n {!isMobile && <div className='rf-flex-1' />}\r\n </>\r\n )\r\n}\r\n\r\nexport { EmergencyContent }\r\n","import { hospitalityApiAddress } from '../models/constants'\r\nimport { EmergencyTypes } from '../models/emergencyTypes'\r\n\r\nasync function fetchEmergencyData(address: string): Promise<EmergencyTypes> {\r\n const res = await fetch(`${address}${hospitalityApiAddress}`)\r\n .then((emergencyData) => {\r\n return emergencyData.json()\r\n })\r\n .catch(() => {\r\n return null\r\n })\r\n\r\n return res\r\n}\r\n\r\nexport { fetchEmergencyData }\r\n"],"names":[],"version":3,"file":"Emergency.d5810ff2.js.map","sourceRoot":"../"}
@@ -1 +0,0 @@
1
- {"mappings":"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","sources":["src/components/History/HistoryList.tsx","src/hooks/useMessageActivities.ts","src/components/History/HistoryItem.tsx","src/components/History/HistoryQA.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\n\r\nimport useMessageActivities from '../../hooks/useMessageActivities'\r\nimport { CurrentSubView, TemplateTarget } from '../../models/enums'\r\nimport preventEvents from '../../utils/preventEvents'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\n\r\nimport TemplateGlobal from '../Templates/TemplateGlobal'\r\nimport HistoryItem from './HistoryItem'\r\n\r\nconst HistoryList = (): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const isWidget = useSelector((state: RootState) => state.viewReducer.isWidget)\r\n const isBorne = useSelector((state: RootState) => state.viewReducer.isBorne)\r\n\r\n const activities = useMessageActivities()\r\n const scrollRef = useRef<HTMLDivElement>(null)\r\n const divRef = useRef<HTMLDivElement>(null)\r\n\r\n const scrollToRef = (): void => {\r\n if (scrollRef && scrollRef.current !== null) {\r\n scrollRef.current.scrollIntoView({\r\n behavior: 'smooth',\r\n block: 'nearest'\r\n })\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n setTimeout(() => {\r\n scrollToRef()\r\n }, 200)\r\n }, [])\r\n\r\n useEffect(() => {\r\n divRef?.current && isWidget && preventEvents(null, divRef)\r\n }, [divRef?.current])\r\n\r\n const handleClose = (): void => {\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindow', callback: () => dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindowHistory' })) }))\r\n }\r\n\r\n return (\r\n <TemplateGlobal onClick={handleClose} remote={true} target={TemplateTarget.history}>\r\n <div\r\n ref={divRef}\r\n className={`rf-h-full rf-flex rf-flex-col rf-pb-4 rf-px-4 large:rf-px-6 rf-overflow-y-scroll ${isBorne ? 'rf-mt-[25vh] rf-mb-[15vh] rf-scrollbar-thin' : 'rf-scrollbar-hidden'}`}\r\n >\r\n {/* Title */}\r\n <div className='rf-mb-6 rf-title-bold-size-auto'>{capitalizeFirstLetter(translation.history.title, locale)}</div>\r\n\r\n {/* History items */}\r\n {activities.map((activity, key) => {\r\n return <HistoryItem key={key} activity={activity} />\r\n })}\r\n <div ref={scrollRef} />\r\n </div>\r\n </TemplateGlobal>\r\n )\r\n}\r\n\r\nexport default HistoryList\r\n","import type { HistoryActivity, RetorikActivity } from '../models/activityTypes'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../store'\r\nimport { createNewQuestionForTimestamp } from '../utils/activityUtils'\r\n\r\nexport default function useMessageActivities(): Array<HistoryActivity> {\r\n const activities = useSelector((state: RootState) => state.activityReducer.messageActivities)\r\n // processedId contains the ids of the activities already processed (because useActivities gives duplicate activities with different state depending on if it's been spoken or not )\r\n const processedId: Array<string> = []\r\n const history: HistoryActivity[] = []\r\n\r\n activities.forEach((activity) => {\r\n if (activity.id && !processedId.includes(activity.id)) {\r\n processedId.push(activity.id)\r\n // Check if this is a question or an answer (questions from the user don't have a replyToId field)\r\n if (activity.replyToId) {\r\n const question: HistoryActivity | undefined = history.find((historyItem) => historyItem.question.id === activity.replyToId)\r\n if (question) {\r\n question.answers.push(activity)\r\n } else {\r\n const newQuestion: RetorikActivity = createNewQuestionForTimestamp(activity)\r\n\r\n history.push({\r\n question: newQuestion,\r\n answers: [activity]\r\n })\r\n }\r\n } else {\r\n if ((activity as RetorikActivity).label === 'Davi.BringupMessage' && (activity as RetorikActivity).text) {\r\n const newQuestion: RetorikActivity = createNewQuestionForTimestamp(activity)\r\n history.push({\r\n question: newQuestion,\r\n answers: [activity]\r\n })\r\n } else {\r\n history.push({\r\n question: activity,\r\n answers: []\r\n })\r\n }\r\n }\r\n }\r\n })\r\n\r\n return history\r\n}\r\n","import React from 'react'\r\nimport type { HistoryActivity } from '../../models/activityTypes'\r\nimport HistoryQA from './HistoryQA'\r\n\r\ninterface HistoryItemProps {\r\n activity: HistoryActivity\r\n}\r\n\r\nconst HistoryItem = ({ activity }: HistoryItemProps): JSX.Element => {\r\n return (\r\n <div className='rf-mb-4 rf-flex rf-flex-col rf-justify-start rf-items-start rf-gap-4 rf-text-size-auto'>\r\n {/* Question */}\r\n {activity?.question && activity.question.type === 'message' && (\r\n <HistoryQA activity={activity.question} isQuestion={true} />\r\n )}\r\n\r\n {/* Answers */}\r\n {activity.answers.map((answer, j) => {\r\n return answer.type === 'message' ? (\r\n <HistoryQA key={j} activity={answer} isQuestion={false} />\r\n ) : (\r\n <React.Fragment />\r\n )\r\n })}\r\n </div>\r\n )\r\n}\r\n\r\nexport default HistoryItem\r\n","import React from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\nimport type { RetorikActivity } from '../../models/activityTypes'\r\nimport { getTextWithoutSpeechMarkdown } from '../../utils/speechMarkdownUtils'\r\nimport Attachments from '../Attachments/Attachments'\r\n\r\ninterface HistoryQAProps {\r\n activity: RetorikActivity\r\n isQuestion: boolean\r\n}\r\n\r\nconst HistoryQA = ({ activity, isQuestion }: HistoryQAProps): JSX.Element => {\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const time = activity.localTimestamp ? new Date(activity.localTimestamp) : activity.timestamp ? new Date(activity.timestamp) : new Date()\r\n\r\n return activity.text || !!activity.attachments?.length ? (\r\n <div className='rf-w-full rf-flex rf-flex-col rf-gap-1'>\r\n {/* Time */}\r\n <div className='rf-text-[#9A9A9A]'>\r\n {time.toLocaleString(locale, {\r\n hour: 'numeric',\r\n minute: 'numeric'\r\n })}\r\n </div>\r\n\r\n {/* Question or Answer */}\r\n <div className={`${isQuestion ? 'rf-text-secondary' : 'rf-text-textModePanelConversationBot'}`}>\r\n {activity.htmlText ? (\r\n <div\r\n dangerouslySetInnerHTML={{\r\n __html: activity.htmlText\r\n }}\r\n />\r\n ) : activity.text ? (\r\n getTextWithoutSpeechMarkdown(activity.text)\r\n ) : (\r\n ''\r\n )}\r\n {/* Display attachments if there are some and the display mode wasn't a list */}\r\n {!!activity.attachments?.length && !(activity.attachmentLayout && activity.attachmentLayout.toLowerCase() === 'davilist') && (\r\n <div className={`rf-w-full rf-min-h-16 rf-overflow-x-hidden rf-overflow-y-auto ${activity.text && 'rf-pt-4'}`}>\r\n <Attachments activity={activity} history={true} />\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n ) : (\r\n <React.Fragment />\r\n )\r\n}\r\n\r\nexport default HistoryQA\r\n"],"names":[],"version":3,"file":"HistoryList.3b4b1ffb.js.map","sourceRoot":"../"}
@@ -1 +0,0 @@
1
- {"mappings":"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","sources":["src/components/History/HistoryList.tsx","src/hooks/useMessageActivities.ts","src/components/History/HistoryItem.tsx","src/components/History/HistoryQA.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\n\r\nimport useMessageActivities from '../../hooks/useMessageActivities'\r\nimport { CurrentSubView, TemplateTarget } from '../../models/enums'\r\nimport preventEvents from '../../utils/preventEvents'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\n\r\nimport TemplateGlobal from '../Templates/TemplateGlobal'\r\nimport HistoryItem from './HistoryItem'\r\n\r\nconst HistoryList = (): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const isWidget = useSelector((state: RootState) => state.viewReducer.isWidget)\r\n const isBorne = useSelector((state: RootState) => state.viewReducer.isBorne)\r\n\r\n const activities = useMessageActivities()\r\n const scrollRef = useRef<HTMLDivElement>(null)\r\n const divRef = useRef<HTMLDivElement>(null)\r\n\r\n const scrollToRef = (): void => {\r\n if (scrollRef && scrollRef.current !== null) {\r\n scrollRef.current.scrollIntoView({\r\n behavior: 'smooth',\r\n block: 'nearest'\r\n })\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n setTimeout(() => {\r\n scrollToRef()\r\n }, 200)\r\n }, [])\r\n\r\n useEffect(() => {\r\n divRef?.current && isWidget && preventEvents(null, divRef)\r\n }, [divRef?.current])\r\n\r\n const handleClose = (): void => {\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindow', callback: () => dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindowHistory' })) }))\r\n }\r\n\r\n return (\r\n <TemplateGlobal onClick={handleClose} remote={true} target={TemplateTarget.history}>\r\n <div\r\n ref={divRef}\r\n className={`rf-h-full rf-flex rf-flex-col rf-pb-4 rf-px-4 large:rf-px-6 rf-overflow-y-scroll ${isBorne ? 'rf-mt-[25vh] rf-mb-[15vh] rf-scrollbar-thin' : 'rf-scrollbar-hidden'}`}\r\n >\r\n {/* Title */}\r\n <div className='rf-mb-6 rf-title-bold-size-auto'>{capitalizeFirstLetter(translation.history.title, locale)}</div>\r\n\r\n {/* History items */}\r\n {activities.map((activity, key) => {\r\n return <HistoryItem key={key} activity={activity} />\r\n })}\r\n <div ref={scrollRef} />\r\n </div>\r\n </TemplateGlobal>\r\n )\r\n}\r\n\r\nexport default HistoryList\r\n","import type { HistoryActivity, RetorikActivity } from '../models/activityTypes'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../store'\r\nimport { createNewQuestionForTimestamp } from '../utils/activityUtils'\r\n\r\nexport default function useMessageActivities(): Array<HistoryActivity> {\r\n const activities = useSelector((state: RootState) => state.activityReducer.messageActivities)\r\n // processedId contains the ids of the activities already processed (because useActivities gives duplicate activities with different state depending on if it's been spoken or not )\r\n const processedId: Array<string> = []\r\n const history: HistoryActivity[] = []\r\n\r\n activities.forEach((activity) => {\r\n if (activity.id && !processedId.includes(activity.id)) {\r\n processedId.push(activity.id)\r\n // Check if this is a question or an answer (questions from the user don't have a replyToId field)\r\n if (activity.replyToId) {\r\n const question: HistoryActivity | undefined = history.find((historyItem) => historyItem.question.id === activity.replyToId)\r\n if (question) {\r\n question.answers.push(activity)\r\n } else {\r\n const newQuestion: RetorikActivity = createNewQuestionForTimestamp(activity)\r\n\r\n history.push({\r\n question: newQuestion,\r\n answers: [activity]\r\n })\r\n }\r\n } else {\r\n if ((activity as RetorikActivity).label === 'Davi.BringupMessage' && (activity as RetorikActivity).text) {\r\n const newQuestion: RetorikActivity = createNewQuestionForTimestamp(activity)\r\n history.push({\r\n question: newQuestion,\r\n answers: [activity]\r\n })\r\n } else {\r\n history.push({\r\n question: activity,\r\n answers: []\r\n })\r\n }\r\n }\r\n }\r\n })\r\n\r\n return history\r\n}\r\n","import React from 'react'\r\nimport type { HistoryActivity } from '../../models/activityTypes'\r\nimport HistoryQA from './HistoryQA'\r\n\r\ninterface HistoryItemProps {\r\n activity: HistoryActivity\r\n}\r\n\r\nconst HistoryItem = ({ activity }: HistoryItemProps): JSX.Element => {\r\n return (\r\n <div className='rf-mb-4 rf-flex rf-flex-col rf-justify-start rf-items-start rf-gap-4 rf-text-size-auto'>\r\n {/* Question */}\r\n {activity?.question && activity.question.type === 'message' && (\r\n <HistoryQA activity={activity.question} isQuestion={true} />\r\n )}\r\n\r\n {/* Answers */}\r\n {activity.answers.map((answer, j) => {\r\n return answer.type === 'message' ? (\r\n <HistoryQA key={j} activity={answer} isQuestion={false} />\r\n ) : (\r\n <React.Fragment />\r\n )\r\n })}\r\n </div>\r\n )\r\n}\r\n\r\nexport default HistoryItem\r\n","import React from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\nimport type { RetorikActivity } from '../../models/activityTypes'\r\nimport { getTextWithoutSpeechMarkdown } from '../../utils/speechMarkdownUtils'\r\nimport Attachments from '../Attachments/Attachments'\r\n\r\ninterface HistoryQAProps {\r\n activity: RetorikActivity\r\n isQuestion: boolean\r\n}\r\n\r\nconst HistoryQA = ({ activity, isQuestion }: HistoryQAProps): JSX.Element => {\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const time = activity.localTimestamp ? new Date(activity.localTimestamp) : activity.timestamp ? new Date(activity.timestamp) : new Date()\r\n\r\n return activity.text || !!activity.attachments?.length ? (\r\n <div className='rf-w-full rf-flex rf-flex-col rf-gap-1'>\r\n {/* Time */}\r\n <div className='rf-text-[#9A9A9A]'>\r\n {time.toLocaleString(locale, {\r\n hour: 'numeric',\r\n minute: 'numeric'\r\n })}\r\n </div>\r\n\r\n {/* Question or Answer */}\r\n <div className={`${isQuestion ? 'rf-text-secondary' : 'rf-text-textModePanelConversationBot'}`}>\r\n {activity.htmlText ? (\r\n <div\r\n dangerouslySetInnerHTML={{\r\n __html: activity.htmlText\r\n }}\r\n />\r\n ) : activity.text ? (\r\n getTextWithoutSpeechMarkdown(activity.text)\r\n ) : (\r\n ''\r\n )}\r\n {/* Display attachments if there are some and the display mode wasn't a list */}\r\n {!!activity.attachments?.length && !(activity.attachmentLayout && activity.attachmentLayout.toLowerCase() === 'davilist') && (\r\n <div className={`rf-w-full rf-min-h-16 rf-overflow-x-hidden rf-overflow-y-auto ${activity.text && 'rf-pt-4'}`}>\r\n <Attachments activity={activity} history={true} />\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n ) : (\r\n <React.Fragment />\r\n )\r\n}\r\n\r\nexport default HistoryQA\r\n"],"names":[],"version":3,"file":"HistoryList.e5c01f21.js.map"}
@@ -1 +0,0 @@
1
- {"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,MAAM,uCAAiB;IACrB,MAAM,WAAW,CAAA,GAAA,kBAAU;IAC3B,MAAM,SAAS,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,MAAM;IAC3E,MAAM,cAAc,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,mBAAmB;IAC7F,MAAM,YAAY,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,SAAS;IACjF,MAAM,cAAc,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,cAAc,CAAC,aAAa,CAAC,WAAW;IAEpG,MAAM,CAAC,iBAAiB,mBAAmB,GAAG,CAAA,GAAA,eAAO,EAAU;IAE/D,MAAM,cAAc,CAAC;QACnB,SAAS,CAAA,GAAA,mBAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA,GAAA,qBAAa,EAAE,IAAI;QAEjE,gHAAgH;QAChH,IAAI,CAAC,SACH,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;YAAE,MAAM;YAAoB,UAAU,IAAM,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;oBAAE,MAAM;gBAA4B;QAAI;IAE9K;IAEA,MAAM,eAAe,CAAC;QACpB,mBAAmB;IACrB;IAEA;;;;GAIC,GACD,MAAM,eAAe,CAAC;QACpB,MAAM,UAAU,aAAa;QAC7B,IAAI,SAAS;YACX,SAAS,CAAA,GAAA,mBAAW,EAAE,MAAM,CAAC,SAAS,CAAC;YACvC,CAAC,eACC,WAAW;gBACT,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;oBAAE,MAAM;gBAAiB;YACtE,GAAG;QACP;QAEA,YAAY;IACd;IAEA,qBACE,gBAAC,CAAA,GAAA,cAAa;QAAE,SAAS,IAAM,YAAY;QAAQ,QAAQ;QAAM,QAAQ,CAAA,GAAA,qBAAa,EAAE,SAAS;kBAC/F,cAAA,iBAAC;YAAI,WAAU;;8BAEb,gBAAC;oBAAI,WAAU;8BAAwC,CAAA,GAAA,4BAAoB,EAAE,YAAY,QAAQ,CAAC,MAAM,EAAE;;8BAG1G,gBAAC;oBAAI,WAAU;8BAAqC,CAAA,GAAA,4BAAoB,EAAE,YAAY,QAAQ,CAAC,MAAM,EAAE;;gBAGtG,UAAU,GAAG,CAAC,CAAC,UAAU;oBACxB,qBACE,gBAAC;wBAAc,WAAW,CAAC,qDAAqD,EAAE,QAAQ,KAAK,uBAAuB;kCACpH,cAAA,gBAAC,CAAA,GAAA,YAAI;4BAAE,OAAO,CAAA,GAAA,6CAAqB,CAAC,CAAC,SAAS;4BAAE,SAAS,aAAa;4BAAiB,cAAc,IAAY,aAAa;;uBADtH;gBAId;8BAGA,gBAAC;oBAAI,WAAU;8BACb,cAAA,gBAAC;wBAAO,WAAU;wBAA+F,SAAS,IAAY,aAAa;kCAChJ,CAAA,GAAA,4BAAoB,EAAE,YAAY,MAAM,CAAC,QAAQ,EAAE;;;;;;AAMhE;IAEA,2CAAe","sources":["src/components/Language/LanguageChoice.tsx"],"sourcesContent":["import React, { useState } from 'react'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\n\r\nimport languageInMotherTongue from '../../translations/languageCodeToMotherTongue.json'\r\nimport { CurrentSubView, TemplateTarget } from '../../models/enums'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\n\r\nimport TemplateGlobal from '../Templates/TemplateGlobal'\r\nimport { Radio } from '../Utils'\r\n\r\nconst LanguageChoice = (): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const supported = useSelector((state: RootState) => state.localeReducer.supported)\r\n const skipWelcome = useSelector((state: RootState) => state.retorikReducer.configuration.skipWelcome)\r\n\r\n const [currentLanguage, setCurrentLanguage] = useState<string>(locale)\r\n\r\n const handleClose = (changed?: boolean): void => {\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n\r\n // Only send events when language has not been changed, either way it will collide with the TriggerWelcome event\r\n if (!changed) {\r\n dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindow', callback: () => dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindowLanguages' })) }))\r\n }\r\n }\r\n\r\n const handleChange = (language: string): void => {\r\n setCurrentLanguage(language)\r\n }\r\n\r\n /**\r\n * Change current locale with the one selected if they are different.\r\n * Send a 'TriggerWelcome' event to get the welcome message in the new language.\r\n * @param language string\r\n */\r\n const handleSelect = (language: string): void => {\r\n const changed = language !== locale\r\n if (changed) {\r\n dispatch(storeActions.locale.setLocale(language))\r\n !skipWelcome &&\r\n setTimeout(() => {\r\n dispatch(storeActions.directline.sendEvent({ name: 'TriggerWelcome' }))\r\n }, 150)\r\n }\r\n\r\n handleClose(changed)\r\n }\r\n\r\n return (\r\n <TemplateGlobal onClick={() => handleClose(false)} remote={true} target={TemplateTarget.languages}>\r\n <div className='rf-h-full rf-flex rf-flex-col rf-justify-center rf-px-4 large:rf-px-6'>\r\n {/* Title */}\r\n <div className='rf-title-bold-size-auto rf-font-bold'>{capitalizeFirstLetter(translation.language.change, locale)}</div>\r\n\r\n {/* Subtitle */}\r\n <div className='rf-text-lightgray rf-pt-1 rf-pb-2'>{capitalizeFirstLetter(translation.language.select, locale)}</div>\r\n\r\n {/* Languages */}\r\n {supported.map((language, key) => {\r\n return (\r\n <div key={key} className={`rf-w-full rf-py-4 rf-border-t rf-border-t-menuBorder ${key === 0 && 'large:rf-border-t-0'}`}>\r\n <Radio title={languageInMotherTongue[language]} checked={language === currentLanguage} handleChange={(): void => handleChange(language)} />\r\n </div>\r\n )\r\n })}\r\n\r\n {/* Validation button */}\r\n <div className='rf-w-full rf-mt-8 rf-flex rf-justify-center'>\r\n <button className='rf-px-8 rf-py-3 rf-text-secondary rf-font-bold rf-border-2 rf-border-secondary rf-rounded-lg' onClick={(): void => handleSelect(currentLanguage)}>\r\n {capitalizeFirstLetter(translation.common.validate, locale)}\r\n </button>\r\n </div>\r\n </div>\r\n </TemplateGlobal>\r\n )\r\n}\r\n\r\nexport default LanguageChoice\r\n"],"names":[],"version":3,"file":"LanguageChoice.1d866cfa.js.map"}
@@ -1 +0,0 @@
1
- {"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,MAAM,uCAAiB;IACrB,MAAM,WAAW,CAAA,GAAA,6BAAU;IAC3B,MAAM,SAAS,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,MAAM;IAC3E,MAAM,cAAc,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,mBAAmB;IAC7F,MAAM,YAAY,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,SAAS;IACjF,MAAM,cAAc,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,cAAc,CAAC,aAAa,CAAC,WAAW;IAEpG,MAAM,CAAC,iBAAiB,mBAAmB,GAAG,CAAA,GAAA,qBAAO,EAAU;IAE/D,MAAM,cAAc,CAAC;QACnB,SAAS,CAAA,GAAA,mBAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA,GAAA,qBAAa,EAAE,IAAI;QAEjE,gHAAgH;QAChH,IAAI,CAAC,SACH,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;YAAE,MAAM;YAAoB,UAAU,IAAM,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;oBAAE,MAAM;gBAA4B;QAAI;IAE9K;IAEA,MAAM,eAAe,CAAC;QACpB,mBAAmB;IACrB;IAEA;;;;GAIC,GACD,MAAM,eAAe,CAAC;QACpB,MAAM,UAAU,aAAa;QAC7B,IAAI,SAAS;YACX,SAAS,CAAA,GAAA,mBAAW,EAAE,MAAM,CAAC,SAAS,CAAC;YACvC,CAAC,eACC,WAAW;gBACT,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;oBAAE,MAAM;gBAAiB;YACtE,GAAG;QACP;QAEA,YAAY;IACd;IAEA,qBACE,gCAAC,CAAA,GAAA,cAAa;QAAE,SAAS,IAAM,YAAY;QAAQ,QAAQ;QAAM,QAAQ,CAAA,GAAA,qBAAa,EAAE,SAAS;kBAC/F,cAAA,iCAAC;YAAI,WAAU;;8BAEb,gCAAC;oBAAI,WAAU;8BAAwC,CAAA,GAAA,4BAAoB,EAAE,YAAY,QAAQ,CAAC,MAAM,EAAE;;8BAG1G,gCAAC;oBAAI,WAAU;8BAAqC,CAAA,GAAA,4BAAoB,EAAE,YAAY,QAAQ,CAAC,MAAM,EAAE;;gBAGtG,UAAU,GAAG,CAAC,CAAC,UAAU;oBACxB,qBACE,gCAAC;wBAAc,WAAW,CAAC,qDAAqD,EAAE,QAAQ,KAAK,uBAAuB;kCACpH,cAAA,gCAAC,CAAA,GAAA,YAAI;4BAAE,OAAO,CAAA,GAAA,6CAAqB,CAAC,CAAC,SAAS;4BAAE,SAAS,aAAa;4BAAiB,cAAc,IAAY,aAAa;;uBADtH;gBAId;8BAGA,gCAAC;oBAAI,WAAU;8BACb,cAAA,gCAAC;wBAAO,WAAU;wBAA+F,SAAS,IAAY,aAAa;kCAChJ,CAAA,GAAA,4BAAoB,EAAE,YAAY,MAAM,CAAC,QAAQ,EAAE;;;;;;AAMhE;IAEA,2CAAe","sources":["src/components/Language/LanguageChoice.tsx"],"sourcesContent":["import React, { useState } from 'react'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\n\r\nimport languageInMotherTongue from '../../translations/languageCodeToMotherTongue.json'\r\nimport { CurrentSubView, TemplateTarget } from '../../models/enums'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\n\r\nimport TemplateGlobal from '../Templates/TemplateGlobal'\r\nimport { Radio } from '../Utils'\r\n\r\nconst LanguageChoice = (): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const supported = useSelector((state: RootState) => state.localeReducer.supported)\r\n const skipWelcome = useSelector((state: RootState) => state.retorikReducer.configuration.skipWelcome)\r\n\r\n const [currentLanguage, setCurrentLanguage] = useState<string>(locale)\r\n\r\n const handleClose = (changed?: boolean): void => {\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n\r\n // Only send events when language has not been changed, either way it will collide with the TriggerWelcome event\r\n if (!changed) {\r\n dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindow', callback: () => dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindowLanguages' })) }))\r\n }\r\n }\r\n\r\n const handleChange = (language: string): void => {\r\n setCurrentLanguage(language)\r\n }\r\n\r\n /**\r\n * Change current locale with the one selected if they are different.\r\n * Send a 'TriggerWelcome' event to get the welcome message in the new language.\r\n * @param language string\r\n */\r\n const handleSelect = (language: string): void => {\r\n const changed = language !== locale\r\n if (changed) {\r\n dispatch(storeActions.locale.setLocale(language))\r\n !skipWelcome &&\r\n setTimeout(() => {\r\n dispatch(storeActions.directline.sendEvent({ name: 'TriggerWelcome' }))\r\n }, 150)\r\n }\r\n\r\n handleClose(changed)\r\n }\r\n\r\n return (\r\n <TemplateGlobal onClick={() => handleClose(false)} remote={true} target={TemplateTarget.languages}>\r\n <div className='rf-h-full rf-flex rf-flex-col rf-justify-center rf-px-4 large:rf-px-6'>\r\n {/* Title */}\r\n <div className='rf-title-bold-size-auto rf-font-bold'>{capitalizeFirstLetter(translation.language.change, locale)}</div>\r\n\r\n {/* Subtitle */}\r\n <div className='rf-text-lightgray rf-pt-1 rf-pb-2'>{capitalizeFirstLetter(translation.language.select, locale)}</div>\r\n\r\n {/* Languages */}\r\n {supported.map((language, key) => {\r\n return (\r\n <div key={key} className={`rf-w-full rf-py-4 rf-border-t rf-border-t-menuBorder ${key === 0 && 'large:rf-border-t-0'}`}>\r\n <Radio title={languageInMotherTongue[language]} checked={language === currentLanguage} handleChange={(): void => handleChange(language)} />\r\n </div>\r\n )\r\n })}\r\n\r\n {/* Validation button */}\r\n <div className='rf-w-full rf-mt-8 rf-flex rf-justify-center'>\r\n <button className='rf-px-8 rf-py-3 rf-text-secondary rf-font-bold rf-border-2 rf-border-secondary rf-rounded-lg' onClick={(): void => handleSelect(currentLanguage)}>\r\n {capitalizeFirstLetter(translation.common.validate, locale)}\r\n </button>\r\n </div>\r\n </div>\r\n </TemplateGlobal>\r\n )\r\n}\r\n\r\nexport default LanguageChoice\r\n"],"names":[],"version":3,"file":"LanguageChoice.cce361a3.js.map","sourceRoot":"../"}
@@ -1 +0,0 @@
1
- {"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,MAAM,qCAAe;IACnB,MAAM,WAAW,CAAA,GAAA,6BAAU;IAC3B,MAAM,SAAS,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,MAAM;IAC3E,MAAM,cAAc,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,WAAW;IACrF,MAAM,WAAW,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,WAAW,CAAC,QAAQ;IAC7E,MAAM,mBAAmB,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,WAAW,CAAC,gBAAgB;IAC7F,MAAM,gBAAgB,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,cAAc,CAAC,aAAa,CAAC,aAAa;IACxG,MAAM,WAAW,CAAA,GAAA,6BAAU,EAAE,CAAC,QAAqB,MAAM,cAAc,CAAC,aAAa,CAAC,QAAQ;IAE9F,CAAA,GAAA,4BAAc,EAAE;QACd,IAAI,EAAC,qBAAA,+BAAA,SAAU,QAAQ,KAAI,EAAC,qBAAA,+BAAA,SAAU,SAAS,GAAE;YAC/C,SAAS,CAAA,GAAA,mBAAW,EAAE,OAAO,CAAC,oBAAoB,CAAC;YACnD,SAAS,CAAA,GAAA,mBAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA,GAAA,qBAAa,EAAE,IAAI;QACnE;IACF,GAAG;QAAC;KAAS;IAEb,MAAM,oBAAoB,CAAA,GAAA,oBAAM,EAAgC;QAC9D,IAAI,CAAA,qBAAA,+BAAA,SAAU,QAAQ,KAAI,SAAS,SAAS,EAC1C,OAAO;YAAC,qBAAA,+BAAA,SAAU,QAAQ;YAAE,SAAS,SAAS;SAAC;QAGjD,OAAO;IACT,GAAG;QAAC;KAAS;IAEb,MAAM,aAAa;QACjB,SACE,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;YAChC,MAAM;YACN,UAAU;gBACR,SAAS,CAAA,GAAA,mBAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA,GAAA,qBAAa,EAAE,IAAI;gBACjE,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;oBAAE,MAAM;gBAAsB;YAC3E;QACF;IAEJ;IAEA,qBACE,gCAAC,CAAA,GAAA,cAAa;QAAE,QAAQ,CAAA,GAAA,qBAAa,EAAE,GAAG;QAAE,SAAS;kBAClD,kCACC,iCAAC,CAAA,GAAA,sCAAI,EAAE,QAAQ;;8BACb,gCAAC,CAAA,GAAA,2BAAa;oBACZ,QAAQ;oBACR,UAAU;oBACV,eAAe,CAAC,CAAC;oBACjB,eAAe;oBACf,cAAc;oBACd,WAAW,iBAAiB,SAAS,IAAI;oBACzC,mBAAmB,iBAAiB,iBAAiB;oBACrD,UAAU,iBAAiB,QAAQ;oBACnC,aAAa,CAAC,MAA0B,QAAkC,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,WAAW,CAAC;4BAAE,MAAM;4BAAM,OAAO;wBAAM;oBAClJ,2BAA2B,CAAC,OAAS,SAAS,CAAA,GAAA,mBAAW,EAAE,KAAK,CAAC,yBAAyB,CAAC;;8BAI7F,gCAAC,CAAA,GAAA,cAAyB;oBAAE,kBAAkB;oBAAM,SAAS;;;2BAG/D,gCAAC,CAAA,GAAA,sCAAI,EAAE,QAAQ;;AAIvB;IAEA,2CAAe","sources":["src/components/Map/MapContainer.tsx"],"sourcesContent":["import React, { useLayoutEffect, useMemo } from 'react'\r\nimport { LatLngExpression } from 'leaflet'\r\nimport { Map as InteractiveMap } from '@davi-ai/retorik-map'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport { CurrentSubView, TemplateTarget } from '../../models/enums'\r\nimport TemplateGlobal from '../Templates/TemplateGlobal'\r\nimport AbsoluteLargeClosingButton from '../Utils/SubView/AbsoluteLargeClosingButton'\r\n\r\nconst MapContainer = (): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const baseAddress = useSelector((state: RootState) => state.localeReducer.baseAddress)\r\n const isWidget = useSelector((state: RootState) => state.viewReducer.isWidget)\r\n const mapConfiguration = useSelector((state: RootState) => state.viewReducer.mapConfiguration)\r\n const isUsedOnBorne = useSelector((state: RootState) => state.retorikReducer.configuration.isUsedOnBorne)\r\n const location = useSelector((state: RootState) => state.retorikReducer.configuration.position)\r\n\r\n useLayoutEffect(() => {\r\n if (!location?.latitude || !location?.longitude) {\r\n dispatch(storeActions.retorik.setShowPositionModal(true))\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n }\r\n }, [location])\r\n\r\n const processedLocation = useMemo<LatLngExpression | undefined>(() => {\r\n if (location?.latitude && location.longitude) {\r\n return [location?.latitude, location.longitude]\r\n }\r\n\r\n return undefined\r\n }, [location])\r\n\r\n const handleBack = (): void => {\r\n dispatch(\r\n storeActions.directline.sendEvent({\r\n name: 'Davi.CloseWindow',\r\n callback: () => {\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindowMap' }))\r\n }\r\n })\r\n )\r\n }\r\n\r\n return (\r\n <TemplateGlobal target={TemplateTarget.map} onClick={handleBack}>\r\n {processedLocation ? (\r\n <React.Fragment>\r\n <InteractiveMap\r\n locale={locale}\r\n isWidget={isWidget}\r\n isUsedOnBorne={!!isUsedOnBorne}\r\n tenantAddress={baseAddress}\r\n userLocation={processedLocation}\r\n mapCenter={mapConfiguration.mapCenter || processedLocation}\r\n limitAroundCenter={mapConfiguration.limitAroundCenter}\r\n settings={mapConfiguration.settings}\r\n sendMessage={(text: string | undefined, value: Record<string, string>) => dispatch(storeActions.directline.sendMessage({ text: text, value: value }))}\r\n setModalFullscreenContent={(data) => dispatch(storeActions.utils.setModalFullscreenContent(data))}\r\n />\r\n\r\n {/* Closing button */}\r\n <AbsoluteLargeClosingButton dashboardVisible={true} onClick={handleBack} />\r\n </React.Fragment>\r\n ) : (\r\n <React.Fragment />\r\n )}\r\n </TemplateGlobal>\r\n )\r\n}\r\n\r\nexport default MapContainer\r\n"],"names":[],"version":3,"file":"MapContainer.14c28128.js.map","sourceRoot":"../"}
@@ -1 +0,0 @@
1
- {"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,MAAM,qCAAe;IACnB,MAAM,WAAW,CAAA,GAAA,kBAAU;IAC3B,MAAM,SAAS,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,MAAM;IAC3E,MAAM,cAAc,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,aAAa,CAAC,WAAW;IACrF,MAAM,WAAW,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,WAAW,CAAC,QAAQ;IAC7E,MAAM,mBAAmB,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,WAAW,CAAC,gBAAgB;IAC7F,MAAM,gBAAgB,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,cAAc,CAAC,aAAa,CAAC,aAAa;IACxG,MAAM,WAAW,CAAA,GAAA,kBAAU,EAAE,CAAC,QAAqB,MAAM,cAAc,CAAC,aAAa,CAAC,QAAQ;IAE9F,CAAA,GAAA,sBAAc,EAAE;QACd,IAAI,CAAC,UAAU,YAAY,CAAC,UAAU,WAAW;YAC/C,SAAS,CAAA,GAAA,mBAAW,EAAE,OAAO,CAAC,oBAAoB,CAAC;YACnD,SAAS,CAAA,GAAA,mBAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA,GAAA,qBAAa,EAAE,IAAI;QACnE;IACF,GAAG;QAAC;KAAS;IAEb,MAAM,oBAAoB,CAAA,GAAA,cAAM,EAAgC;QAC9D,IAAI,UAAU,YAAY,SAAS,SAAS,EAC1C,OAAO;YAAC,UAAU;YAAU,SAAS,SAAS;SAAC;QAGjD,OAAO;IACT,GAAG;QAAC;KAAS;IAEb,MAAM,aAAa;QACjB,SACE,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;YAChC,MAAM;YACN,UAAU;gBACR,SAAS,CAAA,GAAA,mBAAW,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAA,GAAA,qBAAa,EAAE,IAAI;gBACjE,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,SAAS,CAAC;oBAAE,MAAM;gBAAsB;YAC3E;QACF;IAEJ;IAEA,qBACE,gBAAC,CAAA,GAAA,cAAa;QAAE,QAAQ,CAAA,GAAA,qBAAa,EAAE,GAAG;QAAE,SAAS;kBAClD,kCACC,iBAAC,CAAA,GAAA,YAAI,EAAE,QAAQ;;8BACb,gBAAC,CAAA,GAAA,UAAa;oBACZ,QAAQ;oBACR,UAAU;oBACV,eAAe,CAAC,CAAC;oBACjB,eAAe;oBACf,cAAc;oBACd,WAAW,iBAAiB,SAAS,IAAI;oBACzC,mBAAmB,iBAAiB,iBAAiB;oBACrD,UAAU,iBAAiB,QAAQ;oBACnC,aAAa,CAAC,MAA0B,QAAkC,SAAS,CAAA,GAAA,mBAAW,EAAE,UAAU,CAAC,WAAW,CAAC;4BAAE,MAAM;4BAAM,OAAO;wBAAM;oBAClJ,2BAA2B,CAAC,OAAS,SAAS,CAAA,GAAA,mBAAW,EAAE,KAAK,CAAC,yBAAyB,CAAC;;8BAI7F,gBAAC,CAAA,GAAA,cAAyB;oBAAE,kBAAkB;oBAAM,SAAS;;;2BAG/D,gBAAC,CAAA,GAAA,YAAI,EAAE,QAAQ;;AAIvB;IAEA,2CAAe","sources":["src/components/Map/MapContainer.tsx"],"sourcesContent":["import React, { useLayoutEffect, useMemo } from 'react'\r\nimport { LatLngExpression } from 'leaflet'\r\nimport { Map as InteractiveMap } from '@davi-ai/retorik-map'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport { CurrentSubView, TemplateTarget } from '../../models/enums'\r\nimport TemplateGlobal from '../Templates/TemplateGlobal'\r\nimport AbsoluteLargeClosingButton from '../Utils/SubView/AbsoluteLargeClosingButton'\r\n\r\nconst MapContainer = (): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const baseAddress = useSelector((state: RootState) => state.localeReducer.baseAddress)\r\n const isWidget = useSelector((state: RootState) => state.viewReducer.isWidget)\r\n const mapConfiguration = useSelector((state: RootState) => state.viewReducer.mapConfiguration)\r\n const isUsedOnBorne = useSelector((state: RootState) => state.retorikReducer.configuration.isUsedOnBorne)\r\n const location = useSelector((state: RootState) => state.retorikReducer.configuration.position)\r\n\r\n useLayoutEffect(() => {\r\n if (!location?.latitude || !location?.longitude) {\r\n dispatch(storeActions.retorik.setShowPositionModal(true))\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n }\r\n }, [location])\r\n\r\n const processedLocation = useMemo<LatLngExpression | undefined>(() => {\r\n if (location?.latitude && location.longitude) {\r\n return [location?.latitude, location.longitude]\r\n }\r\n\r\n return undefined\r\n }, [location])\r\n\r\n const handleBack = (): void => {\r\n dispatch(\r\n storeActions.directline.sendEvent({\r\n name: 'Davi.CloseWindow',\r\n callback: () => {\r\n dispatch(storeActions.utils.setCurrentSubView(CurrentSubView.none))\r\n dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindowMap' }))\r\n }\r\n })\r\n )\r\n }\r\n\r\n return (\r\n <TemplateGlobal target={TemplateTarget.map} onClick={handleBack}>\r\n {processedLocation ? (\r\n <React.Fragment>\r\n <InteractiveMap\r\n locale={locale}\r\n isWidget={isWidget}\r\n isUsedOnBorne={!!isUsedOnBorne}\r\n tenantAddress={baseAddress}\r\n userLocation={processedLocation}\r\n mapCenter={mapConfiguration.mapCenter || processedLocation}\r\n limitAroundCenter={mapConfiguration.limitAroundCenter}\r\n settings={mapConfiguration.settings}\r\n sendMessage={(text: string | undefined, value: Record<string, string>) => dispatch(storeActions.directline.sendMessage({ text: text, value: value }))}\r\n setModalFullscreenContent={(data) => dispatch(storeActions.utils.setModalFullscreenContent(data))}\r\n />\r\n\r\n {/* Closing button */}\r\n <AbsoluteLargeClosingButton dashboardVisible={true} onClick={handleBack} />\r\n </React.Fragment>\r\n ) : (\r\n <React.Fragment />\r\n )}\r\n </TemplateGlobal>\r\n )\r\n}\r\n\r\nexport default MapContainer\r\n"],"names":[],"version":3,"file":"MapContainer.f22ad81f.js.map"}
@@ -1 +0,0 @@
1
- {"mappings":"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","sources":["src/components/News/NewsContainer.tsx","src/components/News/Time.tsx","src/components/News/News.tsx","src/hooks/useNews.tsx","src/components/News/Banner.tsx","src/components/News/BannerTopMobile.tsx","src/components/News/BannerTopLarge.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react'\r\nimport { useDispatch, useSelector } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\n\r\nimport type { NewsConfig } from '../../models/types'\r\nimport { Routes } from '../../models/enums'\r\n\r\nimport Background from '../Common/Background'\r\nimport Time from '../News/Time'\r\nimport News from '../News/News'\r\nimport Weather from '../Weather/Weather'\r\nimport AbsoluteLargeClosingButton from '../Utils/SubView/AbsoluteLargeClosingButton'\r\nimport CloseButton from '../Common/CloseButton'\r\nimport MenuDisplayer from '../Menus/MenuDisplayer'\r\nimport { BackButton } from '../Menu/Common'\r\n\r\ninterface NewsContainerProps {\r\n hideMenu?: boolean\r\n isRetorikNews?: boolean\r\n loop?: boolean\r\n fromVeille?: boolean\r\n handleEndedWithoutloop?: () => void\r\n}\r\n\r\n// Steps enum\r\nenum Steps {\r\n opening = 1,\r\n news,\r\n events,\r\n weather,\r\n ending\r\n}\r\n\r\nconst NewsContainer = ({ hideMenu, isRetorikNews, loop, fromVeille, handleEndedWithoutloop }: NewsContainerProps): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const configuration = useSelector((state: RootState) => state.retorikReducer.configuration)\r\n const displaySubtitles = useSelector((state: RootState) => state.retorikReducer.displaySubtitles)\r\n const muted = useSelector((state: RootState) => state.speechReducer.muted)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n const isLandscape = useSelector((state: RootState) => state.viewReducer.isLandscape)\r\n const isBorne = useSelector((state: RootState) => state.viewReducer.isBorne)\r\n const configurations = useSelector((state: RootState) => state.viewReducer.configurations)\r\n const conversationId = useSelector((state: RootState) => state.activityReducer.conversationId)\r\n const storedConversationData = useSelector((state: RootState) => state.directlineReducer.storedVeilleConversationData)\r\n\r\n const [displayData, setDisplayData] = useState<NewsConfig>(configurations.views.news || configurations.views.home)\r\n const [step, setStep] = useState<number>(configurations.views.news?.openingVideo ? Steps.opening : Steps.news)\r\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n const newsEndedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n const oldDiplaySubtitles = useRef<boolean>(displaySubtitles)\r\n\r\n /**\r\n * On call :\r\n * - if the component is news-only, return\r\n * - else set ViewContext's route state to 'home'\r\n */\r\n const handleBack = (): void => {\r\n if (isRetorikNews) {\r\n return\r\n }\r\n dispatch(storeActions.view.setRoute(Routes.Home))\r\n }\r\n\r\n useEffect(() => {\r\n configuration.useOldRemote && dispatch(storeActions.view.setDisplayControls(false))\r\n // Force muted state to false if we are not in the veille\r\n muted && !fromVeille && dispatch(storeActions.speech.setMuted(false))\r\n // Force hiding subtitles if we are in the veille\r\n fromVeille && dispatch(storeActions.retorik.setDisplaySubtitles(false))\r\n\r\n return () => {\r\n // If we exit news from the veille, let's store the conversation id for next turn, clear activity store and set back subtitles\r\n if (fromVeille) {\r\n !storedConversationData?.id && conversationId && dispatch(storeActions.directline.setStoredVeilleConversationData(conversationId))\r\n dispatch(storeActions.activity.resetActivityStore())\r\n dispatch(storeActions.retorik.setDisplaySubtitles(oldDiplaySubtitles.current))\r\n }\r\n // Send closing events unless we are using RetorikNews component\r\n if (!isRetorikNews) {\r\n dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindow', callback: () => dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindowNews' })) }))\r\n }\r\n }\r\n }, [])\r\n\r\n /**\r\n * On step change :\r\n * - switch on the current step to launch corresponding processing\r\n * On component unmount :\r\n * - clear timerRef timeout\r\n */\r\n useEffect(() => {\r\n switch (step) {\r\n case Steps.opening: {\r\n dispatch(storeActions.retorik.setDisplayAgentInNews(false))\r\n const videoUrl = configurations.views.news?.openingVideo\r\n videoUrl && !fromVeille ? setViewContextCurrentConfiguration(videoUrl as string) : setStep(Steps.news)\r\n break\r\n }\r\n case Steps.news:\r\n dispatch(storeActions.retorik.setDisplayAgentInNews(true))\r\n setDisplayData(configurations.views.news || configurations.views.home)\r\n break\r\n case Steps.events:\r\n break\r\n case Steps.weather:\r\n dispatch(storeActions.retorik.setDisplayAgentInNews(false))\r\n // If the position is known, display the weather page during 10 seconds, otherwise switch to the next step directly\r\n configuration.position?.latitude && configuration.position?.longitude\r\n ? (timerRef.current = setTimeout(() => {\r\n setStep(Steps.ending)\r\n }, 10000))\r\n : setStep(Steps.ending)\r\n break\r\n case Steps.ending: {\r\n dispatch(storeActions.retorik.setDisplayAgentInNews(false))\r\n const videoUrl = configurations.views.news?.openingVideo\r\n videoUrl && !fromVeille ? setViewContextCurrentConfiguration(videoUrl as string) : exitNewsOrLoop()\r\n break\r\n }\r\n default:\r\n break\r\n }\r\n\r\n return (): void => {\r\n timerRef?.current && clearTimeout(timerRef.current)\r\n newsEndedTimerRef?.current && clearTimeout(newsEndedTimerRef.current)\r\n }\r\n }, [step])\r\n\r\n /**\r\n * On call :\r\n * - set the current display configuration to have the given video as background\r\n * @param videoUrl\r\n */\r\n const setViewContextCurrentConfiguration = (videoUrl: string): void => {\r\n setDisplayData({\r\n ...configurations.views.news,\r\n background: {\r\n video: videoUrl,\r\n style: 'video'\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * On call :\r\n * - if the component is news-only :\r\n * + if 'loop' is explicitly set to false, call props' handleEndedWithoutloop method if defined. Call handleBack method otherwise\r\n * + if 'loop' is not false, loop by setting step state to Steps.news\r\n * - or else if 'loop' parameter in configuration is true, get back to Steps.news step. Call handleBack method otherwise\r\n */\r\n const exitNewsOrLoop = (): void => {\r\n // Relaunch from the start if this is a news-only component and loop hasn't explicitly been set to false\r\n if (isRetorikNews) {\r\n if (fromVeille) {\r\n loop ? setStep(Steps.news) : handleEndedWithoutloop?.()\r\n } else {\r\n displayData.loop !== false || loop ? setStep(Steps.news) : handleEndedWithoutloop ? handleEndedWithoutloop() : handleBack()\r\n }\r\n } else {\r\n // Relaunch from the start if the loop is activated, otherwise get back to homepage\r\n displayData.loop || loop ? setStep(Steps.news) : handleBack()\r\n }\r\n }\r\n\r\n /**\r\n * On video end :\r\n * - if we are at the opening step, let's set the step state to Steps.news to launch the news\r\n * - if we are at the ending step, call exitNewsOrLoop function\r\n */\r\n const handleVideoEnd = (): void => {\r\n switch (step) {\r\n case Steps.opening:\r\n setStep(Steps.news)\r\n break\r\n case Steps.ending:\r\n exitNewsOrLoop()\r\n break\r\n }\r\n }\r\n\r\n /**\r\n * On news end :\r\n * - wait 3 seconds\r\n * - get to the next step (Steps.events)\r\n */\r\n const handleNewsEnd = (): void => {\r\n newsEndedTimerRef &&\r\n (newsEndedTimerRef.current = setTimeout(() => {\r\n // setStep(Steps.events)\r\n setStep(Steps.weather)\r\n }, 3000))\r\n }\r\n\r\n return (\r\n <div className='rf-relative rf-col-start-1 rf-col-span-full rf-row-start-1 rf-row-span-full rf-grid rf-grid-cols-8 rf-grid-rows-12'>\r\n <Background config={displayData.background} videoLoop={false} videoMuted={true} onVideoEnded={handleVideoEnd} />\r\n\r\n {/* Timer + back button in mobile / widget mode */}\r\n {isMobile && !isRetorikNews && !hideMenu ? (\r\n <div className='rf-relative rf-z-util rf-col-start-1 rf-col-span-full rf-row-start-1 rf-flex rf-flex-col rf-gap-2 rf-items-start'>\r\n <BackButton title={translation.common.back} handleBack={handleBack} className='rf-pr-2 rf-mt-4 rf-ml-4 rf-text-size-auto rf-bg-truewhite rf-rounded-lg' />\r\n <Time belowReturnButton={true} />\r\n </div>\r\n ) : (\r\n <Time />\r\n )}\r\n\r\n {/* News step */}\r\n {step === Steps.news && <News intervalInSeconds={displayData.intervalInSeconds ? (displayData.intervalInSeconds as number) : undefined} onEnd={handleNewsEnd} isRetorikNews={isRetorikNews} />}\r\n\r\n {step === Steps.weather && configuration.position?.latitude && configuration.position?.longitude && <Weather handleClose={handleBack} />}\r\n\r\n {/* Closing button if it needs to be displayed */}\r\n {!hideMenu && <AbsoluteLargeClosingButton dashboardVisible={true} onClick={handleBack} />}\r\n\r\n {!hideMenu && isLandscape && !configuration.useOldRemote && !isRetorikNews && <CloseButton onClick={handleBack} showLabel={true} />}\r\n\r\n {!hideMenu && isBorne && !configuration.useOldRemote && !isRetorikNews && <MenuDisplayer hideMenu={configuration?.hideMenu} />}\r\n </div>\r\n )\r\n}\r\n\r\nexport default NewsContainer\r\n","import React, { useEffect, useState, useRef } from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\n\r\ninterface TimeProps {\r\n belowReturnButton?: boolean\r\n}\r\n\r\nconst Time = ({ belowReturnButton }: TimeProps): JSX.Element => {\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const [time, setTime] = useState<string>('')\r\n const timerRef: React.MutableRefObject<any> = useRef(null)\r\n\r\n /**\r\n * Set current time (hours and minutes) depending on the locale (ex: adds AM/PM when needed)\r\n */\r\n const setCurrentTime = (): void => {\r\n const now = new Date()\r\n setTime(\r\n now.toLocaleTimeString(locale, {\r\n hour: '2-digit',\r\n minute: '2-digit'\r\n })\r\n )\r\n }\r\n\r\n /**\r\n * On component mount :\r\n * - set time\r\n * - set interval for time update\r\n * On component unmount :\r\n * - clear interval\r\n */\r\n useEffect(() => {\r\n setCurrentTime()\r\n timerRef && (timerRef.current = setInterval(setCurrentTime, 1000))\r\n\r\n return (): void => timerRef && clearInterval(timerRef.current)\r\n }, [])\r\n\r\n return (\r\n <div className={`rf-relative ${belowReturnButton ? 'rf-ml-4' : 'rf-col-start-1 rf-col-span-2 rf-row-start-1 rf-row-span-2 rf-self-start rf-justify-self-start rf-m-4 large:rf-m-8'}`}>\r\n <div className='rf-w-fit rf-h-fit rf-flex rf-flex-col rf-justify-start rf-items-start rf-text-white'>\r\n {/* Text 'Live' + round */}\r\n <div className='rf-w-full rf-text-size-auto rf-px-3 rf-py-0 large:rf-px-4 large:rf-py-1 rf-text-center rf-font-semibold rf-bg-red-600 rf-whitespace-nowrap'>\r\n {`${translation.news.live.toLocaleUpperCase(locale)} \\u25cf`}\r\n </div>\r\n {/* Time */}\r\n <div className='rf-w-full rf-title-size-auto rf-px-3 rf-py-0 large:rf-px-4 large:rf-py-1 rf-text-center rf-font-bold rf-bg-blue-500'>{time}</div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport default Time\r\n","import React, { useEffect, useMemo, useState, useRef } from 'react'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport useNews from '../../hooks/useNews'\r\n\r\nimport type { Image, Media } from '../../models/attachmentTypes'\r\nimport { RetorikActivity } from '../../models/activityTypes'\r\nimport { DeviceType, Routes } from '../../models/enums'\r\n\r\nimport Banner from './Banner'\r\nimport { Carousel } from '../Utils'\r\n\r\ntype NewsProps = {\r\n intervalInSeconds?: number\r\n onEnd: () => void\r\n isRetorikNews?: boolean\r\n}\r\n\r\nconst News = ({ intervalInSeconds = 3, onEnd, isRetorikNews }: NewsProps): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const { newsAttachments, activity } = useNews()\r\n const route = useSelector((state: RootState) => state.viewReducer.route)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n const newsConfiguration = useSelector((state: RootState) => state.viewReducer.configurations.views.news)\r\n const currentDeviceType = useSelector((state: RootState) => state.viewReducer.currentDeviceType)\r\n const retorikNewsEnded = useSelector((state: RootState) => state.utilsReducer.retorikNewsEnded)\r\n\r\n const [carouselGridRowStart, setCarouselGridRowStart] = useState<number>()\r\n const [carouselGridRowSpan, setCarouselGridRowSpan] = useState<number>()\r\n const [bannerGridRowStart, setBannerGridRowStart] = useState<number>(10)\r\n const [bannerGridRowSpan, setBannerGridRowSpan] = useState<number>(3)\r\n // Banner's align-self is flex-end if the position of the banner hasn't been changed, flex-start in borne / landscape modes otherwise\r\n const [alignSelfEnd, setAlignSelfEnd] = useState<boolean>(true)\r\n const [current, setCurrent] = useState<number>(0)\r\n const timerRef = useRef<NodeJS.Timer | null>(null)\r\n\r\n const news = useMemo(() => {\r\n return newsAttachments.map((newsAttachement) => newsAttachement.content)\r\n }, [newsAttachments])\r\n\r\n useEffect(() => {\r\n if (!newsAttachments.length) {\r\n setTimeout(() => {\r\n dispatch(storeActions.directline.sendEvent({ name: 'news.getAllNews' }))\r\n }, 2000)\r\n }\r\n\r\n return (): void => {\r\n timerRef.current && clearTimeout(timerRef.current)\r\n }\r\n }, [])\r\n\r\n useEffect(() => {\r\n switch (currentDeviceType) {\r\n case DeviceType.mobile:\r\n case DeviceType.widget: {\r\n // Set carousel's and banner's positions\r\n setAlignSelfEnd(true)\r\n setCarouselGridRowStart(1)\r\n setCarouselGridRowSpan(9)\r\n setBannerGridRowStart(10)\r\n setBannerGridRowSpan(3)\r\n break\r\n }\r\n case DeviceType.landscape:\r\n case DeviceType.widgetLandscape: {\r\n // Check banner's position and set carousel's position if there are no position data for this one\r\n if (newsConfiguration?.bannerPosition?.landscape) {\r\n const start = newsConfiguration.bannerPosition.landscape.containerRowStart || 10\r\n const end = newsConfiguration.bannerPosition.landscape.containerRowEnd || 13\r\n\r\n setAlignSelfEnd(false)\r\n setBannerGridRowStart(start)\r\n setBannerGridRowSpan(end - start)\r\n\r\n if (!newsConfiguration?.mediaPosition?.landscape) {\r\n // The base row span of the carousel is 9, if the custom position of the banner allows this span, let's keep it. If not, let's use the max span available.\r\n if (start > 9) {\r\n setCarouselGridRowStart(start - 9)\r\n setCarouselGridRowSpan(9)\r\n } else {\r\n setCarouselGridRowStart(1)\r\n setCarouselGridRowSpan(start - 1)\r\n }\r\n\r\n break\r\n }\r\n } else {\r\n setAlignSelfEnd(true)\r\n setBannerGridRowStart(10)\r\n setBannerGridRowSpan(3)\r\n }\r\n\r\n // Check carousel's position\r\n if (newsConfiguration?.mediaPosition?.landscape) {\r\n const start = newsConfiguration.mediaPosition.landscape.containerRowStart || 1\r\n const end = newsConfiguration.mediaPosition.landscape.containerRowEnd || 10\r\n\r\n setCarouselGridRowStart(start)\r\n setCarouselGridRowStart(end - start)\r\n } else {\r\n setCarouselGridRowStart(1)\r\n setCarouselGridRowSpan(9)\r\n }\r\n\r\n break\r\n }\r\n case DeviceType.borne:\r\n case DeviceType.widgetBorne: {\r\n // Check banner's position and set carousel's position if there are no position data for this one\r\n if (newsConfiguration?.bannerPosition?.borne) {\r\n const start = newsConfiguration.bannerPosition.borne.containerRowStart || 10\r\n const end = newsConfiguration.bannerPosition.borne.containerRowEnd || 13\r\n\r\n setAlignSelfEnd(false)\r\n setBannerGridRowStart(start)\r\n setBannerGridRowSpan(end - start)\r\n\r\n if (!newsConfiguration?.mediaPosition?.borne) {\r\n // The base row span of the carousel is 4, if the custom position of the banner allows this span, let's keep it. If not, let's use the max span available.\r\n if (start > 4) {\r\n setCarouselGridRowStart(start - 4)\r\n setCarouselGridRowSpan(4)\r\n } else {\r\n setCarouselGridRowStart(1)\r\n setCarouselGridRowSpan(start - 1)\r\n }\r\n\r\n break\r\n }\r\n } else {\r\n setAlignSelfEnd(true)\r\n setBannerGridRowStart(10)\r\n setBannerGridRowSpan(3)\r\n }\r\n\r\n // Check carousel's position\r\n if (newsConfiguration?.mediaPosition?.borne) {\r\n const start = newsConfiguration.mediaPosition.borne.containerRowStart || 7\r\n const end = newsConfiguration.mediaPosition.borne.containerRowEnd || 11\r\n\r\n setCarouselGridRowStart(start)\r\n setCarouselGridRowSpan(end - start)\r\n } else {\r\n setCarouselGridRowStart(7)\r\n setCarouselGridRowSpan(4)\r\n }\r\n break\r\n }\r\n }\r\n }, [newsConfiguration, currentDeviceType])\r\n\r\n useEffect(() => {\r\n const currentNew = news[current]\r\n if (currentNew) {\r\n const textTitle = newsConfiguration?.removeTitleFromTextToSpeak ? '' : `${currentNew.title}, <break/> `\r\n const textSubtitle = newsConfiguration?.removeSubtitleFromTextToSpeak ? '' : `${currentNew.subtitle}: <break/> `\r\n\r\n const tempActivity: RetorikActivity = {\r\n ...activity,\r\n speak: `${textTitle}${textSubtitle}${currentNew.text}`\r\n } as RetorikActivity\r\n\r\n dispatch(storeActions.speech.addToStreamingQueue(tempActivity))\r\n }\r\n }, [activity, current])\r\n\r\n const currentMedia = useMemo<Array<Image | Media>>(() => {\r\n const currentNew = news[current]\r\n if (currentNew) {\r\n if (currentNew.media?.length) {\r\n return currentNew.media\r\n } else if (currentNew.image?.url) {\r\n return [currentNew.image]\r\n }\r\n }\r\n\r\n return []\r\n }, [news, current])\r\n\r\n useEffect(() => {\r\n if (retorikNewsEnded) {\r\n if (news.length) {\r\n if (current < news.length - 1) {\r\n const delay = current < news.length - 1 ? intervalInSeconds : intervalInSeconds * 3\r\n timerRef.current && clearTimeout(timerRef.current)\r\n if (route === Routes.News || isRetorikNews) {\r\n timerRef.current = setTimeout(next, delay * 1000)\r\n }\r\n } else {\r\n onEnd()\r\n }\r\n }\r\n\r\n dispatch(storeActions.utils.setRetorikNewsEnded(false))\r\n }\r\n }, [retorikNewsEnded])\r\n\r\n const next = (): void => {\r\n const next = (current + 1) % news.length\r\n changeNews(next)\r\n }\r\n\r\n const changeNews = (next: number): void => {\r\n setCurrent(next)\r\n }\r\n\r\n return news.length && current >= 0 ? (\r\n <React.Fragment>\r\n {/* Carousel in landscape / borne display */}\r\n {!isMobile && (\r\n <div\r\n className='rf-relative rf-col-start-5 rf-col-span-3 large-vertical:rf-col-start-2 large-vertical:rf-col-end-8 rf-flex rf-justify-center rf-items-center'\r\n style={{\r\n gridRow: `${carouselGridRowStart} / span ${carouselGridRowSpan}`\r\n }}\r\n >\r\n {currentMedia.length ? (\r\n <Carousel className='rf-z-[10] rf-max-h-4/5 large-vertical:rf-max-h-11/12 rf-max-w-full' medias={news[current].media || [news[current].image || { url: '' }]} />\r\n ) : (\r\n <React.Fragment />\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Lower banner with title / subtitle / text */}\r\n <Banner news={news[current]} gridRowStart={bannerGridRowStart} gridRowSpan={bannerGridRowSpan} alignSelfEnd={alignSelfEnd} />\r\n </React.Fragment>\r\n ) : (\r\n <React.Fragment />\r\n )\r\n}\r\n\r\nexport default News\r\n","import { CONTENT_TYPE_NEWS, NewsContent } from '../models/attachmentTypes'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../store'\r\nimport type { RetorikActivity } from '../models/activityTypes'\r\n\r\ntype NewsAttachment = {\r\n contentType: string\r\n content: NewsContent\r\n}\r\n\r\nconst useNews = (): {\r\n newsAttachments: Array<NewsAttachment>\r\n activity?: RetorikActivity\r\n} => {\r\n const activities = useSelector((state: RootState) => state.activityReducer.botEventActivities)\r\n\r\n if (!activities.length) {\r\n return { newsAttachments: [] }\r\n }\r\n\r\n // Filter messages that can income during news, with label = Davi.BringupMessage\r\n const filterBringUpActivities = activities.filter((act: any) => act.label !== 'Davi.BringupMessage')\r\n\r\n const activity = filterBringUpActivities[filterBringUpActivities.length - 1] as any\r\n\r\n if (!activity || !activity.attachments?.length) {\r\n return { newsAttachments: [], activity }\r\n }\r\n\r\n const newsAttachments: NewsAttachment[] = []\r\n activity.attachments.forEach((attachment) => {\r\n if (attachment.contentType === CONTENT_TYPE_NEWS) {\r\n newsAttachments.push({\r\n contentType: CONTENT_TYPE_NEWS,\r\n content: attachment.content || ''\r\n })\r\n }\r\n })\r\n\r\n return { newsAttachments, activity }\r\n}\r\n\r\nexport default useNews\r\n","import React, { useEffect, useMemo, useRef, useState } from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\nimport type { NewsContent } from '../../models/attachmentTypes'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\nimport BannerTopMobile from './BannerTopMobile'\r\nimport BannerTopLarge from './BannerTopLarge'\r\n\r\ninterface BannerProps {\r\n news: NewsContent\r\n gridRowStart: number\r\n gridRowSpan: number\r\n alignSelfEnd: boolean\r\n}\r\n\r\nconst Banner = ({ news, gridRowStart, gridRowSpan, alignSelfEnd }: BannerProps): JSX.Element => {\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const locale = useSelector((state: RootState) => state.localeReducer.localeForRetorikStudioContent)\r\n const localizedBannerTitle = useSelector((state: RootState) => state.localeReducer.localizedBannerTitle)\r\n const isRTL = useSelector((state: RootState) => state.localeReducer.isRTL)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n const currentWidth = useSelector((state: RootState) => state.viewReducer.currentWidth)\r\n const newsConfiguration = useSelector((state: RootState) => state.viewReducer.configurations.views.news)\r\n\r\n const timerRef: React.MutableRefObject<any> = useRef(null)\r\n const [scrollDuration, setScrollDuration] = useState<number>(0)\r\n\r\n const category = useMemo<string>(() => {\r\n return news.category || newsConfiguration?.bannerTitleLocalized?.[locale] || localizedBannerTitle || newsConfiguration?.bannerTitle || translation.news.continuous\r\n }, [news, newsConfiguration, locale, localizedBannerTitle, translation])\r\n\r\n /**\r\n * Set animation for text horizontal scrolling if necessary\r\n */\r\n const updateDuration = (): void => {\r\n // Reset animation\r\n setScrollDuration(0)\r\n // Set animation, after a 1s timeout\r\n timerRef &&\r\n (timerRef.current = setTimeout(() => {\r\n setScrollDuration(Math.floor(news.text.length / 11))\r\n }, 1000))\r\n }\r\n\r\n /**\r\n * On news props change :\r\n * - call updateDuration function\r\n * On component unmount :\r\n * - clear timeout\r\n */\r\n useEffect(() => {\r\n updateDuration()\r\n\r\n return (): void => timerRef && clearTimeout(timerRef.current)\r\n }, [news])\r\n\r\n return (\r\n <div\r\n dir={isRTL ? 'rtl' : 'ltr'}\r\n className='rf-h-fit rf-z-util rf-col-start-1 rf-col-span-full large:rf-mb-6 rf-flex rf-flex-col rf-items-center rf-glass-background rf-text-white'\r\n style={{\r\n alignSelf: alignSelfEnd ? 'flex-end' : 'flex-start',\r\n gridRow: `${gridRowStart} / span ${gridRowSpan}`\r\n }}\r\n >\r\n {/* Category + Image (mobile) + Title + Subtitle */}\r\n {isMobile ? (\r\n <BannerTopMobile category={category} title={news.title} subtitle={news.subtitle} url={news.image?.url} />\r\n ) : (\r\n <BannerTopLarge category={category} title={news.title} subtitle={news.subtitle} />\r\n )}\r\n\r\n {/* Text */}\r\n <div\r\n dir='ltr'\r\n className='rf-w-full rf-pr-4 rf-py-2 large:rf-py-4 rf-subtitle-size-auto rf-text-black rf-bg-white rf-overflow-clip'\r\n style={{\r\n paddingLeft: currentWidth\r\n }}\r\n >\r\n {scrollDuration !== 0 ? (\r\n <p\r\n className='rf-w-max rf-whitespace-nowrap rf-animate-hScroll'\r\n style={{\r\n animation: `rf-hScroll ${scrollDuration}s infinite linear`,\r\n paddingRight: currentWidth\r\n }}\r\n >\r\n {news.text ? capitalizeFirstLetter(news.text) : '...'}\r\n </p>\r\n ) : (\r\n <p className='rf-w-max rf-whitespace-nowrap'>{news.text ? capitalizeFirstLetter(news.text) : '...'}</p>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport default Banner\r\n","import React from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\n\r\ninterface BannerTopMobileProps {\r\n category: string\r\n title?: string\r\n subtitle?: string\r\n url?: string\r\n}\r\n\r\nconst BannerTopMobile = ({ category, title, subtitle, url }: BannerTopMobileProps): JSX.Element => {\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n\r\n return (\r\n <React.Fragment>\r\n <div className='rf-w-full rf-px-4 rf-py-2 rf-font-bold rf-bg-red-600 rf-whitespace-nowrap rf-text-size-auto'>{category?.toLocaleUpperCase(locale)}</div>\r\n\r\n <div className='rf-w-full rf-flex rf-flex-row'>\r\n {/* Image */}\r\n {url && (\r\n <div\r\n className='rf-aspect-video rf-w-1/4'\r\n style={{\r\n backgroundImage: `url(${url})`,\r\n backgroundSize: 'cover',\r\n backgroundRepeat: 'no-repeat',\r\n backgroundPosition: 'center'\r\n }}\r\n />\r\n )}\r\n\r\n {/* Title + Subtitle */}\r\n <div className='rf-px-4 rf-py-1 rf-font-bold'>\r\n <div className='rf-text-size-auto rf-line-clamp-1'>{title && title.toLocaleUpperCase(locale)}</div>\r\n <div className='rf-text-basecustom rf-line-clamp-2'>{subtitle ? capitalizeFirstLetter(subtitle) : '...'}</div>\r\n </div>\r\n </div>\r\n </React.Fragment>\r\n )\r\n}\r\n\r\nexport default BannerTopMobile\r\n","import React from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\n\r\ninterface BannerTopLargeProps {\r\n category: string\r\n title?: string\r\n subtitle?: string\r\n}\r\n\r\nconst BannerTopLarge = ({ category, title, subtitle }: BannerTopLargeProps): JSX.Element => {\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n\r\n return (\r\n <React.Fragment>\r\n {/* Category + title */}\r\n <div className='rf-w-full rf-flex rf-flex-row rf-justify-start rf-text-size-auto'>\r\n <div className='rf-px-4 rf-py-3 rf-font-bold rf-bg-red-600 rf-whitespace-nowrap'>{category?.toLocaleUpperCase(locale)}</div>\r\n <div className='rf-px-4 rf-mb-2 rf-mt-2 large:rf-mt-3 rf-font-bold rf-line-clamp-1'>{title?.toLocaleUpperCase(locale)}</div>\r\n </div>\r\n\r\n {/* Subtitle */}\r\n <div className='rf-w-full rf-h-fit rf-flex rf-flex-row rf-justify-start'>\r\n <div className='rf-px-4 rf-my-2 large:rf-my-3 rf-title-large-size-auto rf-line-clamp-2'>{subtitle ? capitalizeFirstLetter(subtitle) : '...'}</div>\r\n </div>\r\n </React.Fragment>\r\n )\r\n}\r\n\r\nexport default BannerTopLarge\r\n"],"names":[],"version":3,"file":"NewsContainer.463e74de.js.map"}
@@ -1 +0,0 @@
1
- {"mappings":"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","sources":["src/components/News/NewsContainer.tsx","src/components/News/Time.tsx","src/components/News/News.tsx","src/hooks/useNews.tsx","src/components/News/Banner.tsx","src/components/News/BannerTopMobile.tsx","src/components/News/BannerTopLarge.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react'\r\nimport { useDispatch, useSelector } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\n\r\nimport type { NewsConfig } from '../../models/types'\r\nimport { Routes } from '../../models/enums'\r\n\r\nimport Background from '../Common/Background'\r\nimport Time from '../News/Time'\r\nimport News from '../News/News'\r\nimport Weather from '../Weather/Weather'\r\nimport AbsoluteLargeClosingButton from '../Utils/SubView/AbsoluteLargeClosingButton'\r\nimport CloseButton from '../Common/CloseButton'\r\nimport MenuDisplayer from '../Menus/MenuDisplayer'\r\nimport { BackButton } from '../Menu/Common'\r\n\r\ninterface NewsContainerProps {\r\n hideMenu?: boolean\r\n isRetorikNews?: boolean\r\n loop?: boolean\r\n fromVeille?: boolean\r\n handleEndedWithoutloop?: () => void\r\n}\r\n\r\n// Steps enum\r\nenum Steps {\r\n opening = 1,\r\n news,\r\n events,\r\n weather,\r\n ending\r\n}\r\n\r\nconst NewsContainer = ({ hideMenu, isRetorikNews, loop, fromVeille, handleEndedWithoutloop }: NewsContainerProps): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const configuration = useSelector((state: RootState) => state.retorikReducer.configuration)\r\n const displaySubtitles = useSelector((state: RootState) => state.retorikReducer.displaySubtitles)\r\n const muted = useSelector((state: RootState) => state.speechReducer.muted)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n const isLandscape = useSelector((state: RootState) => state.viewReducer.isLandscape)\r\n const isBorne = useSelector((state: RootState) => state.viewReducer.isBorne)\r\n const configurations = useSelector((state: RootState) => state.viewReducer.configurations)\r\n const conversationId = useSelector((state: RootState) => state.activityReducer.conversationId)\r\n const storedConversationData = useSelector((state: RootState) => state.directlineReducer.storedVeilleConversationData)\r\n\r\n const [displayData, setDisplayData] = useState<NewsConfig>(configurations.views.news || configurations.views.home)\r\n const [step, setStep] = useState<number>(configurations.views.news?.openingVideo ? Steps.opening : Steps.news)\r\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n const newsEndedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n const oldDiplaySubtitles = useRef<boolean>(displaySubtitles)\r\n\r\n /**\r\n * On call :\r\n * - if the component is news-only, return\r\n * - else set ViewContext's route state to 'home'\r\n */\r\n const handleBack = (): void => {\r\n if (isRetorikNews) {\r\n return\r\n }\r\n dispatch(storeActions.view.setRoute(Routes.Home))\r\n }\r\n\r\n useEffect(() => {\r\n configuration.useOldRemote && dispatch(storeActions.view.setDisplayControls(false))\r\n // Force muted state to false if we are not in the veille\r\n muted && !fromVeille && dispatch(storeActions.speech.setMuted(false))\r\n // Force hiding subtitles if we are in the veille\r\n fromVeille && dispatch(storeActions.retorik.setDisplaySubtitles(false))\r\n\r\n return () => {\r\n // If we exit news from the veille, let's store the conversation id for next turn, clear activity store and set back subtitles\r\n if (fromVeille) {\r\n !storedConversationData?.id && conversationId && dispatch(storeActions.directline.setStoredVeilleConversationData(conversationId))\r\n dispatch(storeActions.activity.resetActivityStore())\r\n dispatch(storeActions.retorik.setDisplaySubtitles(oldDiplaySubtitles.current))\r\n }\r\n // Send closing events unless we are using RetorikNews component\r\n if (!isRetorikNews) {\r\n dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindow', callback: () => dispatch(storeActions.directline.sendEvent({ name: 'Davi.CloseWindowNews' })) }))\r\n }\r\n }\r\n }, [])\r\n\r\n /**\r\n * On step change :\r\n * - switch on the current step to launch corresponding processing\r\n * On component unmount :\r\n * - clear timerRef timeout\r\n */\r\n useEffect(() => {\r\n switch (step) {\r\n case Steps.opening: {\r\n dispatch(storeActions.retorik.setDisplayAgentInNews(false))\r\n const videoUrl = configurations.views.news?.openingVideo\r\n videoUrl && !fromVeille ? setViewContextCurrentConfiguration(videoUrl as string) : setStep(Steps.news)\r\n break\r\n }\r\n case Steps.news:\r\n dispatch(storeActions.retorik.setDisplayAgentInNews(true))\r\n setDisplayData(configurations.views.news || configurations.views.home)\r\n break\r\n case Steps.events:\r\n break\r\n case Steps.weather:\r\n dispatch(storeActions.retorik.setDisplayAgentInNews(false))\r\n // If the position is known, display the weather page during 10 seconds, otherwise switch to the next step directly\r\n configuration.position?.latitude && configuration.position?.longitude\r\n ? (timerRef.current = setTimeout(() => {\r\n setStep(Steps.ending)\r\n }, 10000))\r\n : setStep(Steps.ending)\r\n break\r\n case Steps.ending: {\r\n dispatch(storeActions.retorik.setDisplayAgentInNews(false))\r\n const videoUrl = configurations.views.news?.openingVideo\r\n videoUrl && !fromVeille ? setViewContextCurrentConfiguration(videoUrl as string) : exitNewsOrLoop()\r\n break\r\n }\r\n default:\r\n break\r\n }\r\n\r\n return (): void => {\r\n timerRef?.current && clearTimeout(timerRef.current)\r\n newsEndedTimerRef?.current && clearTimeout(newsEndedTimerRef.current)\r\n }\r\n }, [step])\r\n\r\n /**\r\n * On call :\r\n * - set the current display configuration to have the given video as background\r\n * @param videoUrl\r\n */\r\n const setViewContextCurrentConfiguration = (videoUrl: string): void => {\r\n setDisplayData({\r\n ...configurations.views.news,\r\n background: {\r\n video: videoUrl,\r\n style: 'video'\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * On call :\r\n * - if the component is news-only :\r\n * + if 'loop' is explicitly set to false, call props' handleEndedWithoutloop method if defined. Call handleBack method otherwise\r\n * + if 'loop' is not false, loop by setting step state to Steps.news\r\n * - or else if 'loop' parameter in configuration is true, get back to Steps.news step. Call handleBack method otherwise\r\n */\r\n const exitNewsOrLoop = (): void => {\r\n // Relaunch from the start if this is a news-only component and loop hasn't explicitly been set to false\r\n if (isRetorikNews) {\r\n if (fromVeille) {\r\n loop ? setStep(Steps.news) : handleEndedWithoutloop?.()\r\n } else {\r\n displayData.loop !== false || loop ? setStep(Steps.news) : handleEndedWithoutloop ? handleEndedWithoutloop() : handleBack()\r\n }\r\n } else {\r\n // Relaunch from the start if the loop is activated, otherwise get back to homepage\r\n displayData.loop || loop ? setStep(Steps.news) : handleBack()\r\n }\r\n }\r\n\r\n /**\r\n * On video end :\r\n * - if we are at the opening step, let's set the step state to Steps.news to launch the news\r\n * - if we are at the ending step, call exitNewsOrLoop function\r\n */\r\n const handleVideoEnd = (): void => {\r\n switch (step) {\r\n case Steps.opening:\r\n setStep(Steps.news)\r\n break\r\n case Steps.ending:\r\n exitNewsOrLoop()\r\n break\r\n }\r\n }\r\n\r\n /**\r\n * On news end :\r\n * - wait 3 seconds\r\n * - get to the next step (Steps.events)\r\n */\r\n const handleNewsEnd = (): void => {\r\n newsEndedTimerRef &&\r\n (newsEndedTimerRef.current = setTimeout(() => {\r\n // setStep(Steps.events)\r\n setStep(Steps.weather)\r\n }, 3000))\r\n }\r\n\r\n return (\r\n <div className='rf-relative rf-col-start-1 rf-col-span-full rf-row-start-1 rf-row-span-full rf-grid rf-grid-cols-8 rf-grid-rows-12'>\r\n <Background config={displayData.background} videoLoop={false} videoMuted={true} onVideoEnded={handleVideoEnd} />\r\n\r\n {/* Timer + back button in mobile / widget mode */}\r\n {isMobile && !isRetorikNews && !hideMenu ? (\r\n <div className='rf-relative rf-z-util rf-col-start-1 rf-col-span-full rf-row-start-1 rf-flex rf-flex-col rf-gap-2 rf-items-start'>\r\n <BackButton title={translation.common.back} handleBack={handleBack} className='rf-pr-2 rf-mt-4 rf-ml-4 rf-text-size-auto rf-bg-truewhite rf-rounded-lg' />\r\n <Time belowReturnButton={true} />\r\n </div>\r\n ) : (\r\n <Time />\r\n )}\r\n\r\n {/* News step */}\r\n {step === Steps.news && <News intervalInSeconds={displayData.intervalInSeconds ? (displayData.intervalInSeconds as number) : undefined} onEnd={handleNewsEnd} isRetorikNews={isRetorikNews} />}\r\n\r\n {step === Steps.weather && configuration.position?.latitude && configuration.position?.longitude && <Weather handleClose={handleBack} />}\r\n\r\n {/* Closing button if it needs to be displayed */}\r\n {!hideMenu && <AbsoluteLargeClosingButton dashboardVisible={true} onClick={handleBack} />}\r\n\r\n {!hideMenu && isLandscape && !configuration.useOldRemote && !isRetorikNews && <CloseButton onClick={handleBack} showLabel={true} />}\r\n\r\n {!hideMenu && isBorne && !configuration.useOldRemote && !isRetorikNews && <MenuDisplayer hideMenu={configuration?.hideMenu} />}\r\n </div>\r\n )\r\n}\r\n\r\nexport default NewsContainer\r\n","import React, { useEffect, useState, useRef } from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\n\r\ninterface TimeProps {\r\n belowReturnButton?: boolean\r\n}\r\n\r\nconst Time = ({ belowReturnButton }: TimeProps): JSX.Element => {\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n const [time, setTime] = useState<string>('')\r\n const timerRef: React.MutableRefObject<any> = useRef(null)\r\n\r\n /**\r\n * Set current time (hours and minutes) depending on the locale (ex: adds AM/PM when needed)\r\n */\r\n const setCurrentTime = (): void => {\r\n const now = new Date()\r\n setTime(\r\n now.toLocaleTimeString(locale, {\r\n hour: '2-digit',\r\n minute: '2-digit'\r\n })\r\n )\r\n }\r\n\r\n /**\r\n * On component mount :\r\n * - set time\r\n * - set interval for time update\r\n * On component unmount :\r\n * - clear interval\r\n */\r\n useEffect(() => {\r\n setCurrentTime()\r\n timerRef && (timerRef.current = setInterval(setCurrentTime, 1000))\r\n\r\n return (): void => timerRef && clearInterval(timerRef.current)\r\n }, [])\r\n\r\n return (\r\n <div className={`rf-relative ${belowReturnButton ? 'rf-ml-4' : 'rf-col-start-1 rf-col-span-2 rf-row-start-1 rf-row-span-2 rf-self-start rf-justify-self-start rf-m-4 large:rf-m-8'}`}>\r\n <div className='rf-w-fit rf-h-fit rf-flex rf-flex-col rf-justify-start rf-items-start rf-text-white'>\r\n {/* Text 'Live' + round */}\r\n <div className='rf-w-full rf-text-size-auto rf-px-3 rf-py-0 large:rf-px-4 large:rf-py-1 rf-text-center rf-font-semibold rf-bg-red-600 rf-whitespace-nowrap'>\r\n {`${translation.news.live.toLocaleUpperCase(locale)} \\u25cf`}\r\n </div>\r\n {/* Time */}\r\n <div className='rf-w-full rf-title-size-auto rf-px-3 rf-py-0 large:rf-px-4 large:rf-py-1 rf-text-center rf-font-bold rf-bg-blue-500'>{time}</div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport default Time\r\n","import React, { useEffect, useMemo, useState, useRef } from 'react'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport useNews from '../../hooks/useNews'\r\n\r\nimport type { Image, Media } from '../../models/attachmentTypes'\r\nimport { RetorikActivity } from '../../models/activityTypes'\r\nimport { DeviceType, Routes } from '../../models/enums'\r\n\r\nimport Banner from './Banner'\r\nimport { Carousel } from '../Utils'\r\n\r\ntype NewsProps = {\r\n intervalInSeconds?: number\r\n onEnd: () => void\r\n isRetorikNews?: boolean\r\n}\r\n\r\nconst News = ({ intervalInSeconds = 3, onEnd, isRetorikNews }: NewsProps): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const { newsAttachments, activity } = useNews()\r\n const route = useSelector((state: RootState) => state.viewReducer.route)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n const newsConfiguration = useSelector((state: RootState) => state.viewReducer.configurations.views.news)\r\n const currentDeviceType = useSelector((state: RootState) => state.viewReducer.currentDeviceType)\r\n const retorikNewsEnded = useSelector((state: RootState) => state.utilsReducer.retorikNewsEnded)\r\n\r\n const [carouselGridRowStart, setCarouselGridRowStart] = useState<number>()\r\n const [carouselGridRowSpan, setCarouselGridRowSpan] = useState<number>()\r\n const [bannerGridRowStart, setBannerGridRowStart] = useState<number>(10)\r\n const [bannerGridRowSpan, setBannerGridRowSpan] = useState<number>(3)\r\n // Banner's align-self is flex-end if the position of the banner hasn't been changed, flex-start in borne / landscape modes otherwise\r\n const [alignSelfEnd, setAlignSelfEnd] = useState<boolean>(true)\r\n const [current, setCurrent] = useState<number>(0)\r\n const timerRef = useRef<NodeJS.Timer | null>(null)\r\n\r\n const news = useMemo(() => {\r\n return newsAttachments.map((newsAttachement) => newsAttachement.content)\r\n }, [newsAttachments])\r\n\r\n useEffect(() => {\r\n if (!newsAttachments.length) {\r\n setTimeout(() => {\r\n dispatch(storeActions.directline.sendEvent({ name: 'news.getAllNews' }))\r\n }, 2000)\r\n }\r\n\r\n return (): void => {\r\n timerRef.current && clearTimeout(timerRef.current)\r\n }\r\n }, [])\r\n\r\n useEffect(() => {\r\n switch (currentDeviceType) {\r\n case DeviceType.mobile:\r\n case DeviceType.widget: {\r\n // Set carousel's and banner's positions\r\n setAlignSelfEnd(true)\r\n setCarouselGridRowStart(1)\r\n setCarouselGridRowSpan(9)\r\n setBannerGridRowStart(10)\r\n setBannerGridRowSpan(3)\r\n break\r\n }\r\n case DeviceType.landscape:\r\n case DeviceType.widgetLandscape: {\r\n // Check banner's position and set carousel's position if there are no position data for this one\r\n if (newsConfiguration?.bannerPosition?.landscape) {\r\n const start = newsConfiguration.bannerPosition.landscape.containerRowStart || 10\r\n const end = newsConfiguration.bannerPosition.landscape.containerRowEnd || 13\r\n\r\n setAlignSelfEnd(false)\r\n setBannerGridRowStart(start)\r\n setBannerGridRowSpan(end - start)\r\n\r\n if (!newsConfiguration?.mediaPosition?.landscape) {\r\n // The base row span of the carousel is 9, if the custom position of the banner allows this span, let's keep it. If not, let's use the max span available.\r\n if (start > 9) {\r\n setCarouselGridRowStart(start - 9)\r\n setCarouselGridRowSpan(9)\r\n } else {\r\n setCarouselGridRowStart(1)\r\n setCarouselGridRowSpan(start - 1)\r\n }\r\n\r\n break\r\n }\r\n } else {\r\n setAlignSelfEnd(true)\r\n setBannerGridRowStart(10)\r\n setBannerGridRowSpan(3)\r\n }\r\n\r\n // Check carousel's position\r\n if (newsConfiguration?.mediaPosition?.landscape) {\r\n const start = newsConfiguration.mediaPosition.landscape.containerRowStart || 1\r\n const end = newsConfiguration.mediaPosition.landscape.containerRowEnd || 10\r\n\r\n setCarouselGridRowStart(start)\r\n setCarouselGridRowStart(end - start)\r\n } else {\r\n setCarouselGridRowStart(1)\r\n setCarouselGridRowSpan(9)\r\n }\r\n\r\n break\r\n }\r\n case DeviceType.borne:\r\n case DeviceType.widgetBorne: {\r\n // Check banner's position and set carousel's position if there are no position data for this one\r\n if (newsConfiguration?.bannerPosition?.borne) {\r\n const start = newsConfiguration.bannerPosition.borne.containerRowStart || 10\r\n const end = newsConfiguration.bannerPosition.borne.containerRowEnd || 13\r\n\r\n setAlignSelfEnd(false)\r\n setBannerGridRowStart(start)\r\n setBannerGridRowSpan(end - start)\r\n\r\n if (!newsConfiguration?.mediaPosition?.borne) {\r\n // The base row span of the carousel is 4, if the custom position of the banner allows this span, let's keep it. If not, let's use the max span available.\r\n if (start > 4) {\r\n setCarouselGridRowStart(start - 4)\r\n setCarouselGridRowSpan(4)\r\n } else {\r\n setCarouselGridRowStart(1)\r\n setCarouselGridRowSpan(start - 1)\r\n }\r\n\r\n break\r\n }\r\n } else {\r\n setAlignSelfEnd(true)\r\n setBannerGridRowStart(10)\r\n setBannerGridRowSpan(3)\r\n }\r\n\r\n // Check carousel's position\r\n if (newsConfiguration?.mediaPosition?.borne) {\r\n const start = newsConfiguration.mediaPosition.borne.containerRowStart || 7\r\n const end = newsConfiguration.mediaPosition.borne.containerRowEnd || 11\r\n\r\n setCarouselGridRowStart(start)\r\n setCarouselGridRowSpan(end - start)\r\n } else {\r\n setCarouselGridRowStart(7)\r\n setCarouselGridRowSpan(4)\r\n }\r\n break\r\n }\r\n }\r\n }, [newsConfiguration, currentDeviceType])\r\n\r\n useEffect(() => {\r\n const currentNew = news[current]\r\n if (currentNew) {\r\n const textTitle = newsConfiguration?.removeTitleFromTextToSpeak ? '' : `${currentNew.title}, <break/> `\r\n const textSubtitle = newsConfiguration?.removeSubtitleFromTextToSpeak ? '' : `${currentNew.subtitle}: <break/> `\r\n\r\n const tempActivity: RetorikActivity = {\r\n ...activity,\r\n speak: `${textTitle}${textSubtitle}${currentNew.text}`\r\n } as RetorikActivity\r\n\r\n dispatch(storeActions.speech.addToStreamingQueue(tempActivity))\r\n }\r\n }, [activity, current])\r\n\r\n const currentMedia = useMemo<Array<Image | Media>>(() => {\r\n const currentNew = news[current]\r\n if (currentNew) {\r\n if (currentNew.media?.length) {\r\n return currentNew.media\r\n } else if (currentNew.image?.url) {\r\n return [currentNew.image]\r\n }\r\n }\r\n\r\n return []\r\n }, [news, current])\r\n\r\n useEffect(() => {\r\n if (retorikNewsEnded) {\r\n if (news.length) {\r\n if (current < news.length - 1) {\r\n const delay = current < news.length - 1 ? intervalInSeconds : intervalInSeconds * 3\r\n timerRef.current && clearTimeout(timerRef.current)\r\n if (route === Routes.News || isRetorikNews) {\r\n timerRef.current = setTimeout(next, delay * 1000)\r\n }\r\n } else {\r\n onEnd()\r\n }\r\n }\r\n\r\n dispatch(storeActions.utils.setRetorikNewsEnded(false))\r\n }\r\n }, [retorikNewsEnded])\r\n\r\n const next = (): void => {\r\n const next = (current + 1) % news.length\r\n changeNews(next)\r\n }\r\n\r\n const changeNews = (next: number): void => {\r\n setCurrent(next)\r\n }\r\n\r\n return news.length && current >= 0 ? (\r\n <React.Fragment>\r\n {/* Carousel in landscape / borne display */}\r\n {!isMobile && (\r\n <div\r\n className='rf-relative rf-col-start-5 rf-col-span-3 large-vertical:rf-col-start-2 large-vertical:rf-col-end-8 rf-flex rf-justify-center rf-items-center'\r\n style={{\r\n gridRow: `${carouselGridRowStart} / span ${carouselGridRowSpan}`\r\n }}\r\n >\r\n {currentMedia.length ? (\r\n <Carousel className='rf-z-[10] rf-max-h-4/5 large-vertical:rf-max-h-11/12 rf-max-w-full' medias={news[current].media || [news[current].image || { url: '' }]} />\r\n ) : (\r\n <React.Fragment />\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Lower banner with title / subtitle / text */}\r\n <Banner news={news[current]} gridRowStart={bannerGridRowStart} gridRowSpan={bannerGridRowSpan} alignSelfEnd={alignSelfEnd} />\r\n </React.Fragment>\r\n ) : (\r\n <React.Fragment />\r\n )\r\n}\r\n\r\nexport default News\r\n","import { CONTENT_TYPE_NEWS, NewsContent } from '../models/attachmentTypes'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../store'\r\nimport type { RetorikActivity } from '../models/activityTypes'\r\n\r\ntype NewsAttachment = {\r\n contentType: string\r\n content: NewsContent\r\n}\r\n\r\nconst useNews = (): {\r\n newsAttachments: Array<NewsAttachment>\r\n activity?: RetorikActivity\r\n} => {\r\n const activities = useSelector((state: RootState) => state.activityReducer.botEventActivities)\r\n\r\n if (!activities.length) {\r\n return { newsAttachments: [] }\r\n }\r\n\r\n // Filter messages that can income during news, with label = Davi.BringupMessage\r\n const filterBringUpActivities = activities.filter((act: any) => act.label !== 'Davi.BringupMessage')\r\n\r\n const activity = filterBringUpActivities[filterBringUpActivities.length - 1] as any\r\n\r\n if (!activity || !activity.attachments?.length) {\r\n return { newsAttachments: [], activity }\r\n }\r\n\r\n const newsAttachments: NewsAttachment[] = []\r\n activity.attachments.forEach((attachment) => {\r\n if (attachment.contentType === CONTENT_TYPE_NEWS) {\r\n newsAttachments.push({\r\n contentType: CONTENT_TYPE_NEWS,\r\n content: attachment.content || ''\r\n })\r\n }\r\n })\r\n\r\n return { newsAttachments, activity }\r\n}\r\n\r\nexport default useNews\r\n","import React, { useEffect, useMemo, useRef, useState } from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\nimport type { NewsContent } from '../../models/attachmentTypes'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\nimport BannerTopMobile from './BannerTopMobile'\r\nimport BannerTopLarge from './BannerTopLarge'\r\n\r\ninterface BannerProps {\r\n news: NewsContent\r\n gridRowStart: number\r\n gridRowSpan: number\r\n alignSelfEnd: boolean\r\n}\r\n\r\nconst Banner = ({ news, gridRowStart, gridRowSpan, alignSelfEnd }: BannerProps): JSX.Element => {\r\n const translation = useSelector((state: RootState) => state.localeReducer.currentTranslations)\r\n const locale = useSelector((state: RootState) => state.localeReducer.localeForRetorikStudioContent)\r\n const localizedBannerTitle = useSelector((state: RootState) => state.localeReducer.localizedBannerTitle)\r\n const isRTL = useSelector((state: RootState) => state.localeReducer.isRTL)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n const currentWidth = useSelector((state: RootState) => state.viewReducer.currentWidth)\r\n const newsConfiguration = useSelector((state: RootState) => state.viewReducer.configurations.views.news)\r\n\r\n const timerRef: React.MutableRefObject<any> = useRef(null)\r\n const [scrollDuration, setScrollDuration] = useState<number>(0)\r\n\r\n const category = useMemo<string>(() => {\r\n return news.category || newsConfiguration?.bannerTitleLocalized?.[locale] || localizedBannerTitle || newsConfiguration?.bannerTitle || translation.news.continuous\r\n }, [news, newsConfiguration, locale, localizedBannerTitle, translation])\r\n\r\n /**\r\n * Set animation for text horizontal scrolling if necessary\r\n */\r\n const updateDuration = (): void => {\r\n // Reset animation\r\n setScrollDuration(0)\r\n // Set animation, after a 1s timeout\r\n timerRef &&\r\n (timerRef.current = setTimeout(() => {\r\n setScrollDuration(Math.floor(news.text.length / 11))\r\n }, 1000))\r\n }\r\n\r\n /**\r\n * On news props change :\r\n * - call updateDuration function\r\n * On component unmount :\r\n * - clear timeout\r\n */\r\n useEffect(() => {\r\n updateDuration()\r\n\r\n return (): void => timerRef && clearTimeout(timerRef.current)\r\n }, [news])\r\n\r\n return (\r\n <div\r\n dir={isRTL ? 'rtl' : 'ltr'}\r\n className='rf-h-fit rf-z-util rf-col-start-1 rf-col-span-full large:rf-mb-6 rf-flex rf-flex-col rf-items-center rf-glass-background rf-text-white'\r\n style={{\r\n alignSelf: alignSelfEnd ? 'flex-end' : 'flex-start',\r\n gridRow: `${gridRowStart} / span ${gridRowSpan}`\r\n }}\r\n >\r\n {/* Category + Image (mobile) + Title + Subtitle */}\r\n {isMobile ? (\r\n <BannerTopMobile category={category} title={news.title} subtitle={news.subtitle} url={news.image?.url} />\r\n ) : (\r\n <BannerTopLarge category={category} title={news.title} subtitle={news.subtitle} />\r\n )}\r\n\r\n {/* Text */}\r\n <div\r\n dir='ltr'\r\n className='rf-w-full rf-pr-4 rf-py-2 large:rf-py-4 rf-subtitle-size-auto rf-text-black rf-bg-white rf-overflow-clip'\r\n style={{\r\n paddingLeft: currentWidth\r\n }}\r\n >\r\n {scrollDuration !== 0 ? (\r\n <p\r\n className='rf-w-max rf-whitespace-nowrap rf-animate-hScroll'\r\n style={{\r\n animation: `rf-hScroll ${scrollDuration}s infinite linear`,\r\n paddingRight: currentWidth\r\n }}\r\n >\r\n {news.text ? capitalizeFirstLetter(news.text) : '...'}\r\n </p>\r\n ) : (\r\n <p className='rf-w-max rf-whitespace-nowrap'>{news.text ? capitalizeFirstLetter(news.text) : '...'}</p>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport default Banner\r\n","import React from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\n\r\ninterface BannerTopMobileProps {\r\n category: string\r\n title?: string\r\n subtitle?: string\r\n url?: string\r\n}\r\n\r\nconst BannerTopMobile = ({ category, title, subtitle, url }: BannerTopMobileProps): JSX.Element => {\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n\r\n return (\r\n <React.Fragment>\r\n <div className='rf-w-full rf-px-4 rf-py-2 rf-font-bold rf-bg-red-600 rf-whitespace-nowrap rf-text-size-auto'>{category?.toLocaleUpperCase(locale)}</div>\r\n\r\n <div className='rf-w-full rf-flex rf-flex-row'>\r\n {/* Image */}\r\n {url && (\r\n <div\r\n className='rf-aspect-video rf-w-1/4'\r\n style={{\r\n backgroundImage: `url(${url})`,\r\n backgroundSize: 'cover',\r\n backgroundRepeat: 'no-repeat',\r\n backgroundPosition: 'center'\r\n }}\r\n />\r\n )}\r\n\r\n {/* Title + Subtitle */}\r\n <div className='rf-px-4 rf-py-1 rf-font-bold'>\r\n <div className='rf-text-size-auto rf-line-clamp-1'>{title && title.toLocaleUpperCase(locale)}</div>\r\n <div className='rf-text-basecustom rf-line-clamp-2'>{subtitle ? capitalizeFirstLetter(subtitle) : '...'}</div>\r\n </div>\r\n </div>\r\n </React.Fragment>\r\n )\r\n}\r\n\r\nexport default BannerTopMobile\r\n","import React from 'react'\r\nimport { useSelector } from 'react-redux'\r\nimport { RootState } from '../../store'\r\nimport { capitalizeFirstLetter } from '../../utils/capitalizeFirstLetter'\r\n\r\ninterface BannerTopLargeProps {\r\n category: string\r\n title?: string\r\n subtitle?: string\r\n}\r\n\r\nconst BannerTopLarge = ({ category, title, subtitle }: BannerTopLargeProps): JSX.Element => {\r\n const locale = useSelector((state: RootState) => state.localeReducer.locale)\r\n\r\n return (\r\n <React.Fragment>\r\n {/* Category + title */}\r\n <div className='rf-w-full rf-flex rf-flex-row rf-justify-start rf-text-size-auto'>\r\n <div className='rf-px-4 rf-py-3 rf-font-bold rf-bg-red-600 rf-whitespace-nowrap'>{category?.toLocaleUpperCase(locale)}</div>\r\n <div className='rf-px-4 rf-mb-2 rf-mt-2 large:rf-mt-3 rf-font-bold rf-line-clamp-1'>{title?.toLocaleUpperCase(locale)}</div>\r\n </div>\r\n\r\n {/* Subtitle */}\r\n <div className='rf-w-full rf-h-fit rf-flex rf-flex-row rf-justify-start'>\r\n <div className='rf-px-4 rf-my-2 large:rf-my-3 rf-title-large-size-auto rf-line-clamp-2'>{subtitle ? capitalizeFirstLetter(subtitle) : '...'}</div>\r\n </div>\r\n </React.Fragment>\r\n )\r\n}\r\n\r\nexport default BannerTopLarge\r\n"],"names":[],"version":3,"file":"NewsContainer.d9de093c.js.map","sourceRoot":"../"}
@@ -1 +0,0 @@
1
- {"mappings":"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","sources":["src/components/ChatbotAndSubtitles/ThreeJsWrapper.tsx","src/components/ChatbotAndSubtitles/CalibrationScreen.tsx","src/components/Veille/FaceDetector.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useState } from 'react'\r\nimport { Character, CreationTool, setCharacterState, addViseme, setVisemes, flushLipSyncData, CharacterState, presets, Object3D } from '@davi-ai/react-bodyengine-three'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport type { CalibrationData } from '../../store/models/types'\r\nimport { RecognitionState, Source3DEngine } from '../../models/enums'\r\nimport MicrophoneLoader from '../Loader/MicrophoneLoader'\r\nimport CalibrationScreen from './CalibrationScreen'\r\n\r\ninterface EyeTrackingData {\r\n webcamHeight: number\r\n webcamRotation: number\r\n ratioPixelToCentimeter: number\r\n agentEyesHeight: number\r\n distanceFromDevice: number\r\n worldDistancePerDegree: number\r\n cameraX: number\r\n cameraZ: number\r\n}\r\n\r\ninterface ThreeJsWrapperAgentData {\r\n url: string\r\n animationsUrl?: string\r\n source?: string\r\n gender: 'male' | 'female' | 'other'\r\n}\r\n\r\ninterface ThreeJsWrapperProps {\r\n agentData: ThreeJsWrapperAgentData\r\n visible: boolean\r\n height?: string | number\r\n size?: string | number\r\n cameraPreset?: keyof typeof presets\r\n calibration?: CalibrationData\r\n centered: boolean\r\n}\r\n\r\nconst ThreeJsWrapper = ({ agentData, visible, height, size, cameraPreset, calibration, centered }: ThreeJsWrapperProps): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const gpuData = useSelector((state: RootState) => state.retorikReducer.gpuData)\r\n const speaking = useSelector((state: RootState) => state.speechReducer.speaking)\r\n const loaderClosed = useSelector((state: RootState) => state.retorikReducer.loaderClosed)\r\n const recognitionState = useSelector((state: RootState) => state.speechReducer.activeRecognitionState)\r\n const lastRecognitionInterim = useSelector((state: RootState) => state.speechReducer.lastRecognitionInterim)\r\n const singleViseme = useSelector((state: RootState) => state.speechReducer.singleVisemeAdded)\r\n const multiVisemes = useSelector((state: RootState) => state.speechReducer.multiVisemesAdded)\r\n const streamingQueue = useSelector((state: RootState) => state.speechReducer.streamingQueue)\r\n const characterLoaded = useSelector((state: RootState) => state.viewReducer.characterLoaded)\r\n const isMobile = useSelector((state: RootState) => state.viewReducer.isMobile)\r\n\r\n const [targets, setTargets] = useState<Array<Object3D>>([])\r\n const [dynamicData, setDynamicData] = useState<\r\n | {\r\n webcamHeight: number\r\n ratioPixelToCentimeter: number\r\n deltaAgentHeightAgentWorldHeightInCentimeters: number\r\n cameraRotationInDegrees: number\r\n distanceFromAgentToCameraInCentimeters: number\r\n }\r\n | undefined\r\n >(undefined)\r\n const [openCalibration, setOpenCalibration] = useState<boolean>(false)\r\n\r\n /**\r\n * Use model's source to get the right loader. Default to avaturn loader\r\n */\r\n const type = useMemo<CreationTool | null>(() => {\r\n if (agentData.source) {\r\n switch (agentData.source.toLowerCase()) {\r\n case Source3DEngine.avatarsdk:\r\n case Source3DEngine.avatarsdkbis:\r\n return CreationTool.avatarsdk\r\n case Source3DEngine.cc3:\r\n case Source3DEngine.cc4:\r\n return CreationTool.cc3\r\n case Source3DEngine.avaturn:\r\n default:\r\n return CreationTool.avaturn\r\n }\r\n }\r\n\r\n return CreationTool.avaturn\r\n }, [agentData])\r\n\r\n useEffect(() => {\r\n if ((!calibration?.static?.enabled && !calibration?.dynamic?.enabled) || isMobile) dispatch(storeActions.view.setCalibrationCompleted(true))\r\n }, [calibration, isMobile])\r\n\r\n useEffect(() => {\r\n // Check if we should open the calibration screen or not\r\n if ((calibration?.static?.enabled || calibration?.dynamic?.enabled) && !isMobile) {\r\n // If there are some static data in the props or the local storage, we can directly set the targets without opening the calibration screen\r\n if (calibration?.static?.enabled && calibration.static.staticTarget) {\r\n const o = new Object3D()\r\n o.position.set(calibration.static.staticTarget.x, calibration.static.staticTarget.y, calibration.static.staticTarget.z)\r\n setTargets([o])\r\n setOpenCalibration(false)\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n } else if (calibration?.static?.enabled && calibration.static.loadStaticTargetFromLocalStorage && localStorage.getItem('Retorik.Framework.Static.Target')) {\r\n const calibrationData = JSON.parse(localStorage.getItem('Retorik.Framework.Static.Target') || '{}') as {\r\n x: number\r\n y: number\r\n z: number\r\n }\r\n const o = new Object3D()\r\n o.position.set(calibrationData.x, calibrationData.y, calibrationData.z)\r\n setTargets([o])\r\n setOpenCalibration(false)\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n } else if (calibration.dynamic?.enabled && calibration.dynamic.dynamicData) {\r\n // Check if all the mandatory dynamic data are in the props\r\n if (\r\n calibration.dynamic.dynamicData.webcamHeight &&\r\n calibration.dynamic.dynamicData.ratioPixelToCentimeter &&\r\n calibration.dynamic.dynamicData.deltaAgentHeightAgentWorldHeightInCentimeters &&\r\n calibration.dynamic.dynamicData.distanceFromAgentToCameraInCentimeters\r\n ) {\r\n setDynamicData({ ...calibration.dynamic.dynamicData, cameraRotationInDegrees: calibration.dynamic.dynamicData.cameraRotationInDegrees || 0 })\r\n }\r\n\r\n setOpenCalibration(true)\r\n } else if (calibration.dynamic?.enabled && calibration.dynamic.loadDynamicDataFromLocalStorage && localStorage.getItem('Retorik.Framework.Dynamic.Data')) {\r\n // Check if the local storage data is complete\r\n const calibrationData = JSON.parse(localStorage.getItem('Retorik.Framework.Dynamic.Data') || '{}')\r\n if (\r\n calibrationData.webcamHeight &&\r\n calibrationData.ratioPixelToCentimeter &&\r\n calibrationData.deltaAgentHeightAgentWorldHeightInCentimeters &&\r\n calibrationData.distanceFromAgentToCameraInCentimeters\r\n ) {\r\n setDynamicData({ ...calibrationData, cameraRotationInDegrees: calibrationData.cameraRotationInDegrees || 0 })\r\n }\r\n\r\n setOpenCalibration(true)\r\n } else {\r\n setOpenCalibration(true)\r\n }\r\n } else {\r\n setOpenCalibration(false)\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n }\r\n }, [calibration, isMobile])\r\n\r\n useEffect(() => {\r\n singleViseme && addViseme(singleViseme)\r\n }, [singleViseme])\r\n\r\n useEffect(() => {\r\n multiVisemes.length && setVisemes(multiVisemes)\r\n }, [multiVisemes])\r\n\r\n useEffect(() => {\r\n if (speaking || streamingQueue.length) {\r\n setCharacterState(CharacterState.speaking)\r\n } else if (recognitionState === RecognitionState.Closed) {\r\n setCharacterState(CharacterState.idle)\r\n } else if (lastRecognitionInterim) {\r\n setCharacterState(CharacterState.listening)\r\n } else {\r\n setCharacterState(CharacterState.waiting)\r\n }\r\n }, [speaking, recognitionState, lastRecognitionInterim, streamingQueue])\r\n\r\n useEffect(() => {\r\n !speaking && flushLipSyncData()\r\n }, [speaking])\r\n\r\n return (\r\n <React.Fragment>\r\n <div\r\n style={{\r\n height: size || '100%',\r\n paddingTop: height || 0,\r\n visibility: characterLoaded && visible ? 'visible' : 'hidden'\r\n }}\r\n >\r\n {type && (\r\n <Character\r\n url={agentData.url}\r\n type={type}\r\n animationsUrl={agentData?.animationsUrl || 'https://cdn.retorik.ai/bodyengine-three/animations/cc4/female/standing/'}\r\n gender={agentData?.gender === 'male' ? 'male' : 'female'}\r\n onLoadingCompleted={() => dispatch(storeActions.view.setCharacterLoaded(true))}\r\n camera={presets[cameraPreset || 'default']}\r\n targets={targets}\r\n autoLookAt={true}\r\n detectGpuData={gpuData}\r\n license='fake-license'\r\n />\r\n )}\r\n </div>\r\n {!characterLoaded && (\r\n <div className='rf-absolute rf-top-0 rf-left-0 rf-w-full rf-h-full rf-flex rf-justify-center rf-items-center'>\r\n <div className='rf-w-1/4 rf-aspect-square'>\r\n <MicrophoneLoader />\r\n </div>\r\n </div>\r\n )}\r\n\r\n {openCalibration && loaderClosed && (\r\n <CalibrationScreen\r\n centered={centered}\r\n staticCalibrationEnabled={!!calibration?.static?.enabled}\r\n dynamicCalibrationEnabled={!!calibration?.dynamic?.enabled}\r\n setTargets={(targets: Array<Object3D>) => setTargets(targets)}\r\n dynamicData={dynamicData}\r\n />\r\n )}\r\n </React.Fragment>\r\n )\r\n}\r\n\r\nexport default ThreeJsWrapper\r\nexport type { EyeTrackingData }\r\n","import React, { useEffect, useRef, useState } from 'react'\r\nimport { Object3D, getCameraPosition, getCharacterHeight, setLookAtCamera, setShowFirstTarget } from '@davi-ai/react-bodyengine-three'\r\nimport type { Detection } from '@mediapipe/tasks-vision'\r\nimport { useSelector, useDispatch } from 'react-redux'\r\nimport { RootState, storeActions } from '../../store'\r\nimport FaceDetector from '../Veille/FaceDetector'\r\n\r\ninterface CalibrationScreenProps {\r\n centered: boolean\r\n staticCalibrationEnabled: boolean\r\n dynamicCalibrationEnabled: boolean\r\n dynamicData?: {\r\n webcamHeight: number\r\n ratioPixelToCentimeter: number\r\n deltaAgentHeightAgentWorldHeightInCentimeters: number\r\n cameraRotationInDegrees: number\r\n distanceFromAgentToCameraInCentimeters: number\r\n }\r\n setTargets: (targets: Array<Object3D>) => void\r\n}\r\n\r\nenum CalibrationMode {\r\n none = 1,\r\n static,\r\n dynamic\r\n}\r\n\r\nconst CalibrationScreen = ({ centered, staticCalibrationEnabled, dynamicCalibrationEnabled, dynamicData, setTargets }: CalibrationScreenProps): JSX.Element => {\r\n const dispatch = useDispatch()\r\n const cameraPosition = getCameraPosition()\r\n const characterHeight = getCharacterHeight()\r\n const characterLoaded = useSelector((state: RootState) => state.viewReducer.characterLoaded)\r\n const calibrationCompleted = useSelector((state: RootState) => state.viewReducer.calibrationCompleted)\r\n\r\n const [calibrationMode, setCalibrationMode] = useState<CalibrationMode>(dynamicData ? CalibrationMode.dynamic : CalibrationMode.none)\r\n const [distanceFromDevice, setDistanceFromDevice] = useState<number>(dynamicData?.distanceFromAgentToCameraInCentimeters || 0)\r\n const [webcamRotation, setWebcamRotation] = useState<number>(0)\r\n const [agentEyesHeightOnScreen, setAgentEyesHeightOnScreen] = useState<number>(0)\r\n const [worldDistancePerDegree, setWorldDistancePerDegree] = useState<number>(0)\r\n const [currentAngleInDegrees, setCurrentAngleInDegrees] = useState<number>(0)\r\n const [cameraX, setCameraX] = useState<number>(0)\r\n const [cameraY, setCameraY] = useState<number>(0)\r\n const [cameraZ, setCameraZ] = useState<number>(0)\r\n\r\n const cameraXRef = useRef<number>(0)\r\n const cameraYRef = useRef<number>(0)\r\n const cameraZRef = useRef<number>(0)\r\n const currentAngleInDegreesRef = useRef<number>(0)\r\n const webcamHeightRef = useRef<number>(dynamicData?.webcamHeight || 0)\r\n const userEyesHeightRef = useRef<number>(0)\r\n const agentEyesHeightRef = useRef<number>(0)\r\n const distanceFromDeviceRef = useRef<number>(0)\r\n const webcamRotatedRef = useRef<number>(dynamicData?.cameraRotationInDegrees || 0)\r\n const deltaAgentHeightAgentWorldHeightInCentimetersRef = useRef<number>(dynamicData?.deltaAgentHeightAgentWorldHeightInCentimeters || 0)\r\n const ratioPixelToCentimeterRef = useRef<number>(dynamicData?.ratioPixelToCentimeter || 0)\r\n const calibrationCompletedRef = useRef<boolean>(calibrationCompleted)\r\n const counterRef = useRef<number>(0)\r\n\r\n useEffect(() => {\r\n // If dynamic data are given, let's validate immediately to set calibratoin as completed\r\n dynamicData && handleValidate()\r\n }, [])\r\n\r\n useEffect(() => {\r\n characterLoaded && !dynamicData && setLookAtCamera(true)\r\n\r\n return () => {\r\n setLookAtCamera(false)\r\n }\r\n }, [characterLoaded])\r\n\r\n useEffect(() => {\r\n if (worldDistancePerDegree && !dynamicData) {\r\n const o = new Object3D()\r\n o.position.set(cameraX, cameraY + currentAngleInDegrees * worldDistancePerDegree, Math.max(cameraZ / 5, 0.3))\r\n setTargets([o])\r\n }\r\n }, [currentAngleInDegrees, worldDistancePerDegree, distanceFromDevice, cameraX, cameraY, cameraZ])\r\n\r\n useEffect(() => {\r\n if (cameraPosition && !(cameraPosition.x === 0 && cameraPosition.y === 0)) {\r\n const zDistanceCameraPlusUser = cameraPosition.z + distanceFromDevice / 100\r\n setCameraX(cameraPosition.x)\r\n setCameraY(cameraPosition.y)\r\n setCameraZ(zDistanceCameraPlusUser)\r\n cameraXRef.current = cameraPosition.x\r\n cameraYRef.current = cameraPosition.y\r\n cameraZRef.current = zDistanceCameraPlusUser\r\n // Get Y world distance for one degree using tangent. The z distance is divided by 5 with 0.3 at the lowest to show a visible height bar when calibrating\r\n setWorldDistancePerDegree(Math.tan(Math.PI / 180) * Math.max(zDistanceCameraPlusUser / 5, 0.3))\r\n }\r\n }, [cameraPosition, distanceFromDevice])\r\n\r\n useEffect(() => {\r\n if (!dynamicData) {\r\n characterHeight && agentEyesHeightOnScreen && (deltaAgentHeightAgentWorldHeightInCentimetersRef.current = (characterHeight - characterHeight / 16) * 100 - agentEyesHeightOnScreen)\r\n }\r\n }, [characterHeight, agentEyesHeightOnScreen])\r\n\r\n useEffect(() => {\r\n !dynamicData && (webcamRotatedRef.current = webcamRotation)\r\n }, [webcamRotation])\r\n\r\n useEffect(() => {\r\n calibrationCompletedRef.current = calibrationCompleted\r\n }, [calibrationCompleted])\r\n\r\n useEffect(() => {\r\n if (!dynamicData && calibrationMode === CalibrationMode.static) {\r\n setShowFirstTarget(!calibrationCompleted)\r\n }\r\n }, [calibrationMode, calibrationCompleted])\r\n\r\n const handleReset = () => {\r\n setCurrentAngleInDegrees(0)\r\n currentAngleInDegreesRef.current = 0\r\n }\r\n\r\n const handleValidate = () => {\r\n setLookAtCamera(false)\r\n if (calibrationMode === CalibrationMode.static) {\r\n // In static mode, store the target in local storage to be able to reuse it later and avoid asking the user to calibrate again if the data are valid\r\n localStorage.setItem('Retorik.Framework.Static.Target', JSON.stringify({ x: cameraX, y: cameraY + currentAngleInDegrees * worldDistancePerDegree, z: cameraZ }))\r\n } else if (calibrationMode === CalibrationMode.dynamic && ratioPixelToCentimeterRef.current) {\r\n localStorage.setItem(\r\n 'Retorik.Framework.Dynamic.Data',\r\n JSON.stringify({\r\n webcamHeight: webcamHeightRef.current,\r\n ratioPixelToCentimeter: ratioPixelToCentimeterRef.current,\r\n deltaAgentHeightAgentWorldHeightInCentimeters: deltaAgentHeightAgentWorldHeightInCentimetersRef.current,\r\n cameraRotationInDegrees: webcamRotatedRef.current,\r\n distanceFromAgentToCameraInCentimeters: distanceFromDeviceRef.current\r\n })\r\n )\r\n setTargets([])\r\n }\r\n\r\n dispatch(storeActions.view.setCalibrationCompleted(true))\r\n }\r\n\r\n const handleFaceDetected = (detections?: Array<Detection>, width?: number, height?: number): void => {\r\n counterRef.current++\r\n if (detections?.length && width && height) {\r\n // The detections are inverted in X and Y axis (the origin is the top right corner of the image)\r\n const webcamPositionY = webcamRotatedRef.current === 0 ? height / 2 : width / 2\r\n const userPositionY = webcamRotatedRef.current === 0 ? height * (1 - detections[0].keypoints[0].y) : width * (1 - detections[0].keypoints[0].x)\r\n\r\n if (calibrationCompletedRef.current) {\r\n // Check if the mandatory data have been filled (webcam / agent / user heights + distance user <-> device)\r\n if (webcamHeightRef.current && ratioPixelToCentimeterRef.current && deltaAgentHeightAgentWorldHeightInCentimetersRef.current !== 0) {\r\n const deltaHeightInPixels = webcamPositionY - userPositionY\r\n const userEyesHeightInCentimeters = webcamHeightRef.current - deltaHeightInPixels * ratioPixelToCentimeterRef.current\r\n const targetYInWorldCoordinates = (userEyesHeightInCentimeters + deltaAgentHeightAgentWorldHeightInCentimetersRef.current) / 100\r\n\r\n const o = new Object3D()\r\n o.position.set(cameraXRef.current, targetYInWorldCoordinates, cameraZRef.current)\r\n setTargets([o])\r\n }\r\n } else {\r\n // The detections are inverted in X and Y axis (the origin is the top right corner of the image)\r\n if (webcamHeightRef.current && userEyesHeightRef.current && distanceFromDeviceRef.current) {\r\n // Get the difference in height between the webcam and the user's eyes in cm, then use the detection to get the same difference in pixels on the webcam's image\r\n const deltaHeightInCentimeters = Math.abs(webcamHeightRef.current - userEyesHeightRef.current)\r\n const deltaHeightInPixels = Math.abs(webcamPositionY - userPositionY)\r\n\r\n deltaHeightInPixels && (ratioPixelToCentimeterRef.current = deltaHeightInCentimeters / deltaHeightInPixels)\r\n }\r\n }\r\n }\r\n }\r\n\r\n return (\r\n <div\r\n id='retorik-framework-animation-container-calibration'\r\n className={`rf-absolute rf-top-0 rf-h-full rf-w-full rf-grid rf-grid-cols-1 rf-grid-rows-1 ${!centered && 'landscape-retorik:rf-translate-x-1/4'}`}\r\n >\r\n {calibrationMode === CalibrationMode.dynamic && (\r\n <div className='rf-relative rf-z-1 rf-h-full rf-w-full rf-col-start-1 rf-col-span-1 rf-row-start-1 rf-row-span-1 rf-flex rf-justify-start rf-items-start'>\r\n <FaceDetector detectionThreshold={0.8} onFaceDetected={handleFaceDetected} showThumbnail={!calibrationCompleted} rotation={webcamRotation} />\r\n </div>\r\n )}\r\n\r\n {!calibrationCompleted && (\r\n <React.Fragment>\r\n {calibrationMode === CalibrationMode.none ? (\r\n <div className='rf-h-full rf-w-full rf-col-start-1 rf-col-span-1 rf-row-start-1 rf-row-span-1 rf-flex rf-flex-col rf-justify-center rf-items-center rf-gap-4 rf-bg-white rf-bg-opacity-50'>\r\n <p className='rf-text-medium-size-auto'>Choisissez un mode de calibrage :</p>\r\n <div className='rf-flex rf-flex-row rf-gap-4'>\r\n {staticCalibrationEnabled && (\r\n <div\r\n className='rf-px-4 rf-py-2 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer'\r\n onClick={() => setCalibrationMode(CalibrationMode.static)}\r\n >\r\n STATIQUE\r\n </div>\r\n )}\r\n\r\n {dynamicCalibrationEnabled && (\r\n <div\r\n className='rf-px-4 rf-py-2 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer'\r\n onClick={() => setCalibrationMode(CalibrationMode.dynamic)}\r\n >\r\n DYNAMIQUE\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n ) : (\r\n <div className='rf-relative rf-h-full rf-w-full rf-col-start-1 rf-col-span-1 rf-row-start-1 rf-row-span-1 rf-flex rf-flex-col rf-justify-center rf-gap-4'>\r\n {calibrationMode === CalibrationMode.dynamic ? (\r\n <div className='rf-absolute rf-left-32 rf-flex rf-flex-col rf-justify-center rf-items-center rf-gap-4'>\r\n <div className='rf-grid rf-grid-cols-2 rf-grid-rows-3 rf-gap-4'>\r\n <p className='rf-font-bold'>Hauteur webcam (en cm)</p>\r\n <input\r\n type='number'\r\n min={0}\r\n max={300}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n webcamHeightRef.current = parseInt(e.target.value!)\r\n }}\r\n />\r\n <p className='rf-font-bold'>Votre taille (en cm)</p>\r\n <input\r\n type='number'\r\n min={50}\r\n max={300}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n // We estimate the height of the user's eyes is 12 cm less than their total height\r\n userEyesHeightRef.current = parseInt(e.target.value!) - 12\r\n }}\r\n />\r\n <p className='rf-font-bold'>Hauteur des yeux de l'agent (en cm)</p>\r\n <input\r\n type='number'\r\n min={50}\r\n max={300}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n setAgentEyesHeightOnScreen(parseInt(e.target.value!))\r\n agentEyesHeightRef.current = parseInt(e.target.value!)\r\n }}\r\n />\r\n <p className='rf-font-bold'>Distance utilisateur - borne (en cm)</p>\r\n <input\r\n type='number'\r\n min={20}\r\n max={100}\r\n onChange={(e: React.ChangeEvent<HTMLInputElement>) => {\r\n setDistanceFromDevice(parseInt(e.target.value!))\r\n distanceFromDeviceRef.current = parseInt(e.target.value!)\r\n }}\r\n />\r\n <p className='rf-font-bold'>Rotation de la webcam (en degrés)</p>\r\n <div className='rf-flex rf-flex-row rf-gap-2'>\r\n <button\r\n className={`rf-px-2 rf-py-1 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer ${webcamRotation === 0 && 'rf-bg-opacity-100'}`}\r\n onClick={() => setWebcamRotation(0)}\r\n >\r\n 0\r\n </button>\r\n <button\r\n className={`rf-px-2 rf-py-1 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer ${webcamRotation === 90 && 'rf-bg-opacity-100'}`}\r\n onClick={() => setWebcamRotation(90)}\r\n >\r\n 90\r\n </button>\r\n <button\r\n className={`rf-px-2 rf-py-1 rf-border rf-border-primary rf-rounded-lg rf-bg-primary rf-bg-opacity-50 rf-cursor-pointer ${webcamRotation === -90 && 'rf-bg-opacity-100'}`}\r\n onClick={() => setWebcamRotation(-90)}\r\n >\r\n -90\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div className='rf-h-16 rf-w-16 rf-flex rf-justify-center rf-items-center rf-bg-white rf-border rf-border-black rf-rounded-lg hover: rf-cursor-pointer' onClick={handleValidate}>\r\n Done\r\n </div>\r\n </div>\r\n ) : (\r\n <div className='rf-ml-4 rf-flex rf-flex-col rf-gap-4'>\r\n <div className='rf-flex rf-flex-row rf-items-center rf-gap-4'>\r\n <input\r\n type='range'\r\n min={-25}\r\n max={25}\r\n step={1}\r\n value={currentAngleInDegrees}\r\n onChange={(e) => {\r\n const val = parseInt(e.target.value)\r\n setCurrentAngleInDegrees(val)\r\n currentAngleInDegreesRef.current = val\r\n }}\r\n className='rf-range-vertical rf-w-8 rf-h-80 rf-appearance-none rf-border rf-border-black rf-rounded-lg rf-cursor-pointer'\r\n style={{ writingMode: 'vertical-lr', direction: 'rtl' }}\r\n />\r\n <div className='rf-w-fit rf-p-4 rf-flex rf-flex-col rf-justify-center rf-gap-2 rf-bg-white rf-border rf-border-black rf-rounded-lg'>\r\n <p>Position actuelle de la cible : </p>\r\n <p>{`x: ${cameraX}`}</p>\r\n <p>{`y: ${cameraY + (currentAngleInDegrees ? currentAngleInDegrees * worldDistancePerDegree : 0)}`}</p>\r\n <p>{`z: ${Math.max(cameraZ / 5, 0.3)}`}</p>\r\n <p>{`angle: ${currentAngleInDegrees}°`}</p>\r\n </div>\r\n </div>\r\n\r\n <div className='rf-flex rf-flex-row rf-gap-2'>\r\n <div className='rf-h-10 rf-px-4 rf-flex rf-justify-center rf-items-center rf-bg-white rf-border rf-border-black rf-rounded-lg rf-cursor-pointer' onClick={() => handleReset()}>\r\n Reset\r\n </div>\r\n <div className='rf-h-10 rf-px-4 rf-flex rf-justify-center rf-items-center rf-bg-white rf-border rf-border-black rf-rounded-lg rf-cursor-pointer' onClick={handleValidate}>\r\n Done\r\n </div>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </React.Fragment>\r\n )}\r\n </div>\r\n )\r\n}\r\n\r\nexport default CalibrationScreen\r\n","import React, { useEffect, useState, useRef } from 'react'\r\nimport { FaceDetector as MediapipeFaceDetector, FilesetResolver, Detection } from '@mediapipe/tasks-vision'\r\n\r\ninterface FaceDetectorProps {\r\n detectionThreshold: number\r\n onFaceDetected: (detections?: Array<Detection>, imageWidth?: number, imageHeight?: number) => void\r\n showThumbnail?: boolean\r\n rotation?: number\r\n}\r\n\r\nconst runningMode = 'VIDEO'\r\nlet lastVideoTime = -1\r\nconst defaultConstraints: MediaStreamConstraints = {\r\n video: {\r\n facingMode: 'user'\r\n }\r\n}\r\n\r\nconst FaceDetector = ({ detectionThreshold, onFaceDetected, showThumbnail, rotation }: FaceDetectorProps): JSX.Element => {\r\n const [webcamWidth, setWebcamWidth] = useState<number>(0)\r\n const [webcamHeight, setWebcamHeight] = useState<number>(0)\r\n const [faceDetector, setFaceDetector] = useState<MediapipeFaceDetector | undefined>()\r\n const videoRef = useRef<HTMLVideoElement>(null)\r\n const rotationRef = useRef<number>(rotation || 0)\r\n\r\n useEffect(() => {\r\n rotationRef.current = rotation || 0\r\n }, [rotation])\r\n\r\n useEffect(() => {\r\n const createfaceDetector = async () => {\r\n const vision = await FilesetResolver.forVisionTasks('https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.0/wasm')\r\n const newFaceDetector = await MediapipeFaceDetector.createFromOptions(vision, {\r\n baseOptions: {\r\n modelAssetPath: `https://storage.googleapis.com/mediapipe-models/face_detector/blaze_face_short_range/float16/1/blaze_face_short_range.tflite`,\r\n delegate: 'GPU'\r\n },\r\n runningMode: runningMode\r\n })\r\n\r\n newFaceDetector && setFaceDetector(newFaceDetector)\r\n }\r\n\r\n const initializefaceDetector = async () => {\r\n navigator.mediaDevices\r\n .getUserMedia(defaultConstraints)\r\n .then((display) => {\r\n const settings = display.getVideoTracks()[0].getSettings()\r\n setWebcamWidth(settings.width || 0)\r\n setWebcamHeight(settings.height || 0)\r\n createfaceDetector()\r\n })\r\n .catch((error) => console.warn('Retorik Framework > an error occured when trying to use the webcam : ', error))\r\n }\r\n\r\n initializefaceDetector()\r\n }, [])\r\n\r\n const predictWebcam = async () => {\r\n if (faceDetector && videoRef.current) {\r\n let startTimeMs = performance.now()\r\n\r\n // Detect faces using detectForVideo\r\n if (videoRef.current.currentTime !== lastVideoTime) {\r\n lastVideoTime = videoRef.current.currentTime\r\n const detections = faceDetector.detectForVideo(videoRef.current, startTimeMs, { rotationDegrees: rotationRef.current }).detections\r\n\r\n if (detections.length) {\r\n const score = detections[0].categories[0].score\r\n score > detectionThreshold && onFaceDetected(detections, videoRef.current.videoWidth, videoRef.current.videoHeight)\r\n }\r\n }\r\n }\r\n\r\n // Call this function again to keep predicting when the browser is ready\r\n window.requestAnimationFrame(predictWebcam)\r\n }\r\n\r\n useEffect(() => {\r\n if (faceDetector && videoRef.current) {\r\n // Activate the webcam stream\r\n navigator.mediaDevices\r\n .getUserMedia(defaultConstraints)\r\n .then((stream) => {\r\n if (videoRef.current) {\r\n videoRef.current.srcObject = stream\r\n videoRef.current.addEventListener('loadeddata', predictWebcam)\r\n }\r\n })\r\n .catch((err) => {\r\n console.error(err)\r\n })\r\n }\r\n }, [faceDetector])\r\n\r\n return (\r\n <div id='retorik-framework-face-detector' className={`rf-absolute rf-top-0 rf-left-0 ${!showThumbnail && 'rf-invisible'}`}>\r\n <video\r\n ref={videoRef}\r\n src=''\r\n autoPlay\r\n style={{\r\n rotate: `${rotation}deg`,\r\n width: showThumbnail ? webcamWidth / 2 : webcamWidth,\r\n height: showThumbnail ? webcamHeight / 2 : webcamHeight\r\n }}\r\n />\r\n </div>\r\n )\r\n}\r\n\r\nexport default FaceDetector\r\n"],"names":[],"version":3,"file":"ThreeJsWrapper.c02a077f.js.map","sourceRoot":"../"}