Compare commits

..

3 Commits

Author SHA1 Message Date
Diego Rodríguez Baquero
1350f3f7cf fixes 2021-10-10 13:58:19 -05:00
Diego Rodríguez Baquero
08a182d165 standard fix 2021-10-10 13:51:38 -05:00
Diego Rodríguez Baquero
63b55df637 fix: modernify code 2021-10-10 13:49:13 -05:00
25 changed files with 9749 additions and 9437 deletions

View File

@@ -12,8 +12,8 @@ jobs:
node: node:
- '16' - '16'
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- uses: actions/setup-node@v3 - uses: actions/setup-node@v2
with: with:
node-version: ${{ matrix.node }} node-version: ${{ matrix.node }}
- run: npm install - run: npm install

View File

@@ -5,11 +5,11 @@ jobs:
package_linux: package_linux:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- uses: actions/setup-node@v3 - uses: actions/setup-node@v2
with: with:
node-version: '16' node-version: '16'
- uses: actions/cache@v3 - uses: actions/cache@v2
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@@ -17,7 +17,7 @@ jobs:
${{ runner.os }}-node- ${{ runner.os }}-node-
- run: npm install - run: npm install
- run: npm run package -- linux - run: npm run package -- linux
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v2
with: with:
name: linux name: linux
path: | path: |
@@ -27,11 +27,11 @@ jobs:
package_macos: package_macos:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- uses: actions/setup-node@v3 - uses: actions/setup-node@v2
with: with:
node-version: '16' node-version: '16'
- uses: actions/cache@v3 - uses: actions/cache@v2
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@@ -39,7 +39,7 @@ jobs:
${{ runner.os }}-node- ${{ runner.os }}-node-
- run: npm install - run: npm install
- run: npm run package -- darwin - run: npm run package -- darwin
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v2
with: with:
name: macos name: macos
path: | path: |
@@ -48,11 +48,11 @@ jobs:
package_windows: package_windows:
runs-on: windows-latest runs-on: windows-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- uses: actions/setup-node@v3 - uses: actions/setup-node@v2
with: with:
node-version: '16' node-version: '16'
- uses: actions/cache@v3 - uses: actions/cache@v2
with: with:
path: ~/.npm path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
@@ -60,7 +60,7 @@ jobs:
${{ runner.os }}-node- ${{ runner.os }}-node-
- run: npm install - run: npm install
- run: npm run package -- win32 - run: npm run package -- win32
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v2
with: with:
name: windows name: windows
path: | path: |

View File

@@ -12,12 +12,12 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/stale@v6 - uses: actions/stale@v4
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?' stale-issue-message: 'Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?'
stale-pr-message: 'Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?' stale-pr-message: 'Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?'
exempt-issue-labels: accepted,blocked,dependency,security,meta exempt-issue-labels: accepted,blocked,bug,dependency,enhancement,'help wanted',question,security,meta
exempt-pr-labels: accepted,blocked,bug,dependency,security,meta exempt-pr-labels: accepted,blocked,bug,dependency,enhancement,'help wanted',question,security,meta
stale-issue-label: 'stale' stale-issue-label: 'stale'
stale-pr-label: 'stale' stale-pr-label: 'stale'

View File

