From 0db7e688a33cc941964902fca4a6792d1b290478 Mon Sep 17 00:00:00 2001 From: EnixCoda Date: Sun, 17 Jun 2018 01:30:00 +0800 Subject: [PATCH] refactor: extract logic core --- package.json | 1 + src/components/SideBar.js | 187 ++++++++++++++------------------------ src/driver/Driver.js | 19 ++++ src/driver/core.js | 101 ++++++++++++++++++++ src/utils/DOMHelper.js | 9 ++ 5 files changed, 197 insertions(+), 120 deletions(-) create mode 100644 src/driver/Driver.js create mode 100644 src/driver/core.js diff --git a/package.json b/package.json index e8a146c..b7d80a2 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dependencies": { "nprogress": "^0.2.0", "octicons": "^7.1.0", + "prop-types": "^15.6.1", "react": "^16.4.0", "react-dom": "^16.4.0" }, diff --git a/src/components/SideBar.js b/src/components/SideBar.js index b4fb8f6..957d2df 100644 --- a/src/components/SideBar.js +++ b/src/components/SideBar.js @@ -1,5 +1,8 @@ import React from 'react' -import NProgress from 'nprogress' +import PropTypes from 'prop-types' + +import connect from '../driver/Driver' +import core from '../driver/core' import FileExplorer from './FileExplorer' import ToggleShowButton from './ToggleShowButton' @@ -9,133 +12,70 @@ import ResizeHandler from './ResizeHandler' import Portal from './Portal' import cx from '../utils/cx' -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' -// initial width of side bar const baseSize = 260 -export default class SideBar extends React.Component { - state = { + +class SideBar extends React.Component { + static propTypes = { + // initial width of side bar + baseSize: PropTypes.number, // current width of side bar - size: 260, + size: PropTypes.number, // whether Gitako side bar should be shown - shouldShow: false, + shouldShow: PropTypes.bool, // whether show settings pane - showSettings: false, + showSettings: PropTypes.bool, // whether failed loading the repo due to it is private - errorDueToAuth: false, + errorDueToAuth: PropTypes.bool, // got access token for GitHub - hasAccessToken: false, + hasAccessToken: PropTypes.bool, // the shortcut string for toggle sidebar - toggleShowSideBarShortcut: '', + toggleShowSideBarShortcut: PropTypes.string, // meta data for the repository - metaData: null, + metaData: PropTypes.object, // file tree data + treeData: PropTypes.object, + + init: PropTypes.func.isRequired, + onPJAXEnd: PropTypes.func.isRequired, + setShouldShow: PropTypes.func.isRequired, + toggleShowSideBar: PropTypes.func.isRequired, + toggleShowSettings: PropTypes.func.isRequired, + onHasAccessTokenChange: PropTypes.func.isRequired, + onKeyDown: PropTypes.func.isRequired, + onShortcutChange: PropTypes.func.isRequired, + onResize: PropTypes.func.isRequired, + setMetaData: PropTypes.func.isRequired, + } + + static defaultProps = { + baseSize, + size: baseSize, + shouldShow: false, + showSettings: false, + errorDueToAuth: false, + hasAccessToken: false, + toggleShowSideBarShortcut: '', + metaData: null, treeData: null, } - async componentWillMount() { - try { - const metaDataFromUrl = URLHelper.parse() - this.setState({ metaData: metaDataFromUrl }) - DOMHelper.decorateGitHubPageContent() - const [accessToken, shortcut] = await Promise.all([ - storageHelper.getAccessToken(), - storageHelper.getShortcut(), - ]) - this.setState({ hasAccessToken: Boolean(accessToken), toggleShowSideBarShortcut: shortcut }) - const metaDataFromAPI = await GitHubHelper.getRepoMeta({ ...metaDataFromUrl, accessToken }) - const branchName = metaDataFromUrl.branchName || metaDataFromAPI['default_branch'] - const metaData = { ...metaDataFromUrl, branchName, api: metaDataFromAPI } - this.setState({ metaData }) - const shouldShow = URLHelper.isInCodePage(metaData) - this.setShouldShow(shouldShow) - if (shouldShow) { - NProgress.start() - } - const treeData = await GitHubHelper.getTreeData({ ...metaData, accessToken }) - this.logoContainerElement = DOMHelper.insertLogo() - this.setState({ treeData }) - if (shouldShow) { - NProgress.done() - } + constructor(props) { + super(props) + const { init } = props + init() + } - window.addEventListener('pjax:complete', this.onPJAXEnd) - window.addEventListener('keydown', this.onKeyDown) - } 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 - this.setState({ - showSettings: repoPageType !== null, - errorDueToAuth, - }) - this.setShouldShow(errorDueToAuth) - } else { - console.error(err) - this.setShouldShow(false) - } - } + componentDidMount() { + const { onPJAXEnd, onKeyDown } = this.props + window.addEventListener('pjax:complete', onPJAXEnd) + window.addEventListener('keydown', onKeyDown) } componentWillUnmount() { - window.removeEventListener('pjax:complete', this.onPJAXEnd) - window.removeEventListener('keydown', this.onKeyDown) - } - - onPJAXEnd = () => { - NProgress.done() - const { metaData } = this.state - const mergedMetaData = { ...metaData, ...URLHelper.parse() } - this.setState({ - metaData: mergedMetaData, - }) - this.setShouldShow(URLHelper.isInCodePage(mergedMetaData)) - DOMHelper.decorateGitHubPageContent() - DOMHelper.focusSearchInput() - } - - setShouldShow = shouldShow => { - this.setState({ shouldShow }) - DOMHelper.setBodyIndent(shouldShow) - } - - toggleShowSideBar = () => { - const { shouldShow } = this.state - this.setShouldShow(!shouldShow) - } - - toggleShowSettings = () => { - const { showSettings } = this.state - this.setState({ showSettings: !showSettings }) - } - - onHasAccessTokenChange = hasAccessToken => { - this.setState({ hasAccessToken }) - } - - onKeyDown = e => { - const { toggleShowSideBarShortcut } = this.state - if (toggleShowSideBarShortcut) { - const keys = keyHelper.parseEvent(e) - if (keys === toggleShowSideBarShortcut) { - this.toggleShowSideBar() - } - } - } - - onShortcutChange = shortcut => { - this.setState({ toggleShowSideBarShortcut: shortcut }) - } - - onResize = size => { - this.setState({ - size, - }) + const { onPJAXEnd, onKeyDown } = this.props + window.removeEventListener('pjax:complete', onPJAXEnd) + window.removeEventListener('keydown', onKeyDown) } renderAccessDeniedError() { @@ -151,7 +91,7 @@ export default class SideBar extends React.Component { } renderContent() { - const { errorDueToAuth, metaData, treeData, showSettings } = this.state + const { errorDueToAuth, metaData, treeData, showSettings } = this.props return (
{metaData && } @@ -171,21 +111,26 @@ export default class SideBar extends React.Component { showSettings, hasAccessToken, toggleShowSideBarShortcut, - loading, - } = this.state + logoContainerElement, + toggleShowSideBar, + onResize, + toggleShowSettings, + onShortcutChange, + onHasAccessTokenChange, + } = this.props return (
- - + +
- +
{this.renderContent()} + ) + } + } + } +} diff --git a/src/driver/core.js b/src/driver/core.js new file mode 100644 index 0000000..5f44d73 --- /dev/null +++ b/src/driver/core.js @@ -0,0 +1,101 @@ +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 onPJAXEnd = () => { + dispatch(({ metaData }) => { + DOMHelper.mountTopProgressBar() + const mergedMetaData = { ...metaData, ...URLHelper.parse() } + setShouldShow(URLHelper.isInCodePage(mergedMetaData)) + setMetaData(mergedMetaData) + DOMHelper.decorateGitHubPageContent() + DOMHelper.focusSearchInput() + }) + } + + 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 onShortcutChange = shortcut => dispatch({ toggleShowSideBarShortcut: shortcut }) + + const onResize = size => dispatch({ size }) + + const setMetaData = metaData => dispatch({ metaData }) + + return { + init, + onPJAXEnd, + setShouldShow, + toggleShowSideBar, + toggleShowSettings, + onHasAccessTokenChange, + onKeyDown, + onShortcutChange, + onResize, + setMetaData, + } +} diff --git a/src/utils/DOMHelper.js b/src/utils/DOMHelper.js index e768b30..c7e5ddf 100644 --- a/src/utils/DOMHelper.js +++ b/src/utils/DOMHelper.js @@ -311,6 +311,13 @@ function decorateGitHubPageContent() { attachCopySnippet() } +function mountTopProgressBar() { + NProgress.start() +} + +function unmountTopProgressBar() { + NProgress.done() +} export default { loadWithPJAX, @@ -326,4 +333,6 @@ export default { setBodyIndent, scrollToNodeElement, scrollToRepoContent, + mountTopProgressBar, + unmountTopProgressBar, }