Skip to content

Commit

Permalink
errors & alerts. avoid ghost calls and new collapse button (#59)
Browse files Browse the repository at this point in the history
* UI. Avoid ghost calls and new collapse button
* alerts. Created new style for alerts
* alerts. Clear all alerts on close notification button
* avatar. New avatar UI
* timer. Fixed wrong caller time
  • Loading branch information
tonyco97 authored Oct 29, 2024
1 parent 138675f commit d6f1e3f
Show file tree
Hide file tree
Showing 26 changed files with 675 additions and 204 deletions.
5 changes: 5 additions & 0 deletions docs/EVENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ eventDispatch(`<event-name>`, `<data-object>`)
{}
```

- `phone-island-all-alerts-removed` The dispatch of clear alerts status

```json
{}
```

## Listen Call Events - phone-island-call-*

Expand Down
383 changes: 323 additions & 60 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"dependencies": {
"@fortawesome/free-solid-svg-icons": "^6.2.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^1.7.18",
"@headlessui/react": "^2.2.0",
"@nethesis/nethesis-light-svg-icons": "github:nethesis/Font-Awesome#ns-light",
"@nethesis/nethesis-solid-svg-icons": "github:nethesis/Font-Awesome#ns-solid",
"@rematch/core": "^2.2.0",
Expand Down Expand Up @@ -130,7 +130,7 @@
"rollup-plugin-terser": "^7.0.2",
"storybook": "^7.6.20",
"tailwind-scrollbar": "^3.1.0",
"tailwindcss": "^3.4.1",
"tailwindcss": "^3.4.14",
"typescript": "^4.8.4",
"webm-duration-fix": "^1.0.4",
"webpack": "^5.74.0"
Expand Down
19 changes: 18 additions & 1 deletion public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,26 @@
},
"Call": {
"In progress...": "In progress...",
"Outgoing call": "Outgoing call"
"Outgoing call": "Outgoing call",
"Incoming call": "Incoming call"
},
"Transfer": {
"No users found": "No users found"
},
"Errors": {
"browser_permissions": "Browser Permissions Error",
"user_permissions": "User Permissions Error",
"unknown_media_permissions": "Unknown Media Permissions Error",
"webrtc_down": "WebRTC Down",
"socket_down": "Socket Down",
"busy_camera": "Busy Camera",
"call_transfered": "Call Transferred Successfully",
"The browser doesn't have permission to access camera or microphone.": "The browser doesn't have permission to access camera or microphone.",
"You must accept audio and video permissions.": "You must accept audio and video permissions.",
"Web Phone can't access audio or camera on this device.": "Web Phone can't access audio or camera on this device.",
"Web Phone connection is down.": "Web Phone connection is down.",
"Server connection is down.": "Server connection is down.",
"Camera is used by another application.": "Camera is used by another application.",
"Call transferred successfully.": "Call transferred successfully."
}
}
19 changes: 18 additions & 1 deletion public/locales/it/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,26 @@
},
"Call": {
"In progress...": "In corso...",
"Outgoing call": "Chiamata in uscita"
"Outgoing call": "Chiamata in uscita",
"Incoming call": "Chiamata in arrivo"
},
"Transfer": {
"No users found": "Nessun utente trovato"
},
"Errors": {
"browser_permissions": "Errore di autorizzazione",
"user_permissions": "Errore di autorizzazione",
"unknown_media_permissions": "Errore di autorizzazione",
"webrtc_down": "WebRTC non disponibile",
"socket_down": "Socket non disponibile",
"busy_camera": "Camera occupata",
"call_transfered": "Chiamata trasferita con successo",
"The browser doesn't have permission to access camera or microphone.": "Il browser non ha il permesso di accedere alla fotocamera o al microfono.",
"You must accept audio and video permissions.": "Devi accettare i permessi audio e video.",
"Web Phone can't access audio or camera on this device.": "Il Web Phone non può accedere all'audio o alla fotocamera su questo dispositivo.",
"Web Phone connection is down.": "La connessione del Web Phone è interrotta.",
"Server connection is down.": "La connessione al server è interrotta.",
"Camera is used by another application.": "La fotocamera è utilizzata da un'altra applicazione.",
"Call transferred successfully.": "Chiamata trasferita con successo."
}
}
4 changes: 4 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ export const PhoneIsland: FC<PhoneIslandProps> = ({
console.log('Transfer failed')
})

useEventListener('phone-island-all-alerts-removed', () => {
console.log('All alerts removed')
})

return (
<>
<Provider store={store}>
Expand Down
2 changes: 1 addition & 1 deletion src/components/AlertGuard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (C) 2024 Nethesis S.r.l.
// SPDX-License-Identifier: AGPL-3.0-or-later

import React, { useEffect, type FC, type ReactNode } from 'react'
import React, { type FC, type ReactNode } from 'react'
import { useSelector } from 'react-redux'
import { RootState } from '../store'
import AlertView from './AlertView'
Expand Down
43 changes: 0 additions & 43 deletions src/components/AlertView/Alert.tsx

This file was deleted.

90 changes: 62 additions & 28 deletions src/components/AlertView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,76 @@
// Copyright (C) 2024 Nethesis S.r.l.
// SPDX-License-Identifier: AGPL-3.0-or-later

import React, { type FC } from 'react'
import Alert from './Alert'
import { useSelector } from 'react-redux'
import { RootState } from '../../store'
import { motion } from 'framer-motion'
import React, { FC } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Dispatch, RootState } from '../../store'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faTimes, faCircleXmark, faCircleCheck } from '@fortawesome/free-solid-svg-icons'
import { Button } from '../Button'
import { t } from 'i18next'
import { eventDispatch } from '../../utils'

/**
* Shows user alerts
*/
const AlertView: FC = () => {
const { data, status } = useSelector((state: RootState) => state.alerts)
const { data } = useSelector((state: RootState) => state.alerts)
const dispatch = useDispatch<Dispatch>()

// Extract active alerts
const activeAlerts = Object.values(data).filter((alert: any) => alert.active)

// Display the latest active alert
const latestAlert = activeAlerts.length > 0 ? activeAlerts[activeAlerts.length - 1] : null

const handleClearAllAlerts = () => {
dispatch.alerts.removeAllAlerts()
eventDispatch('phone-island-all-alerts-removed', {})
}

return (
<motion.div
className={`pi-flex pi-flex-col pi-gap-4 pi-mb-6 pi-overflow-y-auto pi-custom-scrollbar ${
status.activeAlertsCount > 1 && 'pi-pr-2'
}`}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
style={{
maxHeight: '5.5rem',
}}
>
{/* Show alerts */}
{Object.values(data).map(
(alert:any, index) =>
alert.active && (
<Alert
key={index}
type='alert'
color={alert?.success ? 'green' : alert?.break ? 'red' : 'orange'}
message={alert?.message}
latestAlert && (
<div className='pi-relative pi-rounded-md pi-w-full pi-flex pi-mt-[-1rem]'>
<div className='pi-flex pi-items-center'>
<div
className={`pi-flex pi-items-center pi-justify-center pi-flex-shrink-0 pi-mr-4 pi-rounded-full pi-h-10 pi-w-10 pi-mt-[-0.8rem] ${
latestAlert?.type === 'call_transfered'
? 'pi-bg-green-200 dark:pi-bg-green-900'
: 'pi-bg-rose-200 dark:pi-bg-rose-900'
}`}
>
{/* Icon */}
<FontAwesomeIcon
icon={latestAlert?.type === 'call_transfered' ? faCircleCheck : faCircleXmark}
className={`pi-h-4 pi-w-4 ${
latestAlert?.type === 'call_transfered'
? 'pi-text-green-700 dark:pi-text-green-200'
: 'pi-text-rose-700 dark:pi-text-rose-200'
}`}
aria-hidden='true'
/>
),
)}
</motion.div>
</div>

<div className='ml-3'>
<h3 className='pi-text-lg pi-font-medium pi-text-gray-900 dark:pi-text-gray-50 pi-dark:text-rose-100'>
{t(`Errors.${latestAlert?.type}`)}
</h3>
<div className='pi-text-sm pi-font-normal pi-text-gray-700 dark:pi-text-gray-200 pi-dark:text-rose-200 pi-leading-5'>
{t(`Errors.${latestAlert?.message}`)}
</div>
</div>
</div>

{/* Close button */}
<Button
variant='transparent'
onClick={() => handleClearAllAlerts()}
className='pi-absolute pi-right-[-0.5rem] pi-top-[38%] pi-transform pi--translate-y-1/2'
>
<FontAwesomeIcon icon={faTimes} className='pi-text-gray-700 dark:pi-text-gray-50 pi-w-4 pi-h-4' />
</Button>
</div>
)
)
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/AudioPlayerView/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export const Avatar: FC<AvatarProps> = ({ type }) => {
<motion.div
animate={
isOpen
? { width: '48px', height: '48px', borderRadius: '12px' }
: { width: '24px', height: '24px', borderRadius: '6px' }
? { width: '56px', height: '56px', borderRadius: '26px' }
: { width: '24px', height: '24px', borderRadius: '26px' }
}
className='pi-w-12 pi-h-12 pi-bg-gray-500 pi-rounded-xl pi-flex pi-items-center pi-justify-center pi-flex-shrink-0 pi-flex-grow-0'
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const Button: FC<ButtonProps> = ({
neutral:
'pi-bg-transparent enabled:hover:pi-bg-gray-500 enabled:hover:pi-border-gray-500 pi-border pi-border-gray-700 focus:pi-ring-0',
transparent:
'pi-bg-transparent dark:enabled:hover:pi-bg-gray-500 enabled:hover:pi-bg-gray-400 focus:pi-ring-offset-gray-200 dark:focus:pi-ring-gray-500 dark:focus:pi-ring-gray-500 focus:pi-ring-gray-400 dark:pi-text-white',
'pi-bg-transparent dark:enabled:hover:pi-bg-gray-600/30 enabled:hover:pi-bg-gray-200/70 focus:pi-ring-offset-gray-200 dark:focus:pi-ring-gray-500 dark:focus:pi-ring-gray-500 focus:pi-ring-gray-400 dark:pi-text-white',
},
background: {
base: {
Expand Down
10 changes: 5 additions & 5 deletions src/components/CallView/Actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,14 @@ const Actions: FC = () => {
<>
<div
className={`${
!intrudeListenStatus.isListen && !intrudeListenStatus.isIntrude
!intrudeListenStatus?.isListen && !intrudeListenStatus?.isIntrude
? 'pi-grid pi-grid-cols-4 pi-auto-cols-max pi-gap-y-5 pi-justify-items-center pi-place-items-center pi-justify-center'
: intrudeListenStatus.isIntrude
? 'pi-mb-6 pi-grid pi-grid-cols-1 pi-auto-cols-max pi-gap-y-5 pi-justify-items-center pi-place-items-center pi-justify-center'
: 'pi-hidden'
} `}
>
{!(intrudeListenStatus.isIntrude || intrudeListenStatus.isListen) && (
{!(intrudeListenStatus?.isIntrude || intrudeListenStatus?.isListen) && (
<Button
variant='default'
active={paused ? true : false}
Expand All @@ -152,7 +152,7 @@ const Actions: FC = () => {
)}
</Button>
)}
{!intrudeListenStatus.isListen && (
{!intrudeListenStatus?.isListen && (
<Button
variant='default'
active={muted ? true : false}
Expand Down Expand Up @@ -198,14 +198,14 @@ const Actions: FC = () => {
>
{actionsExpanded ? (
<FontAwesomeIcon
className='pi-text-gray-700 dark:pi-text-gray-300'
className='pi-text-gray-700 dark:pi-text-gray-200'
size='xl'
icon={faChevronUp}
/>
) : (
<FontAwesomeIcon
size='xl'
className='pi-text-gray-700 dark:pi-text-gray-300'
className='pi-text-gray-700 dark:pi-text-gray-200'
icon={faChevronDown}
/>
)}
Expand Down
10 changes: 5 additions & 5 deletions src/components/CallView/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import { RootState } from '../../store'

const iconVariants = {
open: {
width: '48px',
height: '48px',
borderRadius: '12px',
width: '56px',
height: '56px',
borderRadius: '26px',
},
closed: {
width: '24px',
height: '24px',
borderRadius: '6px',
borderRadius: '26px',
},
}

Expand All @@ -39,7 +39,7 @@ const Avatar: FC = () => {
return (
<>
<motion.div
className='pi-relative'
className={`pi-relative ${isOpen ? 'pi-mt-[-0.25rem]' : ''}`}
animate={isOpen ? 'open' : 'closed'}
variants={iconVariants}
>
Expand Down
10 changes: 6 additions & 4 deletions src/components/CallView/DisplayName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const DisplayName: FC<DisplayNameProps> = () => {
const NameMotion = motion(StyledName)

// Get the displayName of the currentCall store
const { displayName } = useSelector((state: RootState) => state.currentCall)
const { displayName, incoming } = useSelector((state: RootState) => state.currentCall)
const intrudeListenStatus = useSelector((state: RootState) => state.listen)

const { t } = useTranslation()
Expand All @@ -38,7 +38,7 @@ const DisplayName: FC<DisplayNameProps> = () => {
className='pi-whitespace-nowrap pi-relative pi-overflow-hidden'
>
<div
className={`pi-w-fit pi-relative pi-inline-block pi-text-gray-900 dark:pi-text-gray-200 ${
className={`pi-w-fit pi-relative pi-inline-block pi-text-gray-950 dark:pi-text-gray-50 ${
animateText && 'animated-text'
}`}
ref={nameText}
Expand All @@ -56,7 +56,7 @@ const DisplayName: FC<DisplayNameProps> = () => {
className='pi-whitespace-nowrap pi-relative pi-overflow-hidden'
>
<div
className={`pi-w-fit pi-relative pi-inline-block pi-text-gray-900 dark:pi-text-gray-200 ${
className={`pi-w-fit pi-relative pi-inline-block pi-text-gray-950 dark:pi-text-gray-50 ${
animateText && 'animated-text'
}`}
ref={nameText}
Expand All @@ -74,7 +74,7 @@ const DisplayName: FC<DisplayNameProps> = () => {
className='pi-whitespace-nowrap pi-relative pi-overflow-hidden '
>
<div
className={`pi-w-fit pi-relative pi-inline-block pi-text-gray-900 dark:pi-text-gray-200 ${
className={`pi-w-fit pi-relative pi-inline-block pi-text-gray-950 dark:pi-text-gray-50 ${
animateText && 'animated-text'
}`}
ref={nameText}
Expand All @@ -83,6 +83,8 @@ const DisplayName: FC<DisplayNameProps> = () => {
? 'PBX'
: displayName
? displayName
: incoming
? t('Call.Incoming call') || '-'
: t('Call.Outgoing call') || '-'}
</div>
<div className='pi-w-6 pi-absolute pi-right-0 pi-top-0 pi-h-full pi-bg-gradient-to-r pi-from-transparent dark:pi-to-gray-950 pi-to-gray-50'>
Expand Down
Loading

0 comments on commit d6f1e3f

Please sign in to comment.