@@ -70,6 +70,7 @@ export default function ChatInput({
70
70
( ) => redux . getStore ( "account" ) . get_account_id ( ) ,
71
71
[ ] ,
72
72
) ;
73
+
73
74
const [ input , setInput ] = useState < string > ( ( ) => {
74
75
const dbInput = syncdb
75
76
?. get_one ( {
@@ -85,6 +86,7 @@ export default function ChatInput({
85
86
const input = dbInput ?? propsInput ;
86
87
return input ;
87
88
} ) ;
89
+ const currentInputRef = useRef < string > ( input ) ;
88
90
89
91
const isMountedRef = useIsMountedRef ( ) ;
90
92
const lastSavedRef = useRef < string | null > ( null ) ;
@@ -97,7 +99,6 @@ export default function ChatInput({
97
99
// but definitely don't save (thus updating active) if
98
100
// the input didn't really change, since we use active for
99
101
// showing that a user is writing to other users.
100
- console . log ( "saveChat" , { date } ) ;
101
102
const input0 = syncdb
102
103
. get_one ( {
103
104
event : "draft" ,
@@ -123,9 +124,42 @@ export default function ChatInput({
123
124
}
124
125
} ,
125
126
SAVE_DEBOUNCE_MS ,
126
- { leading : true } ,
127
+ {
128
+ leading : true ,
129
+ } ,
127
130
) ;
128
131
132
+ useEffect ( ( ) => {
133
+ return ( ) => {
134
+ // save before unmounting. This is very important since if a new reply comes in,
135
+ // then the input component gets unmounted, then remounted BELOW the reply.
136
+ // Note: it is still slightly annoying, due to loss of focus... however, data
137
+ // loss is NOT ok, whereas loss of focus is.
138
+ const input = currentInputRef . current ;
139
+ if ( input == null || syncdb == null ) {
140
+ return ;
141
+ }
142
+ if (
143
+ syncdb . get_one ( {
144
+ event : "draft" ,
145
+ sender_id,
146
+ date,
147
+ } ) == null
148
+ ) {
149
+ return ;
150
+ }
151
+
152
+ syncdb . set ( {
153
+ event : "draft" ,
154
+ sender_id,
155
+ input,
156
+ date, // it's a primary key so can't use this to represent when user last edited this; use other date for editing past chats.
157
+ active : Date . now ( ) ,
158
+ } ) ;
159
+ syncdb . commit ( ) ;
160
+ } ;
161
+ } , [ ] ) ;
162
+
129
163
useEffect ( ( ) => {
130
164
if ( syncdb == null ) return ;
131
165
const onSyncdbChange = ( ) => {
@@ -138,6 +172,7 @@ export default function ChatInput({
138
172
const input = x ?. get ( "input" ) ;
139
173
if ( input != null && input !== lastSavedRef . current ) {
140
174
setInput ( input ) ;
175
+ currentInputRef . current = input ;
141
176
lastSavedRef . current = null ;
142
177
}
143
178
} ;
@@ -161,6 +196,7 @@ export default function ChatInput({
161
196
enableMentions = { true }
162
197
submitMentionsRef = { submitMentionsRef }
163
198
onChange = { ( input ) => {
199
+ currentInputRef . current = input ;
164
200
/* BUG: in Markdown mode this stops getting
165
201
called after you paste in an image. It works
166
202
fine in Slate/Text mode. See
0 commit comments