@@ -33,9 +33,13 @@ import {wrapperStyles} from './ConfigToolbar.styles';
33
33
export function ConfigToolbar ( ) {
34
34
const [ showConfig , setShowConfig ] = useState ( false ) ;
35
35
const [ configFeaturesState , setConfigFeaturesState ] = useState < Configuration [ 'FEATURE' ] > ( Config . getConfig ( ) . FEATURE ) ;
36
- const [ intervalId , setIntervalId ] = useState < number | null > ( null ) ; // For managing setInterval
36
+ const [ intervalId , setIntervalId ] = useState < number | null > ( null ) ; // Stores active timeout id (renamed kept for minimal change)
37
37
const messageCountRef = useRef < number > ( 0 ) ; // For the message count
38
38
const [ prefix , setPrefix ] = useState ( 'Message -' ) ; // Prefix input
39
+ // Delay between automated messages in seconds (can be fractional). 0 = send back-to-back.
40
+ const [ messageDelaySec , setMessageDelaySec ] = useState < number > ( 0 ) ;
41
+ // Ref to always access latest delay inside async loop without re-registering timers
42
+ const messageDelaySecRef = useRef < number > ( messageDelaySec ) ;
39
43
const wrapperRef = useRef ( null ) ;
40
44
const [ avsDebuggerEnabled , setAvsDebuggerEnabled ] = useState ( ! ! window . wire ?. app ?. debug ?. isEnabledAvsDebugger ( ) ) ; //
41
45
@@ -52,52 +56,56 @@ export function ConfigToolbar() {
52
56
} ;
53
57
} , [ ] ) ;
54
58
59
+ useEffect ( ( ) => {
60
+ messageDelaySecRef . current = messageDelaySec ;
61
+ } , [ messageDelaySec ] ) ;
62
+
55
63
const startSendingMessages = ( ) => {
56
64
if ( intervalId ) {
57
65
return ;
58
66
}
59
67
60
- let isRequestInProgress = false ;
61
-
62
- const id = window . setInterval ( async ( ) => {
63
- if ( isRequestInProgress ) {
64
- return ;
65
- }
66
-
68
+ const sendNext = async ( ) => {
67
69
const conversationState = container . resolve ( ConversationState ) ;
68
70
const activeConversation = conversationState ?. activeConversation ( ) ;
69
71
if ( ! activeConversation ) {
72
+ if ( intervalId ) {
73
+ const MS_IN_SEC = 1000 ;
74
+ const retryId = window . setTimeout ( sendNext , ( messageDelaySecRef . current || 0 ) * MS_IN_SEC ) ;
75
+ setIntervalId ( retryId ) ;
76
+ }
70
77
return ;
71
78
}
72
79
73
- isRequestInProgress = true ;
74
-
75
80
try {
76
81
await window . wire . app . repository . message . sendTextWithLinkPreview ( {
77
82
conversation : activeConversation ,
78
83
textMessage : `${ prefix } ${ messageCountRef . current } ` ,
79
84
mentions : [ ] ,
80
85
quoteEntity : undefined ,
81
86
} ) ;
82
-
83
87
messageCountRef . current ++ ;
84
88
} catch ( error ) {
85
89
console . error ( 'Error sending message:' , error ) ;
86
- } finally {
87
- isRequestInProgress = false ;
88
90
}
89
- } , 100 ) ;
90
91
91
- setIntervalId ( id ) ;
92
+ const MS_IN_SEC = 1000 ;
93
+ const delayMs = ( messageDelaySecRef . current || 0 ) * MS_IN_SEC ;
94
+ const nextId = window . setTimeout ( sendNext , delayMs ) ;
95
+ setIntervalId ( nextId ) ;
96
+ } ;
97
+
98
+ const firstId = window . setTimeout ( sendNext , 0 ) ;
99
+ setIntervalId ( firstId ) ;
92
100
} ;
93
101
94
102
// Stop sending messages and reset the counter
95
103
const stopSendingMessages = ( ) => {
96
104
if ( intervalId ) {
97
- clearInterval ( intervalId ) ;
105
+ clearTimeout ( intervalId ) ;
98
106
setIntervalId ( null ) ;
99
- messageCountRef . current = 0 ;
100
107
}
108
+ messageCountRef . current = 0 ;
101
109
} ;
102
110
103
111
// Update the config state when form input changes
@@ -184,14 +192,15 @@ export function ConfigToolbar() {
184
192
return null ;
185
193
}
186
194
195
+ const isSending = intervalId !== null ;
196
+
187
197
return (
188
198
< div ref = { wrapperRef } css = { wrapperStyles } >
189
199
< h3 > Developer Menu</ h3 >
190
200
< h4 style = { { color : 'red' , fontWeight : 'bold' } } >
191
201
Caution: Modifying these settings can affect the behavior of the application. Ensure you understand the
192
202
implications of each change before proceeding. Changes may cause unexpected behavior.
193
203
</ h4 >
194
- < div > { renderConfig ( configFeaturesState ) } </ div >
195
204
196
205
< hr />
197
206
@@ -212,8 +221,26 @@ export function ConfigToolbar() {
212
221
onChange = { event => setPrefix ( event . currentTarget . value ) }
213
222
placeholder = "Prefix for the messages"
214
223
/>
215
- < Button onClick = { startSendingMessages } > Send Incremented Messages</ Button >
216
- < Button onClick = { stopSendingMessages } > Stop Sending Messages</ Button >
224
+ < div style = { { marginTop : '8px' } } >
225
+ < label htmlFor = "message-delay-input" style = { { display : 'block' , fontWeight : 'bold' } } >
226
+ Delay Between Messages (seconds)
227
+ </ label >
228
+ < Input
229
+ id = "message-delay-input"
230
+ type = "number"
231
+ min = { 0 }
232
+ step = { 0.1 }
233
+ value = { messageDelaySec }
234
+ onChange = { event => {
235
+ const val = parseFloat ( event . currentTarget . value ) ;
236
+ setMessageDelaySec ( Number . isNaN ( val ) || val < 0 ? 0 : val ) ;
237
+ } }
238
+ placeholder = "0"
239
+ />
240
+ </ div >
241
+ < Button onClick = { isSending ? stopSendingMessages : startSendingMessages } >
242
+ { isSending ? 'Stop Sending Messages' : 'Send Incremented Messages' }
243
+ </ Button >
217
244
218
245
< h3 > Database dump & restore </ h3 >
219
246
< h6 style = { { color : 'red' , fontWeight : 'bold' } } >
@@ -222,6 +249,9 @@ export function ConfigToolbar() {
222
249
</ h6 >
223
250
< Button onClick = { ( ) => window . wire ?. app ?. debug ?. dumpIndexedDB ( ) } > Dump IndexedDB</ Button >
224
251
< Button onClick = { ( ) => window . wire ?. app ?. debug ?. restoreIndexedDB ( ) } > Restore IndexedDB</ Button >
252
+
253
+ < h3 > Environment Variables</ h3 >
254
+ < div > { renderConfig ( configFeaturesState ) } </ div >
225
255
</ div >
226
256
) ;
227
257
}
0 commit comments