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

Commit

Permalink
Coverts DownloadItem and DownloadsBar
Browse files Browse the repository at this point in the history
Auditors:

Test Plan:
  • Loading branch information
NejcZdovc committed Jun 6, 2017
1 parent b55a1ee commit baed5bb
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 85 deletions.
162 changes: 124 additions & 38 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 @@ -36,147 +38,231 @@ class DownloadItem extends ImmutableComponent {
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 () {
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.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

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} />
? <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} />
? <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} />
? <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} />
? <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} />
? <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} />
? <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} />
? <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} />
? <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 +272,4 @@ class DownloadItem extends ImmutableComponent {
}
}

module.exports = DownloadItem
module.exports = ReduxComponent.connect(DownloadItem)
42 changes: 20 additions & 22 deletions app/renderer/components/download/downloadsBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
const React = require('react')

// Components
const ImmutableComponent = require('../immutableComponent')
const ReduxComponent = require('../reduxComponent')
const Button = require('../common/button')
const BrowserButton = require('../common/browserButton')
const DownloadItem = require('./downloadItem')
Expand All @@ -19,47 +19,45 @@ const appActions = require('../../../../js/actions/appActions')

// Utils
const contextMenus = require('../../../../js/contextMenus')

const downloadUtil = require('../../../../js/state/downloadUtil')
const cx = require('../../../../js/lib/classSet')

class DownloadsBar extends ImmutableComponent {
constructor () {
super()
class DownloadsBar extends React.Component {
constructor (props) {
super(props)
this.onHideDownloadsToolbar = this.onHideDownloadsToolbar.bind(this)
this.onShowDownloads = this.onShowDownloads.bind(this)
}

onHideDownloadsToolbar () {
windowActions.setDownloadsToolbarVisible(false)
webviewActions.setWebviewFocused()
}

onShowDownloads () {
appActions.createTabRequested({
activateIfOpen: true,
url: 'about:downloads'
})
windowActions.setDownloadsToolbarVisible(false)
}

mergeProps (state, dispatchProps, ownProps) {
const props = {}
// used in renderer
props.downloads = downloadUtil.getDownloadItems(state)

return props
}

render () {
const getComputedStyle = require('../../getComputedStyle')
const downloadItemWidth = Number.parseInt(getComputedStyle('--download-item-width'), 10)
const downloadItemMargin = Number.parseInt(getComputedStyle('--download-item-margin'), 10)
const downloadBarPadding = Number.parseInt(getComputedStyle('--download-bar-padding'), 10)
const downloadBarButtons = Number.parseInt(getComputedStyle('--download-bar-buttons'), 10)
const numItems = Math.floor((this.props.windowWidth - (downloadBarPadding * 2) - downloadBarButtons) / (downloadItemWidth + downloadItemMargin))
return <div className='downloadsBar'
onContextMenu={contextMenus.onDownloadsToolbarContextMenu.bind(null, undefined, undefined)}>
<div className='downloadItems'>
{
this.props.downloads
.sort((x, y) => x.get('startTime') - y.get('startTime'))
.skip(this.props.downloads.size - numItems)
.reverse()
.map((download, downloadId) =>
<DownloadItem download={download}
windowWidth={this.props.windowWidth}
deleteConfirmationVisible={this.props.deleteConfirmationVisible}
downloadId={downloadId}
downloadsSize={this.props.downloads.size} />)
this.props.downloads.map(downloadId =>
<DownloadItem downloadId={downloadId} />
)
}
</div>
<div className={cx({
Expand All @@ -81,7 +79,7 @@ class DownloadsBar extends ImmutableComponent {
}
}

module.exports = DownloadsBar
module.exports = ReduxComponent.connect(DownloadsBar)

const styles = StyleSheet.create({
downloadsBar__downloadBarButtons: {
Expand Down
5 changes: 1 addition & 4 deletions app/renderer/components/main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -892,10 +892,7 @@ class Main extends ImmutableComponent {
</div>
{
this.props.windowState.getIn(['ui', 'downloadsToolbar', 'isVisible']) && this.props.appState.get('downloads') && this.props.appState.get('downloads').size > 0
? <DownloadsBar
windowWidth={window.innerWidth}
deleteConfirmationVisible={this.props.appState.get('deleteConfirmationVisible')}
downloads={this.props.appState.get('downloads')} />
? <DownloadsBar />
: null
}
</div>
Expand Down
Loading

0 comments on commit baed5bb

Please sign in to comment.