Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(*): add possibility to hide viewed files/directories from tree view #180

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 64 additions & 43 deletions src/js/components/actions/index.jsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,70 @@
import React from 'react'

const Actions = ({ filter, filterFiles, onFullWidth, onOptions, onClose, onReloadTree }) => (
<div className='actions'>
<input type='text' value={filter} className='actions-filter' placeholder='Type to filter files' onChange={filterFiles} />

<div className='actions-small-button'>
<button onClick={onFullWidth} className='full-width-button' title='Toggle full width mode'>
<span className='tooltipped tooltipped-s' aria-label='Toggle full width mode'>
<svg className='octicon' xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'>
<path d='M24 9h-2v-7h-7v-2h9v9zm-9 15v-2h7v-7h2v9h-9zm-15-9h2v7h7v2h-9v-9zm9-15v2h-7v7h-2v-9h9z' />
</svg>
</span>
</button>
</div>
import React, { useState } from 'react'

<div className='actions-small-button'>
<button onClick={onReloadTree} className='reload-tree-button'>
<span className='tooltipped tooltipped-s' aria-label='Reload tree'>
<svg className='octicon octicon-sync' xmlns='http://www.w3.org/2000/svg' width='16px' height='16px' viewBox='0 0 16 16'>
<path fillRule='evenodd' d='M8 2.5a5.487 5.487 0 0 0-4.131 1.869l1.204 1.204A.25.25 0 0 1 4.896 6H1.25A.25.25 0 0 1 1 5.75V2.104a.25.25 0 0 1 .427-.177l1.38 1.38A7.001 7.001 0 0 1 14.95 7.16a.75.75 0 1 1-1.49.178A5.501 5.501 0 0 0 8 2.5zM1.705 8.005a.75.75 0 0 1 .834.656a5.501 5.501 0 0 0 9.592 2.97l-1.204-1.204a.25.25 0 0 1 .177-.427h3.646a.25.25 0 0 1 .25.25v3.646a.25.25 0 0 1-.427.177l-1.38-1.38A7.001 7.001 0 0 1 1.05 8.84a.75.75 0 0 1 .656-.834z' />
</svg>
</span>
</button>
</div>
const Actions = ({ filter, filterFiles, onFullWidth, onOptions, onClose, onReloadTree, onShowViewed, onHideViewed }) => {
const [isViewedHidden, setIsViewedHidden] = useState(false)

<div className='actions-small-button'>
<button onClick={onOptions} className='settings-button'>
<span className='tooltipped tooltipped-s' aria-label='Show settings'>
<svg className='octicon octicon-gear' viewBox='0 0 14 16' width='14' height='16' aria-hidden='true'>
<path fillRule='evenodd' d='M14 8.77v-1.6l-1.94-.64-.45-1.09.88-1.84-1.13-1.13-1.81.91-1.09-.45-.69-1.92h-1.6l-.63 1.94-1.11.45-1.84-.88-1.13 1.13.91 1.81-.45 1.09L0 7.23v1.59l1.94.64.45 1.09-.88 1.84 1.13 1.13 1.81-.91 1.09.45.69 1.92h1.59l.63-1.94 1.11-.45 1.84.88 1.13-1.13-.92-1.81.47-1.09L14 8.75v.02zM7 11c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z' />
</svg>
</span>
</button>
</div>
const handleHideViewed = () => {
if (isViewedHidden) onShowViewed()
else onHideViewed()

setIsViewedHidden(!isViewedHidden)
}

return (
<div className='actions'>
<input type='text' value={filter} className='actions-filter' placeholder='Type to filter files' onChange={filterFiles} />

<div className='actions-small-button'>
<button onClick={onFullWidth} className='full-width-button' title='Toggle full width mode'>
<span className='tooltipped tooltipped-s' aria-label='Toggle full width mode'>
<svg className='octicon' xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'>
<path d='M24 9h-2v-7h-7v-2h9v9zm-9 15v-2h7v-7h2v9h-9zm-15-9h2v7h7v2h-9v-9zm9-15v2h-7v7h-2v-9h9z' />
</svg>
</span>
</button>
</div>

<div className='actions-small-button'>
<button onClick={onReloadTree} className='reload-tree-button'>
<span className='tooltipped tooltipped-s' aria-label='Reload tree'>
<svg className='octicon octicon-sync' xmlns='http://www.w3.org/2000/svg' width='16px' height='16px' viewBox='0 0 16 16'>
<path fillRule='evenodd' d='M8 2.5a5.487 5.487 0 0 0-4.131 1.869l1.204 1.204A.25.25 0 0 1 4.896 6H1.25A.25.25 0 0 1 1 5.75V2.104a.25.25 0 0 1 .427-.177l1.38 1.38A7.001 7.001 0 0 1 14.95 7.16a.75.75 0 1 1-1.49.178A5.501 5.501 0 0 0 8 2.5zM1.705 8.005a.75.75 0 0 1 .834.656a5.501 5.501 0 0 0 9.592 2.97l-1.204-1.204a.25.25 0 0 1 .177-.427h3.646a.25.25 0 0 1 .25.25v3.646a.25.25 0 0 1-.427.177l-1.38-1.38A7.001 7.001 0 0 1 1.05 8.84a.75.75 0 0 1 .656-.834z' />
</svg>
</span>
</button>
</div>

<div className='actions-small-button'>
<button onClick={onOptions} className='settings-button'>
<span className='tooltipped tooltipped-s' aria-label='Show settings'>
<svg className='octicon octicon-gear' viewBox='0 0 14 16' width='14' height='16' aria-hidden='true'>
<path fillRule='evenodd' d='M14 8.77v-1.6l-1.94-.64-.45-1.09.88-1.84-1.13-1.13-1.81.91-1.09-.45-.69-1.92h-1.6l-.63 1.94-1.11.45-1.84-.88-1.13 1.13.91 1.81-.45 1.09L0 7.23v1.59l1.94.64.45 1.09-.88 1.84 1.13 1.13 1.81-.91 1.09.45.69 1.92h1.59l.63-1.94 1.11-.45 1.84.88 1.13-1.13-.92-1.81.47-1.09L14 8.75v.02zM7 11c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z' />
</svg>
</span>
</button>
</div>

<div className='actions-small-button'>
<button onClick={handleHideViewed} className='settings-button'>
<span className='tooltipped tooltipped-s' aria-label='Hide viewed files'>
<svg color={isViewedHidden ? 'red' : 'currentColor'} className='octicon octicon-gear' viewBox='0 0 14 16' width='14' height='16' aria-hidden='true'>
<path fillRule='evenodd' d='M14 8.77v-1.6l-1.94-.64-.45-1.09.88-1.84-1.13-1.13-1.81.91-1.09-.45-.69-1.92h-1.6l-.63 1.94-1.11.45-1.84-.88-1.13 1.13.91 1.81-.45 1.09L0 7.23v1.59l1.94.64.45 1.09-.88 1.84 1.13 1.13 1.81-.91 1.09.45.69 1.92h1.59l.63-1.94 1.11-.45 1.84.88 1.13-1.13-.92-1.81.47-1.09L14 8.75v.02zM7 11c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3z' />
</svg>
</span>
</button>
</div>
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just reused an existing icon. Please, let me know which icon should I use here and which color to use when "function" is active, and I'll update PR. or just feel free to update yourself


<div className='actions-small-button'>
<button onClick={onClose} className='close-button'>
<span className='tooltipped tooltipped-s' aria-label='Close'>
<svg className='octicon octicon-x' viewBox='0 0 12 16' width='12' height='16' aria-hidden='true'>
<path fillRule='evenodd' d='M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z' />
</svg>
</span>
</button>
<div className='actions-small-button'>
<button onClick={onClose} className='close-button'>
<span className='tooltipped tooltipped-s' aria-label='Close'>
<svg className='octicon octicon-x' viewBox='0 0 12 16' width='12' height='16' aria-hidden='true'>
<path fillRule='evenodd' d='M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48L7.48 8z' />
</svg>
</span>
</button>
</div>
</div>
</div>
)
)
}

