diff --git a/docs/EVENTS.md b/docs/EVENTS.md index 126c462..deabbed 100644 --- a/docs/EVENTS.md +++ b/docs/EVENTS.md @@ -494,6 +494,15 @@ eventDispatch(``, ``) {} ``` +- `phone-island-action-physical` The dispatch of physical phone call or action + + ```json + { + "url": "http://username:password@physicalPhoneIp/cgi-bin/ConfigManApp.com?key=numberCalled;ENTER", + "urlType": "call" + } + ```` + ## Listen Recording Events - phone-island-recording-* - `phone-island-recording-open` The event to show the recording view. diff --git a/src/components/AlertView/index.tsx b/src/components/AlertView/index.tsx index 6be7df3..10628ae 100644 --- a/src/components/AlertView/index.tsx +++ b/src/components/AlertView/index.tsx @@ -30,7 +30,7 @@ const AlertView: FC = () => { return ( latestAlert && ( -
+
= () => { const [animateText, setAnimateText] = useState(false) @@ -22,9 +23,9 @@ const DisplayName: FC = () => { useLayoutEffect(() => { if ( - nameContainer.current && - nameText.current && - nameText.current.clientWidth - nameContainer.current.clientWidth > 5 + nameContainer?.current && + nameText?.current && + nameText?.current?.clientWidth - nameContainer?.current?.clientWidth > 5 ) { setAnimateText(true) } @@ -74,22 +75,22 @@ const DisplayName: FC = () => { className='pi-whitespace-nowrap pi-relative pi-overflow-hidden ' >
- {displayName && displayName === '' - ? 'PBX' - : displayName - ? displayName - : incoming - ? t('Call.Incoming call') || '-' - : t('Call.Outgoing call') || '-'} -
-
- {' '} + {displayName && displayName === '' ? ( + 'PBX' + ) : displayName ? ( + + ) : incoming ? ( + t('Call.Incoming call') || '-' + ) : ( + t('Call.Outgoing call') || '-' + )}
+
)} diff --git a/src/components/Socket.tsx b/src/components/Socket.tsx index d802fb9..dcfce44 100644 --- a/src/components/Socket.tsx +++ b/src/components/Socket.tsx @@ -15,6 +15,7 @@ import { dispatchServerReload, dispatchParkingUpdate, dispatchExtensions, + dispatchUrlCall, } from '../events' import { store } from '../store' import { eventDispatch, withTimeout } from '../utils' @@ -84,6 +85,7 @@ export const Socket: FC = ({ // Handle transferring data const { transferring, transferSwitching, transferCalls } = store.getState().currentCall + const view = store.getState().island.view // Check conversation isn't empty if (Object.keys(conv).length > 0) { // With conversation @@ -136,6 +138,11 @@ export const Socket: FC = ({ if (userInformation?.default_device?.type === 'physical') { checkDefaultDeviceConversationActive(conv) } + if (view === 'call' && transferring) { + dispatch.currentCall.updateCurrentCall({ + transferring: false, + }) + } } // Handle not connected calls else if (conv && !conv.connected) { @@ -403,6 +410,12 @@ export const Socket: FC = ({ // Dispatch serverReload event dispatchParkingUpdate() }) + + // `callNethLink` is the socket event when user make a call or a action from NethLink and has a physical device + socket.current.on('callNethLink', (link, urlType) => { + // Dispatch phone island physical call event with the link and the urlType + dispatchUrlCall(link, urlType) + }) } initSocketConnection() diff --git a/src/components/TextScroll.tsx b/src/components/TextScroll.tsx new file mode 100644 index 0000000..bb650fd --- /dev/null +++ b/src/components/TextScroll.tsx @@ -0,0 +1,39 @@ +/* Copyright (C) 2024 Nethesis S.r.l. */ +/* SPDX-License-Identifier: AGPL-3.0-or-later */ + +import React, { useState, useEffect } from 'react' + +interface TextScrollProps { + text: string +} + +const TextScroll: React.FC = ({ text }) => { + const [scrollText, setScrollText] = useState(false) + + useEffect(() => { + if (text.length > 15) { + setScrollText(true) + } else { + setScrollText(false) + } + }, [text]) + + return ( + <> + {scrollText ? ( +
+
+ {text} + {text} +
+
+ ) : ( +
+ {text} +
+ )} + + ) +} + +export default TextScroll diff --git a/src/events/SocketEvents.ts b/src/events/SocketEvents.ts index f38aae6..6177d31 100644 --- a/src/events/SocketEvents.ts +++ b/src/events/SocketEvents.ts @@ -130,3 +130,17 @@ export function dispatchParkingUpdate() { // Dispatch the event on window for external handlers eventDispatch('phone-island-parking-update', {}) } + +/** + * The dispatch function for url physical call + * + * @param event The parking update event from socket + */ +export function dispatchUrlCall(url: string, urlType: string) { + // Dispatch the event on window for external handlers + let urlCallObject = { + url: url, + urlType: urlType, + } + eventDispatch('phone-island-action-physical', { urlCallObject }) +} diff --git a/src/index.css b/src/index.css index 806eb7f..42f2758 100644 --- a/src/index.css +++ b/src/index.css @@ -46,3 +46,23 @@ input::placeholder { font-size: 14px; opacity: 1; } + +@keyframes scrollText { + 0% { + transform: translateX(0); + } + 100% { + transform: translateX(-50%); + } +} + +.text-container { + width: 200px; + overflow: hidden; +} + +.text-wrapper { + display: inline-block; + white-space: nowrap; + animation: scrolltext 15s linear infinite; +} diff --git a/src/stories/Call.stories.tsx b/src/stories/Call.stories.tsx index fd1a1ea..324b56e 100644 --- a/src/stories/Call.stories.tsx +++ b/src/stories/Call.stories.tsx @@ -29,10 +29,6 @@ const meta: Meta = { export default meta -// Uses the configuration token from .env -const config = process.env.CONFIG_TOKEN -type Story = StoryObj - const CallTemplate = (args: any) => { const [eventName, setEventName] = useState('phone-island-recording-open') //take the number from input field @@ -156,6 +152,11 @@ const CallTemplate = (args: any) => { setToastMessage('Phone island is detached...') }) + useEventListener('phone-island-action-physical', (data) => { + console.log('Phone island physical call', data) + setToastMessage('Phone island physical action...') + }) + const toastNotification = () => { return (
diff --git a/tailwind.config.js b/tailwind.config.js index a22653f..5d36d2b 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -26,9 +26,14 @@ module.exports = { left: '100%', }, }, + scroll: { + '0%': { transform: 'translateX(0)' }, + '100%': { transform: 'translateX(-100%)' }, + }, }, animation: { 'animated-text': '3s linear 0s infinite alternate move', + 'scroll-text': 'scroll 10s linear infinite', 'custom-ping': 'ping 2s cubic-bezier(0, 0, 0.2, 1) infinite', }, fontFamily: {