@@ -6,6 +6,8 @@ import useAsyncFn from 'react-use/lib/useAsyncFn';
6
6
import useInterval from 'react-use/lib/useInterval' ;
7
7
import { filesize } from 'filesize' ;
8
8
9
+ import type { PubkeyType } from 'libsession_util_nodejs' ;
10
+ import { chunk } from 'lodash' ;
9
11
import { Flex } from '../../basic/Flex' ;
10
12
import { SpacerXS } from '../../basic/Text' ;
11
13
import { localize } from '../../../localization/localeTools' ;
@@ -15,14 +17,48 @@ import { SessionButton, SessionButtonColor } from '../../basic/SessionButton';
15
17
import { ToastUtils , UserUtils } from '../../../session/utils' ;
16
18
import { getLatestReleaseFromFileServer } from '../../../session/apis/file_server_api/FileServerApi' ;
17
19
import { SessionSpinner } from '../../loading' ;
18
- import { setDebugMode } from '../../../state/ducks/debug' ;
19
20
import { updateDebugMenuModal } from '../../../state/ducks/modalDialog' ;
21
+ import { setDebugMode } from '../../../state/ducks/debug' ;
20
22
import LIBSESSION_CONSTANTS from '../../../session/utils/libsession/libsession_constants' ;
21
23
import { type ReleaseChannels } from '../../../updater/types' ;
22
24
import { fetchLatestRelease } from '../../../session/fetch_latest_release' ;
23
25
import { saveLogToDesktop } from '../../../util/logger/renderer_process_logging' ;
24
26
import { DURATION } from '../../../session/constants' ;
25
27
import { Errors } from '../../../types/Errors' ;
28
+ import { PubKey } from '../../../session/types' ;
29
+ import { ConvoHub } from '../../../session/conversations' ;
30
+ import { ConversationTypeEnum } from '../../../models/types' ;
31
+ import { ContactsWrapperActions } from '../../../webworker/workers/browser/libsession_worker_interface' ;
32
+ import { usePolling } from '../../../hooks/usePolling' ;
33
+
34
+ const hexRef = [ '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' ] ;
35
+
36
+ function genRandomHexString ( length : number ) {
37
+ const result = [ ] ;
38
+
39
+ for ( let n = 0 ; n < length ; n ++ ) {
40
+ result . push ( hexRef [ Math . floor ( Math . random ( ) * 16 ) ] ) ;
41
+ }
42
+ return result . join ( '' ) ;
43
+ }
44
+
45
+ async function generateOneRandomContact ( ) {
46
+ const numBytes = PubKey . PUBKEY_LEN - 2 ;
47
+
48
+ const hexBuffer = genRandomHexString ( numBytes ) ;
49
+ const id : PubkeyType = `05${ hexBuffer } ` ;
50
+ const created = await ConvoHub . use ( ) . getOrCreateAndWait ( id , ConversationTypeEnum . PRIVATE ) ;
51
+ // now() is not going to be synced on devices, instead createdAt will be used.
52
+ // createdAt is set to now in libsession-util itself,
53
+ // but we still need to mark that conversation as active
54
+ // for it to be inserted in the config
55
+ created . setKey ( 'active_at' , Date . now ( ) ) ;
56
+ created . setKey ( 'isApproved' , true ) ;
57
+ created . setSessionDisplayNameNoCommit ( id . slice ( 2 , 8 ) ) ;
58
+
59
+ await created . commit ( ) ;
60
+ return created ;
61
+ }
26
62
27
63
const CheckVersionButton = ( { channelToCheck } : { channelToCheck : ReleaseChannels } ) => {
28
64
const [ loading , setLoading ] = useState ( false ) ;
@@ -172,12 +208,68 @@ const ClearOldLogsButton = () => {
172
208
onClick = { ( ) => {
173
209
void handleDeleteAllLogs ( ) ;
174
210
} }
211
+ style = { { minWidth : '250px' } }
175
212
>
176
213
Clear old logs { filesize ( logSize ) }
177
214
</ SessionButton >
178
215
) ;
179
216
} ;
180
217
218
+ const dummyContactPerClick = 500 ;
219
+
220
+ async function fetchContactsCountAndUpdate ( ) {
221
+ const count = ( await ContactsWrapperActions . getAll ( ) ) . length ;
222
+ if ( count && Number . isFinite ( count ) ) {
223
+ return count ;
224
+ }
225
+ return 0 ;
226
+ }
227
+
228
+ function AddDummyContactButton ( ) {
229
+ const [ loading , setLoading ] = useState ( false ) ;
230
+ const [ addedCount , setAddedCount ] = useState ( 0 ) ;
231
+
232
+ const { data : contactsCount } = usePolling (
233
+ fetchContactsCountAndUpdate ,
234
+ 1000 ,
235
+ 'AddDummyContactButton'
236
+ ) ;
237
+
238
+ return (
239
+ < SessionButton
240
+ onClick = { async ( ) => {
241
+ if ( loading ) {
242
+ return ;
243
+ }
244
+ try {
245
+ setLoading ( true ) ;
246
+ setAddedCount ( 0 ) ;
247
+ const chunkSize = 10 ;
248
+ const allIndexes = Array . from ( { length : dummyContactPerClick } ) . map ( ( _unused , i ) => i ) ;
249
+ const chunks = chunk ( allIndexes , chunkSize ) ;
250
+ for ( let chunkIndex = 0 ; chunkIndex < chunks . length ; chunkIndex ++ ) {
251
+ // eslint-disable-next-line no-await-in-loop
252
+ await Promise . all ( chunks [ chunkIndex ] . map ( ( ) => generateOneRandomContact ( ) ) ) ;
253
+ setAddedCount ( Math . min ( chunkIndex * chunkSize , dummyContactPerClick ) ) ;
254
+ }
255
+ } finally {
256
+ setLoading ( false ) ;
257
+ setAddedCount ( 0 ) ;
258
+ }
259
+ } }
260
+ disabled = { loading }
261
+ >
262
+ { loading ? (
263
+ < >
264
+ { addedCount } /{ dummyContactPerClick } ...
265
+ </ >
266
+ ) : (
267
+ `Add ${ dummyContactPerClick } contacts (${ contactsCount } )`
268
+ ) }
269
+ </ SessionButton >
270
+ ) ;
271
+ }
272
+
181
273
export const DebugActions = ( ) => {
182
274
const dispatch = useDispatch ( ) ;
183
275
@@ -246,6 +338,7 @@ export const DebugActions = () => {
246
338
>
247
339
Open storage profile
248
340
</ SessionButton >
341
+ < AddDummyContactButton />
249
342
</ Flex >
250
343
</ >
251
344
) ;
0 commit comments