diff options
| author | Allen Hutchison <[email protected]> | 2025-05-05 09:44:59 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-05-05 09:44:59 -0700 |
| commit | 74f8f5eaa91b817acd687c8f8ff37b39a6a57265 (patch) | |
| tree | cdc623c1a6d944badc2031018989dde3e47d0a4c /packages/cli/src/ui/hooks/useHistoryManager.ts | |
| parent | 2b309a8abbc6619a8ca4aeb6b5a82589efcdaeb7 (diff) | |
feat(cli): add useHistoryManager hook for chat history (#234)
Co-authored-by: Brandon Keiji <[email protected]>
Diffstat (limited to 'packages/cli/src/ui/hooks/useHistoryManager.ts')
| -rw-r--r-- | packages/cli/src/ui/hooks/useHistoryManager.ts | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/packages/cli/src/ui/hooks/useHistoryManager.ts b/packages/cli/src/ui/hooks/useHistoryManager.ts new file mode 100644 index 00000000..baf9f7c5 --- /dev/null +++ b/packages/cli/src/ui/hooks/useHistoryManager.ts @@ -0,0 +1,70 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { useState, useRef, useCallback } from 'react'; +import { HistoryItem } from '../types.js'; + +export interface UseHistoryManagerReturn { + history: HistoryItem[]; + addItemToHistory: ( + itemData: Omit<HistoryItem, 'id'>, + baseTimestamp: number, + ) => number; // Return the ID of the added item + updateHistoryItem: ( + id: number, + updates: Partial<Omit<HistoryItem, 'id'>>, + ) => void; + clearHistory: () => void; +} + +/** + * Custom hook to manage the chat history state. + * + * Encapsulates the history array, message ID generation, adding items, + * updating items, and clearing the history. + */ +export function useHistoryManager(): UseHistoryManagerReturn { + const [history, setHistory] = useState<HistoryItem[]>([]); + const messageIdCounterRef = useRef(0); + + // Generates a unique message ID based on a timestamp and a counter. + const getNextMessageId = useCallback((baseTimestamp: number): number => { + // Increment *before* adding to ensure uniqueness against the base timestamp + messageIdCounterRef.current += 1; + return baseTimestamp + messageIdCounterRef.current; + }, []); + + // Adds a new item to the history state with a unique ID and returns the ID. + const addItemToHistory = useCallback( + (itemData: Omit<HistoryItem, 'id'>, baseTimestamp: number): number => { + const id = getNextMessageId(baseTimestamp); + const newItem: HistoryItem = { ...itemData, id } as HistoryItem; + setHistory((prevHistory) => [...prevHistory, newItem]); + return id; // Return the generated ID + }, + [getNextMessageId], + ); + + // Updates an existing history item identified by its ID. + const updateHistoryItem = useCallback( + (id: number, updates: Partial<Omit<HistoryItem, 'id'>>) => { + setHistory((prevHistory) => + prevHistory.map((item) => + item.id === id ? ({ ...item, ...updates } as HistoryItem) : item, + ), + ); + }, + [], + ); + + // Clears the entire history state. + const clearHistory = useCallback(() => { + setHistory([]); + messageIdCounterRef.current = 0; // Reset counter when history is cleared + }, []); + + return { history, addItemToHistory, updateHistoryItem, clearHistory }; +} |
