1
1
import React , { Component } from 'react' ;
2
2
import bytes from 'bytes' ;
3
3
import algoliasearch from 'algoliasearch/lite' ;
4
+ import qs from 'qs' ;
4
5
5
6
import Aside from './Aside' ;
6
7
import FileBrowser from './FileBrowser' ;
@@ -63,6 +64,15 @@ class Details extends Component {
63
64
this . setState ( prevState => ( { ...content , loaded : true } ) ) ;
64
65
setHead ( content ) ;
65
66
this . getDocuments ( ) ;
67
+
68
+ // Opens the file browser if the search has a 'files' param.
69
+ const { files } = qs . parse ( location . search , {
70
+ ignoreQueryPrefix : true ,
71
+ } ) ;
72
+
73
+ if ( files !== undefined ) {
74
+ this . setState ( { isBrowsingFiles : true } ) ;
75
+ }
66
76
} )
67
77
. catch ( e => {
68
78
if ( e . message === OBJECT_DOESNT_EXIST ) {
@@ -71,6 +81,12 @@ class Details extends Component {
71
81
} ) ;
72
82
}
73
83
} ) ;
84
+
85
+ window . addEventListener ( 'popstate' , this . _onPopState ) ;
86
+ }
87
+
88
+ componentWillUnmount ( ) {
89
+ window . removeEventListener ( 'popstate' , this . _onPopState ) ;
74
90
}
75
91
76
92
getGithub ( { url, state } ) {
@@ -295,14 +311,54 @@ class Details extends Component {
295
311
}
296
312
297
313
_openFileBrowser = evt => {
298
- this . setState ( { isBrowsingFiles : true } ) ;
314
+ // Ignore if is already browsing the files (prevent pushing state to the history repeatedly)
315
+ if ( ! this . state . isBrowsingFiles ) {
316
+ this . _setFilesSearchParam ( true ) ;
317
+
318
+ this . setState ( { isBrowsingFiles : true } ) ;
319
+ }
299
320
evt . preventDefault ( ) ;
300
321
} ;
301
322
302
323
_closeFileBrowser = evt => {
324
+ this . _setFilesSearchParam ( false ) ;
325
+
303
326
this . setState ( { isBrowsingFiles : false } ) ;
304
327
evt . preventDefault ( ) ;
305
328
} ;
329
+
330
+ // Add/remove the 'files' param from the search (push to the history)
331
+ _setFilesSearchParam = active => {
332
+ // The strictNullHandling option is used to avoid that the qs includes a '=' at the end of empty params
333
+ const search = qs . parse ( location . search , {
334
+ ignoreQueryPrefix : true ,
335
+ strictNullHandling : true ,
336
+ } ) ;
337
+
338
+ if ( active ) {
339
+ search . files = null ;
340
+ } else {
341
+ delete search . files ;
342
+ }
343
+
344
+ window . history . pushState (
345
+ null ,
346
+ null ,
347
+ location . pathname +
348
+ qs . stringify ( search , { addQueryPrefix : true , strictNullHandling : true } )
349
+ ) ;
350
+ } ;
351
+
352
+ _onPopState = ( { state } ) => {
353
+ // Open or close the file browser based on the current search
354
+ const { files } = qs . parse ( location . search , { ignoreQueryPrefix : true } ) ;
355
+
356
+ if ( files !== undefined ) {
357
+ this . setState ( { isBrowsingFiles : true } ) ;
358
+ } else if ( this . state . isBrowsingFiles ) {
359
+ this . setState ( { isBrowsingFiles : false } ) ;
360
+ }
361
+ } ;
306
362
}
307
363
308
364
export default Details ;
0 commit comments