Add files
This commit is contained in:
26
src/renderer/components/create-torrent-error-page.js
Normal file
26
src/renderer/components/create-torrent-error-page.js
Normal file
@ -0,0 +1,26 @@
|
||||
const React = require('react')
|
||||
|
||||
const { dispatcher } = require('../lib/dispatcher')
|
||||
|
||||
module.exports = class CreateTorrentErrorPage extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<div className='create-torrent'>
|
||||
<h2>Create torrent</h2>
|
||||
<p className='torrent-info'>
|
||||
<p>
|
||||
Sorry, you must select at least one file that is not a hidden file.
|
||||
</p>
|
||||
<p>
|
||||
Hidden files, starting with a . character, are not included.
|
||||
</p>
|
||||
</p>
|
||||
<p className='float-right'>
|
||||
<button className='button-flat light' onClick={dispatcher('cancel')}>
|
||||
Cancel
|
||||
</button>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
31
src/renderer/components/delete-all-torrents-modal.js
Normal file
31
src/renderer/components/delete-all-torrents-modal.js
Normal file
@ -0,0 +1,31 @@
|
||||
const React = require('react')
|
||||
|
||||
const ModalOKCancel = require('./modal-ok-cancel')
|
||||
const { dispatch, dispatcher } = require('../lib/dispatcher')
|
||||
|
||||
module.exports = class DeleteAllTorrentsModal extends React.Component {
|
||||
render () {
|
||||
const { state: { modal: { deleteData } } } = this.props
|
||||
const message = deleteData
|
||||
? 'Are you sure you want to remove all the torrents from the list and delete the data files?'
|
||||
: 'Are you sure you want to remove all the torrents from the list?'
|
||||
const buttonText = deleteData ? 'REMOVE DATA' : 'REMOVE'
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p><strong>{message}</strong></p>
|
||||
<ModalOKCancel
|
||||
cancelText='CANCEL'
|
||||
onCancel={dispatcher('exitModal')}
|
||||
okText={buttonText}
|
||||
onOK={handleRemove}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
function handleRemove () {
|
||||
dispatch('deleteAllTorrents', deleteData)
|
||||
dispatch('exitModal')
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/renderer/components/header.js
Normal file
68
src/renderer/components/header.js
Normal file
@ -0,0 +1,68 @@
|
||||
const React = require('react')
|
||||
|
||||
const { dispatcher } = require('../lib/dispatcher')
|
||||
|
||||
class Header extends React.Component {
|
||||
render () {
|
||||
const loc = this.props.state.location
|
||||
return (
|
||||
<div
|
||||
className='header'
|
||||
onMouseMove={dispatcher('mediaMouseMoved')}
|
||||
onMouseEnter={dispatcher('mediaControlsMouseEnter')}
|
||||
onMouseLeave={dispatcher('mediaControlsMouseLeave')}
|
||||
role='navigation'
|
||||
>
|
||||
{this.getTitle()}
|
||||
<div className='nav left float-left'>
|
||||
<i
|
||||
className={'icon back ' + (loc.hasBack() ? '' : 'disabled')}
|
||||
title='Back'
|
||||
onClick={dispatcher('back')}
|
||||
role='button'
|
||||
aria-disabled={!loc.hasBack()}
|
||||
aria-label='Back'
|
||||
>
|
||||
chevron_left
|
||||
</i>
|
||||
<i
|
||||
className={'icon forward ' + (loc.hasForward() ? '' : 'disabled')}
|
||||
title='Forward'
|
||||
onClick={dispatcher('forward')}
|
||||
role='button'
|
||||
aria-disabled={!loc.hasForward()}
|
||||
aria-label='Forward'
|
||||
>
|
||||
chevron_right
|
||||
</i>
|
||||
</div>
|
||||
<div className='nav right float-right'>
|
||||
{this.getAddButton()}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
getTitle () {
|
||||
if (process.platform !== 'darwin') return null
|
||||
const state = this.props.state
|
||||
return (<div className='title ellipsis'>{state.window.title}</div>)
|
||||
}
|
||||
|
||||
getAddButton () {
|
||||
const state = this.props.state
|
||||
if (state.location.url() !== 'home') return null
|
||||
return (
|
||||
<i
|
||||
className='icon add'
|
||||
title='Add torrent'
|
||||
onClick={dispatcher('openFiles')}
|
||||
role='button'
|
||||
>
|
||||
add
|
||||
</i>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Header
|
||||
35
src/renderer/components/heading.js
Normal file
35
src/renderer/components/heading.js
Normal file
@ -0,0 +1,35 @@
|
||||
const React = require('react')
|
||||
const PropTypes = require('prop-types')
|
||||
|
||||
const colors = require('material-ui/styles/colors')
|
||||
|
||||
class Heading extends React.Component {
|
||||
static get propTypes () {
|
||||
return {
|
||||
level: PropTypes.number
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultProps () {
|
||||
return {
|
||||
level: 1
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
const HeadingTag = 'h' + this.props.level
|
||||
const style = {
|
||||
color: colors.grey100,
|
||||
fontSize: 20,
|
||||
marginBottom: 15,
|
||||
marginTop: 30
|
||||
}
|
||||
return (
|
||||
<HeadingTag style={style}>
|
||||
{this.props.children}
|
||||
</HeadingTag>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Heading
|
||||
27
src/renderer/components/modal-ok-cancel.js
Normal file
27
src/renderer/components/modal-ok-cancel.js
Normal file
@ -0,0 +1,27 @@
|
||||
const React = require('react')
|
||||
const FlatButton = require('material-ui/FlatButton').default
|
||||
const RaisedButton = require('material-ui/RaisedButton').default
|
||||
|
||||
module.exports = class ModalOKCancel extends React.Component {
|
||||
render () {
|
||||
const cancelStyle = { marginRight: 10, color: 'black' }
|
||||
const { cancelText, onCancel, okText, onOK } = this.props
|
||||
return (
|
||||
<div className='float-right'>
|
||||
<FlatButton
|
||||
className='control cancel'
|
||||
style={cancelStyle}
|
||||
label={cancelText}
|
||||
onClick={onCancel}
|
||||
/>
|
||||
<RaisedButton
|
||||
className='control ok'
|
||||
primary
|
||||
label={okText}
|
||||
onClick={onOK}
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
51
src/renderer/components/open-torrent-address-modal.js
Normal file
51
src/renderer/components/open-torrent-address-modal.js
Normal file
@ -0,0 +1,51 @@
|
||||
const React = require('react')
|
||||
const TextField = require('material-ui/TextField').default
|
||||
const { clipboard } = require('electron')
|
||||
|
||||
const ModalOKCancel = require('./modal-ok-cancel')
|
||||
const { dispatch, dispatcher } = require('../lib/dispatcher')
|
||||
const { isMagnetLink } = require('../lib/torrent-player')
|
||||
|
||||
module.exports = class OpenTorrentAddressModal extends React.Component {
|
||||
render () {
|
||||
return (
|
||||
<div className='open-torrent-address-modal'>
|
||||
<p><label>Enter torrent address or magnet link</label></p>
|
||||
<div>
|
||||
<TextField
|
||||
id='torrent-address-field'
|
||||
className='control'
|
||||
ref={(c) => { this.torrentURL = c }}
|
||||
fullWidth
|
||||
onKeyDown={handleKeyDown.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
<ModalOKCancel
|
||||
cancelText='CANCEL'
|
||||
onCancel={dispatcher('exitModal')}
|
||||
okText='OK'
|
||||
onOK={handleOK.bind(this)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.torrentURL.input.focus()
|
||||
const clipboardContent = clipboard.readText()
|
||||
|
||||
if (isMagnetLink(clipboardContent)) {
|
||||
this.torrentURL.input.value = clipboardContent
|
||||
this.torrentURL.input.select()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyDown (e) {
|
||||
if (e.which === 13) handleOK.call(this) /* hit Enter to submit */
|
||||
}
|
||||
|
||||
function handleOK () {
|
||||
dispatch('exitModal')
|
||||
dispatch('addTorrent', this.torrentURL.input.value)
|
||||
}
|
||||
85
src/renderer/components/path-selector.js
Normal file
85
src/renderer/components/path-selector.js
Normal file
@ -0,0 +1,85 @@
|
||||
const path = require('path')
|
||||
|
||||
const colors = require('material-ui/styles/colors')
|
||||
const remote = require('@electron/remote')
|
||||
const React = require('react')
|
||||
const PropTypes = require('prop-types')
|
||||
|
||||
const RaisedButton = require('material-ui/RaisedButton').default
|
||||
const TextField = require('material-ui/TextField').default
|
||||
|
||||
// Lets you pick a file or directory.
|
||||
// Uses the system Open File dialog.
|
||||
// You can't edit the text field directly.
|
||||
class PathSelector extends React.Component {
|
||||
static propTypes () {
|
||||
return {
|
||||
className: PropTypes.string,
|
||||
dialog: PropTypes.object,
|
||||
id: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
title: PropTypes.string.isRequired,
|
||||
value: PropTypes.string
|
||||
}
|
||||
}
|
||||
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.handleClick = this.handleClick.bind(this)
|
||||
}
|
||||
|
||||
handleClick () {
|
||||
const opts = Object.assign({
|
||||
defaultPath: path.dirname(this.props.value || ''),
|
||||
properties: ['openFile', 'openDirectory']
|
||||
}, this.props.dialog)
|
||||
|
||||
const filenames = remote.dialog.showOpenDialogSync(remote.getCurrentWindow(), opts)
|
||||
if (!Array.isArray(filenames)) return
|
||||
this.props.onChange && this.props.onChange(filenames[0])
|
||||
}
|
||||
|
||||
render () {
|
||||
const id = this.props.title.replace(' ', '-').toLowerCase()
|
||||
const wrapperStyle = {
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
width: '100%'
|
||||
}
|
||||
const labelStyle = {
|
||||
flex: '0 auto',
|
||||
marginRight: 10,
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap'
|
||||
}
|
||||
const textareaStyle = {
|
||||
color: colors.grey50
|
||||
}
|
||||
const textFieldStyle = {
|
||||
flex: '1'
|
||||
}
|
||||
const text = this.props.value || ''
|
||||
const buttonStyle = {
|
||||
marginLeft: 10
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={this.props.className} style={wrapperStyle}>
|
||||
<div className='label' style={labelStyle}>
|
||||
{this.props.title}:
|
||||
</div>
|
||||
<TextField
|
||||
className='control' disabled id={id} value={text}
|
||||
inputStyle={textareaStyle} style={textFieldStyle}
|
||||
/>
|
||||
<RaisedButton
|
||||
className='control' label='Change' onClick={this.handleClick}
|
||||
style={buttonStyle}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PathSelector
|
||||
31
src/renderer/components/remove-torrent-modal.js
Normal file
31
src/renderer/components/remove-torrent-modal.js
Normal file
@ -0,0 +1,31 @@
|
||||
const React = require('react')
|
||||
|
||||
const ModalOKCancel = require('./modal-ok-cancel')
|
||||
const { dispatch, dispatcher } = require('../lib/dispatcher')
|
||||
|
||||
module.exports = class RemoveTorrentModal extends React.Component {
|
||||
render () {
|
||||
const state = this.props.state
|
||||
const message = state.modal.deleteData
|
||||
? 'Are you sure you want to remove this torrent from the list and delete the data file?'
|
||||
: 'Are you sure you want to remove this torrent from the list?'
|
||||
const buttonText = state.modal.deleteData ? 'REMOVE DATA' : 'REMOVE'
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p><strong>{message}</strong></p>
|
||||
<ModalOKCancel
|
||||
cancelText='CANCEL'
|
||||
onCancel={dispatcher('exitModal')}
|
||||
okText={buttonText}
|
||||
onOK={handleRemove}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
function handleRemove () {
|
||||
dispatch('deleteTorrent', state.modal.infoHash, state.modal.deleteData)
|
||||
dispatch('exitModal')
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/renderer/components/show-more.js
Normal file
55
src/renderer/components/show-more.js
Normal file
@ -0,0 +1,55 @@
|
||||
const React = require('react')
|
||||
const PropTypes = require('prop-types')
|
||||
|
||||
const RaisedButton = require('material-ui/RaisedButton').default
|
||||
|
||||
class ShowMore extends React.Component {
|
||||
static get propTypes () {
|
||||
return {
|
||||
defaultExpanded: PropTypes.bool,
|
||||
hideLabel: PropTypes.string,
|
||||
showLabel: PropTypes.string
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultProps () {
|
||||
return {
|
||||
hideLabel: 'Hide more...',
|
||||
showLabel: 'Show more...'
|
||||
}
|
||||
}
|
||||
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
expanded: !!this.props.defaultExpanded
|
||||
}
|
||||
|
||||
this.handleClick = this.handleClick.bind(this)
|
||||
}
|
||||
|
||||
handleClick () {
|
||||
this.setState({
|
||||
expanded: !this.state.expanded
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
const label = this.state.expanded
|
||||
? this.props.hideLabel
|
||||
: this.props.showLabel
|
||||
return (
|
||||
<div className='show-more' style={this.props.style}>
|
||||
{this.state.expanded ? this.props.children : null}
|
||||
<RaisedButton
|
||||
className='control'
|
||||
onClick={this.handleClick}
|
||||
label={label}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ShowMore
|
||||
45
src/renderer/components/unsupported-media-modal.js
Normal file
45
src/renderer/components/unsupported-media-modal.js
Normal file
@ -0,0 +1,45 @@
|
||||
const React = require('react')
|
||||
const { shell } = require('electron')
|
||||
|
||||
const ModalOKCancel = require('./modal-ok-cancel')
|
||||
const { dispatcher } = require('../lib/dispatcher')
|
||||
|
||||
module.exports = class UnsupportedMediaModal extends React.Component {
|
||||
render () {
|
||||
const state = this.props.state
|
||||
const err = state.modal.error
|
||||
const message = (err && err.getMessage)
|
||||
? err.getMessage()
|
||||
: err
|
||||
const onAction = state.modal.externalPlayerInstalled
|
||||
? dispatcher('openExternalPlayer')
|
||||
: () => this.onInstall()
|
||||
const actionText = state.modal.externalPlayerInstalled
|
||||
? 'PLAY IN ' + state.getExternalPlayerName().toUpperCase()
|
||||
: 'INSTALL VLC'
|
||||
const errorMessage = state.modal.externalPlayerNotFound
|
||||
? 'Couldn\'t run external player. Please make sure it\'s installed.'
|
||||
: ''
|
||||
return (
|
||||
<div>
|
||||
<p><strong>Sorry, we can't play that file.</strong></p>
|
||||
<p>{message}</p>
|
||||
<ModalOKCancel
|
||||
cancelText='CANCEL'
|
||||
onCancel={dispatcher('backToList')}
|
||||
okText={actionText}
|
||||
onOK={onAction}
|
||||
/>
|
||||
<p className='error-text'>{errorMessage}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
onInstall () {
|
||||
shell.openExternal('https://www.videolan.org/vlc/')
|
||||
|
||||
// TODO: dcposch send a dispatch rather than modifying state directly
|
||||
const state = this.props.state
|
||||
state.modal.externalPlayerInstalled = true // Assume they'll install it successfully
|
||||
}
|
||||
}
|
||||
37
src/renderer/components/update-available-modal.js
Normal file
37
src/renderer/components/update-available-modal.js
Normal file
@ -0,0 +1,37 @@
|
||||
const React = require('react')
|
||||
const { shell } = require('electron')
|
||||
|
||||
const ModalOKCancel = require('./modal-ok-cancel')
|
||||
const { dispatch } = require('../lib/dispatcher')
|
||||
|
||||
module.exports = class UpdateAvailableModal extends React.Component {
|
||||
render () {
|
||||
const state = this.props.state
|
||||
return (
|
||||
<div className='update-available-modal'>
|
||||
<p><strong>A new version of WebTorrent is available: v{state.modal.version}</strong></p>
|
||||
<p>
|
||||
We have an auto-updater for Windows and Mac.
|
||||
We don't have one for Linux yet, so you'll have to download the new version manually.
|
||||
</p>
|
||||
<ModalOKCancel
|
||||
cancelText='SKIP THIS RELEASE'
|
||||
onCancel={handleSkip}
|
||||
okText='SHOW DOWNLOAD PAGE'
|
||||
onOK={handleShow}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
function handleShow () {
|
||||
// TODO: use the GitHub urls from config.js
|
||||
shell.openExternal('https://github.com/leenkx/leenkxbox/releases')
|
||||
dispatch('exitModal')
|
||||
}
|
||||
|
||||
function handleSkip () {
|
||||
dispatch('skipVersion', state.modal.version)
|
||||
dispatch('exitModal')
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user