export default Actions
44 changes: 24 additions & 20 deletions src/js/components/file/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class File extends React.Component {
}

render () {
const { name, href, hasComments, isDeleted, isVisible, diffStats, filter, isViewed } = this.props
const { name, href, hasComments, isDeleted, isVisible, diffStats, filter, isViewed, hideViewed } = this.props
const { options = {} } = this.state
const className = getClassWithColor(name)
const topClassName = [
Expand All @@ -51,25 +51,29 @@ class File extends React.Component {
const highlightedName = (index === -1) ? name : this.getHighlight({ name, filter, index })

return (
<div className={topClassName}>
<span className={`icon ${className}`} />
<a href={href} className='link-gray-dark'>{highlightedName}</a>
{options.diffStats && diffStats && <DiffStats diffStats={diffStats} />}
{hasComments
? (
<svg className='github-pr-file-comment octicon octicon-comment text-gray' viewBox='0 0 16 16' width='16' height='16' aria-hidden='true'>
<path fillRule='evenodd' d='M14 1H2c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1h2v3.5L7.5 11H14c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 9H7l-2 2v-2H2V2h12v8z' />
</svg>
)
: null}
{isViewed
? (
<svg className='github-pr-file-checkmark octicon octicon-check' viewBox='0 0 12 16' version='1.1' width='12' height='16' aria-hidden='true'>
<path fillRule='evenodd' d='M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z' />
</svg>
)
: null}
</div>
isViewed && hideViewed
? null
: (
<div className={topClassName}>
<span className={`icon ${className}`} />
<a href={href} className='link-gray-dark'>{highlightedName}</a>
{options.diffStats && diffStats && <DiffStats diffStats={diffStats} />}
{hasComments
? (
<svg className='github-pr-file-comment octicon octicon-comment text-gray' viewBox='0 0 16 16' width='16' height='16' aria-hidden='true'>
<path fillRule='evenodd' d='M14 1H2c-.55 0-1 .45-1 1v8c0 .55.45 1 1 1h2v3.5L7.5 11H14c.55 0 1-.45 1-1V2c0-.55-.45-1-1-1zm0 9H7l-2 2v-2H2V2h12v8z' />
</svg>
)
: null}
{isViewed
? (
<svg className='github-pr-file-checkmark octicon octicon-check' viewBox='0 0 12 16' version='1.1' width='12' height='16' aria-hidden='true'>
<path fillRule='evenodd' d='M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5L12 5z' />
</svg>
)
: null}
</div>
)
)
}
}
Expand Down
12 changes: 8 additions & 4 deletions src/js/components/folder/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Folder extends React.Component {
}

render () {
const { children, nodeLabel, isViewed } = this.props
const { children, nodeLabel, isViewed, hideViewed } = this.props

const display = (
<div>
Expand All @@ -24,9 +24,13 @@ class Folder extends React.Component {
)

return (
<TreeView nodeLabel={display} defaultCollapsed={false}>
{children}
</TreeView>
isViewed && hideViewed
? null
: (
<TreeView nodeLabel={display} defaultCollapsed={false}>
{children}
</TreeView>
)
)
}
}
Expand Down
23 changes: 18 additions & 5 deletions src/js/components/tree/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ const fullScreenStorageKey = '__better_github_pr_full_screen'
class Tree extends React.Component {
constructor (props) {
super(props)
this.onReloadTree = this.props.reloadTree
this.handleOnReloadTree = this.props.reloadTree

this.handleClose = this.handleClose.bind(this)
this.handleOnShowViewed = this.handleOnShowViewed.bind(this)
this.handleOnHideViewed = this.handleOnHideViewed.bind(this)
this.onScroll = this.onScroll.bind(this)
this.onResizerMouseDown = this.onResizerMouseDown.bind(this)
this.onMouseMove = this.onMouseMove.bind(this)
Expand All @@ -40,7 +42,8 @@ class Tree extends React.Component {
show: true,
visibleElement: null,
filter: '',
options: {}
options: {},
hideViewed: false
}
}

Expand Down Expand Up @@ -137,6 +140,14 @@ class Tree extends React.Component {
this.setWidth(0, false)
}

handleOnShowViewed () {
this.setState({ hideViewed: false })
}

handleOnHideViewed () {
this.setState({ hideViewed: true })
}

handleFullWidth () {
const fullScreenState = document.querySelector('body').classList.toggle('full-width')
window.localStorage.setItem(fullScreenStorageKey, fullScreenState)
Expand Down Expand Up @@ -174,7 +185,7 @@ class Tree extends React.Component {
}

render () {
const { root, filter, show, visibleElement } = this.state
const { root, filter, show, visibleElement, hideViewed } = this.state

if (!show) {
return null
Expand All @@ -189,13 +200,15 @@ class Tree extends React.Component {
onFullWidth={this.handleFullWidth}
onOptions={this.handleOptions}
onClose={this.handleClose}
onReloadTree={this.onReloadTree}
onReloadTree={this.handleOnReloadTree}
onShowViewed={this.handleOnShowViewed}
onHideViewed={this.handleOnHideViewed}
/>
<div className='file-container'>
<div>
{root.list.map(node => (
<span key={node.nodeLabel}>
{createTree({ ...node, visibleElement, filter })}
{createTree({ ...node, visibleElement, filter, hideViewed })}
</span>
))}
</div>
Expand Down
7 changes: 4 additions & 3 deletions src/js/createTree.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { isFileViewed } from './lib'
import File from './components/file'
import Folder from './components/folder'

export const createTree = ({ nodeLabel, list, href, hasComments, isDeleted, diffElement, diffStats, visibleElement, filter }) => {
export const createTree = ({ nodeLabel, list, href, hasComments, isDeleted, diffElement, diffStats, visibleElement, filter, hideViewed }) => {
if (href) {
const isVisible = (diffElement === visibleElement)
const isViewed = isFileViewed(diffElement)
Expand All @@ -19,14 +19,15 @@ export const createTree = ({ nodeLabel, list, href, hasComments, isDeleted, diff
diffStats={diffStats}
isViewed={isViewed}
filter={filter}
hideViewed={hideViewed}
/>
)
}

const rawChildren = list.map(node => createTree({ ...node, visibleElement, filter }))
const rawChildren = list.map(node => createTree({ ...node, visibleElement, filter, hideViewed }))

return (
<Folder key={nodeLabel} nodeLabel={nodeLabel} isViewed={rawChildren.every(child => child.props.isViewed)}>
<Folder key={nodeLabel} nodeLabel={nodeLabel} isViewed={rawChildren.every(child => child.props.isViewed)} hideViewed={hideViewed}>
{rawChildren.map(node => (
<span key={node.key}>
{node}
Expand Down
2 changes: 1 addition & 1 deletion src/js/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Top extends React.Component {
this.calculateTree()
}

loadTree() {
loadTree () {
const { tree } = createFileTree()
this.setState({ tree })
}
Expand Down