import { wait } from '@proton/shared/lib/helpers/promise' ; import { useRef , useState } from 'react' ; import { useHandler , useIsMounted , useNotifications } from '@proton/components' ; import { Abortable } from '@proton/components/hooks/useHandler' ; import { c } from 'ttag' ; import SavingDraftNotification , { SavingDraftNotificationAction , } from '../../components/notifications/SavingDraftNotification' ; import { useOnCompose } from '../../containers/ComposeProvider' ; import { PromiseHandlers } from '../usePromise' ; import { MessageState } from '../../logic/messages/messagesTypes' ; export interface UseCloseHandlerParameters { modelMessage : MessageState ; syncedMessage : MessageState ; lock : boolean ; ensureMessageContent : ( ) => void ; uploadInProgress : boolean ; promiseUpload : Promise < void > ; pendingAutoSave : PromiseHandlers < void > ; autoSave : ( ( message : MessageState ) => Promise < void > ) & Abortable ; saveNow : ( message : MessageState ) => Promise < void > ; onClose : ( ) => void ; onDiscard : ( ) => void ; onMessageAlreadySent : ( ) => void ; } export const useCloseHandler = ( { modelMessage , syncedMessage , lock , ensureMessageContent , saveNow , uploadInProgress , pendingAutoSave , promiseUpload , onClose , onDiscard , onMessageAlreadySent , } ) => { const { createNotification , hideNotification } = useNotifications ( ) ; const isMounted = useIsMounted ( ) ; const onCompose = useOnCompose ( ) ; const [ saving , setSavingUnsafe ] = useState ( false ) ; const setSaving = ( value ) => { if ( isMounted ( ) ) { setSavingUnsafe ( value ) ; } } ; const notficationRef = useRef < SavingDraftNotificationAction > ( ) ; const handleManualSaveAfterUploads = useHandler ( async ( notificationID ) => { try { await saveNow ( modelMessage ) ; notficationRef . current ?. saved ( ) ; await wait ( 3000 ) ; } finally { hideNotification ( notificationID ) ; setSaving ( false ) ; } } ) ; const handleManualSave = useHandler ( async ( ) => { if ( syncedMessage . draftFlags ?. isSentDraft ) { onMessageAlreadySent ( ) ; return ; } const notificationID = createNotification ( { text : ( < SavingDraftNotification ref = { notficationRef } onDiscard = { ( ) => { if ( notificationID ) { hideNotification ( notificationID ) ; } void onDiscard ( ) ; } } />), expiration : - 1 , disableAutoClose : true , } ) ; setSaving ( true ) ; ensureMessageContent ( ) ; try { await promiseUpload ; } catch ( error ) { hideNotification ( notificationID ) ; setSaving ( false ) ; throw error ; } await handleManualSaveAfterUploads ( notificationID ) ; } ) ; const handleClose = useHandler ( async ( ) => { onClose ( ) ; if ( syncedMessage . draftFlags ?. isSentDraft ) { createNotification ( { text : c ( 'Error' ) . t `This message has already been sent` , type : 'error' , } ) ; return ; } if ( lock ) { return ; } ensureMessageContent ( ) ; if ( pendingAutoSave . isPending || uploadInProgress ) { try { await handleManualSave ( ) ; } catch { createNotification ( { text : c ( 'Error' ) . t `Draft could not be saved. Try again.` , type : 'error' , } ) ; onCompose ( { existingDraft : modelMessage , fromUndo : true } ) ; } } } ) ; return { handleClose , handleManualSave , saving } ; } ;