Skip to content

Commit

Permalink
Merge pull request #21 from jacr1/feature/concat-single-folders
Browse files Browse the repository at this point in the history
Concatenate single folders together
  • Loading branch information
berzniz authored Oct 4, 2018
2 parents b06bc9a + b5cf32a commit 641c9ae
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 14 deletions.
86 changes: 80 additions & 6 deletions src/js/components/tree.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,34 @@ import React from 'react'
import Branch from './branch.jsx'
import { isElementVisible } from '../lib'

// Minimum and maximum resizable area width
const MIN_WIDTH = 55
const MAX_WIDTH = 700

const widthLocalStorageKey = '__better_github_pr_tree_width'

class Tree extends React.Component {
constructor (props) {
super(props)

this.onClose = this.onClose.bind(this)
this.onScroll = this.onScroll.bind(this)
this.onResizerMouseDown = this.onResizerMouseDown.bind(this)
this.onMouseMove = this.onMouseMove.bind(this)
this.onMouseUp = this.onMouseUp.bind(this)
this.toggleDocumentFullWidth = this.toggleDocumentFullWidth.bind(this)

this.isResizing = false
this.resizeDelta = 0

this.treeContainer = document.querySelector('.__better_github_pr')
this.reviewContainers = document.querySelectorAll('.enable_better_github_pr .diff-view, .enable_better_github_pr .commit.full-commit.prh-commit')

// Set initial width from value saved to localStorrage
const savedWitdh = window.localStorage.getItem(widthLocalStorageKey)
if (savedWitdh) {
this.setWidth(parseInt(savedWitdh, 10))
}

this.state = {
show: true,
Expand All @@ -20,13 +42,44 @@ class Tree extends React.Component {
window.addEventListener('load', this.onScroll, false)
window.addEventListener('scroll', this.onScroll, false)
window.addEventListener('resize', this.onScroll, false)

this.resizer.addEventListener('mousedown', this.onResizerMouseDown, false)
document.addEventListener('mousemove', this.onMouseMove, false)
document.addEventListener('mouseup', this.onMouseUp, false)
}

componentWillUnmount () {
window.removeEventListener('DOMContentLoaded', this.onScroll, false)
window.removeEventListener('load', this.onScroll, false)
window.removeEventListener('scroll', this.onScroll, false)
window.removeEventListener('resize', this.onScroll, false)

this.resizer.removeEventListener('mousedown', this.onResizerMouseDown, false)
document.removeEventListener('mousemove', this.onMouseMove, false)
document.removeEventListener('mouseup', this.onMouseUp, false)
}

onResizerMouseDown () {
this.isResizing = true
this.treeContainer.classList.add('__better_github_pr_noselect')
this.prevWidth = this.treeContainer.offsetWidth
this.startResizeX = this.resizer.getBoundingClientRect().x
}

onMouseMove (e) {
if (!this.isResizing) return

this.resizeDelta = e.clientX - this.startResizeX
let newWidth = this.prevWidth + this.resizeDelta
setTimeout(() => this.setWidth(newWidth), 0)
}

onMouseUp () {
if (!this.isResizing) return

this.isResizing = false
this.treeContainer.classList.remove('__better_github_pr_noselect')
window.localStorage.setItem(widthLocalStorageKey, this.treeContainer.offsetWidth)
}

onScroll () {
Expand All @@ -45,6 +98,23 @@ class Tree extends React.Component {
const show = false
this.setState({ show })
document.body.classList.toggle('enable_better_github_pr', show)
this.setWidth(0, false)
}

setWidth (width, withConstraints = true) {
if (withConstraints) {
if (width <= MIN_WIDTH) width = MIN_WIDTH
if (width >= MAX_WIDTH) width = MAX_WIDTH
}

this.treeContainer.style.width = `${width}px`
this.reviewContainers.forEach((element, index) => {
element.style['margin-left'] = `${width + 10}px`
})
}

toggleDocumentFullWidth () {
document.querySelector('body').classList.toggle('__better_github_pr_wide')
}

render () {
Expand All @@ -56,13 +126,17 @@ class Tree extends React.Component {
}

return (
<div>
<div >
<button onClick={this.toggleDocumentFullWidth} className='__better_github_pr_full_width' title='Toggle maximum width of github content' />
<button onClick={this.onClose} className='close_button'></button>
{root.list.map(node => (
<span key={node.nodeLabel}>
<Branch {...node} visibleElement={visibleElement} />
</span>
))}
<div>
<div className='_better_github_pr_resizer' ref={node => { this.resizer = node }} />
{root.list.map(node => (
<span key={node.nodeLabel}>
<Branch {...node} visibleElement={visibleElement} />
</span>
))}
</div>
</div>
)
}
Expand Down
19 changes: 19 additions & 0 deletions src/js/folderconcat/folder-concat.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const folderConcat = (node) => {
// file or empty
if (node.list === undefined || node.list.length === 0 || (node.href !== null && node.href !== undefined)) {
return node
}

if (node.list.length === 1) {
let collapsed = folderConcat(node.list[0])
// if the last collapsed thing is a folder merge into one.
if (node.nodeLabel !== '/' && (collapsed.href === null || collapsed.href === undefined)) {
node.nodeLabel = node.nodeLabel + '/' + collapsed.nodeLabel
node.hasComments = collapsed.hasComments || node.hasComments
node.list = collapsed.list
}
return node
}
node.list.map(x => folderConcat(x))
return node
}
4 changes: 3 additions & 1 deletion src/js/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react'
import { render } from 'react-dom'
import Tree from './components/tree'
import { createFileTree, createRootElement } from './lib'
import { folderConcat } from './folderconcat/folder-concat'
import './style.css'

const { document, MutationObserver, parseInt } = window
Expand All @@ -23,7 +24,8 @@ const renderTree = () => {
return
}

const { tree, count } = createFileTree()
let { tree, count } = createFileTree()
tree = folderConcat(tree)
render(<Tree root={tree} />, rootElement)
if (fileCount !== count) {
setTimeout(renderTree.bind(this, rootElement), 100)
Expand Down
73 changes: 66 additions & 7 deletions src/js/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,29 @@
display: none;
}

._better_github_pr_resizer {
position: absolute;
width: 5px;
height: 100%;
background: lightgray;
right: 0;
top: 0;
cursor: col-resize;
opacity: .4;
transition: opacity .2s ease;
z-index: 1;
}

._better_github_pr_resizer:hover {
opacity: 1;
}

.enable_better_github_pr .__better_github_pr {
display: block;
position: relative;
margin-top: 20px;
padding: 10px;
width: 240px;
overflow: auto;
padding: 30px 10px 0;
width: 330px;
height: calc(100vh - 61px);
background-color: #fafbfc;
border: 1px solid #e1e4e8;
Expand All @@ -22,23 +38,66 @@
}

.__better_github_pr > div {
display: inline-block;
overflow: auto;
height: 100%;
padding-bottom: 10px;
}

.__better_github_pr > div > div {
width: fit-content;
}

.__better_github_pr .close_button {
background: none;
border: none;
position: absolute;
top: 0;
right: 0;
top: 1px;
right: 10px;
padding: 5px 2px;
}

.__better_github_pr_full_width {
width: 16px;
height: 16px;
background-size: cover;
position: absolute;
top: 6px;
right: 40px;
cursor: pointer;
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjwhRE9DVFlQRSBzdmcgIFBVQkxJQyAnLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4nICAnaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkJz48c3ZnIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDMyIDMyIiBoZWlnaHQ9IjMycHgiIGlkPSLQodC70L7QuV8xIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjMycHgiIHhtbDpzcGFjZT0icHJlc2VydmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxnIGlkPSJGdWxsc2NyZWVuIj48cGF0aCBkPSJNMzIsMWMwLTAuNTU4LTAuNDQyLTEtMS0xbC04Ljk4NSwwYy0wLjU2OCwwLTAuOTkxLDAuNDQ4LTAuOTkyLDEuMDE2QzIxLjAyMywxLjU4MywyMS40NDcsMiwyMi4wMTUsMkwzMCwyICAgbC0wLjAxNiw4LjAyM2MwLDAuNTY4LDAuNDMyLDEsMSwxYzAuNTY4LTAuMDAxLDEtMC40MzIsMS0xTDMyLDEuMDE1YzAtMC4wMDMtMC4wMDEtMC4wMDUtMC4wMDEtMC4wMDdDMzEuOTk5LDEuMDA1LDMyLDEuMDAzLDMyLDF6ICAgIiBmaWxsPSIjMTIxMzEzIi8+PHBhdGggZD0iTTEwLjAxNiwwSDEuMDMxQzEuMDI4LDAsMS4wMjYsMC4wMDEsMS4wMjMsMC4wMDFDMS4wMjEsMC4wMDEsMS4wMTgsMCwxLjAxNiwwYy0wLjU1OCwwLTEsMC40NDItMSwxICAgTDAsMTAuMDA4QzAsMTAuNTc2LDAuNDQ4LDExLDEuMDE2LDExQzEuNTgzLDExLDIsMTAuNTc2LDIsMTAuMDA4TDIuMDE2LDJoOGMwLjU2OCwwLDEtMC40MzIsMS0xQzExLjAxNSwwLjQzMiwxMC41ODMsMCwxMC4wMTYsMHoiIGZpbGw9IiMxMjEzMTMiLz48cGF0aCBkPSJNOS45ODUsMzBIMnYtOGMwLTAuNTY4LTAuNDMyLTEtMS0xYy0wLjU2OCwwLTEsMC40MzItMSwxdjguOTg1YzAsMC4wMDMsMC4wMDEsMC4wMDUsMC4wMDEsMC4wMDcgICBDMC4wMDEsMzAuOTk1LDAsMzAuOTk3LDAsMzFjMCwwLjU1OCwwLjQ0MiwxLDEsMWg4Ljk4NWMwLjU2OCwwLDAuOTkxLTAuNDQ4LDAuOTkyLTEuMDE2QzEwLjk3NywzMC40MTcsMTAuNTUzLDMwLDkuOTg1LDMweiIgZmlsbD0iIzEyMTMxMyIvPjxwYXRoIGQ9Ik0zMC45ODQsMjEuMDIzYy0wLjU2OCwwLTAuOTg1LDAuNDI0LTAuOTg0LDAuOTkyVjMwbC04LDBjLTAuNTY4LDAtMSwwLjQzMi0xLDFjMCwwLjU2OCwwLjQzMiwxLDEsMSAgIGw4Ljk4NSwwYzAuMDAzLDAsMC4wMDUtMC4wMDEsMC4wMDctMC4wMDFDMzAuOTk1LDMxLjk5OCwzMC45OTcsMzIsMzEsMzJjMC41NTgsMCwxLTAuNDQyLDEtMXYtOC45ODUgICBDMzIsMjEuNDQ3LDMxLjU1MiwyMS4wMjMsMzAuOTg0LDIxLjAyM3oiIGZpbGw9IiMxMjEzMTMiLz48L2c+PGcvPjxnLz48Zy8+PGcvPjxnLz48Zy8+PC9zdmc+');
background-color: transparent;
border: none;
}

.__better_github_pr_noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}

.__better_github_pr_wide .container {
min-width: 980px;
width: 96% !important;
transition: width .2s ease;
}

.__better_github_pr_wide .repository-content .discussion-timeline {
width: calc(100% - 220px) !important;
}

.__better_github_pr_wide .repository-content .discussion-timeline .timeline-new-comment {
max-width: 100% !important;
}

/* GitHub page changes */

.enable_better_github_pr .diff-view,
.enable_better_github_pr .commit.full-commit.prh-commit {
margin-left: 250px;
margin-left: 340px;
}

.enable_better_github_pr .diff-view .file-header {
Expand Down

0 comments on commit 641c9ae

Please sign in to comment.