Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #305 #527

Merged
merged 11 commits into from
Aug 8, 2019
116 changes: 28 additions & 88 deletions pages/doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,22 @@ import { RightPanel } from '../src/Documentation/RightPanel/RightPanel'
import Page from '../src/Page'
import SearchForm from '../src/SearchForm'
import Page404 from '../src/Page404'
import PerfectScrollbar from 'perfect-scrollbar'
shcheklein marked this conversation as resolved.
Show resolved Hide resolved
import Hamburger from '../src/Hamburger'
// utils
import fetch from 'isomorphic-fetch'
import kebabCase from 'lodash.kebabcase'
import compact from 'lodash.compact'
import flatten from 'lodash.flatten'
import { scroller, animateScroll } from 'react-scroll'
import 'core-js/fn/array/find-index'
// styles
import styled from 'styled-components'
import { media } from '../src/styles'
// json
import sidebar from '../src/Documentation/sidebar'
// sidebar data and helpers
import sidebar, { getItemByPath } from '../src/Documentation/SidebarMenu/helper'

export default class Documentation extends Component {
constructor() {
super()
this.state = {
currentSection: 0,
currentFile: null,
currentItem: {},
markdown: '',
headings: [],
pageNotFound: false,
Expand All @@ -54,52 +49,14 @@ export default class Documentation extends Component {
search: false
})
}
window.addEventListener('popstate', this.loadStateFromURL)
this.ps = new PerfectScrollbar('#sidebar-menu', {
// wheelPropagation: window.innerWidth <= 572
wheelPropagation: true
})
}

componentDidUpdate() {
this.ps.update()
window.addEventListener('popstate', this.loadStateFromURL)
}

componentWillUnmount() {
window.removeEventListener('popstate', this.loadStateFromURL)
}

loadStateFromURL = () => {
const { pathname } = window.location
const sectionURL = pathname.split('/')[2] // match section from URL
const sectionIndex = sidebar.findIndex(
section => (section.slug || kebabCase(section.name)) === sectionURL
)
if (sectionIndex === -1) {
sectionURL
? this.setState({ pageNotFound: true })
: this.onSectionSelect(0)
} else {
const fileURL = pathname.split('/')[3] // match file from URL
const sectionFiles = flatten(sidebar[sectionIndex].files)
const fileIndex = sectionFiles.findIndex(
file => kebabCase(file.slice(0, -3)) === fileURL
)
if (fileIndex === -1) {
fileURL
? this.setState({ pageNotFound: true })
: this.onSectionSelect(sectionIndex)
} else {
this.loadFile({
section: sectionIndex,
file: sectionFiles[fileIndex],
parseHeadings: true,
pageNotFound: false
})
}
}
}

