Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Converts DownloadItem and DownloadsBar into redux #9271

Merged
merged 1 commit into from
Jun 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
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
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