import { typingTimeout } from 'config' import { useAppDispatch } from 'domains/store' import { setActiveEntryType, setBlockAutoEntrySwitch, setUserEntryType, } from 'domains/store/slice' import { useCallback, useEffect, useRef } from 'preact/hooks' import { useSeamlyCommands, useSeamlyOptions } from 'ui/hooks/seamly-hooks' import { useSeamlyStateContext } from 'ui/hooks/seamly-state-hooks' import { actionTypes } from 'ui/utils/seamly-utils' export const useSeamlyTyping = () => { const { sendAction } = useSeamlyCommands() const { features } = useSeamlyOptions() const { typingPeekahead } = features || {} const typingTimerId = useRef | null>(null) const sendEndTypingTimerId = useRef | null>( null, ) const isTyping = useRef(false) const typingIntervalId = useRef | null>(null) useEffect(() => { return () => { if (typingIntervalId.current) clearInterval(typingIntervalId.current) if (typingTimerId.current) clearTimeout(typingTimerId.current) if (sendEndTypingTimerId.current) clearTimeout(sendEndTypingTimerId.current) } }, []) const sendTypingState = (state, currentMessage) => { sendAction({ type: actionTypes.typing, state, ...(typingPeekahead && typingPeekahead.enabled ? { body: { currentMessage, }, } : {}), }) } return (e) => { if ((e.code && e.code === 'Enter') || e.keyCode === 13) { return } isTyping.current = true if (!typingIntervalId.current) { sendTypingState(true, e.target.value) typingIntervalId.current = setInterval(() => { if (!isTyping.current && typingIntervalId.current) { clearInterval(typingIntervalId.current) typingIntervalId.current = null } else if (typingPeekahead && typingPeekahead.enabled) { sendTypingState(true, e.target.value) } }, typingTimeout) } if (typingTimerId.current) clearTimeout(typingTimerId.current) if (sendEndTypingTimerId.current) clearTimeout(sendEndTypingTimerId.current) typingTimerId.current = setTimeout(() => { isTyping.current = false }, 300) sendEndTypingTimerId.current = setTimeout(() => { sendTypingState(false, e.target.value) }, typingTimeout) } } export const useSeamlyEntry = () => { const { default: defaultEntry, active, userSelected, options, optionsOverride, } = useSeamlyStateContext().entryMeta const dispatch = useAppDispatch() const activeEntry = userSelected || active || defaultEntry const activeEntryOptions = (optionsOverride && optionsOverride[activeEntry]) || (options && options[activeEntry]) || {} const dispatchBlockAutoEntrySwitch = useCallback( (value) => { dispatch(setBlockAutoEntrySwitch(value)) }, [dispatch], ) const dispatchActiveEntryType = useCallback( (entryType) => { dispatch(setActiveEntryType(entryType)) }, [dispatch], ) const dispatchUserEntryType = useCallback( (entryType) => { dispatch(setUserEntryType(entryType)) }, [dispatch], ) const cancelEntrySelection = useCallback(() => { if (userSelected) { dispatchUserEntryType(null) } else { dispatchActiveEntryType(defaultEntry) } }, [ dispatchActiveEntryType, dispatchUserEntryType, defaultEntry, userSelected, ]) return { activeEntry, activeEntryOptions, setActiveEntryType: dispatchActiveEntryType, setUserEntryType: dispatchUserEntryType, cancelEntrySelection, setBlockAutoEntrySwitch: dispatchBlockAutoEntrySwitch, } }