/* * Copyright © 2024 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). */ import React, { createContext, ReactNode, useContext, useState } from 'react'; import { ChatScreen } from '../types/state.types'; export interface WidgetContextType { syncState: boolean; isOpen: boolean; screen: ChatScreen; scroll: number; setSyncState: (syncState: boolean) => void; setIsOpen: (isOpen: boolean) => void; setScreen: (screen: ChatScreen) => void; setScroll: (scroll: number) => void; } const WidgetContext = createContext(undefined); const WidgetProvider: React.FC<{ onOpen?: () => void; onClose?: () => void; onScrollToTop?: () => void; defaultScreen?: ChatScreen; children: ReactNode; }> = ({ onOpen, onClose, onScrollToTop, defaultScreen = 'prechat', children, }) => { const [syncState, setSyncState] = useState(true); const [isOpen, setIsOpen] = useState(false); const [screen, setScreen] = useState(defaultScreen); const [scroll, setScroll] = useState(100); const handleSetSyncState = (newState: boolean) => { setSyncState(newState); }; const handleSetIsOpen = (newState: boolean) => { setIsOpen(newState); if (syncState) { if (newState) { onOpen && onOpen(); } else { onClose && onClose(); } } }; const handleSetScreen = (newScreen: ChatScreen) => { setScreen( ['prechat', 'postchat', 'webview'].includes(newScreen) ? newScreen : 'chat', ); }; const handleSetScroll = (newScroll: number) => { setScroll(newScroll); if (onScrollToTop && syncState && newScroll === 0) { onScrollToTop(); } }; const contextValue = { syncState, isOpen, screen, scroll, setSyncState: handleSetSyncState, setIsOpen: handleSetIsOpen, setScreen: handleSetScreen, setScroll: handleSetScroll, }; return ( {children} ); }; export const useWidget = () => { const context = useContext(WidgetContext); if (context === undefined) { throw new Error('useWidget must be used within a WidgetProvider'); } return context; }; export default WidgetProvider;