refactor(driver): split core and link

This commit is contained in:
EnixCoda 2018-06-17 20:40:51 +08:00
parent 1fea1072a7
commit ac3505f859
3 changed files with 102 additions and 81 deletions

View file

@ -1,13 +1,12 @@
import React from 'react' import React from 'react'
export default function(core) { export default function connect(core) {
return function(ComponentClass) { return function linkComponent(ComponentClass) {
return class Driven extends React.PureComponent { return class AwesomeApp extends React.PureComponent {
static displayName = `Driven${ComponentClass.name}` static displayName = `Driven${ComponentClass.name}`
state = {} state = {}
dispatch = this.setState.bind(this) boundCore = core(this)
boundCore = core(this.dispatch)
render() { render() {
return ( return (

View file

@ -1,101 +1,103 @@
import link from './link'
import DOMHelper, { REPO_TYPE_PRIVATE } from '../utils/DOMHelper' import DOMHelper, { REPO_TYPE_PRIVATE } from '../utils/DOMHelper'
import GitHubHelper, { NOT_FOUND, BAD_CREDENTIALS } from '../utils/GitHubHelper' import GitHubHelper, { NOT_FOUND, BAD_CREDENTIALS } from '../utils/GitHubHelper'
import storageHelper from '../utils/storageHelper' import storageHelper from '../utils/storageHelper'
import URLHelper from '../utils/URLHelper' import URLHelper from '../utils/URLHelper'
import keyHelper from '../utils/keyHelper' import keyHelper from '../utils/keyHelper'
export default function(dispatch) { const init = dispatch => async () => {
const init = async () => { try {
try { DOMHelper.decorateGitHubPageContent()
DOMHelper.decorateGitHubPageContent() const metaData = URLHelper.parse()
const metaData = URLHelper.parse() dispatch(setMetaData, metaData)
setMetaData(metaData) const [accessToken, shortcut] = await Promise.all([
const [accessToken, shortcut] = await Promise.all([ storageHelper.getAccessToken(),
storageHelper.getAccessToken(), storageHelper.getShortcut(),
storageHelper.getShortcut(), ])
]) dispatch({ hasAccessToken: Boolean(accessToken), toggleShowSideBarShortcut: shortcut })
dispatch({ hasAccessToken: Boolean(accessToken), toggleShowSideBarShortcut: shortcut }) const metaDataFromAPI = await GitHubHelper.getRepoMeta({ ...metaData, accessToken })
const metaDataFromAPI = await GitHubHelper.getRepoMeta({ ...metaData, accessToken }) const branchName = metaData.branchName || metaDataFromAPI['default_branch']
const branchName = metaData.branchName || metaDataFromAPI['default_branch'] Object.assign(metaData, { branchName, api: metaDataFromAPI })
Object.assign(metaData, { branchName, api: metaDataFromAPI }) dispatch(setMetaData, metaData)
setMetaData(metaData) const shouldShow = URLHelper.isInCodePage(metaData)
const shouldShow = URLHelper.isInCodePage(metaData) dispatch(setShouldShow, shouldShow)
setShouldShow(shouldShow) if (shouldShow) {
if (shouldShow) { DOMHelper.mountTopProgressBar()
DOMHelper.mountTopProgressBar() }
} const treeData = await GitHubHelper.getTreeData({ ...metaData, accessToken })
const treeData = await GitHubHelper.getTreeData({ ...metaData, accessToken }) dispatch({ logoContainerElement: DOMHelper.insertLogo() })
dispatch({ logoContainerElement: DOMHelper.insertLogo() }) dispatch({ treeData })
dispatch({ treeData }) if (shouldShow) {
if (shouldShow) { DOMHelper.unmountTopProgressBar()
DOMHelper.unmountTopProgressBar() }
} } catch (err) {
} catch (err) { // TODO: detect request time exceeds limit
// TODO: detect request time exceeds limit if (err.message === NOT_FOUND || err.message === BAD_CREDENTIALS) {
if (err.message === NOT_FOUND || err.message === BAD_CREDENTIALS) { const repoPageType = await DOMHelper.getRepoPageType()
const repoPageType = await DOMHelper.getRepoPageType() const errorDueToAuth = repoPageType === REPO_TYPE_PRIVATE || err.message === BAD_CREDENTIALS
const errorDueToAuth = repoPageType === REPO_TYPE_PRIVATE || err.message === BAD_CREDENTIALS dispatch({
dispatch({ showSettings: repoPageType !== null,
showSettings: repoPageType !== null, errorDueToAuth,
errorDueToAuth, })
}) dispatch(setShouldShow, errorDueToAuth)
setShouldShow(errorDueToAuth) } else {
} else { console.error(err)
console.error(err) dispatch(setShouldShow, false)
setShouldShow(false)
}
} }
} }
}
const onPJAXEnd = () => { const onPJAXEnd = dispatch => () => {
dispatch(({ metaData }) => { dispatch(({ metaData }) => {
DOMHelper.mountTopProgressBar() DOMHelper.unmountTopProgressBar()
const mergedMetaData = { ...metaData, ...URLHelper.parse() } DOMHelper.decorateGitHubPageContent()
setShouldShow(URLHelper.isInCodePage(mergedMetaData)) DOMHelper.focusSearchInput()
setMetaData(mergedMetaData) const mergedMetaData = { ...metaData, ...URLHelper.parse() }
DOMHelper.decorateGitHubPageContent() dispatch(setShouldShow, URLHelper.isInCodePage(mergedMetaData))
DOMHelper.focusSearchInput() dispatch(setMetaData, mergedMetaData)
}) })
} }
const setShouldShow = shouldShow => { const onKeyDown = dispatch => e => {
dispatch({ shouldShow }) dispatch(({ toggleShowSideBarShortcut }) => {
DOMHelper.setBodyIndent(shouldShow) if (toggleShowSideBarShortcut) {
} const keys = keyHelper.parseEvent(e)
if (keys === toggleShowSideBarShortcut) {
const toggleShowSideBar = () => dispatch(({ shouldShow }) => setShouldShow(!shouldShow)) dispatch(toggleShowSideBar)
const toggleShowSettings = () => dispatch(({ showSettings }) => ({ showSettings: !showSettings }))
const onHasAccessTokenChange = hasAccessToken => dispatch({ hasAccessToken })
const onKeyDown = e => {
dispatch(({ toggleShowSideBarShortcut }) => {
if (toggleShowSideBarShortcut) {
const keys = keyHelper.parseEvent(e)
if (keys === toggleShowSideBarShortcut) {
toggleShowSideBar()
}
} }
}) }
} })
}
const onShortcutChange = shortcut => dispatch({ toggleShowSideBarShortcut: shortcut }) const toggleShowSideBar = dispatch => () => dispatch(({ shouldShow }) => dispatch(setShouldShow, !shouldShow))
const onResize = size => dispatch({ size }) const setShouldShow = dispatch => shouldShow => {
dispatch({ shouldShow })
DOMHelper.setBodyIndent(shouldShow)
}
const setMetaData = metaData => dispatch({ metaData }) const onResize = dispatch => size => dispatch({ size })
return { const toggleShowSettings = dispatch => () => dispatch(({ showSettings }) => ({ showSettings: !showSettings }))
const onHasAccessTokenChange = dispatch => hasAccessToken => dispatch({ hasAccessToken })
const onShortcutChange = dispatch => shortcut => dispatch({ toggleShowSideBarShortcut: shortcut })
const setMetaData = dispatch => metaData => dispatch({ metaData })
export default function(instance) {
return link(instance.setState.bind(instance), {
init, init,
onPJAXEnd, onPJAXEnd,
onKeyDown,
setShouldShow, setShouldShow,
toggleShowSideBar, toggleShowSideBar,
toggleShowSettings, toggleShowSettings,
onHasAccessTokenChange, onHasAccessTokenChange,
onKeyDown,
onShortcutChange, onShortcutChange,
onResize, onResize,
setMetaData, setMetaData,
} })
} }

20
src/driver/link.js Normal file
View file

@ -0,0 +1,20 @@
export default function link(setState, sources) {
const wrappedMethods = {/* sources[key] -> wrappedMethods.method */}
const map = new Map(/* sources.creator -> wrappedMethods.method */)
function dispatch(...args) {
if (Object.values(sources).includes(args[0])) {
map.get(args[0])(...args.slice(1))
} else {
setState(...args)
}
}
Object.entries(sources).forEach(([key, createMethod]) => {
const method = createMethod(dispatch)
wrappedMethods[key] = method
map.set(createMethod, method)
})
return wrappedMethods
}