Skip to content
Snippets Groups Projects
Select Git revision
  • 0013e7439c23bfd2fa55e574a1d745913c9410d6
  • main default protected
  • userHandling
  • snuggle
4 results

ChatState.jsx

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ChatState.jsx 3.37 KiB
    import React, { useContext, useReducer, useState } from 'react';
    import ChatContext from './ChatContext';
    import chatReducer from './ChatReducer';
    import { CHAT_ACTIONS } from './ChatTypes';
    import api from '../../utils/AxiosConfig';
    import { mergeBackendValidation } from '../../utils/ErrorHandling';
    
    // ### EXPORT useContext TO REDUCE NEEDED CODE IN CLIENT FILES
    export function useChat() {
      return useContext(ChatContext);
    }
    
    function ChatState({ children }) {
      // #################################
      // HOOKS
      // #################################
    
      const [chats, dispatchChats] = useReducer(chatReducer, []);
      const [chatHeadings, dispatchChatHeadings] = useReducer(chatReducer, []);
      const [currentChatId, dispatchCurrentChatId] = useReducer(chatReducer, null);
      const [chatHistory, dispatchChatHistory] = useReducer(chatReducer, []);
      const [availableModels, dispatchAvailableModels] = useReducer(chatReducer, []);
    
    
    
      // #################################
      // FUNCTIONS
      // #################################
      // ### FETCH CHATS
      async function fetchAllChats(id = null) {
        try {
          // load all chats and save them
          const items = await api.get('/ai/chats');
          dispatchChats({ type: CHAT_ACTIONS.SET_CHATS, payload: items.data.chats });
          // fetch headings from chats
          fetchChatHeadings(items.data.chats);
          // select chat if id is provided
          if (id) selectChat(id);
          // fetch available models
          const models = await api.post('/ai/models', { filter: '' });
          dispatchAvailableModels({ type: CHAT_ACTIONS.SET_MODELS, payload: models });
        } catch (error) {
          // display errors
          mergeBackendValidation(error.response.status, error.response.data);
        }
      }
    
    
      // ### FETCH HEADINGS FROM CHATS
      function fetchChatHeadings(chats) {
        // create new array
        const headings = [];
        // loop through chats
        chats.forEach(chat => {
          // split history from chat object
          const removedKey = 'chatHistory';
          const { [removedKey]: removed, ...heading } = chat;
          // save in array
          headings.push(heading);
        });
        // save array in state
        dispatchChatHeadings({ type: CHAT_ACTIONS.SET_HEADINGS, payload: headings });
      }
    
    
      // ### FETCH CHAT HISTORY
      function fetchChatHistory(id) {
        dispatchChatHistory({ type: CHAT_ACTIONS.SET_HISTORY, payload: { id, chats } });
      }
    
      // ### UPDATE CHAT HISTORY
      function updateChatHistory(id, history) {
        // define a function to find the chat
        const isSelectedChatId = element => element.id === id;
        // get index of matching item
        const index = chats.findIndex(isSelectedChatId);
        chats[index].chatHistory = history;
    
        dispatchChatHistory({ type: CHAT_ACTIONS.SET_HISTORY, payload: { id, chats } });
      }
    
    
      // ### SELECT CHAT
      function selectChat(id) {
        // return null if no id is provided (just to prevent switching between null and undefined)
        if (!id) id = null;
        // save chat id in state
        dispatchCurrentChatId({ type: CHAT_ACTIONS.UPDATE_CHATID, payload: id });
      }
      // #################################
      // OUTPUT
      // #################################
    
      return (
        <ChatContext.Provider value={{
          fetchAllChats,
          chatHeadings,
          currentChatId,
          selectChat,
          fetchChatHistory,
          chatHistory,
          availableModels,
          updateChatHistory
        }}>
          {children}
        </ChatContext.Provider>
      );
    }
    export default React.memo(ChatState);