import { useState , ChangeEvent } from 'react' ; import { useDispatch } from 'react-redux' ; import { c , msgid } from 'ttag' ; import { Href , generateUID , useNotifications } from '@proton/components' ; import { range } from '@proton/shared/lib/helpers/array' ; import ComposerInnerModal from './ComposerInnerModal' ; import { MAX_EXPIRATION_TIME } from '../../../constants' ; import { MessageChange } from '../Composer' ; import { MessageState } from '../../../logic/messages/messagesTypes' ; import { updateExpires } from '../../../logic/messages/draft/messagesDraftActions' ; const ONE_WEEK = 3600 * 24 * 7 ; const initValues = ( { draftFlags = { } } = { } ) => { const { expiresIn = ONE_WEEK } = draftFlags ; const deltaHours = expiresIn / 3600 ; const deltaDays = Math . floor ( deltaHours / 24 ) ; return { days : deltaDays , hours : deltaHours % 24 , } ; } ; const computeHours = ( { days , hours } ) => hours + days * 24 ; const optionRange = ( size ) => range ( 0 , size ) . map ( ( value ) => ( < option key = { value } value = { value } > { value } < /option>)); interface Props { message ? : MessageState ; onClose : ( ) => void ; onChange : MessageChange ; } const ComposerExpirationModal = ( { message , onClose , onChange } ) => { const dispatch = useDispatch ( ) ; const [ uid ] = useState ( generateUID ( 'password-modal' ) ) ; const values = initValues ( message ) ; const [ days , setDays ] = useState ( values . days ) ; const [ hours , setHours ] = useState ( values . hours ) ; const { createNotification } = useNotifications ( ) ; const valueInHours = computeHours ( { days , hours } ) ; const handleChange = ( setter ) => ( event ) => { const value = Number ( event . target . value ) ; setter ( value ) ; if ( setter === setDays && value === 28 ) { setHours ( 0 ) ; } } ; const handleCancel = ( ) => { onChange ( { draftFlags : { expiresIn : undefined } } ) ; onClose ( ) ; } ; const handleSubmit = ( ) => { if ( Number . isNaN ( valueInHours ) ) { createNotification ( { type : 'error' , text : c ( 'Error' ) . t `Invalid expiration time` , } ) ; return ; } if ( valueInHours === 0 ) { handleCancel ( ) ; return ; } if ( valueInHours > MAX_EXPIRATION_TIME ) { createNotification ( { type : 'error' , text : c ( 'Error' ) . t `The maximum expiration is 4 weeks` , } ) ; return ; } onChange ( { draftFlags : { expiresIn : valueInHours * 3600 } } ) ; dispatch ( updateExpires ( { ID : message ?. localID || '' , expiresIn : valueInHours * 3600 } ) ) ; onClose ( ) ; } ; const disabled = Number . isNaN ( valueInHours ) ; const descriptionExpirationTime = c ( 'Info' ) . t `Expiration time` ; return ( < ComposerInnerModal title = { c ( 'Info' ) . t `Expiration Time` } disabled = { disabled } onSubmit = { handleSubmit } onCancel = { handleCancel } > < p className = "mt0 color-weak" > { c ( 'Info' ) . t `If you are sending this message to a non ProtonMail user, please be sure to set a password for your message.` } < br / > < Href url = "https://protonmail.com/support/knowledge-base/expiration/" > { c ( 'Info' ) . t `Learn more` } < /Href> < /p> < div className = "flex flex-column flex-nowrap mt1 mb1" > < span className = "sr-only" id = { `composer-expiration-string-${ uid }` } > { descriptionExpirationTime } < /span> < div className = "flex flex-gap-0-5 flex-row flex" > < div className = "flex-item-fluid flex flex-column flex-nowrap" > < label htmlFor = { `composer-expiration-days-${ uid }` } className = "mr0-5 text-semibold" > { c ( 'Info' ) . ngettext ( msgid `Day` , `Days` , days ) } < /label> < select id = { `composer-expiration-days-${ uid }` } className = "field mr0-25" value = { days } onChange = { handleChange ( setDays ) } placeholder = { c ( 'Info' ) . ngettext ( msgid `Day` , `Days` , days ) } aria - describedby = { `composer-expiration-string-${ uid }` } data - testid = "composer:expiration-days" > { optionRange ( 7 * 4 + 1 ) } < /select> < /div> < div className = "flex-item-fluid flex flex-column flex-nowrap" > < label htmlFor = { `composer-expiration-hours-${ uid }` } className = "text-semibold" > { c ( 'Info' ) . ngettext ( msgid `Hour` , `Hours` , hours ) } < /label> < select id = { `composer-expiration-hours-${ uid }` } className = "field mr0-25" value = { hours } onChange = { handleChange ( setHours ) } disabled = { days === 28 } aria - describedby = { `composer-expiration-string-${ uid }` } data - testid = "composer:expiration-hours" > { optionRange ( 24 ) } < /select> < /div> < /div> < /div> < /ComposerInnerModal>); } ; export default ComposerExpirationModal ;