Skip to content

Commit d5a4ee6

Browse files
leonardosntHaroenv
authored andcommitted
Feat: URL for files on detail page (#748)
* URL for files on detail page Fixes #594 * Fix url issue
1 parent 3341ad9 commit d5a4ee6

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

js/src/lib/Details/index.js

+57-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { Component } from 'react';
22
import bytes from 'bytes';
33
import algoliasearch from 'algoliasearch/lite';
4+
import qs from 'qs';
45

56
import Aside from './Aside';
67
import FileBrowser from './FileBrowser';
@@ -63,6 +64,15 @@ class Details extends Component {
6364
this.setState(prevState => ({ ...content, loaded: true }));
6465
setHead(content);
6566
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+
}
6676
})
6777
.catch(e => {
6878
if (e.message === OBJECT_DOESNT_EXIST) {
@@ -71,6 +81,12 @@ class Details extends Component {
7181
});
7282
}
7383
});
84+
85+
window.addEventListener('popstate', this._onPopState);
86+
}
87+
88+
componentWillUnmount() {
89+
window.removeEventListener('popstate', this._onPopState);
7490
}
7591

7692
getGithub({ url, state }) {
@@ -295,14 +311,54 @@ class Details extends Component {
295311
}
296312

297313
_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+
}
299320
evt.preventDefault();
300321
};
301322

302323
_closeFileBrowser = evt => {
324+
this._setFilesSearchParam(false);
325+
303326
this.setState({ isBrowsingFiles: false });
304327
evt.preventDefault();
305328
};
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+
};
306362
}
307363

308364
export default Details;

js/src/package.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom';
33
import Details from './lib/Details';
4+
import qs from 'qs';
45

56
/*
67
To get the package id:
78
- production: https://yarnpkg.com/en/package/@kadira/storybook => @kadira/storybook
89
- dev (no rewrite available): http://localhost:4000/lang/en/package/?@kadira/storybook => @kadira/storybook
910
*/
11+
const search = qs.parse(location.search, { ignoreQueryPrefix: true });
1012
const id =
1113
process.env.NODE_ENV == 'production'
1214
? location.pathname
1315
.split('/')
1416
.slice(3)
1517
.join('/')
16-
: location.search.substring(1);
18+
: // Get the first search param. It is necessary because it can have more than one
19+
// param, e.g: when using ?files (to open the file browser).
20+
Object.keys(search)[0];
1721

1822
function languageDropdownAddPackage(pkg) {
1923
const langMenu = document.getElementById('dropdownNavLanguageMenu');

0 commit comments

Comments
 (0)