diff --git a/src/driver/Driver.js b/src/driver/connect.js similarity index 53% rename from src/driver/Driver.js rename to src/driver/connect.js index e7417d2..76d633a 100644 --- a/src/driver/Driver.js +++ b/src/driver/connect.js @@ -1,13 +1,12 @@ import React from 'react' -export default function(core) { - return function(ComponentClass) { - return class Driven extends React.PureComponent { +export default function connect(core) { + return function linkComponent(ComponentClass) { + return class AwesomeApp extends React.PureComponent { static displayName = `Driven${ComponentClass.name}` state = {} - dispatch = this.setState.bind(this) - boundCore = core(this.dispatch) + boundCore = core(this) render() { return ( diff --git a/src/driver/core.js b/src/driver/core.js index 5f44d73..ab964ec 100644 --- a/src/driver/core.js +++ b/src/driver/core.js @@ -1,101 +1,103 @@ +import link from './link' + import DOMHelper, { REPO_TYPE_PRIVATE } from '../utils/DOMHelper' import GitHubHelper, { NOT_FOUND, BAD_CREDENTIALS } from '../utils/GitHubHelper' import storageHelper from '../utils/storageHelper' import URLHelper from '../utils/URLHelper' import keyHelper from '../utils/keyHelper' -export default function(dispatch) { - const init = async () => { - try { - DOMHelper.decorateGitHubPageContent() - const metaData = URLHelper.parse() - setMetaData(metaData) - const [accessToken, shortcut] = await Promise.all([ - storageHelper.getAccessToken(), - storageHelper.getShortcut(), - ]) - dispatch({ hasAccessToken: Boolean(accessToken), toggleShowSideBarShortcut: shortcut }) - const metaDataFromAPI = await GitHubHelper.getRepoMeta({ ...metaData, accessToken }) - const branchName = metaData.branchName || metaDataFromAPI['default_branch'] - Object.assign(metaData, { branchName, api: metaDataFromAPI }) - setMetaData(metaData) - const shouldShow = URLHelper.isInCodePage(metaData) - setShouldShow(shouldShow) - if (shouldShow) { - DOMHelper.mountTopProgressBar() - } - const treeData = await GitHubHelper.getTreeData({ ...metaData, accessToken }) - dispatch({ logoContainerElement: DOMHelper.insertLogo() }) - dispatch({ treeData }) - if (shouldShow) { - DOMHelper.unmountTopProgressBar() - } - } catch (err) { - // TODO: detect request time exceeds limit - if (err.message === NOT_FOUND || err.message === BAD_CREDENTIALS) { - const repoPageType = await DOMHelper.getRepoPageType() - const errorDueToAuth = repoPageType === REPO_TYPE_PRIVATE || err.message === BAD_CREDENTIALS - dispatch({ - showSettings: repoPageType !== null, - errorDueToAuth, - }) - setShouldShow(errorDueToAuth) - } else { - console.error(err) - setShouldShow(false) - } +const init = dispatch => async () => { + try { + DOMHelper.decorateGitHubPageContent() + const metaData = URLHelper.parse() + dispatch(setMetaData, metaData) + const [accessToken, shortcut] = await Promise.all([ + storageHelper.getAccessToken(), + storageHelper.getShortcut(), + ]) + dispatch({ hasAccessToken: Boolean(accessToken), toggleShowSideBarShortcut: shortcut }) + const metaDataFromAPI = await GitHubHelper.getRepoMeta({ ...metaData, accessToken }) + const branchName = metaData.branchName || metaDataFromAPI['default_branch'] + Object.assign(metaData, { branchName, api: metaDataFromAPI }) + dispatch(setMetaData, metaData) + const shouldShow = URLHelper.isInCodePage(metaData) + dispatch(setShouldShow, shouldShow) + if (shouldShow) { + DOMHelper.mountTopProgressBar() + } + const treeData = await GitHubHelper.getTreeData({ ...metaData, accessToken }) + dispatch({ logoContainerElement: DOMHelper.insertLogo() }) + dispatch({ treeData }) + if (shouldShow) { + DOMHelper.unmountTopProgressBar() + } + } catch (err) { + // TODO: detect request time exceeds limit + if (err.message === NOT_FOUND || err.message === BAD_CREDENTIALS) { + const repoPageType = await DOMHelper.getRepoPageType() + const errorDueToAuth = repoPageType === REPO_TYPE_PRIVATE || err.message === BAD_CREDENTIALS + dispatch({ + showSettings: repoPageType !== null, + errorDueToAuth, + }) + dispatch(setShouldShow, errorDueToAuth) + } else { + console.error(err) + dispatch(setShouldShow, false) } } +} - const onPJAXEnd = () => { - dispatch(({ metaData }) => { - DOMHelper.mountTopProgressBar() - const mergedMetaData = { ...metaData, ...URLHelper.parse() } - setShouldShow(URLHelper.isInCodePage(mergedMetaData)) - setMetaData(mergedMetaData) - DOMHelper.decorateGitHubPageContent() - DOMHelper.focusSearchInput() - }) - } +const onPJAXEnd = dispatch => () => { + dispatch(({ metaData }) => { + DOMHelper.unmountTopProgressBar() + DOMHelper.decorateGitHubPageContent() + DOMHelper.focusSearchInput() + const mergedMetaData = { ...metaData, ...URLHelper.parse() } + dispatch(setShouldShow, URLHelper.isInCodePage(mergedMetaData)) + dispatch(setMetaData, mergedMetaData) + }) +} - const setShouldShow = shouldShow => { - dispatch({ shouldShow }) - DOMHelper.setBodyIndent(shouldShow) - } - - const toggleShowSideBar = () => dispatch(({ shouldShow }) => setShouldShow(!shouldShow)) - - 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 onKeyDown = dispatch => e => { + dispatch(({ toggleShowSideBarShortcut }) => { + if (toggleShowSideBarShortcut) { + const keys = keyHelper.parseEvent(e) + if (keys === toggleShowSideBarShortcut) { + dispatch(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, onPJAXEnd, + onKeyDown, setShouldShow, toggleShowSideBar, toggleShowSettings, onHasAccessTokenChange, - onKeyDown, onShortcutChange, onResize, setMetaData, - } + }) } diff --git a/src/driver/link.js b/src/driver/link.js new file mode 100644 index 0000000..2e1a5e7 --- /dev/null +++ b/src/driver/link.js @@ -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 +}