Skip to content

Commit

Permalink
Coverts DownloadItem and DownloadsBar
Browse files Browse the repository at this point in the history
Resolves brave#9260

Auditors: @bsclifton

Test Plan:
- download an item
- check if download item is shown
- check if you can interact with it (note there is a problem with pause/resume, fixed here brave#9246)
  • Loading branch information
NejcZdovc committed Jun 6, 2017
1 parent b55a1ee commit 5584d38
Show file tree
Hide file tree
Showing 8 changed files with 348 additions and 210 deletions.
190 changes: 142 additions & 48 deletions app/renderer/components/download/downloadItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */

const React = require('react')
const Immutable = require('immutable')

// Components
const ImmutableComponent = require('../immutableComponent')
const ReduxComponent = require('../reduxComponent')
const Button = require('../common/button')

// Constants
Expand All @@ -18,12 +19,13 @@ const appActions = require('../../../../js/actions/appActions')
// Utils
const contextMenus = require('../../../../js/contextMenus')
const downloadUtil = require('../../../../js/state/downloadUtil')
const urlUtil = require('../../../../js/lib/urlutil')
const {getOrigin} = require('../../../../js/state/siteUtil')
const cx = require('../../../../js/lib/classSet')

class DownloadItem extends ImmutableComponent {
constructor () {
super()
class DownloadItem extends React.Component {
constructor (props) {
super(props)
this.onRevealDownload = this.onRevealDownload.bind(this)
this.onOpenDownload = this.onOpenDownload.bind(this)
this.onPauseDownload = this.onDownloadActionPerformed.bind(this, PAUSE)
Expand All @@ -33,150 +35,242 @@ class DownloadItem extends ImmutableComponent {
this.onShowDeleteConfirmation = this.onShowDeleteConfirmation.bind(this)
this.onHideDeleteConfirmation = this.onHideDeleteConfirmation.bind(this)
this.onDeleteDownload = this.onDeleteDownload.bind(this)
this.onRedownload = this.onRedownload.bind(this)
this.onReDownload = this.onReDownload.bind(this)
this.onCopyLinkToClipboard = this.onCopyLinkToClipboard.bind(this)
}

onRevealDownload () {
appActions.downloadRevealed(this.props.downloadId)
}

onOpenDownload () {
appActions.downloadOpened(this.props.downloadId)
}

onClearDownload () {
appActions.downloadCleared(this.props.downloadId)
}

onShowDeleteConfirmation () {
appActions.showDownloadDeleteConfirmation()
}

onHideDeleteConfirmation () {
appActions.hideDownloadDeleteConfirmation()
}

onDeleteDownload () {
appActions.hideDownloadDeleteConfirmation()
appActions.downloadDeleted(this.props.downloadId)
}

onDownloadActionPerformed (downloadAction) {
appActions.downloadActionPerformed(this.props.downloadId, downloadAction)
}

onCopyLinkToClipboard () {
appActions.downloadCopiedToClipboard(this.props.downloadId)
}
onRedownload () {

onReDownload () {
appActions.downloadRedownloaded(this.props.downloadId)
}

get isInterrupted () {
return this.props.download.get('state') === downloadStates.INTERRUPTED
return this.props.downloadState === downloadStates.INTERRUPTED
}

get isInProgress () {
return this.props.download.get('state') === downloadStates.IN_PROGRESS
return this.props.downloadState === downloadStates.IN_PROGRESS
}

get isCompleted () {
return this.props.download.get('state') === downloadStates.COMPLETED
return this.props.downloadState === downloadStates.COMPLETED
}

get isCancelled () {
return this.props.download.get('state') === downloadStates.CANCELLED
return this.props.downloadState === downloadStates.CANCELLED
}

get isPaused () {
return this.props.download.get('state') === downloadStates.PAUSED
return this.props.downloadState === downloadStates.PAUSED
}

mergeProps (state, dispatchProps, ownProps) {
const download = state.getIn(['downloads', ownProps.downloadId]) || Immutable.Map()
const origin = getOrigin(download.get('url'))

const props = {}
// used in renderer
props.downloadId = ownProps.downloadId
props.deleteConfirmationVisible = state.get('deleteConfirmationVisible')
props.isLocalFile = urlUtil.isLocalFile(origin)
props.isInsecure = origin && origin.startsWith('http://')
props.percentageComplete = downloadUtil.getPercentageComplete(download)
props.isPendingState = downloadUtil.isPendingState(download)
props.downloadState = download.get('state')
props.totalBytes = download.get('totalBytes')
props.fileName = download.get('filename')
props.origin = origin
props.statel10n = downloadUtil.getL10nId(download)
props.download = download // TODO (nejc) only primitive types
props.allowPause = downloadUtil.shouldAllowPause(props.download)
props.allowResume = downloadUtil.shouldAllowResume(props.download)
props.allowCancel = downloadUtil.shouldAllowCancel(props.download)
props.allowRedownload = downloadUtil.shouldAllowRedownload(props.download)
props.allowCopyLink = downloadUtil.shouldAllowCopyLink(props.download)
props.allowOpenDownloadLocation = downloadUtil.shouldAllowOpenDownloadLocation(props.download)
props.allowDelete = downloadUtil.shouldAllowDelete(props.download)
props.allowRemoveFromList = downloadUtil.shouldAllowRemoveFromList(props.download)

return props
}

render () {
const origin = getOrigin(this.props.download.get('url'))
const localFileOrigins = ['file:', 'blob:', 'data:', 'chrome-extension:', 'chrome:']
const localFile = origin && localFileOrigins.some((localFileOrigin) => origin.startsWith(localFileOrigin))
const l10nStateArgs = {}
const progressStyle = {
width: downloadUtil.getPercentageComplete(this.props.download)
width: this.props.percentageComplete
}
const l10nStateArgs = {}

if (this.isCancelled || this.isInterrupted) {
progressStyle.display = 'none'
} else if (downloadUtil.isPendingState(this.props.download)) {
l10nStateArgs.downloadPercent = downloadUtil.getPercentageComplete(this.props.download)
} else if (this.props.isPendingState) {
l10nStateArgs.downloadPercent = this.props.percentageComplete
}
const isInsecure = origin.startsWith('http://')

return <span
onContextMenu={contextMenus.onDownloadsToolbarContextMenu.bind(null, this.props.downloadId, this.props.download)}
onDoubleClick={this.onOpenDownload}
onMouseLeave={this.onHideDeleteConfirmation}
className={cx({
downloadItem: true,
deleteConfirmationVisible: this.props.deleteConfirmationVisible,
[this.props.download.get('state')]: true
[this.props.downloadState]: true
})}>
{
this.props.deleteConfirmationVisible
? <div className='deleteConfirmation'><span data-l10n-id='downloadDeleteConfirmation' /><Button testId='confirmDeleteButton' l10nId='ok' className='primaryButton confirmDeleteButton' onClick={this.onDeleteDownload} /></div>
? <div className='deleteConfirmation'>
<span data-l10n-id='downloadDeleteConfirmation' /><Button testId='confirmDeleteButton' l10nId='ok' className='primaryButton confirmDeleteButton' onClick={this.onDeleteDownload} />
</div>
: null
}
<div className='downloadActions'>
{
downloadUtil.shouldAllowPause(this.props.download)
? <Button testId='pauseButton' className='pauseButton' l10nId='downloadPause' iconClass='fa-pause' onClick={this.onPauseDownload} />
this.props.allowPause
? <Button
testId='pauseButton'
className='pauseButton'
l10nId='downloadPause'
iconClass='fa-pause'
onClick={this.onPauseDownload}
/>
: null
}
{
downloadUtil.shouldAllowResume(this.props.download)
? <Button testId='resumeButton' className='resumeButton' l10nId='downloadResume' iconClass='fa-play' onClick={this.onResumeDownload} />
this.props.allowResume
? <Button
testId='resumeButton'
className='resumeButton'
l10nId='downloadResume'
iconClass='fa-play'
onClick={this.onResumeDownload}
/>
: null
}
{
downloadUtil.shouldAllowCancel(this.props.download)
? <Button testId='cancelButton' className='cancelButton' l10nId='downloadCancel' iconClass='fa-times' onClick={this.onCancelDownload} />
this.props.allowCancel
? <Button
testId='cancelButton'
className='cancelButton'
l10nId='downloadCancel'
iconClass='fa-times'
onClick={this.onCancelDownload}
/>
: null
}
{
downloadUtil.shouldAllowRedownload(this.props.download)
? <Button testId='redownloadButton' className='redownloadButton' l10nId='downloadRedownload' iconClass='fa-repeat' onClick={this.onRedownload} />
this.props.allowRedownload
? <Button
testId='redownloadButton'
className='redownloadButton'
l10nId='downloadRedownload'
iconClass='fa-repeat'
onClick={this.onReDownload}
/>
: null
}
{
downloadUtil.shouldAllowCopyLink(this.props.download)
? <Button testId='copyLinkButton' className='copyLinkButton' l10nId='downloadCopyLinkLocation' iconClass='fa-link' onClick={this.onCopyLinkToClipboard} />
this.props.allowCopyLink
? <Button
testId='copyLinkButton'
className='copyLinkButton'
l10nId='downloadCopyLinkLocation'
iconClass='fa-link'
onClick={this.onCopyLinkToClipboard}
/>
: null
}
{
downloadUtil.shouldAllowOpenDownloadLocation(this.props.download)
? <Button testId='revealButton' className='revealButton' l10nId='downloadOpenPath' iconClass='fa-folder-open-o' onClick={this.onRevealDownload} />
this.props.allowOpenDownloadLocation
? <Button
testId='revealButton'
className='revealButton'
l10nId='downloadOpenPath'
iconClass='fa-folder-open-o'
onClick={this.onRevealDownload}
/>
: null
}
{
downloadUtil.shouldAllowDelete(this.props.download)
? <Button testId='deleteButton' className='deleteButton' l10nId='downloadDelete' iconClass='fa-trash-o' onClick={this.onShowDeleteConfirmation} />
this.props.allowDelete
? <Button
testId='deleteButton'
className='deleteButton'
l10nId='downloadDelete'
iconClass='fa-trash-o'
onClick={this.onShowDeleteConfirmation}
/>
: null
}
{
downloadUtil.shouldAllowRemoveFromList(this.props.download)
? <Button testId='downloadRemoveFromList' l10nId='downloadRemoveFromList' iconClass='fa-times' className='removeDownloadFromList' onClick={this.onClearDownload} />
this.props.allowRemoveFromList
? <Button
testId='downloadRemoveFromList'
l10nId='downloadRemoveFromList'
iconClass='fa-times'
className='removeDownloadFromList'
onClick={this.onClearDownload}
/>
: null
}
</div>
{
(this.isInProgress || this.isPaused) && this.props.download.get('totalBytes')
(this.isInProgress || this.isPaused) && this.props.totalBytes
? <div data-test-id='downloadProgress' className='downloadProgress' style={progressStyle} />
: null
}
<div className='downloadInfo'>
<span>
<div data-test-id='downloadFilename' className='downloadFilename'
title={this.props.download.get('filename')}>
{
this.props.download.get('filename')
}
<div data-test-id='downloadFilename' className='downloadFilename' title={this.props.fileName}>
{this.props.fileName}
</div>
{
origin
this.props.origin
? <div data-test-id='downloadOrigin' className='downloadOrigin'>
{
isInsecure
this.props.isInsecure
? <span className='fa fa-unlock isInsecure' />
: null
}
<span data-l10n-id={localFile ? 'downloadLocalFile' : null} title={origin}>{localFile ? null : origin}</span>
<span data-l10n-id={this.props.isLocalFile ? 'downloadLocalFile' : null} title={this.props.origin}>
{this.props.isLocalFile ? null : this.props.origin}
</span>
</div>
: null
}
{
this.isCancelled || this.isInterrupted || this.isCompleted || this.isPaused || this.isInProgress
? <div className='downloadState' data-l10n-id={downloadUtil.getL10nId(this.props.download)} data-l10n-args={JSON.stringify(l10nStateArgs)} />
? <div className='downloadState' data-l10n-id={this.props.statel10n} data-l10n-args={JSON.stringify(l10nStateArgs)} />
: null
}
</span>
Expand All @@ -186,4 +280,4 @@ class DownloadItem extends ImmutableComponent {
}
}

module.exports = DownloadItem
module.exports = ReduxComponent.connect(DownloadItem)
Loading

0 comments on commit 5584d38

Please sign in to comment.