@@ -147,7 +147,7 @@ to be installed. For example on Mac, first install
[XQuartz](http://www.xquartz.org/), then run: [XQuartz](http://www.xquartz.org/), then run:
``` ```
$ brew install wine mono brew install wine mono
``` ```
(Requires the [Homebrew](http://brew.sh/) package manager.) (Requires the [Homebrew](http://brew.sh/) package manager.)

18624
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -21,67 +21,67 @@
"url": "https://github.com/webtorrent/webtorrent-desktop/issues" "url": "https://github.com/webtorrent/webtorrent-desktop/issues"
}, },
"dependencies": { "dependencies": {
"@electron/remote": "2.0.8", "@electron/remote": "2.0.1",
"@material-ui/core": "4.12.4",
"airplayer": "github:webtorrent/airplayer#fix-security", "airplayer": "github:webtorrent/airplayer#fix-security",
"application-config": "2.0.0", "application-config": "2.0.0",
"arch": "2.2.0", "arch": "2.2.0",
"auto-launch": "5.0.5", "auto-launch": "5.0.5",
"bitfield": "4.1.0", "bitfield": "4.0.0",
"capture-frame": "4.0.0", "capture-frame": "4.0.0",
"chokidar": "3.5.3", "chokidar": "3.5.2",
"chromecasts": "1.10.2", "chromecasts": "1.10.2",
"create-torrent": "5.0.6", "create-torrent": "5.0.1",
"debounce": "1.2.1", "debounce": "1.2.1",
"dlnacasts": "0.1.0", "dlnacasts": "0.1.0",
"drag-drop": "7.2.0", "drag-drop": "7.2.0",
"es6-error": "4.1.1", "es6-error": "4.1.1",
"fn-getter": "1.0.0", "fn-getter": "1.0.0",
"iso-639-1": "2.1.15", "iso-639-1": "2.1.9",
"languagedetect": "2.0.0", "languagedetect": "2.0.0",
"location-history": "1.1.2", "location-history": "1.1.2",
"music-metadata": "7.13.0", "material-ui": "0.20.2",
"music-metadata": "7.11.4",
"network-address": "1.1.2", "network-address": "1.1.2",
"parse-torrent": "9.1.5", "parse-torrent": "9.1.4",
"prettier-bytes": "1.0.4", "prettier-bytes": "1.0.4",
"prop-types": "15.8.1", "prop-types": "15.7.2",
"react": "17.0.2", "react": "17.0.2",
"react-dom": "17.0.2", "react-dom": "17.0.2",
"rimraf": "3.0.2", "rimraf": "3.0.2",
"run-parallel": "1.2.0", "run-parallel": "1.2.0",
"semver": "7.3.8", "semver": "7.3.5",
"simple-concat": "1.0.1", "simple-concat": "1.0.1",
"simple-get": "4.0.1", "simple-get": "4.0.0",
"srt-to-vtt": "1.1.3", "srt-to-vtt": "1.1.3",
"vlc-command": "1.2.0", "vlc-command": "1.2.0",
"webtorrent": "1.8.32", "webtorrent": "1.5.6",
"winreg": "1.2.4" "winreg": "1.2.4"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "7.19.3", "@babel/cli": "7.15.7",
"@babel/core": "7.19.3", "@babel/core": "7.15.8",
"@babel/eslint-parser": "7.19.1", "@babel/eslint-parser": "7.15.8",
"@babel/plugin-transform-react-jsx": "7.19.0", "@babel/plugin-transform-react-jsx": "7.14.9",
"cross-zip": "4.0.0", "cross-zip": "4.0.0",
"depcheck": "1.4.3", "depcheck": "1.4.2",
"electron": "15.5.7", "electron": "15.1.2",
"electron-notarize": "1.2.1", "electron-notarize": "1.1.1",
"electron-osx-sign": "0.6.0", "electron-osx-sign": "0.5.0",
"electron-packager": "15.5.2", "electron-packager": "15.4.0",
"electron-winstaller": "5.0.0", "electron-winstaller": "5.0.0",
"gh-release": "6.0.4", "gh-release": "6.0.1",
"minimist": "1.2.6", "minimist": "1.2.5",
"nodemon": "2.0.20", "nodemon": "2.0.13",
"open": "8.4.0", "open": "8.3.0",
"plist": "3.0.6", "plist": "3.0.4",
"pngjs": "6.0.0", "pngjs": "6.0.0",
"run-series": "1.1.9", "run-series": "1.1.9",
"spectron": "19.0.0", "spectron": "15.0.0",
"standard": "17.0.0", "standard": "16.0.4",
"tape": "5.6.1" "tape": "5.3.1"
}, },
"engines": { "engines": {
"node": "^16.0.0 || ^18.0.0", "node": "^16.0.0",
"npm": "^7.10.0 || ^8.0.0" "npm": "^7.10.0 || ^8.0.0"
}, },
"homepage": "https://webtorrent.io", "homepage": "https://webtorrent.io",
@@ -113,12 +113,10 @@
"clean": "node ./bin/clean.js", "clean": "node ./bin/clean.js",
"gh-release": "gh-release", "gh-release": "gh-release",
"install-system-deps": "brew install fakeroot dpkg rpm", "install-system-deps": "brew install fakeroot dpkg rpm",
"lint": "standard",
"lint:fix": "standard --fix",
"open-config": "node ./bin/open-config.js", "open-config": "node ./bin/open-config.js",
"package": "node ./bin/package.js", "package": "node ./bin/package.js",
"start": "npm run build && electron --no-sandbox .", "start": "npm run build && electron --no-sandbox .",
"test": "npm run lint && depcheck --ignores=standard,@babel/eslint-parser --ignore-dirs=build,dist", "test": "standard && depcheck --ignores=standard,@babel/eslint-parser --ignore-dirs=build,dist",
"test-integration": "npm run build && node ./test", "test-integration": "npm run build && node ./test",
"update-authors": "./bin/update-authors.sh", "update-authors": "./bin/update-authors.sh",
"watch": "nodemon --exec \"npm run start\" --ext js,css --ignore build/ --ignore dist/" "watch": "nodemon --exec \"npm run start\" --ext js,css --ignore build/ --ignore dist/"

View File

@@ -16,7 +16,6 @@ module.exports = class DeleteAllTorrentsModal extends React.Component {
<p><strong>{message}</strong></p> <p><strong>{message}</strong></p>
<ModalOKCancel <ModalOKCancel
cancelText='CANCEL' cancelText='CANCEL'
color='secondary'
onCancel={dispatcher('exitModal')} onCancel={dispatcher('exitModal')}
okText={buttonText} okText={buttonText}
onOK={handleRemove} onOK={handleRemove}

View File

@@ -11,7 +11,6 @@ class Header extends React.Component {
onMouseMove={dispatcher('mediaMouseMoved')} onMouseMove={dispatcher('mediaMouseMoved')}
onMouseEnter={dispatcher('mediaControlsMouseEnter')} onMouseEnter={dispatcher('mediaControlsMouseEnter')}
onMouseLeave={dispatcher('mediaControlsMouseLeave')} onMouseLeave={dispatcher('mediaControlsMouseLeave')}
role='navigation'
> >
{this.getTitle()} {this.getTitle()}
<div className='nav left float-left'> <div className='nav left float-left'>
@@ -19,9 +18,6 @@ class Header extends React.Component {
className={'icon back ' + (loc.hasBack() ? '' : 'disabled')} className={'icon back ' + (loc.hasBack() ? '' : 'disabled')}
title='Back' title='Back'
onClick={dispatcher('back')} onClick={dispatcher('back')}
role='button'
aria-disabled={!loc.hasBack()}
aria-label='Back'
> >
chevron_left chevron_left
</i> </i>
@@ -29,9 +25,6 @@ class Header extends React.Component {
className={'icon forward ' + (loc.hasForward() ? '' : 'disabled')} className={'icon forward ' + (loc.hasForward() ? '' : 'disabled')}
title='Forward' title='Forward'
onClick={dispatcher('forward')} onClick={dispatcher('forward')}
role='button'
aria-disabled={!loc.hasForward()}
aria-label='Forward'
> >
chevron_right chevron_right
</i> </i>
@@ -57,7 +50,6 @@ class Header extends React.Component {
className='icon add' className='icon add'
title='Add torrent' title='Add torrent'
onClick={dispatcher('openFiles')} onClick={dispatcher('openFiles')}
role='button'
> >
add add
</i> </i>

View File

@@ -1,7 +1,7 @@
const React = require('react') const React = require('react')
const PropTypes = require('prop-types') const PropTypes = require('prop-types')
const grey = require('@material-ui/core/colors/grey').default const colors = require('material-ui/styles/colors')
class Heading extends React.Component { class Heading extends React.Component {
static get propTypes () { static get propTypes () {
@@ -19,7 +19,7 @@ class Heading extends React.Component {
render () { render () {
const HeadingTag = 'h' + this.props.level const HeadingTag = 'h' + this.props.level
const style = { const style = {
color: grey['100'], color: colors.grey100,
fontSize: 20, fontSize: 20,
marginBottom: 15, marginBottom: 15,
marginTop: 30 marginTop: 30

View File

@@ -1,28 +1,26 @@
const React = require('react') const React = require('react')
const Button = require('@material-ui/core/Button').default const FlatButton = require('material-ui/FlatButton').default
const RaisedButton = require('material-ui/RaisedButton').default
module.exports = class ModalOKCancel extends React.Component { module.exports = class ModalOKCancel extends React.Component {
render () { render () {
const cancelStyle = { marginRight: 10, color: 'black' } const cancelStyle = { marginRight: 10, color: 'black' }
const { cancelText, color = 'primary', onCancel, okText, onOK } = this.props const { cancelText, onCancel, okText, onOK } = this.props
return ( return (
<div className='float-right'> <div className='float-right'>
<Button <FlatButton
className='control cancel' className='control cancel'
onClick={onCancel}
style={cancelStyle} style={cancelStyle}
> label={cancelText}
{cancelText} onClick={onCancel}
</Button> />
<Button <RaisedButton
autoFocus
className='control ok' className='control ok'
primary
label={okText}
onClick={onOK} onClick={onOK}
color={color} autoFocus
variant='contained' />
>
{okText}
</Button>
</div> </div>
) )
} }

View File

@@ -1,5 +1,5 @@
const React = require('react') const React = require('react')
const TextField = require('@material-ui/core/TextField').default const TextField = require('material-ui/TextField').default
const { clipboard } = require('electron') const { clipboard } = require('electron')
const ModalOKCancel = require('./modal-ok-cancel') const ModalOKCancel = require('./modal-ok-cancel')

View File

@@ -1,12 +1,12 @@
const path = require('path') const path = require('path')
const colors = require('material-ui/styles/colors')
const remote = require('@electron/remote') const remote = require('@electron/remote')
const React = require('react') const React = require('react')
const PropTypes = require('prop-types') const PropTypes = require('prop-types')
const Button = require('@material-ui/core/Button').default const RaisedButton = require('material-ui/RaisedButton').default
const TextField = require('@material-ui/core/TextField').default const TextField = require('material-ui/TextField').default
const grey = require('@material-ui/core/colors/grey').default
// Lets you pick a file or directory. // Lets you pick a file or directory.
// Uses the system Open File dialog. // Uses the system Open File dialog.
@@ -53,8 +53,10 @@ class PathSelector extends React.Component {
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
whiteSpace: 'nowrap' whiteSpace: 'nowrap'
} }
const textareaStyle = {
color: colors.grey50
}
const textFieldStyle = { const textFieldStyle = {
color: grey['50'],
flex: '1' flex: '1'
} }
const text = this.props.value || '' const text = this.props.value || ''
@@ -68,20 +70,13 @@ class PathSelector extends React.Component {
{this.props.title}: {this.props.title}:
</div> </div>
<TextField <TextField
className='control' className='control' disabled id={id} value={text}
disabled inputStyle={textareaStyle} style={textFieldStyle}
id={id}
style={textFieldStyle}
value={text}
/> />
<Button <RaisedButton
className='control' className='control' label='Change' onClick={this.handleClick}
onClick={this.handleClick}
style={buttonStyle} style={buttonStyle}
variant='contained' />
>
Change
</Button>
</div> </div>
) )
} }

View File

@@ -16,7 +16,6 @@ module.exports = class RemoveTorrentModal extends React.Component {
<p><strong>{message}</strong></p> <p><strong>{message}</strong></p>
<ModalOKCancel <ModalOKCancel
cancelText='CANCEL' cancelText='CANCEL'
color='secondary'
onCancel={dispatcher('exitModal')} onCancel={dispatcher('exitModal')}
okText={buttonText} okText={buttonText}
onOK={handleRemove} onOK={handleRemove}

View File

@@ -1,7 +1,7 @@
const React = require('react') const React = require('react')
const PropTypes = require('prop-types') const PropTypes = require('prop-types')
const Button = require('@material-ui/core/Button').default const RaisedButton = require('material-ui/RaisedButton').default
class ShowMore extends React.Component { class ShowMore extends React.Component {
static get propTypes () { static get propTypes () {
@@ -42,13 +42,11 @@ class ShowMore extends React.Component {
return ( return (
<div className='show-more' style={this.props.style}> <div className='show-more' style={this.props.style}>
{this.state.expanded ? this.props.children : null} {this.state.expanded ? this.props.children : null}
<Button <RaisedButton
className='control' className='control'
onClick={this.handleClick} onClick={this.handleClick}
variant='contained' label={label}
> />
{label}
</Button>
</div> </div>
) )
} }

View File

@@ -113,10 +113,6 @@ module.exports = class TorrentListController {
} }
} }
setGlobalTrackers (globalTrackers) {
ipcRenderer.send('wt-set-global-trackers', globalTrackers)
}
// TODO: use torrentKey, not infoHash // TODO: use torrentKey, not infoHash
toggleTorrent (infoHash) { toggleTorrent (infoHash) {
const torrentSummary = TorrentSummary.getByKey(this.state, infoHash) const torrentSummary = TorrentSummary.getByKey(this.state, infoHash)

View File

@@ -144,7 +144,7 @@ function chromecastPlayer () {
'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Origin': '*',
'Transfer-Encoding': 'chunked' 'Transfer-Encoding': 'chunked'
}) })
res.end(Buffer.from(selectedSubtitle.buffer.slice(21), 'base64')) res.end(Buffer.from(selectedSubtitle.buffer.substr(21), 'base64'))
}).listen(0, () => { }).listen(0, () => {
const port = ret.subServer.address().port const port = ret.subServer.address().port
const subtitlesUrl = 'http://' + state.server.networkAddress + ':' + port + '/' const subtitlesUrl = 'http://' + state.server.networkAddress + ':' + port + '/'

View File

@@ -3,7 +3,6 @@ const path = require('path')
const { EventEmitter } = require('events') const { EventEmitter } = require('events')
const config = require('../../config') const config = require('../../config')
const defaultAnnounceList = require('create-torrent').announceList.map((arr) => arr[0])
const SAVE_DEBOUNCE_INTERVAL = 1000 const SAVE_DEBOUNCE_INTERVAL = 1000
@@ -80,7 +79,6 @@ function getDefaultState () {
getPlayingTorrentSummary, getPlayingTorrentSummary,
getPlayingFileSummary, getPlayingFileSummary,
getExternalPlayerName, getExternalPlayerName,
getGlobalTrackers,
shouldHidePlayerControls shouldHidePlayerControls
} }
} }
@@ -131,8 +129,7 @@ function setupStateSaved () {
soundNotifications: true, soundNotifications: true,
autoAddTorrents: false, autoAddTorrents: false,
torrentsFolderPath: '', torrentsFolderPath: '',
highestPlaybackPriority: true, highestPlaybackPriority: true
globalTrackers: defaultAnnounceList
}, },
torrents: config.DEFAULT_TORRENTS.map(createTorrentObject), torrents: config.DEFAULT_TORRENTS.map(createTorrentObject),
torrentsToResume: [], torrentsToResume: [],
@@ -201,15 +198,8 @@ function shouldHidePlayerControls () {
new Date().getTime() - this.playing.mouseStationarySince > 2000 && new Date().getTime() - this.playing.mouseStationarySince > 2000 &&
!this.playing.mouseInControls && !this.playing.mouseInControls &&
!this.playing.isPaused && !this.playing.isPaused &&
this.playing.location === 'local' this.playing.location === 'local' &&
} this.playing.playbackRate === 1
function getGlobalTrackers () {
const trackers = this.saved.prefs.globalTrackers
if (!trackers) {
return defaultAnnounceList
}
return trackers
} }
async function load (cb) { async function load (cb) {

View File

@@ -124,9 +124,6 @@ function onState (err, _state) {
} }
}) })
// Give global trackers
setGlobalTrackers()
// Restart everything we were torrenting last time the app ran // Restart everything we were torrenting last time the app ran
resumeTorrents() resumeTorrents()
@@ -317,7 +314,6 @@ const dispatchHandlers = {
preferences: () => controllers.prefs().show(), preferences: () => controllers.prefs().show(),
updatePreferences: (key, value) => controllers.prefs().update(key, value), updatePreferences: (key, value) => controllers.prefs().update(key, value),
checkDownloadPath, checkDownloadPath,
updateGlobalTrackers: (trackers) => setGlobalTrackers(trackers),
startFolderWatcher: () => controllers.folderWatcher().start(), startFolderWatcher: () => controllers.folderWatcher().start(),
stopFolderWatcher: () => controllers.folderWatcher().stop(), stopFolderWatcher: () => controllers.folderWatcher().stop(),
@@ -420,10 +416,6 @@ function escapeBack () {
} }
} }
function setGlobalTrackers () {
controllers.torrentList().setGlobalTrackers(state.getGlobalTrackers())
}
// Starts all torrents that aren't paused on program startup // Starts all torrents that aren't paused on program startup
function resumeTorrents () { function resumeTorrents () {
state.saved.torrents state.saved.torrents

View File

@@ -1,9 +1,10 @@
const colors = require('material-ui/styles/colors')
const createGetter = require('fn-getter') const createGetter = require('fn-getter')
const React = require('react') const React = require('react')
const { ThemeProvider, createTheme } = require('@material-ui/core/styles') const darkBaseTheme = require('material-ui/styles/baseThemes/darkBaseTheme').default
const grey = require('@material-ui/core/colors/grey').default const getMuiTheme = require('material-ui/styles/getMuiTheme').default
const red = require('@material-ui/core/colors/red').default const MuiThemeProvider = require('material-ui/styles/MuiThemeProvider').default
const Header = require('../components/header') const Header = require('../components/header')
@@ -32,8 +33,17 @@ const fontFamily = process.platform === 'win32'
? '"Segoe UI", sans-serif' ? '"Segoe UI", sans-serif'
: 'BlinkMacSystemFont, "Helvetica Neue", Helvetica, sans-serif' : 'BlinkMacSystemFont, "Helvetica Neue", Helvetica, sans-serif'
let darkTheme darkBaseTheme.fontFamily = fontFamily
let lightTheme darkBaseTheme.userAgent = false
darkBaseTheme.palette.primary1Color = colors.grey50
darkBaseTheme.palette.primary2Color = colors.grey50
darkBaseTheme.palette.primary3Color = colors.grey600
darkBaseTheme.palette.accent1Color = colors.redA200
darkBaseTheme.palette.accent2Color = colors.redA400
darkBaseTheme.palette.accent3Color = colors.redA100
let darkMuiTheme
let lightMuiTheme
class App extends React.Component { class App extends React.Component {
render () { render () {
@@ -54,66 +64,19 @@ class App extends React.Component {
if (state.window.isFocused) cls.push('is-focused') if (state.window.isFocused) cls.push('is-focused')
if (hideControls) cls.push('hide-video-controls') if (hideControls) cls.push('hide-video-controls')
if (!darkTheme) { if (!darkMuiTheme) {
darkTheme = createTheme({ darkMuiTheme = getMuiTheme(darkBaseTheme)
overrides: {
MuiButton: {
contained: {
backgroundColor: '#303030',
color: 'white',
'&:hover': {
backgroundColor: '#414141',
// Reset on touch devices, it doesn't add specificity
'@media (hover: none)': {
backgroundColor: '#303030',
color: 'white'
}
}
}
},
MuiCheckbox: {
root: {
padding: '0px',
marginRight: '16px'
}
},
MuiFormControlLabel: {
label: {
color: 'white',
fontSize: '0.875rem'
},
root: {
marginLeft: '0px',
marginRight: '0px'
}
}
},
palette: {
primary: {
main: grey['50']
},
secondary: {
main: grey['50']
},
type: 'dark'
},
typography: {
fontFamily
}
}, {
userAgent: false
})
} }
return ( return (
<ThemeProvider theme={darkTheme}> <MuiThemeProvider muiTheme={darkMuiTheme}>
<div className={'app ' + cls.join(' ')}> <div className={'app ' + cls.join(' ')}>
<Header state={state} /> <Header state={state} />
{this.getErrorPopover()} {this.getErrorPopover()}
<div key='content' className='content'>{this.getView()}</div> <div key='content' className='content'>{this.getView()}</div>
{this.getModal()} {this.getModal()}
</div> </div>
</ThemeProvider> </MuiThemeProvider>
) )
} }
@@ -139,32 +102,23 @@ class App extends React.Component {
const state = this.props.state const state = this.props.state
if (!state.modal) return if (!state.modal) return
if (!lightTheme) { if (!lightMuiTheme) {
lightTheme = createTheme({ const lightBaseTheme = require('material-ui/styles/baseThemes/lightBaseTheme').default
palette: { lightBaseTheme.fontFamily = fontFamily
secondary: { lightBaseTheme.userAgent = false
main: red.A200 lightMuiTheme = getMuiTheme(lightBaseTheme)
},
type: 'light'
},
typography: {
fontFamily
}
}, {
userAgent: false
})
} }
const ModalContents = Modals[state.modal.id]() const ModalContents = Modals[state.modal.id]()
return ( return (
<ThemeProvider theme={lightTheme}> <MuiThemeProvider muiTheme={lightMuiTheme}>
<div key='modal' className='modal'> <div key='modal' className='modal'>
<div key='modal-background' className='modal-background' /> <div key='modal-background' className='modal-background' />
<div key='modal-content' className='modal-content'> <div key='modal-content' className='modal-content'>
<ModalContents state={state} /> <ModalContents state={state} />
</div> </div>
</div> </div>
</ThemeProvider> </MuiThemeProvider>
) )
} }

View File

@@ -3,16 +3,17 @@ const path = require('path')
const prettyBytes = require('prettier-bytes') const prettyBytes = require('prettier-bytes')
const React = require('react') const React = require('react')
const Button = require('@material-ui/core/Button').default const { dispatch, dispatcher } = require('../lib/dispatcher')
const TextField = require('@material-ui/core/TextField').default
const Checkbox = require('@material-ui/core/Checkbox').default const FlatButton = require('material-ui/FlatButton').default
const RaisedButton = require('material-ui/RaisedButton').default
const TextField = require('material-ui/TextField').default
const Checkbox = require('material-ui/Checkbox').default
const CreateTorrentErrorPage = require('../components/create-torrent-error-page') const CreateTorrentErrorPage = require('../components/create-torrent-error-page')
const Heading = require('../components/heading') const Heading = require('../components/heading')
const ShowMore = require('../components/show-more') const ShowMore = require('../components/show-more')
const { dispatch, dispatcher } = require('../lib/dispatcher')
// Shows a basic UI to create a torrent, from an already-selected file or folder. // Shows a basic UI to create a torrent, from an already-selected file or folder.
// Includes a "Show Advanced..." button and more advanced UI. // Includes a "Show Advanced..." button and more advanced UI.
class CreateTorrentPage extends React.Component { class CreateTorrentPage extends React.Component {
@@ -98,23 +99,20 @@ class CreateTorrentPage extends React.Component {
{this.renderAdvanced()} {this.renderAdvanced()}
</ShowMore> </ShowMore>
<div className='float-right'> <div className='float-right'>
<Button <FlatButton
className='control cancel' className='control cancel'
onClick={dispatcher('cancel')} label='Cancel'
style={{ style={{
marginRight: 10 marginRight: 10
}} }}
> onClick={dispatcher('cancel')}
Cancel />
</Button> <RaisedButton
<Button
className='control create-torrent-button' className='control create-torrent-button'
label='Create Torrent'
primary
onClick={this.handleSubmit} onClick={this.handleSubmit}
color='primary' />
variant='contained'
>
Create Torrent
</Button>
</div> </div>
</div> </div>
) )
@@ -136,6 +134,10 @@ class CreateTorrentPage extends React.Component {
fileElems.push(<div key='more'>+ {files.length - maxFileElems} more</div>) fileElems.push(<div key='more'>+ {files.length - maxFileElems} more</div>)
} }
// Align the text fields
const textFieldStyle = { width: '' }
const textareaStyle = { margin: 0 }
return ( return (
<div key='advanced' className='create-torrent-advanced'> <div key='advanced' className='create-torrent-advanced'>
<div key='private' className='torrent-attribute'> <div key='private' className='torrent-attribute'>
@@ -144,32 +146,34 @@ class CreateTorrentPage extends React.Component {
className='torrent-is-private control' className='torrent-is-private control'
style={{ display: '' }} style={{ display: '' }}
checked={this.state.isPrivate} checked={this.state.isPrivate}
onChange={this.handleSetIsPrivate} onCheck={this.handleSetIsPrivate}
/> />
</div> </div>
<div key='trackers' className='torrent-attribute'> <div key='trackers' className='torrent-attribute'>
<label>Trackers:</label> <label>Trackers:</label>
<TextField <TextField
className='torrent-trackers control' className='torrent-trackers control'
fullWidth style={textFieldStyle}
maxRows={10} textareaStyle={textareaStyle}
minRows={2} multiLine
multiline rows={2}
onChange={this.handleSetTrackers} rowsMax={10}
value={this.state.trackers} value={this.state.trackers}
onChange={this.handleSetTrackers}
/> />
</div> </div>
<div key='comment' className='torrent-attribute'> <div key='comment' className='torrent-attribute'>
<label>Comment:</label> <label>Comment:</label>
<TextField <TextField
className='torrent-comment control' className='torrent-comment control'
fullWidth style={textFieldStyle}
maxRows={10} textareaStyle={textareaStyle}
minRows={2} hintText='Optionally describe your torrent...'
multiline multiLine
onChange={this.handleSetComment} rows={2}
placeholder='Optionally describe your torrent...' rowsMax={10}
value={this.state.comment} value={this.state.comment}
onChange={this.handleSetComment}
/> />
</div> </div>
<div key='files' className='torrent-attribute'> <div key='files' className='torrent-attribute'>

View File

@@ -1,5 +1,3 @@
/* globals MediaMetadata */
const React = require('react') const React = require('react')
const BitField = require('bitfield').default const BitField = require('bitfield').default
const prettyBytes = require('prettier-bytes') const prettyBytes = require('prettier-bytes')
@@ -37,7 +35,6 @@ module.exports = class Player extends React.Component {
tag.pause() tag.pause()
tag.src = '' tag.src = ''
tag.load() tag.load()
navigator.mediaSession.metadata = null
} }
} }
@@ -54,28 +51,6 @@ function renderMedia (state) {
// Get the <video> or <audio> tag // Get the <video> or <audio> tag
const mediaElement = document.querySelector(state.playing.type) const mediaElement = document.querySelector(state.playing.type)
if (mediaElement !== null) { if (mediaElement !== null) {
if (navigator.mediaSession.metadata === null && mediaElement.played.length !== 0) {
navigator.mediaSession.metadata = new MediaMetadata({
title: state.playing.fileName
})
navigator.mediaSession.setActionHandler('pause', () => {
dispatch('playPause')
})
navigator.mediaSession.setActionHandler('play', () => {
dispatch('playPause')
})
if (Playlist.hasNext(state)) {
navigator.mediaSession.setActionHandler('nexttrack', () => {
dispatch('nextTrack')
})
}
if (Playlist.hasPrevious(state)) {
navigator.mediaSession.setActionHandler('previoustrack', () => {
dispatch('previousTrack')
})
}
}
if (state.playing.isPaused && !mediaElement.paused) { if (state.playing.isPaused && !mediaElement.paused) {
mediaElement.pause() mediaElement.pause()
} else if (!state.playing.isPaused && mediaElement.paused) { } else if (!state.playing.isPaused && mediaElement.paused) {
@@ -635,8 +610,6 @@ function renderPlayerControls (state) {
key='skip-previous' key='skip-previous'
className={'icon skip-previous float-left ' + prevClass} className={'icon skip-previous float-left ' + prevClass}
onClick={dispatcher('previousTrack')} onClick={dispatcher('previousTrack')}
role='button'
aria-label='Previous track'
> >
skip_previous skip_previous
</i>, </i>,
@@ -645,8 +618,6 @@ function renderPlayerControls (state) {
key='play' key='play'
className='icon play-pause float-left' className='icon play-pause float-left'
onClick={dispatcher('playPause')} onClick={dispatcher('playPause')}
role='button'
aria-label={state.playing.isPaused ? 'Play' : 'Pause'}
> >
{state.playing.isPaused ? 'play_arrow' : 'pause'} {state.playing.isPaused ? 'play_arrow' : 'pause'}
</i>, </i>,
@@ -655,8 +626,6 @@ function renderPlayerControls (state) {
key='skip-next' key='skip-next'
className={'icon skip-next float-left ' + nextClass} className={'icon skip-next float-left ' + nextClass}
onClick={dispatcher('nextTrack')} onClick={dispatcher('nextTrack')}
role='button'
aria-label='Next track'
> >
skip_next skip_next
</i>, </i>,
@@ -665,8 +634,6 @@ function renderPlayerControls (state) {
key='fullscreen' key='fullscreen'
className='icon fullscreen float-right' className='icon fullscreen float-right'
onClick={dispatcher('toggleFullScreen')} onClick={dispatcher('toggleFullScreen')}
role='button'
aria-label={state.window.isFullScreen ? 'Exit full screen' : 'Enter full screen'}
> >
{state.window.isFullScreen ? 'fullscreen_exit' : 'fullscreen'} {state.window.isFullScreen ? 'fullscreen_exit' : 'fullscreen'}
</i> </i>
@@ -679,8 +646,6 @@ function renderPlayerControls (state) {
key='subtitles' key='subtitles'
className={'icon closed-caption float-right ' + captionsClass} className={'icon closed-caption float-right ' + captionsClass}
onClick={handleSubtitles} onClick={handleSubtitles}
role='button'
aria-label='Closed captions'
> >
closed_caption closed_caption
</i> </i>
@@ -762,8 +727,6 @@ function renderPlayerControls (state) {
<i <i
className='icon volume-icon float-left' className='icon volume-icon float-left'
onMouseDown={handleVolumeMute} onMouseDown={handleVolumeMute}
role='button'
aria-label='Mute'
> >
{volumeIcon} {volumeIcon}
</i> </i>

View File

@@ -1,12 +1,9 @@
const React = require('react') const React = require('react')
const PropTypes = require('prop-types') const PropTypes = require('prop-types')
const Button = require('@material-ui/core/Button').default const colors = require('material-ui/styles/colors')
const Checkbox = require('@material-ui/core/Checkbox').default const Checkbox = require('material-ui/Checkbox').default
const FormControlLabel = require('@material-ui/core/FormControlLabel').default const RaisedButton = require('material-ui/RaisedButton').default
const TextField = require('@material-ui/core/TextField').default
const grey = require('@material-ui/core/colors/grey').default
const Heading = require('../components/heading') const Heading = require('../components/heading')
const PathSelector = require('../components/path-selector') const PathSelector = require('../components/path-selector')
@@ -31,15 +28,6 @@ class PreferencesPage extends React.Component {
this.handleSoundNotificationsChange = this.handleSoundNotificationsChange =
this.handleSoundNotificationsChange.bind(this) this.handleSoundNotificationsChange.bind(this)
this.handleSetGlobalTrackers =
this.handleSetGlobalTrackers.bind(this)
const globalTrackers = this.props.state.getGlobalTrackers().join('\n')
this.state = {
globalTrackers
}
} }
downloadPathSelector () { downloadPathSelector () {
@@ -65,15 +53,11 @@ class PreferencesPage extends React.Component {
openExternalPlayerCheckbox () { openExternalPlayerCheckbox () {
return ( return (
<Preference> <Preference>
<FormControlLabel
control={
<Checkbox <Checkbox
className='control' className='control'
checked={!this.props.state.saved.prefs.openExternalPlayer} checked={!this.props.state.saved.prefs.openExternalPlayer}
onChange={this.handleOpenExternalPlayerChange}
/>
}
label='Play torrent media files using WebTorrent' label='Play torrent media files using WebTorrent'
onCheck={this.handleOpenExternalPlayerChange}
/> />
</Preference> </Preference>
) )
@@ -86,15 +70,11 @@ class PreferencesPage extends React.Component {
highestPlaybackPriorityCheckbox () { highestPlaybackPriorityCheckbox () {
return ( return (
<Preference> <Preference>
<FormControlLabel
control={
<Checkbox <Checkbox
className='control' className='control'
checked={this.props.state.saved.prefs.highestPlaybackPriority} checked={this.props.state.saved.prefs.highestPlaybackPriority}
onChange={this.handleHighestPlaybackPriorityChange}
/>
}
label='Highest Playback Priority' label='Highest Playback Priority'
onCheck={this.handleHighestPlaybackPriorityChange}
/> />
<p>Pauses all active torrents to allow playback to use all of the available bandwidth.</p> <p>Pauses all active torrents to allow playback to use all of the available bandwidth.</p>
</Preference> </Preference>
@@ -136,15 +116,11 @@ class PreferencesPage extends React.Component {
autoAddTorrentsCheckbox () { autoAddTorrentsCheckbox () {
return ( return (
<Preference> <Preference>
<FormControlLabel
control={
<Checkbox <Checkbox
className='control' className='control'
checked={this.props.state.saved.prefs.autoAddTorrents} checked={this.props.state.saved.prefs.autoAddTorrents}
onChange={(e, value) => { this.handleAutoAddTorrentsChange(e, value) }}
/>
}
label='Watch for new .torrent files and add them immediately' label='Watch for new .torrent files and add them immediately'
onCheck={(e, value) => { this.handleAutoAddTorrentsChange(e, value) }}
/> />
</Preference> </Preference>
) )
@@ -202,13 +178,11 @@ class PreferencesPage extends React.Component {
return ( return (
<Preference> <Preference>
<p>WebTorrent is not currently the default torrent app.</p> <p>WebTorrent is not currently the default torrent app.</p>
<Button <RaisedButton
className='control' className='control'
onClick={this.handleSetDefaultApp} onClick={this.handleSetDefaultApp}
variant='contained' label='Make WebTorrent the default'
> />
Make WebTorrent the default
</Button>
</Preference> </Preference>
) )
} }
@@ -224,15 +198,11 @@ class PreferencesPage extends React.Component {
return ( return (
<Preference> <Preference>
<FormControlLabel
control={
<Checkbox <Checkbox
className='control' className='control'
checked={this.props.state.saved.prefs.startup} checked={this.props.state.saved.prefs.startup}
onChange={this.handleStartupChange}
/>
}
label='Open WebTorrent on startup' label='Open WebTorrent on startup'
onCheck={this.handleStartupChange}
/> />
</Preference> </Preference>
) )
@@ -241,15 +211,11 @@ class PreferencesPage extends React.Component {
soundNotificationsCheckbox () { soundNotificationsCheckbox () {
return ( return (
<Preference> <Preference>
<FormControlLabel
control={
<Checkbox <Checkbox
className='control' className='control'
checked={this.props.state.saved.prefs.soundNotifications} checked={this.props.state.saved.prefs.soundNotifications}
onChange={this.handleSoundNotificationsChange}
/>
}
label='Enable sounds' label='Enable sounds'
onCheck={this.handleSoundNotificationsChange}
/> />
</Preference> </Preference>
) )
@@ -263,37 +229,9 @@ class PreferencesPage extends React.Component {
dispatch('updatePreferences', 'isFileHandler', true) dispatch('updatePreferences', 'isFileHandler', true)
} }
setGlobalTrackers () {
return (
<Preference>
<TextField
className='torrent-trackers control'
fullWidth
maxRows={10}
minRows={2}
multiline
onChange={this.handleSetGlobalTrackers}
value={this.state.globalTrackers}
/>
</Preference>
)
}
handleSetGlobalTrackers (e, globalTrackers) {
this.setState({ globalTrackers })
const announceList = globalTrackers
.split('\n')
.map((s) => s.trim())
.filter((s) => s !== '')
dispatch('updatePreferences', 'globalTrackers', announceList)
dispatch('updateGlobalTrackers', announceList)
}
render () { render () {
const style = { const style = {
color: grey['400'], color: colors.grey400,
marginLeft: 25, marginLeft: 25,
marginRight: 25 marginRight: 25
} }
@@ -316,9 +254,6 @@ class PreferencesPage extends React.Component {
{this.setStartupCheckbox()} {this.setStartupCheckbox()}
{this.soundNotificationsCheckbox()} {this.soundNotificationsCheckbox()}
</PreferencesSection> </PreferencesSection>
<PreferencesSection title='Trackers'>
{this.setGlobalTrackers()}
</PreferencesSection>
</div> </div>
) )
} }

View File

@@ -1,8 +1,8 @@
const React = require('react') const React = require('react')
const prettyBytes = require('prettier-bytes') const prettyBytes = require('prettier-bytes')
const Checkbox = require('@material-ui/core/Checkbox').default const Checkbox = require('material-ui/Checkbox').default
const LinearProgress = require('@material-ui/core/LinearProgress').default const LinearProgress = require('material-ui/LinearProgress').default
const TorrentSummary = require('../lib/torrent-summary') const TorrentSummary = require('../lib/torrent-summary')
const TorrentPlayer = require('../lib/torrent-player') const TorrentPlayer = require('../lib/torrent-player')
@@ -124,19 +124,19 @@ module.exports = class TorrentList extends React.Component {
const isActive = ['downloading', 'seeding'].includes(torrentSummary.status) const isActive = ['downloading', 'seeding'].includes(torrentSummary.status)
return ( return (
<Checkbox <Checkbox
checked={isActive}
className={'control download ' + torrentSummary.status}
key='download-button' key='download-button'
onChange={dispatcher('toggleTorrent', infoHash)} className={'control download ' + torrentSummary.status}
onClick={stopPropagation}
style={{ style={{
display: 'inline-block', display: 'inline-block',
marginRight: '12px', width: 32
'& .MuiSvgIconRoot': {
width: '20px',
height: '20px'
}
}} }}
iconStyle={{
width: 20,
height: 20
}}
checked={isActive}
onClick={stopPropagation}
onCheck={dispatcher('toggleTorrent', infoHash)}
/> />
) )
} }
@@ -155,7 +155,7 @@ module.exports = class TorrentList extends React.Component {
} }
return ( return (
<div key='progress-bar' style={styles.wrapper}> <div key='progress-bar' style={styles.wrapper}>
<LinearProgress style={styles.progress} value={progress} variant='determinate' /> <LinearProgress style={styles.progress} mode='determinate' value={progress} />
</div> </div>
) )
} }

View File

@@ -4,6 +4,7 @@ console.time('init')
const crypto = require('crypto') const crypto = require('crypto')
const util = require('util') const util = require('util')
const defaultAnnounceList = require('create-torrent').announceList
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
const fs = require('fs') const fs = require('fs')
const mm = require('music-metadata') const mm = require('music-metadata')
@@ -15,6 +16,11 @@ const config = require('../config')
const { TorrentKeyNotFoundError } = require('./lib/errors') const { TorrentKeyNotFoundError } = require('./lib/errors')
const torrentPoster = require('./lib/torrent-poster') const torrentPoster = require('./lib/torrent-poster')
// Force use of webtorrent trackers on all torrents
globalThis.WEBTORRENT_ANNOUNCE = defaultAnnounceList
.map((arr) => arr[0])
.filter((url) => url.indexOf('wss://') === 0 || url.indexOf('ws://') === 0)
/** /**
* WebTorrent version. * WebTorrent version.
*/ */
@@ -59,8 +65,6 @@ init()
function init () { function init () {
listenToClientEvents() listenToClientEvents()
ipcRenderer.on('wt-set-global-trackers', (e, globalTrackers) =>
setGlobalTrackers(globalTrackers))
ipcRenderer.on('wt-start-torrenting', (e, torrentKey, torrentID, path, fileModtimes, selections) => ipcRenderer.on('wt-start-torrenting', (e, torrentKey, torrentID, path, fileModtimes, selections) =>
startTorrenting(torrentKey, torrentID, path, fileModtimes, selections)) startTorrenting(torrentKey, torrentID, path, fileModtimes, selections))
ipcRenderer.on('wt-stop-torrenting', (e, infoHash) => ipcRenderer.on('wt-stop-torrenting', (e, infoHash) =>
@@ -95,11 +99,6 @@ function listenToClientEvents () {
client.on('error', (err) => ipcRenderer.send('wt-error', null, err.message)) client.on('error', (err) => ipcRenderer.send('wt-error', null, err.message))
} }
// Sets the default trackers
function setGlobalTrackers (globalTrackers) {
globalThis.WEBTORRENT_ANNOUNCE = globalTrackers
}
// Starts a given TorrentID, which can be an infohash, magnet URI, etc. // Starts a given TorrentID, which can be an infohash, magnet URI, etc.
// Returns a WebTorrent object. See https://git.io/vik9M // Returns a WebTorrent object. See https://git.io/vik9M
function startTorrenting (torrentKey, torrentID, path, fileModtimes, selections) { function startTorrenting (torrentKey, torrentID, path, fileModtimes, selections) {

View File

@@ -354,7 +354,7 @@ textarea,
text-shadow: rgba(0, 0, 0, 0.5) 0 0 4px; text-shadow: rgba(0, 0, 0, 0.5) 0 0 4px;
} }
.torrent .metadata .ellipsis > span:not(:last-child):not(.control)::after { .torrent .metadata span:not(:last-child)::after {
content: ' • '; content: ' • ';
opacity: 0.7; opacity: 0.7;
padding-left: 4px; padding-left: 4px;