initDocsearch = () => {
docsearch({
apiKey: '755929839e113a981f481601c4f52082',
Expand All @@ -109,47 +66,37 @@ export default class Documentation extends Component {
})
}

getLinkHref = (section, file) => {
const sectionSlug =
sidebar[section].slug || kebabCase(sidebar[section].name)
const fileSlug = file ? kebabCase(file.slice(0, -3)) : undefined
return `/doc/${compact([sectionSlug, fileSlug]).join('/')}`
onNavigate = (path, e) => {
e && e.preventDefault()
window.history.pushState(null, null, path)
this.loadPath(path)
}

setCurrentPath = (section, file) => {
window.history.pushState(null, null, this.getLinkHref(section, file))
}
loadStateFromURL = () => this.loadPath(window.location.pathname)

onSectionSelect = (section, e) => {
e && e.preventDefault()
const { indexFile, files } = sidebar[section]
const file = indexFile || flatten(files)[0]
e && this.setCurrentPath(section, indexFile ? undefined : file)
this.loadFile({ file, section, parseHeadings: false })
}
loadPath = path => {
const item = getItemByPath(path)

onFileSelect = (file, section, e) => {
e && e.preventDefault()
this.setCurrentPath(section, file)
this.loadFile({ file, section, parseHeadings: true })
}
if (!item) {
this.setState({ pageNotFound: true, currentItem: {} })

return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's probably better to use else instead of an explicit return

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will change it.

}

loadFile = ({ file, section, parseHeadings }) => {
fetch(`${sidebar[section].folder}/${file}`)
fetch(item.source)
.then(res => {
res.text().then(text => {
this.setState(
{
currentSection: section,
currentFile: file,
markdown: text,
headings: [],
pageNotFound: false,
isMenuOpen: false
isMenuOpen: false,
currentItem: item
},
() => {
this.scrollTop()
parseHeadings && this.parseHeadings(text)
this.parseHeadings(text)
}
)
})
Expand Down Expand Up @@ -208,21 +155,18 @@ export default class Documentation extends Component {

render() {
const {
currentSection,
currentFile,
currentItem: { source, path, label, next, prev },
headings,
markdown,
pageNotFound,
isMenuOpen
} = this.state

const directory = sidebar[currentSection].folder
const githubLink = `https://github.com/iterative/dvc.org/blob/master${directory}/${currentFile}`
const sectionName = sidebar[currentSection].name
const githubLink = `https://github.com/iterative/dvc.org/blob/master${source}`

return (
<Page stickHeader={true}>
<HeadInjector sectionName={sectionName} />
<HeadInjector sectionName={label} />
<Container>
<Backdrop onClick={this.toggleMenu} visible={isMenuOpen} />

Expand All @@ -239,13 +183,10 @@ export default class Documentation extends Component {

<SidebarMenu
sidebar={sidebar}
currentSection={currentSection}
currentFile={currentFile}
currentPath={path}
headings={headings}
getLinkHref={this.getLinkHref}
scrollToLink={this.scrollToLink}
onSectionSelect={this.onSectionSelect}
onFileSelect={this.onFileSelect}
onNavigate={this.onNavigate}
/>
</Side>

Expand All @@ -255,12 +196,11 @@ export default class Documentation extends Component {
<Markdown
markdown={markdown}
githubLink={githubLink}
section={currentSection}
file={currentFile}
onFileSelect={this.onFileSelect}
prev={prev}
next={next}
onNavigate={this.onNavigate}
/>
)}

<RightPanel
headings={headings}
scrollToLink={this.scrollToLink}
Expand Down
29 changes: 6 additions & 23 deletions src/Documentation/Markdown/Markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ import kebabCase from 'lodash.kebabcase'
// styles
import styled from 'styled-components'
import { media } from '../../../src/styles'
// json
import sidebar from '../../../src/Documentation/sidebar'

registerLanguage('dvc', dvc)
registerLanguage('python', python)
Expand Down Expand Up @@ -115,35 +113,26 @@ export default class Markdown extends Component {

handleSwipeGesture = () => {
if (this.isCodeBlock) return
const { section, file, onFileSelect } = this.props
const files = sidebar[section].files
const fileIndex = files.findIndex(f => f === file)
const showPrev = fileIndex > 0
const showNext = fileIndex + 1 < sidebar[section].files.length
const { prev, next, onNavigate } = this.props

if (this.touchstartX - this.touchendX > 100) {
showNext && onFileSelect(files[fileIndex + 1], section)
next && onNavigate(next)
}

if (this.touchendX - this.touchstartX > 100) {
showPrev && onFileSelect(files[fileIndex - 1], section)
prev && onNavigate(prev)
}
}

render() {
const { markdown, githubLink, section, file, onFileSelect } = this.props
const files = sidebar[section].files
const fileIndex = files.findIndex(f => f === file)
const showPrev = fileIndex > 0
const showNext = fileIndex + 1 < sidebar[section].files.length
const { markdown, githubLink, prev, next, onNavigate } = this.props

return (
<Content>
<GithubLink href={githubLink} target="_blank">
<i /> Edit on Github
</GithubLink>
<ReactMarkdown
key={`${section}-${fileIndex}`}
className="markdown-body"
escapeHtml={false}
source={markdown}
Expand All @@ -155,17 +144,11 @@ export default class Markdown extends Component {
astPlugins={[linker()]}
/>
<NavigationButtons>
<Button
onClick={() => onFileSelect(files[fileIndex - 1], section)}
disabled={!showPrev}
>
<Button onClick={() => onNavigate(prev)} disabled={!prev}>
<i className="prev" />
<span>Prev</span>
</Button>
<Button
onClick={() => onFileSelect(files[fileIndex + 1], section)}
disabled={!showNext}
>
<Button onClick={() => onNavigate(next)} disabled={!next}>
<span>Next</span>
<i className="next" />
</Button>
Expand Down
Loading