import { useState , useRef , useLayoutEffect } from 'react' ; import { c } from 'ttag' ; import createListeners from '@proton/shared/lib/helpers/listeners' ; import { wait } from '@proton/shared/lib/helpers/promise' ; import { AppLink , useIsMounted } from '@proton/components' ; import { VIEW_MODE } from '@proton/shared/lib/constants' ; import { isToday , isTomorrow } from 'date-fns' ; import { Message } from '@proton/shared/lib/interfaces/mail/Message' ; import UndoButton from './UndoButton' ; import { formatDateToHuman } from '../../helpers/date' ; export const createSendingMessageNotificationManager = ( ) => { const listeners = createListeners ( ) ; return { ID : - 1 , setProperties : ( promise , onUndo ? ) => { listeners . notify ( promise , onUndo ) ; } , ... listeners , } ; } ; export type SendingMessageNotificationManager = ReturnType < typeof createSendingMessageNotificationManager > ; interface SendingMessageNotificationProps { manager : SendingMessageNotificationManager ; scheduledAt ? : number ; viewMode : number ; message : Message | undefined ; } enum SendingStep { sending , sent , sentWithUndo } const SendingMessageNotification = ( { manager , scheduledAt , viewMode , message } ) => { const [ state , setState ] = useState ( SendingStep . sending ) ; const onUndoRef = useRef < ( ) => Promise < void > | undefined > ( ) ; const isMounted = useIsMounted ( ) ; const getScheduledNotification = ( scheduledAt , onUndo ) => { const scheduleDate = scheduledAt * 1000 ; const { dateString , formattedTime } = formatDateToHuman ( scheduleDate ) ; const getNotificationText = ( ) => { if ( isToday ( scheduleDate ) ) { return c ( 'Info' ) . t `Message will be sent today at ${ formattedTime }` ; } if ( isTomorrow ( scheduleDate ) ) { return c ( 'Info' ) . t `Message will be sent tomorrow at ${ formattedTime }` ; } return c ( 'Info' ) . t `Message will be sent on ${ dateString } at ${ formattedTime }` ; } ; const notification = getNotificationText ( ) ; const linkID = viewMode === VIEW_MODE . GROUP ? message ?. ConversationID : message ?. ID ; return ( < > < span className = "mr1" > { notification } < /span> { onUndo && < UndoButton className = "mr1" onUndo = { onUndo } / > } < AppLink to = { `/scheduled/${ linkID }` } > { c ( 'Action' ) . t `View message` } < /AppLink> < />); } ; useLayoutEffect ( ( ) => { return manager . subscribe ( async ( promise , onUndo ) => { onUndoRef . current = onUndo ; const { undoTimeout } = await promise ; if ( isMounted ( ) ) { setState ( undoTimeout ? SendingStep . sentWithUndo : SendingStep . sent ) ; } if ( undoTimeout ) { await wait ( undoTimeout ) ; if ( isMounted ( ) ) { setState ( SendingStep . sent ) ; } } } ) ; } , [ ] ) ; if ( state === SendingStep . sent ) { return < > { scheduledAt ? getScheduledNotification ( scheduledAt , undefined ) : c ( 'Info' ) . t `Message sent` } < />; } const onUndo = onUndoRef . current ; if ( state === SendingStep . sentWithUndo && onUndo ) { if ( scheduledAt ) { return getScheduledNotification ( scheduledAt , onUndo ) ; } return ( < > < span className = "mr1" > { c ( 'Info' ) . t `Message sent.` } < /span> < UndoButton onUndo = { onUndo } / > < />); } return < > { scheduledAt ? c ( 'Info' ) . t `Scheduling message...` : c ( 'Info' ) . t `Sending message...` } < />; } ; export default SendingMessageNotification ;