import { useCallback } from 'react' ; import { c } from 'ttag' ; import { Contact , ContactEmail } from '@proton/shared/lib/interfaces/contacts' ; import { labelContactEmails , unLabelContactEmails } from '@proton/shared/lib/api/contacts' ; import { useApi , useContactGroups , useContacts , useEventManager , useModals , useNotifications } from '../../hooks' ; import SelectEmailsModal from './modals/SelectEmailsModal' ; param contactEmails returns export const collectContacts = ( contactEmails = [ ] , contacts ) => { return contactEmails . reduce ( ( acc , { ContactID } ) => { acc . duplicate [ ContactID ] = ( acc . duplicate [ ContactID ] || 0 ) + 1 ; if ( acc . duplicate [ ContactID ] === 2 ) { const contact = contacts . find ( ( { ID } ) => ID === ContactID ) ; if ( contact ) { acc . contacts . push ( contact ) ; } } return acc ; } , { contacts : [ ] as Contact [ ] , duplicate : Object . create ( null ) , } ) ; } ; /**
 * Returns a reusable action to apply or remove groups to a list of contact emails
 */ const useApplyGroups = ( ) => { const { createNotification } = useNotifications ( ) ; const { call } = useEventManager ( ) ; const api = useApi ( ) ; const { createModal } = useModals ( ) ; const [ contacts ] = useContacts ( ) as [ Contact [ ] , boolean , any ] ; const [ groups = [ ] ] = useContactGroups ( ) ; const applyGroups = useCallback ( async ( contactEmails , changes , preventNotification = false ) => { const { contacts : collectedContacts } = collectContacts ( contactEmails , contacts ) ; const simpleEmails = contactEmails . filter ( ( contactEmail ) => ! collectedContacts . find ( ( contact ) => contactEmail . ContactID === contact . ID ) ) ; let selectedEmails = [ ] ; if ( collectedContacts . length ) { const groupIDs = Object . entries ( changes ) . filter ( ( [ , isChecked ] ) => isChecked ) . map ( ( [ groupID ] ) => groupID ) ; if ( groupIDs . length ) { selectedEmails = await new Promise < ContactEmail [ ] > ( ( resolve , reject ) => { createModal ( < SelectEmailsModal groupIDs = { groupIDs } contacts = { collectedContacts } onSubmit = { resolve } onClose = { reject } / > ) ; } ) ; } } const listForRemoving = [ ... contactEmails ] ; const listForAdding = [ ... simpleEmails , ... selectedEmails ] ; const groupEntries = Object . entries ( changes ) ; await Promise . all ( groupEntries . map ( ( [ groupID , isChecked ] ) => { if ( isChecked ) { const toLabel = listForAdding . filter ( ( { LabelIDs = [ ] } ) => ! LabelIDs . includes ( groupID ) ) . map ( ( { ID } ) => ID ) ; if ( ! toLabel . length ) { return Promise . resolve ( ) ; } return api ( labelContactEmails ( { LabelID : groupID , ContactEmailIDs : toLabel } ) ) ; } const toUnlabel = listForRemoving . filter ( ( { LabelIDs = [ ] } ) => LabelIDs . includes ( groupID ) ) . map ( ( { ID } ) => ID ) ; if ( ! toUnlabel . length ) { return Promise . resolve ( ) ; } return api ( unLabelContactEmails ( { LabelID : groupID , ContactEmailIDs : toUnlabel } ) ) ; } ) ) ; await call ( ) ; if ( ! preventNotification ) { createNotification ( { text : c ( 'Info' ) . t `Group assignment applied` } ) ; } } , [ contacts , groups ] ) ; return applyGroups ; } ; export default useApplyGroups ;