From bae918302e6a9e8538e4556d1884695b200d9bbd Mon Sep 17 00:00:00 2001 From: EnixCoda Date: Sat, 30 Jun 2018 15:13:11 +0800 Subject: [PATCH] refactor: create and root component --- src/components/Gitako.js | 14 + src/components/Resizable.js | 29 +++ src/components/ResizeHandler.js | 2 +- src/components/SideBar.js | 24 +- src/content.js | 4 +- src/content.less | 442 ++++++++++++++++---------------- src/driver/core/Gitako.js | 9 + src/driver/core/SideBar.js | 6 +- src/driver/core/index.js | 1 + src/utils/DOMHelper.js | 4 +- 10 files changed, 287 insertions(+), 248 deletions(-) create mode 100644 src/components/Gitako.js create mode 100644 src/components/Resizable.js create mode 100644 src/driver/core/Gitako.js diff --git a/src/components/Gitako.js b/src/components/Gitako.js new file mode 100644 index 0000000..832d5cb --- /dev/null +++ b/src/components/Gitako.js @@ -0,0 +1,14 @@ +import React from 'react' +import SideBar from './SideBar' + +import { Gitako as GitakoCore } from '../driver/core' +import connect from '../driver/connect' + +@connect(GitakoCore) +export default class Gitako extends React.PureComponent { + render() { + return ( + + ) + } +} diff --git a/src/components/Resizable.js b/src/components/Resizable.js new file mode 100644 index 0000000..da6114d --- /dev/null +++ b/src/components/Resizable.js @@ -0,0 +1,29 @@ +import React from 'react' +import PropTypes from 'prop-types' +import ResizeHandler from './ResizeHandler' +import cx from '../utils/cx'; + +export default class Resizable extends React.PureComponent { + static propTypes = { + baseSize: PropTypes.number.isRequired, + } + + state = { + size: this.props.baseSize, + } + + onResize = size => this.setState({ size }) + + render() { + const { className, children } = this.props + const { size } = this.state + return ( +
+ +
+ {children} +
+
+ ) + } +} diff --git a/src/components/ResizeHandler.js b/src/components/ResizeHandler.js index 2599e81..ea15733 100644 --- a/src/components/ResizeHandler.js +++ b/src/components/ResizeHandler.js @@ -6,7 +6,7 @@ export default class ResizeHandler extends React.PureComponent { pointerDown = false startX = 0 delta = 0 - baseSize = this.props.baseSize + baseSize = this.props.size subscribeEvents = () => { window.addEventListener('mousemove', this.onPointerMove) diff --git a/src/components/SideBar.js b/src/components/SideBar.js index 4cf539a..4e4ff4f 100644 --- a/src/components/SideBar.js +++ b/src/components/SideBar.js @@ -8,20 +8,16 @@ import FileExplorer from './FileExplorer' import ToggleShowButton from './ToggleShowButton' import MetaBar from './MetaBar' import SettingsBar from './SettingsBar' -import ResizeHandler from './ResizeHandler' import Portal from './Portal' +import Resizable from './Resizable' import cx from '../utils/cx' -const baseSize = 260 - @connect(SideBarCore) export default class Gitako extends React.PureComponent { static propTypes = { // initial width of side bar baseSize: PropTypes.number, - // current width of side bar - size: PropTypes.number, // whether Gitako side bar should be shown shouldShow: PropTypes.bool, // whether show settings pane @@ -47,13 +43,11 @@ export default class Gitako extends React.PureComponent { onAccessTokenChange: PropTypes.func.isRequired, onKeyDown: PropTypes.func.isRequired, onShortcutChange: PropTypes.func.isRequired, - onResize: PropTypes.func.isRequired, setMetaData: PropTypes.func.isRequired, } static defaultProps = { - baseSize, - size: baseSize, + baseSize: 260, shouldShow: false, showSettings: false, errorDueToAuth: false, @@ -110,7 +104,7 @@ export default class Gitako extends React.PureComponent { render() { const { - size, + baseSize, shouldShow, showSettings, accessToken, @@ -118,20 +112,18 @@ export default class Gitako extends React.PureComponent { toggleShowSideBarShortcut, logoContainerElement, toggleShowSideBar, - onResize, toggleShowSettings, onShortcutChange, onAccessTokenChange, setCompressSingleton, } = this.props return ( -
+
-
- -
+ +
{this.renderContent()} + />
-
+
) } diff --git a/src/content.js b/src/content.js index f1ed56b..0bb24d4 100644 --- a/src/content.js +++ b/src/content.js @@ -1,11 +1,11 @@ import React from 'react' import ReactDOM from 'react-dom' -import SideBar from './components/SideBar' +import Gitako from './components/Gitako' import './content.less' const SideBarElement = document.createElement('div') document.body.appendChild(SideBarElement) -ReactDOM.render(, SideBarElement) +ReactDOM.render(, SideBarElement) diff --git a/src/content.less b/src/content.less index 93a5193..9e8f2a5 100644 --- a/src/content.less +++ b/src/content.less @@ -111,7 +111,7 @@ } } -.@{name} { +.@{name}-side-bar { .@{name}-position-wrapper { position: fixed; top: 0; @@ -119,255 +119,253 @@ height: 100vh; z-index: 2; min-width: @side-bar-base-width; + display: flex; + justify-content: flex-end; @media screen and (min-width: @min-screen-width) { width: ~'calc((100vw - ' @github-content-width ~') / 2)'; } - .@{name}-resize-handler { - @resize-handler-width: 16px; - @side-bar-and-handler-width: (@min-screen-width + @resize-handler-width); - position: absolute; - top: 0; - display: none; - width: @resize-handler-width; - height: 100vh; - background: #fafbfc; - cursor: ew-resize; - user-select: none; - border-left: 1px solid #e1e4e8; - - @media screen and (min-width: @min-screen-width) { - display: flex; - align-items: center; - } - - .grabber-icon { - transform: rotate(90deg); - width: 12px; - } - } - .@{name}-side-bar { - position: absolute; - right: 0; - width: @side-bar-base-width; + .gitako-position-content { max-width: 100%; - height: 100%; + } + } + .@{name}-resize-handler { + @resize-handler-width: 16px; + @side-bar-and-handler-width: (@min-screen-width + @resize-handler-width); + display: none; + width: @resize-handler-width; + background: #fafbfc; + cursor: ew-resize; + user-select: none; + border-left: 1px solid #e1e4e8; + + @media screen and (min-width: @min-screen-width) { display: flex; + align-items: center; + } + + .grabber-icon { + transform: rotate(90deg); + width: 12px; + } + } + .@{name}-side-bar-body { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + background: #fafbfc; + border-right: 1px solid #e1e4e8; + border-left: 1px solid #e1e4e8; + overflow: hidden; + + &.hidden { + .hidden; + } + + .octicon { + transition: 0.3s ease; + color: rgba(3, 47, 98, 0.55); + vertical-align: initial; + } + + .octicon-wrapper { + display: inline-block; + width: 16px; + height: 16px; + text-align: center; + vertical-align: middle; + } + + .octicon-color { + color: rgba(3, 47, 98, 0.55); + } + + .@{name}-side-bar-content { + display: flex; + flex: 1; flex-direction: column; - background: #fafbfc; - border-right: 1px solid #e1e4e8; - overflow: hidden; - will-change: transform; - border-left: 1px solid #e1e4e8; - &.hidden { - .hidden; - } + .meta-bar { + position: relative; + padding: 10px; + padding-right: 30px; + font-size: 13px; + line-height: 20px; + color: #586069; + background-color: #f1f8ff; + border-bottom: 1px solid #c8e1ff; - .octicon { - transition: 0.3s ease; - color: rgba(3, 47, 98, 0.55); - vertical-align: initial; - } - - .octicon-wrapper { - display: inline-block; - width: 16px; - height: 16px; - text-align: center; - vertical-align: middle; - } - - .octicon-color { - color: rgba(3, 47, 98, 0.55); - } - - .@{name}-side-bar-content { - display: flex; - flex: 1; - flex-direction: column; - - .meta-bar { - position: relative; - padding: 10px; - padding-right: 30px; - font-size: 13px; - line-height: 20px; - color: #586069; - background-color: #f1f8ff; - border-bottom: 1px solid #c8e1ff; - - a { - // fix a weird bug: - // when gitako failed loading repo, cursor hovering in meta bar will be 'text' - cursor: pointer; - } - - .repo-name { - font-weight: bolder; - } + a { + // fix a weird bug: + // when gitako failed loading repo, cursor hovering in meta bar will be 'text' + cursor: pointer; } - .description { - padding: 4px 10px; - } - - .file-explorer { - width: 100%; - height: 100%; - outline: none; - display: flex; - flex-direction: column; - flex-wrap: nowrap; - &.freeze { - filter: blur(1.5px) opacity(0.6) grayscale(0.9); - pointer-events: none; - } - - /* search input */ - .search-input-wrapper { - input[type='text'].form-control { - box-shadow: none; - width: 100%; - } - } - - .no-results { - padding: 0px 10px; - color: #666; - } - - .files { - flex: 1; - overflow: auto; - } - - .node-item-row { - background: #fff; - &:hover { - background: #f6f8fa; - } - &.focused { - background: #f0f0f6; - } - - .node-item { - word-wrap: normal; - word-break: break-all; - margin: 0; - color: #0366d6; - line-height: 20px; - padding: 6px 0; - cursor: pointer; - border-top: 1px solid #eaecef; - transition: all 0.5s ease; - - // folder icon rotate when expand - &.expanded .octicon.octicon-triangle-right { - transform: rotate(90deg); - } - - .node-item-name { - padding-left: 6px; - vertical-align: middle; - } - - .node-item:hover .node-item-name { - text-decoration: underline; - } - } - } + .repo-name { + font-weight: bolder; } } - .@{name}-settings-bar { - z-index: 2; - background: #fafbfc; + .description { + padding: 4px 10px; + } + + .file-explorer { + width: 100%; + height: 100%; + outline: none; display: flex; flex-direction: column; - &-title { - border-top: 1px solid #eaecef; - padding: 6px 10px; - box-shadow: 0 1px 8px 0 rgba(0,0,0,.2), 0 3px 4px 0 rgba(0,0,0,.14), 0 3px 3px -2px rgba(0,0,0,.12); - z-index: 1; + flex-wrap: nowrap; + &.freeze { + filter: blur(1.5px) opacity(0.6) grayscale(0.9); + pointer-events: none; } - &-content { - padding: 0 10px; + + /* search input */ + .search-input-wrapper { + input[type='text'].form-control { + box-shadow: none; + width: 100%; + } + } + + .no-results { + padding: 0px 10px; + color: #666; + } + + .files { flex: 1; overflow: auto; - position: relative; - - .shadow-shelter { - position: absolute; - width: 100%; - height: 6px; - left: 0; - background: #fafbfc; - z-index: 1; - } - &-section { - padding-bottom: 10px; - } } - .access-token { - border-bottom: none; // prevent overwrite by github style - .hint { - color: #6a737d; - } - } - .access-token-input-control { - display: flex; - margin-top: 8px; - .access-token-input { - flex: 1; - box-shadow: none; - &:disabled { - cursor: not-allowed; + .node-item-row { + background: #fff; + &:hover { + background: #f6f8fa; + } + &.focused { + background: #f0f0f6; + } + + .node-item { + word-wrap: normal; + word-break: break-all; + margin: 0; + color: #0366d6; + line-height: 20px; + padding: 6px 0; + cursor: pointer; + border-top: 1px solid #eaecef; + transition: all 0.5s ease; + + // folder icon rotate when expand + &.expanded .octicon.octicon-triangle-right { + transform: rotate(90deg); + } + + .node-item-name { + padding-left: 6px; + vertical-align: middle; + } + + .node-item:hover .node-item-name { + text-decoration: underline; } } } - .toggle-shortcut { - .hint { - color: #6a737d; - } - } - .toggle-shortcut-input-control { - display: flex; - margin-top: 8px; - .toggle-shortcut-input { - flex: 1; - box-shadow: none; - } - } - .singleton { - .hint { - color: #6a737d; - } - } - .placeholder-row { - flex-shrink: 0; - display: flex; - justify-content: space-between; - align-items: center; - padding: 6px 10px; - border-top: 1px solid #eaecef; + } + } - .version { - color: #999999; - } - .show-settings-icon { - width: 20px; - height: 20px; - cursor: pointer; - } - .hide-settings-icon { - width: 20px; - height: 20px; - cursor: pointer; + .@{name}-settings-bar { + z-index: 2; + background: #fafbfc; + display: flex; + flex-direction: column; + &-title { + border-top: 1px solid #eaecef; + padding: 6px 10px; + box-shadow: 0 1px 8px 0 rgba(0,0,0,.2), 0 3px 4px 0 rgba(0,0,0,.14), 0 3px 3px -2px rgba(0,0,0,.12); + z-index: 1; + } + &-content { + padding: 0 10px; + flex: 1; + overflow: auto; + position: relative; + + .shadow-shelter { + position: absolute; + width: 100%; + height: 6px; + left: 0; + background: #fafbfc; + z-index: 1; + } + &-section { + padding-bottom: 10px; + } + } + .access-token { + border-bottom: none; // prevent overwrite by github style + .hint { + color: #6a737d; + } + } + .access-token-input-control { + display: flex; + margin-top: 8px; + .access-token-input { + flex: 1; + box-shadow: none; + + &:disabled { + cursor: not-allowed; } } } + .toggle-shortcut { + .hint { + color: #6a737d; + } + } + .toggle-shortcut-input-control { + display: flex; + margin-top: 8px; + .toggle-shortcut-input { + flex: 1; + box-shadow: none; + } + } + .singleton { + .hint { + color: #6a737d; + } + } + .placeholder-row { + flex-shrink: 0; + display: flex; + justify-content: space-between; + align-items: center; + padding: 6px 10px; + border-top: 1px solid #eaecef; + + .version { + color: #999999; + } + .show-settings-icon { + width: 20px; + height: 20px; + cursor: pointer; + } + .hide-settings-icon { + width: 20px; + height: 20px; + cursor: pointer; + } + } } } } diff --git a/src/driver/core/Gitako.js b/src/driver/core/Gitako.js new file mode 100644 index 0000000..d23a533 --- /dev/null +++ b/src/driver/core/Gitako.js @@ -0,0 +1,9 @@ +import DOMHelper from '../../utils/DOMHelper' + +const init = dispatch => () => { + DOMHelper.decorateGitHubPageContent() +} + +export default { + init, +} diff --git a/src/driver/core/SideBar.js b/src/driver/core/SideBar.js index c380c3d..139f914 100644 --- a/src/driver/core/SideBar.js +++ b/src/driver/core/SideBar.js @@ -6,7 +6,6 @@ import keyHelper from '../../utils/keyHelper' const init = dispatch => async () => { try { - DOMHelper.decorateGitHubPageContent() const metaData = URLHelper.parse() dispatch(setMetaData, metaData) const { access_token: accessToken, shortcut, compressSingletonFolder } = await configHelper.get() @@ -21,7 +20,7 @@ const init = dispatch => async () => { DOMHelper.mountTopProgressBar() } const treeData = await GitHubHelper.getTreeData({ ...metaData, accessToken }) - dispatch({ logoContainerElement: DOMHelper.insertLogo() }) + dispatch({ logoContainerElement: DOMHelper.insertLogoMountPoint() }) dispatch({ treeData }) if (shouldShow) { DOMHelper.unmountTopProgressBar() @@ -72,8 +71,6 @@ const setShouldShow = dispatch => shouldShow => { DOMHelper.setBodyIndent(shouldShow) } -const onResize = dispatch => size => dispatch({ size }) - const toggleShowSettings = dispatch => () => dispatch(({ showSettings }) => ({ showSettings: !showSettings })) const onAccessTokenChange = dispatch => accessToken => dispatch({ accessToken }) @@ -93,7 +90,6 @@ export default { toggleShowSettings, onAccessTokenChange, onShortcutChange, - onResize, setMetaData, setCompressSingleton, } diff --git a/src/driver/core/index.js b/src/driver/core/index.js index 071ab89..18fb34f 100644 --- a/src/driver/core/index.js +++ b/src/driver/core/index.js @@ -1,2 +1,3 @@ +export { default as Gitako } from './Gitako' export { default as SideBar } from './SideBar' export { default as FileExplorer } from './FileExplorer' diff --git a/src/utils/DOMHelper.js b/src/utils/DOMHelper.js index c7e5ddf..50776e1 100644 --- a/src/utils/DOMHelper.js +++ b/src/utils/DOMHelper.js @@ -24,7 +24,7 @@ function setBodyIndent(shouldShowGitako) { * add the logo element into DOM * */ -function insertLogo() { +function insertLogoMountPoint() { const logoSelector = '.gitako .gitako-logo' const logoElement = document.querySelector(logoSelector) if (logoElement) { @@ -329,7 +329,7 @@ export default { focusFileExplorer, getCurrentPageType, getRepoPageType, - insertLogo, + insertLogoMountPoint, setBodyIndent, scrollToNodeElement, scrollToRepoContent,