1
1
import { JSONContent } from "@tiptap/react" ;
2
- import { useEffect , useState } from "react" ;
2
+ import { useState } from "react" ;
3
3
import { getLocalStorage , setLocalStorage } from "../util/localStorage" ;
4
4
import useUpdatingRef from "./useUpdatingRef" ;
5
5
@@ -10,112 +10,58 @@ const emptyJsonContent = () => ({
10
10
11
11
const MAX_HISTORY_LENGTH = 100 ;
12
12
13
- // Completely isolated memory stores for different history types
14
- // This ensures no crossover between edit and chat histories
15
- const CHAT_HISTORY_STORE : JSONContent [ ] = [ ] ;
16
- const EDIT_HISTORY_STORE : JSONContent [ ] = [ ] ;
17
-
18
- // Initialize the history stores from localStorage (only do this once)
19
- let storesInitialized = false ;
20
- function initializeStores ( ) {
21
-
22
- if ( ! storesInitialized ) {
23
- // Initialize chat history
24
- const chatHistory = getLocalStorage ( 'inputHistory_chat' ) ;
25
- if ( chatHistory ) {
26
- CHAT_HISTORY_STORE . push ( ...chatHistory . slice ( - MAX_HISTORY_LENGTH ) ) ;
27
- }
28
-
29
- // Initialize edit history
30
- const editHistory = getLocalStorage ( 'inputHistory_edit' ) ;
31
- if ( editHistory ) {
32
- EDIT_HISTORY_STORE . push ( ...editHistory . slice ( - MAX_HISTORY_LENGTH ) ) ;
33
- }
34
-
35
- storesInitialized = true ;
36
- }
37
- }
38
-
39
-
40
- // Initialize stores immediately
41
- initializeStores ( ) ;
42
-
43
- /**
44
- * Custom hook for managing input history with complete separation between history types
45
- */
46
13
export function useInputHistory ( historyKey : string ) {
47
- // Determine which history store to use
48
- const historyStore = historyKey === 'edit' ? EDIT_HISTORY_STORE : CHAT_HISTORY_STORE ;
49
- const storageKey = historyKey === 'edit' ? 'inputHistory_edit' as const : 'inputHistory_chat' as const ;
50
-
51
- // Use a reference to the appropriate history store
52
- const [ inputHistory , setInputHistory ] = useState < JSONContent [ ] > ( historyStore ) ;
53
- const [ pendingInput , setPendingInput ] = useState < JSONContent > ( emptyJsonContent ( ) ) ;
14
+ const [ inputHistory , setInputHistory ] = useState < JSONContent [ ] > (
15
+ getLocalStorage ( `inputHistory_${ historyKey } ` ) ?. slice ( - MAX_HISTORY_LENGTH ) ??
16
+ [ ] ,
17
+ ) ;
18
+ const [ pendingInput , setPendingInput ] =
19
+ useState < JSONContent > ( emptyJsonContent ( ) ) ;
54
20
const [ currentIndex , setCurrentIndex ] = useState ( inputHistory . length ) ;
55
-
56
- // Keep the view of history updated when the underlying store changes
57
- useEffect ( ( ) => {
58
- setInputHistory ( [ ...historyStore ] ) ;
59
- setCurrentIndex ( historyStore . length ) ;
60
- } , [ historyStore . length ] ) ;
61
21
62
22
function prev ( currentInput : JSONContent ) {
63
- if ( currentIndex === inputHistory . length ) {
23
+ let index = currentIndex ;
24
+
25
+ if ( index === inputHistory . length ) {
64
26
setPendingInput ( currentInput ) ;
65
27
}
66
28
67
- if ( currentIndex > 0 ) {
68
- setCurrentIndex ( currentIndex - 1 ) ;
69
- return inputHistory [ currentIndex - 1 ] ;
29
+ if ( index > 0 && index <= inputHistory . length ) {
30
+ setCurrentIndex ( ( prevState ) => prevState - 1 ) ;
31
+ return inputHistory [ index - 1 ] ;
70
32
}
71
-
72
- // Stay at the first history item if we're already there
73
- if ( currentIndex === 0 && inputHistory . length > 0 ) {
74
- return inputHistory [ 0 ] ;
75
- }
76
-
77
- return currentInput ;
78
33
}
79
34
80
35
function next ( ) {
81
- if ( currentIndex < inputHistory . length ) {
82
- setCurrentIndex ( currentIndex + 1 ) ;
83
-
84
- if ( currentIndex === inputHistory . length - 1 ) {
36
+ let index = currentIndex ;
37
+ if ( index >= 0 && index < inputHistory . length ) {
38
+ setCurrentIndex ( ( prevState ) => prevState + 1 ) ;
39
+ if ( index === inputHistory . length - 1 ) {
85
40
return pendingInput ;
86
41
}
87
-
88
- return inputHistory [ currentIndex + 1 ] ;
42
+ return inputHistory [ index + 1 ] ;
89
43
}
90
-
91
- // Stay at pending input if we're already at the end
92
- return pendingInput ;
93
44
}
94
45
95
46
function add ( inputValue : JSONContent ) {
96
47
setPendingInput ( emptyJsonContent ( ) ) ;
97
48
98
- // Don't add duplicates
99
49
if (
100
- historyStore . length > 0 &&
101
- JSON . stringify ( historyStore [ historyStore . length - 1 ] ) === JSON . stringify ( inputValue )
50
+ JSON . stringify ( inputHistory [ inputHistory . length - 1 ] ) ===
51
+ JSON . stringify ( inputValue )
102
52
) {
103
- setCurrentIndex ( historyStore . length ) ;
53
+ setCurrentIndex ( inputHistory . length ) ;
104
54
return ;
105
55
}
106
56
107
- // Update the appropriate history store
108
- while ( historyStore . length >= MAX_HISTORY_LENGTH ) {
109
- historyStore . shift ( ) ; // Remove oldest items if we exceed the limit
110
- }
111
- historyStore . push ( inputValue ) ;
112
-
113
- // Update the view of history
114
- setInputHistory ( [ ...historyStore ] ) ;
115
- setCurrentIndex ( historyStore . length ) ;
116
-
117
- // Update localStorage
118
- setLocalStorage ( storageKey , [ ...historyStore ] ) ;
57
+ setCurrentIndex ( inputHistory . length + 1 ) ;
58
+ setInputHistory ( ( prev ) => {
59
+ return [ ...prev , inputValue ] . slice ( - MAX_HISTORY_LENGTH ) ;
60
+ } ) ;
61
+ setLocalStorage (
62
+ `inputHistory_${ historyKey } ` ,
63
+ [ ...inputHistory , inputValue ] . slice ( - MAX_HISTORY_LENGTH ) ,
64
+ ) ;
119
65
}
120
66
121
67
const prevRef = useUpdatingRef ( prev , [ inputHistory ] ) ;
0 commit comments