Compare commits

..

101 Commits

Author SHA1 Message Date
Julen Garcia Leunda
caab9c3b76 Enable uTP 2020-11-27 17:45:07 +01:00
Feross Aboukhadijeh
919af5bf15 Merge pull request #1217 from cezar-carneiro/show-progress-on-cast-screen 2020-11-26 01:44:32 +01:00
Feross Aboukhadijeh
d819acedd5 Merge pull request #1865 from BlueManCZ/patch-1 2020-11-25 22:33:25 +01:00
Feross Aboukhadijeh
54fcc5057b recursively update all deps 2020-11-24 12:02:08 -10:00
Feross Aboukhadijeh
cd5da2fe9b cross-zip@4 2020-11-24 12:00:00 -10:00
Feross Aboukhadijeh
1c79ffc720 bump deps; including electron ~11.0.3
Fixes: https://github.com/webtorrent/webtorrent-desktop/issues/1896
2020-11-24 11:56:17 -10:00
Feross Aboukhadijeh
a1a590fbba travis: disable cache
the cache keeps caching outdated versions which cause test failures
2020-11-22 16:32:36 -10:00
Feross Aboukhadijeh
606c02aef4 Remove extra-lint
- standard enforces 'let' and 'const' now
- I've never been a fan of the <100 chars per line rule since it violates the standard philosophy. it should be possible to write conformant code without needing a tool, so 'magic numbers' like 'no more than X lines/chars/statements' are not ideal
2020-11-22 16:29:59 -10:00
Feross Aboukhadijeh
4f68a8ad0b parse-torrent@9 2020-11-22 16:26:42 -10:00
Feross Aboukhadijeh
37d962fcf3 bump deps 2020-11-22 16:24:46 -10:00
Feross Aboukhadijeh
baf06461df Remove unused 'buble' dependency 2020-11-22 16:20:09 -10:00
Feross Aboukhadijeh
464e63fd92 standard (Fixes for PR #1818) 2020-11-22 16:12:04 -10:00
Feross Aboukhadijeh
2761e9c768 Merge pull request #1818 from surajrathod/master 2020-11-23 03:11:34 +01:00
suraj rathod
0efb5fa7ad Merge branch 'master' into master 2020-11-20 11:27:33 +05:30
Feross Aboukhadijeh
34947c355d standard@16 2020-11-18 12:38:20 -10:00
Feross Aboukhadijeh
958814f2ea use @babel/eslint-parser 2020-11-18 12:37:03 -10:00
Feross Aboukhadijeh
ec0c0c7870 Update package-lock.json 2020-11-18 12:30:13 -10:00
Feross Aboukhadijeh
ec0a1d1bb4 Merge pull request #1895 from webtorrent/electron11 2020-11-18 03:41:45 +01:00
Feross Aboukhadijeh
969d71afec Merge pull request #1698 from webtorrent/babel
Use babel instead of buble
2020-11-18 03:41:19 +01:00
Feross Aboukhadijeh
c1db01b936 Use babel instead of buble
This way we can target just the JSX tranformation. We don't use any other cutting edge JS features that require compilation, nor should we in the future.
2020-11-17 16:40:14 -10:00
Feross Aboukhadijeh
90670a4645 changelog: add link to security issue explanation 2020-11-17 15:42:11 -10:00
Feross Aboukhadijeh
b5fad54f4a Upgrade to Electron 11 2020-11-16 18:03:35 -10:00
Feross Aboukhadijeh
50718d3791 Merge pull request #1887 from webtorrent/fix_lintian_warnings
Fix lintian warnings
2020-11-09 22:58:14 +01:00
Julen Garcia Leunda
bd54a8c214 Fix lintian warnings 2020-11-06 17:13:22 +01:00
Feross Aboukhadijeh
0cd0edf4cc Merge pull request #1886 from webtorrent/throttling
Disable background throttling
2020-11-05 22:30:22 +01:00
Feross Aboukhadijeh
9e0d91f144 Disable background throttling
Reference: https://github.com/webtorrent/webtorrent-desktop/pull/1720#issuecomment-722011487

I actually think we want backgroundThrottling: false so our timers and intervals aren't throttled when the app is backgrounded.
2020-11-04 12:34:48 -10:00
Feross Aboukhadijeh
38d9c4c504 Merge pull request #1885 from webtorrent/bitfield
bitfield@4
2020-11-04 10:15:40 +01:00
Feross Aboukhadijeh
9e1721990d bitfield@4 2020-11-03 13:03:40 -10:00
Feross Aboukhadijeh
a20f82cc61 standard 2020-10-29 11:30:07 -10:00
Feross Aboukhadijeh
630ed76b8c standard 2020-10-28 09:52:07 -10:00
Feross Aboukhadijeh
1155cba4dd Merge pull request #1883 from webtorrent/deps 2020-10-28 19:18:16 +01:00
Feross Aboukhadijeh
2343181e1b Update package-lock.json 2020-10-28 08:15:53 -10:00
Feross Aboukhadijeh
9bb7330caa spectron@12 2020-10-28 08:14:10 -10:00
Feross Aboukhadijeh
3aae1614ea pngjs@6 2020-10-28 08:13:13 -10:00
Feross Aboukhadijeh
cdd308fc4a gh-release@4 2020-10-28 08:12:11 -10:00
Feross Aboukhadijeh
594d18e76e react 17 2020-10-28 08:11:10 -10:00
Feross Aboukhadijeh
50d772eb54 parse-torrent@8 2020-10-28 08:10:43 -10:00
Feross Aboukhadijeh
57ffb5e0c4 bump deps 2020-10-28 08:10:26 -10:00
Feross Aboukhadijeh
49ab4bd201 Merge pull request #1882 from webtorrent/render-deprecated 2020-10-28 19:07:03 +01:00
Feross Aboukhadijeh
7b06acb972 don't rely on deprecated return value from ReactDOM.render 2020-10-27 18:18:30 -10:00
Feross Aboukhadijeh
80b86b5693 standard 2020-10-21 13:50:42 -10:00
Diego Rodríguez Baquero
748b996522 Merge pull request #1875 from webtorrent/dependabot/npm_and_yarn/electron-10.1.2
Bump electron from 10.1.1 to 10.1.2
2020-10-20 10:51:26 -05:00
Julen Garcia Leunda
77877d4201 Merge pull request #1812 from dsernst/scrub-preview
Adds Youtube-style Scrubbing preview
2020-10-20 17:31:43 +02:00
dependabot[bot]
696fa4479c Bump electron from 10.1.1 to 10.1.2
Bumps [electron](https://github.com/electron/electron) from 10.1.1 to 10.1.2.
- [Release notes](https://github.com/electron/electron/releases)
- [Changelog](https://github.com/electron/electron/blob/master/docs/breaking-changes.md)
- [Commits](https://github.com/electron/electron/compare/v10.1.1...v10.1.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-06 17:49:29 +00:00
Feross Aboukhadijeh
e0bb7562be Update package-lock.json 2020-09-03 11:36:21 -07:00
Feross Aboukhadijeh
8f20d9676b electron 10.1.1 2020-09-03 11:35:08 -07:00
BlueManCZ
b61a4e84f5 Remove Version entry 2020-08-29 14:19:36 +02:00
Ivo Šmerek
5def2d3947 Fix StartupWMClass 2020-08-29 13:53:02 +02:00
Feross Aboukhadijeh
ce6326a869 Update RELEASE_PROCESS.md 2020-08-28 17:58:07 -07:00
Feross Aboukhadijeh
7e56550887 Update RELEASE_PROCESS.md 2020-08-28 17:51:12 -07:00
Feross Aboukhadijeh
aa42627d45 0.24.0 2020-08-28 17:19:47 -07:00
Feross Aboukhadijeh
bd6dc1a7c1 authors 2020-08-28 17:19:20 -07:00
Feross Aboukhadijeh
dfedbcea32 add 0.24.0 changelog 2020-08-28 17:18:42 -07:00
Feross Aboukhadijeh
d930b97b30 Merge pull request #1864 from webtorrent/update 2020-08-28 17:14:58 -07:00
Feross Aboukhadijeh
de7899c8f8 Update package-lock.json 2020-08-28 17:06:51 -07:00
Feross Aboukhadijeh
2f53c5e137 bump electron deps 2020-08-28 17:03:33 -07:00
Feross Aboukhadijeh
ff54f48abb bump deps 2020-08-28 17:00:29 -07:00
Feross Aboukhadijeh
a7766e8d3f fixes for capture-frame@4 2020-08-28 16:58:40 -07:00
Feross Aboukhadijeh
844e34e596 capture-frame@4 2020-08-28 16:58:36 -07:00
Julen Garcia Leunda
8515fee681 Merge pull request #1859 from webtorrent/add_m2ts_video_container
Add m2ts video container support
2020-08-17 21:58:32 +02:00
Borewit
10a1ee3a09 Merge pull request #1861 from webtorrent/update-music-metadata
Update music-metadata to version 7.0.2
2020-08-17 19:26:32 +02:00
Borewit
a1b2641130 Update music-metadata to version 7.0.2 2020-08-16 08:48:37 +02:00
Julen Garcia Leunda
bb55b3fab2 Add m2ts video container support 2020-08-12 23:06:14 +02:00
Julen Garcia Leunda
57d02aa316 Merge pull request #1850 from Hinara/patch-1
Fix #1807 (VLC does not start)
2020-07-31 17:11:07 +02:00
David Ernst
d3bfccaa6b Check for type === video in clearPreview() 2020-07-30 19:10:14 -07:00
Julen Garcia Leunda
3a92f596ff Merge pull request #1838 from webtorrent/update-trackers
Update trackers to be consistent
2020-07-30 18:31:43 +02:00
Julen Garcia Leunda
60b4365a76 Merge pull request #1840 from subins2000/fix-1839-no-keyevents-on-user-input
Fix #1839: Prevent keypress events on user input elements
2020-07-30 18:31:22 +02:00
Julen Garcia Leunda
cb0ad73c80 Merge pull request #1754 from hicom150/fix_windows_installer
Fix windows installer event handler
2020-07-30 18:30:59 +02:00
Julen Garcia Leunda
9c865050bb Merge pull request #1847 from webtorrent/update-music-metadata
Update music metadata
2020-07-30 18:30:08 +02:00
Hinara
0edeaa4d58 Accept null value as playerPath 2020-07-30 15:06:26 +02:00
Mathias Rasmussen
dfd1ca3a8e Merge pull request #1841 from webtorrent/update_loading_gif
Update loading GIF
2020-07-30 03:59:49 +02:00
Borewit
75d9939b98 Update dependency music-metadata to version 7 2020-07-29 18:00:29 +02:00
Hinara
f88d5426c9 Fix #1807
eb5a291c8b/src/renderer/lib/migrations.js (L219) cause external player to be a empty string instead of a null one
2020-07-25 02:39:09 +02:00
Borewit
1b7d4f09a9 Fix issue #1833, only pass metadata. Prevent MetadataCollector (from music-metadata) is serialized. 2020-07-21 23:00:22 +02:00
Alex
680376c4a6 Update loading.gif 2020-07-17 21:14:15 +02:00
Subin Siby
15cca44bd2 Fix #1839: Prevent keypress events on user input elements 2020-07-17 18:47:23 +05:30
Feross Aboukhadijeh
29d17870cb Update trackers to be consistent
Updated all .torrent files to include:

```
  "announce": [
    "udp://tracker.leechers-paradise.org:6969",
    "udp://tracker.coppersurfer.tk:6969",
    "udp://tracker.opentrackr.org:1337",
    "udp://explodie.org:6969",
    "udp://tracker.empire-js.us:1337",
    "wss://tracker.btorrent.xyz",
    "wss://tracker.openwebtorrent.com"
  ]
```

Removed dead trackers from the list.
2020-07-16 20:18:15 -07:00
Feross Aboukhadijeh
c150d22c97 Update package-lock.json 2020-07-16 10:14:43 -07:00
Feross Aboukhadijeh
4e0c1ed393 Update CHANGELOG.md 2020-07-15 23:04:06 -07:00
Feross Aboukhadijeh
c6240c3253 Update CHANGELOG.md 2020-07-15 22:38:58 -07:00
Feross Aboukhadijeh
5deb0d7e9a Merge pull request #1835 from webtorrent/osx-notarize
Add macOS Notarization
2020-07-16 07:28:56 +02:00
Feross Aboukhadijeh
803cce808b Add macOS Notarization
Fixes: https://github.com/webtorrent/webtorrent-desktop/issues/1675
2020-07-15 22:26:29 -07:00
Feross Aboukhadijeh
8e89c0962b 0.23.0 2020-07-15 20:13:51 -07:00
Feross Aboukhadijeh
50cc394a27 Update CHANGELOG.md 2020-07-15 20:13:51 -07:00
Feross Aboukhadijeh
0165d541b8 update dep 2020-07-15 20:13:51 -07:00
Feross Aboukhadijeh
5af36428fa Merge pull request #1834 from webtorrent/electron10 2020-07-16 05:01:40 +02:00
Feross Aboukhadijeh
48ad571a59 electron 10: re-enable remote module
Electron 10 disables the remote module by default. We've always tried to avoid using `remote` in WTD so there aren't many occurrances of it, but there are still a few places where we use it
2020-07-15 20:01:08 -07:00
Feross Aboukhadijeh
57a003d7c5 electron 10 crash reporter changes
Crash reporter doesn't need to be started in child processes, and in fact the functions are all deprecated. Instead start it from the main process, and the child processes will automatically be covered

Change of params to crashReporter.start() function
2020-07-15 19:44:34 -07:00
Feross Aboukhadijeh
5f5b13d7fe update to electron 10.0.0-beta.11 2020-07-15 19:42:08 -07:00
SurajRathod
ab9f86d6c9 added .vscode ignore 2020-06-06 17:47:38 +05:30
SurajRathod
583cecc661 selective import 2020-06-06 17:46:30 +05:30
David Ernst
c4b318bd5f Clean up code and add better comments 2020-05-02 11:40:00 -07:00
David Ernst
d55acf9c12 Fix 'extra-lint' errors 2020-05-01 22:41:19 -07:00
David Ernst
24bc40c95e Fix preview border rendering 2020-05-01 22:06:05 -07:00
David Ernst
0716444be5 Working video scrubbing preview 2020-05-01 21:57:42 -07:00
David Ernst
85c0e99e16 Only show previews for video 2020-05-01 21:05:29 -07:00
David Ernst
0b57961ff7 Basic placeholder UI for scrubbing preview 2020-05-01 19:43:47 -07:00
Julen Garcia Leunda
97426621bf Fix windows installer event handler 2019-12-12 22:48:13 +01:00
Cezar Carneiro
ab41d55e4b fix ETA and reorganize 2017-08-02 22:52:45 -03:00
Cezar Carneiro
739e7a50f7 improve infos 2017-08-02 00:03:52 -03:00
Cezar Carneiro
64ff5ebfd5 show percentage, size, speed and peers 2017-07-31 22:47:53 -03:00
52 changed files with 5658 additions and 4464 deletions

1
.gitignore vendored
View File

@@ -2,6 +2,7 @@ node_modules/
build/
dist/
npm-debug.log*
.vscode/
# JetBrains IntelliJ IDEA project files
.idea

View File

@@ -1,3 +1,5 @@
language: node_js
node_js:
- lts/*
cache:
npm: false

View File

@@ -77,5 +77,7 @@
- Ameet Kaustav (akaustav@users.noreply.github.com)
- gpatarin (gael.patarin@outlook.com)
- Gael Patarin (gael.patarin@outlook.com)
- Subin Siby (mail@subinsb.com)
- Hinara (hinara.turevel@gmail.com)
#### Generated by bin/update-authors.sh.

View File

@@ -1,15 +1,38 @@
# WebTorrent Desktop Version History
## v0.23.0 - 2020-07-15
## v0.24.0 - 2020-08-28
This release contains a critical security fix.
### Added
- Support the `.m2ts` video container format ([hicom150](https://github.com/hicom150))
### Changed
- Update to Electron 10 beta [\#1834](https://github.com/webtorrent/webtorrent-desktop/pull/1834)
- Update to Electron 10.1.0 [\#1864](https://github.com/webtorrent/webtorrent-desktop/pull/1864) ([feross](https://github.com/feross))
- Update the Windows installer loading image [\#1841](https://github.com/webtorrent/webtorrent-desktop/pull/1841) ([alxhotel](https://github.com/alxhotel))
### Fixed
- Fix music metadata not showing up [\#1847](https://github.com/webtorrent/webtorrent-desktop/pull/1847) ([Borewit](https://github.com/Borewit))
- Fix the "Play in VLC" functionality [\#1850](https://github.com/webtorrent/webtorrent-desktop/pull/1850) ([Hinara](https://github.com/Hinara))
- Prevent shortcuts from activating when user input elements are focused [\#1840](https://github.com/webtorrent/webtorrent-desktop/pull/1840) ([subins2000](https://github.com/subins2000))
## v0.23.0 - 2020-07-15
🔒 This release contains a critical security fix. Please update as soon as possible. [\#1837](https://github.com/webtorrent/webtorrent-desktop/issues/1837#issuecomment-729320901)
### Added
- Add macOS Notarization [\#1834](https://github.com/webtorrent/webtorrent-desktop/pull/1834) ([feross](https://github.com/feross))
### Changed
- Update to Electron 10 beta [\#1834](https://github.com/webtorrent/webtorrent-desktop/pull/1834) ([feross](https://github.com/feross))
## v0.22.0 - 2020-07-15
❤️✨ A new version of WebTorrent Desktop is out! ❤️✨
### Added
- Linux `.rpm` packages and `arm64` builds are now available! [\#1694](https://github.com/webtorrent/webtorrent-desktop/pull/1694) ([hicom150](https://github.com/hicom150))
@@ -23,7 +46,7 @@ This release contains a critical security fix.
- Update to Electron 9 [\#1729](https://github.com/webtorrent/webtorrent-desktop/pull/1729) [\#1832](https://github.com/webtorrent/webtorrent-desktop/issues/1832)
- Update to music-metadata 4.8.0 [\#1719](https://github.com/webtorrent/webtorrent-desktop/pull/1719) ([Borewit](https://github.com/Borewit))
- Update Windows build documentation [\#1715](https://github.com/webtorrent/webtorrent-desktop/pull/1715) ([RecoX](https://github.com/RecoX))
- Remove unneeded dependencies
- Remove unneeded dependencies ([feross](https://github.com/feross))
### Fixed
@@ -32,8 +55,8 @@ This release contains a critical security fix.
- Fix percentage rounding error [\#1716](https://github.com/webtorrent/webtorrent-desktop/pull/1716) ([pR0Ps](https://github.com/pR0Ps))
- Fix path-selector in preferences page [\#1702](https://github.com/webtorrent/webtorrent-desktop/pull/1702) ([314eter](https://github.com/314eter))
- Fix path-selector in preferences page [\#1704](https://github.com/webtorrent/webtorrent-desktop/pull/1702) ([mathiasvr](https://github.com/mathiasvr))
- Fix: Increase height of 'About' window [\#1737](https://github.com/webtorrent/webtorrent-desktop/pull/1737)
- Fix "Save Torrent File As..." [\#1743](https://github.com/webtorrent/webtorrent-desktop/pull/1743)
- Fix: Increase height of 'About' window [\#1737](https://github.com/webtorrent/webtorrent-desktop/pull/1737) ([akaustav](https://github.com/akaustav))
- Fix "Save Torrent File As..." [\#1743](https://github.com/webtorrent/webtorrent-desktop/pull/1743) ([gpatarin](https://github.com/gpatarin))
## v0.21.0 - 2019-09-14

View File

@@ -74,17 +74,29 @@
**This is the most important part.**
- Manually download the binaries for each platform from Github.
- Manually download the binaries for each platform from Github.
**Do not use your locally built binaries.** Modern OSs treat executables differently if they've
been downloaded, even though the files are byte for byte identical. This ensures that the
codesigning worked and is valid.
- Smoke test WebTorrent Desktop on each platform.
- Smoke test WebTorrent Desktop on each platform. Before a release, check that the following basic use cases work correctly:
See Smoke Tests below for details. Open DevTools
on Windows and Mac, and ensure that the auto updater is running. If the auto updater does not
run, users will successfully auto update to this new version, and then be stuck there forever.
1. Click "Play" to stream a built-in torrent (e.g. Sintel)
- Ensure that seeking to undownloaded region works and plays immediately.
- Ensure that sintel.mp4 gets downloaded to `~/Downloads`.
2. Check that the auto-updater works
- Open the console and check for the line "No update available" to indicate that the auto-updater is working. (If the auto updater does not run, users will successfully auto update to this new version, and then be stuck there forever.)
3. Add a new .torrent file via drag-and-drop.
- Ensure that it gets added to the list and starts downloading.
4. Remove a torrent from the client
- Ensure that the file is removed from `~/Downloads`
5. Create and seed a new a torrent via drag-and-drop.
- Ensure that the torrent gets created and seeding begins.
### 4. Ship it
@@ -93,25 +105,5 @@
Create a pull request in [webtorrent.io](https://github.com/webtorrent/webtorrent.io). Update
`config.js`, updating the desktop app version.
As soon as this PR is merged, Jenkins will automatically redeploy the WebTorrent website, and
Once this PR is merged and Feross redeploys the WebTorrent website,
hundreds of thousands of users around the world will start auto updating. **Merge with care.**
## Smoke Tests
Before a release, check that the following basic use cases work correctly:
1. Click "Play" to stream a built-in torrent (e.g. Sintel)
- Ensure that seeking to undownloaded region works and plays immediately.
- Ensure that sintel.mp4 gets downloaded to `~/Downloads`.
2. Check that the auto-updater works
- Open the console and check for the line "No update available" to indicate that the auto-updater is working.
3. Add a new .torrent file via drag-and-drop.
- Ensure that it gets added to the list and starts downloading.
4. Remove a torrent from the client
- Ensure that the file is removed from `~/Downloads`
5. Create and seed a new a torrent via drag-and-drop.
- Ensure that the torrent gets created and seeding begins.

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.debugger</key>
<true/>
</dict>
</plist>

View File

@@ -1,39 +0,0 @@
#!/usr/bin/env node
const walkSync = require('walk-sync')
const fs = require('fs')
const path = require('path')
let hasErrors = false
// Find all Javascript source files
const files = walkSync('src', { globs: ['**/*.js'] })
console.log('Running extra-lint on ' + files.length + ' files...')
// Read each file, line by line
files.forEach(function (file) {
const filepath = path.join('src', file)
const lines = fs.readFileSync(filepath, 'utf8').split('\n')
lines.forEach(function (line, i) {
let error
// No lines over 100 characters
if (line.length > 100) {
error = 'Line >100 chars'
}
if (line.match(/^var /) || line.match(/ var /)) {
error = 'Use const or let'
}
if (error) {
const name = path.basename(file)
console.log('%s:%d - %s:\n%s', name, i + 1, error, line)
hasErrors = true
}
})
})
if (hasErrors) process.exit(1)
else console.log('Looks good!')

View File

@@ -266,6 +266,7 @@ function buildDarwin (cb) {
function signApp (cb) {
const sign = require('electron-osx-sign')
const { notarize } = require('electron-notarize')
/*
* Sign the app with Apple Developer ID certificates. We sign the app for 2 reasons:
@@ -281,16 +282,37 @@ function buildDarwin (cb) {
* - Membership in the Apple Developer Program
*/
const signOpts = {
verbose: true,
app: appPath,
platform: 'darwin',
verbose: true
identity: 'Developer ID Application: WebTorrent, LLC (5MAMC8G3L8)',
hardenedRuntime: true,
entitlements: path.join(config.ROOT_PATH, 'bin', 'darwin-entitlements.plist'),
'entitlements-inherit': path.join(config.ROOT_PATH, 'bin', 'darwin-entitlements.plist'),
'signature-flags': 'library'
}
const notarizeOpts = {
appBundleId: darwin.appBundleId,
appPath,
appleId: 'feross@feross.org',
appleIdPassword: '@keychain:AC_PASSWORD'
}
console.log('Mac: Signing app...')
sign(signOpts, function (err) {
if (err) return cb(err)
console.log('Mac: Signed app.')
cb(null)
console.log('Mac: Notarizing app...')
notarize(notarizeOpts).then(
function () {
console.log('Mac: Notarized app.')
cb(null)
},
function (err) {
cb(err)
})
})
}
@@ -523,7 +545,17 @@ function buildLinux (cb) {
},
categories: ['Network', 'FileTransfer', 'P2P'],
mimeType: ['application/x-bittorrent', 'x-scheme-handler/magnet', 'x-scheme-handler/stream-magnet'],
desktopTemplate: path.join(config.STATIC_PATH, 'linux/webtorrent-desktop.ejs')
desktopTemplate: path.join(config.STATIC_PATH, 'linux/webtorrent-desktop.ejs'),
lintianOverrides: [
'unstripped-binary-or-object',
'embedded-library',
'missing-dependency-on-libc',
'changelog-file-missing-in-native-package',
'description-synopsis-is-duplicated',
'setuid-binary',
'binary-without-manpage',
'shlib-with-executable-bit'
]
}
installer(options).then(

9153
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +1,83 @@
{
"name": "webtorrent-desktop",
"description": "WebTorrent, the streaming torrent client. For Mac, Windows, and Linux.",
"version": "0.23.0",
"version": "0.24.0",
"author": {
"name": "WebTorrent, LLC",
"email": "feross@webtorrent.io",
"url": "https://webtorrent.io"
},
"babel": {
"plugins": [
[
"@babel/plugin-transform-react-jsx",
{
"useBuiltIns": true
}
]
]
},
"bugs": {
"url": "https://github.com/webtorrent/webtorrent-desktop/issues"
},
"dependencies": {
"airplayer": "github:webtorrent/airplayer#fix-security",
"application-config": "^2.0.0",
"arch": "^2.1.2",
"arch": "^2.2.0",
"auto-launch": "^5.0.5",
"bitfield": "^3.0.0",
"capture-frame": "^3.0.2",
"chokidar": "^3.4.1",
"bitfield": "^4.0.0",
"capture-frame": "^4.0.0",
"chokidar": "^3.4.3",
"chromecasts": "^1.9.1",
"create-torrent": "^4.4.2",
"debounce": "^1.2.0",
"dlnacasts": "^0.1.0",
"drag-drop": "^6.0.2",
"drag-drop": "^6.1.0",
"es6-error": "^4.1.1",
"fn-getter": "^1.0.0",
"iso-639-1": "^2.1.3",
"iso-639-1": "^2.1.4",
"languagedetect": "^2.0.0",
"location-history": "^1.1.2",
"material-ui": "^0.20.2",
"music-metadata": "6.3.6",
"music-metadata": "^7.5.0",
"network-address": "^1.1.2",
"parse-torrent": "^7.1.3",
"parse-torrent": "^9.1.0",
"prettier-bytes": "^1.0.4",
"prop-types": "^15.7.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"rimraf": "^3.0.2",
"run-parallel": "^1.1.9",
"run-parallel": "^1.1.10",
"semver": "^7.3.2",
"simple-concat": "^1.0.0",
"simple-concat": "^1.0.1",
"simple-get": "^4.0.0",
"srt-to-vtt": "^1.1.3",
"vlc-command": "^1.2.0",
"webtorrent": ">=0.108.6",
"webtorrent": ">=0.111.0",
"winreg": "^1.2.4"
},
"devDependencies": {
"babel-eslint": "^10.1.0",
"buble": "^0.20.0",
"cross-zip": "^3.1.0",
"depcheck": "^1.0.0",
"electron": "~9.1.0",
"electron-osx-sign": "^0.4.17",
"electron-packager": "^15.0.0",
"@babel/cli": "^7.12.8",
"@babel/core": "^7.12.9",
"@babel/eslint-parser": "^7.12.1",
"@babel/plugin-transform-react-jsx": "^7.12.7",
"cross-zip": "^4.0.0",
"depcheck": "^1.3.1",
"electron": "~11.0.3",
"electron-notarize": "^1.0.0",
"electron-osx-sign": "^0.5.0",
"electron-packager": "^15.1.0",
"electron-winstaller": "^4.0.1",
"gh-release": "^3.5.0",
"gh-release": "^4.0.3",
"minimist": "^1.2.5",
"nodemon": "^2.0.4",
"open": "^7.0.4",
"nodemon": "^2.0.6",
"open": "^7.3.0",
"plist": "^3.0.1",
"pngjs": "^5.0.0",
"run-series": "^1.1.8",
"spectron": "~11.0.0",
"pngjs": "^6.0.0",
"run-series": "^1.1.9",
"spectron": "~12.0.0",
"standard": "*",
"tape": "^5.0.1",
"walk-sync": "^2.2.0"
"tape": "^5.0.1"
},
"engines": {
"node": ">=4.0.0"
@@ -86,7 +98,7 @@
"optionalDependencies": {
"appdmg": "^0.6.0",
"electron-installer-debian": "^3.1.0",
"electron-installer-redhat": "^3.1.0"
"electron-installer-redhat": "^3.2.0"
},
"private": true,
"productName": "WebTorrent",
@@ -95,19 +107,19 @@
"url": "git://github.com/webtorrent/webtorrent-desktop.git"
},
"scripts": {
"build": "buble src --target chrome:71 --output build",
"build": "babel src --out-dir build",
"clean": "node ./bin/clean.js",
"gh-release": "gh-release",
"install-system-deps": "brew install fakeroot dpkg rpm",
"open-config": "node ./bin/open-config.js",
"package": "node ./bin/package.js",
"start": "npm run build && electron --no-sandbox .",
"test": "standard && depcheck --ignores=standard,babel-eslint --ignore-dirs=build,dist && node ./bin/extra-lint.js",
"test": "standard && depcheck --ignores=standard,@babel/eslint-parser --ignore-dirs=build,dist",
"test-integration": "npm run build && node ./test",
"update-authors": "./bin/update-authors.sh",
"watch": "nodemon --exec \"npm run start\" --ext js,css --ignore build/ --ignore dist/"
},
"standard": {
"parser": "babel-eslint"
"parser": "@babel/eslint-parser"
}
}

View File

@@ -1,6 +1,6 @@
const appConfig = require('application-config')('WebTorrent')
const path = require('path')
const electron = require('electron')
const { app, remote } = require('electron')
const arch = require('arch')
const APP_NAME = 'WebTorrent'
@@ -126,10 +126,10 @@ function getPath (key) {
return ''
} else if (process.type === 'renderer') {
// Electron renderer process
return electron.remote.app.getPath(key)
return remote.app.getPath(key)
} else {
// Electron main process
return electron.app.getPath(key)
return app.getPath(key)
}
}

View File

@@ -4,11 +4,12 @@ module.exports = {
function init () {
const config = require('./config')
const electron = require('electron')
const { crashReporter } = require('electron')
electron.crashReporter.start({
companyName: config.APP_NAME,
crashReporter.start({
productName: config.APP_NAME,
submitURL: config.CRASH_REPORT_URL
submitURL: config.CRASH_REPORT_URL,
globalExtra: { _companyName: config.APP_NAME },
compress: true
})
}

View File

@@ -2,7 +2,7 @@ module.exports = {
init
}
const electron = require('electron')
const { dialog } = require('electron')
const config = require('../config')
const log = require('./log')
@@ -44,7 +44,7 @@ function onResponse (err, res, data) {
}
}
electron.dialog.showMessageBox({
dialog.showMessageBox({
type: 'info',
buttons: ['OK'],
title: data.title,

View File

@@ -6,7 +6,7 @@ module.exports = {
openFiles
}
const electron = require('electron')
const { dialog } = require('electron')
const log = require('./log')
const windows = require('./windows')
@@ -34,13 +34,13 @@ function openSeedDirectory () {
log('openSeedDirectory')
const opts = process.platform === 'darwin'
? {
title: 'Select a file or folder for the torrent.',
properties: ['openFile', 'openDirectory']
}
title: 'Select a file or folder for the torrent.',
properties: ['openFile', 'openDirectory']
}
: {
title: 'Select a folder for the torrent.',
properties: ['openDirectory']
}
title: 'Select a folder for the torrent.',
properties: ['openDirectory']
}
showOpenSeed(opts)
}
@@ -53,15 +53,15 @@ function openFiles () {
log('openFiles')
const opts = process.platform === 'darwin'
? {
title: 'Select a file or folder to add.',
properties: ['openFile', 'openDirectory']
}
title: 'Select a file or folder to add.',
properties: ['openFile', 'openDirectory']
}
: {
title: 'Select a file to add.',
properties: ['openFile']
}
title: 'Select a file to add.',
properties: ['openFile']
}
setTitle(opts.title)
const selectedPaths = electron.dialog.showOpenDialogSync(windows.main.win, opts)
const selectedPaths = dialog.showOpenDialogSync(windows.main.win, opts)
resetTitle()
if (!Array.isArray(selectedPaths)) return
windows.main.dispatch('onOpen', selectedPaths)
@@ -79,7 +79,7 @@ function openTorrentFile () {
properties: ['openFile', 'multiSelections']
}
setTitle(opts.title)
const selectedPaths = electron.dialog.showOpenDialogSync(windows.main.win, opts)
const selectedPaths = dialog.showOpenDialogSync(windows.main.win, opts)
resetTitle()
if (!Array.isArray(selectedPaths)) return
selectedPaths.forEach(function (selectedPath) {
@@ -114,7 +114,7 @@ function resetTitle () {
*/
function showOpenSeed (opts) {
setTitle(opts.title)
const selectedPaths = electron.dialog.showOpenDialogSync(windows.main.win, opts)
const selectedPaths = dialog.showOpenDialogSync(windows.main.win, opts)
resetTitle()
if (!Array.isArray(selectedPaths)) return
windows.main.dispatch('showCreateTorrent', selectedPaths)

View File

@@ -17,12 +17,12 @@ let proc = null
function checkInstall (playerPath, cb) {
// check for VLC if external player has not been specified by the user
// otherwise assume the player is installed
if (playerPath == null) return vlcCommand(cb)
if (!playerPath) return vlcCommand(cb)
process.nextTick(() => cb(null))
}
function spawn (playerPath, url, title) {
if (playerPath != null) return spawnExternal(playerPath, [url])
if (playerPath) return spawnExternal(playerPath, [url])
// Try to find and use VLC if external player is not specified
vlcCommand((err, vlcPath) => {

View File

@@ -25,8 +25,7 @@ function uninstall () {
}
function installDarwin () {
const electron = require('electron')
const app = electron.app
const { app } = require('electron')
// On Mac, only protocols that are listed in `Info.plist` can be set as the
// default handler at runtime.

View File

@@ -1,12 +1,14 @@
console.time('init')
const electron = require('electron')
const app = electron.app
const { app, ipcMain } = require('electron')
// Start crash reporter early, so it takes effect for child processes
const crashReporter = require('../crash-reporter')
crashReporter.init()
const parallel = require('run-parallel')
const config = require('../config')
const crashReporter = require('../crash-reporter')
const ipc = require('./ipc')
const log = require('./log')
const menu = require('./menu')
@@ -64,8 +66,6 @@ function init () {
app.setPath('temp', path.join(config.CONFIG_PATH, 'Temp'))
}
const ipcMain = electron.ipcMain
let isReady = false // app ready, windows can be created
app.ipcReady = false // main window has finished loading and IPC is ready
app.isQuitting = false
@@ -109,10 +109,6 @@ function init () {
ipc.init()
app.once('will-finish-launching', function () {
crashReporter.init()
})
app.once('ipcReady', function () {
log('Command line args:', argv)
processArgv(argv)
@@ -199,9 +195,13 @@ function onAppOpen (newArgv) {
// Development: 2 args, eg: electron .
// Test: 4 args, eg: electron -r .../mocks.js .
function sliceArgv (argv) {
return argv.slice(config.IS_PRODUCTION ? 1
: config.IS_TEST ? 4
: 2)
return argv.slice(
config.IS_PRODUCTION
? 1
: config.IS_TEST
? 4
: 2
)
}
function processArgv (argv) {

View File

@@ -3,9 +3,7 @@ module.exports = {
setModule
}
const electron = require('electron')
const app = electron.app
const { app, ipcMain } = require('electron')
const log = require('./log')
const menu = require('./menu')
@@ -23,14 +21,12 @@ function setModule (name, module) {
}
function init () {
const ipc = electron.ipcMain
ipc.once('ipcReady', function (e) {
ipcMain.once('ipcReady', function (e) {
app.ipcReady = true
app.emit('ipcReady')
})
ipc.once('ipcReadyWebTorrent', function (e) {
ipcMain.once('ipcReadyWebTorrent', function (e) {
app.ipcReadyWebTorrent = true
log('sending %d queued messages from the main win to the webtorrent window',
messageQueueMainToWebTorrent.length)
@@ -44,11 +40,11 @@ function init () {
* Dialog
*/
ipc.on('openTorrentFile', () => {
ipcMain.on('openTorrentFile', () => {
const dialog = require('./dialog')
dialog.openTorrentFile()
})
ipc.on('openFiles', () => {
ipcMain.on('openFiles', () => {
const dialog = require('./dialog')
dialog.openFiles()
})
@@ -57,11 +53,11 @@ function init () {
* Dock
*/
ipc.on('setBadge', (e, ...args) => {
ipcMain.on('setBadge', (e, ...args) => {
const dock = require('./dock')
dock.setBadge(...args)
})
ipc.on('downloadFinished', (e, ...args) => {
ipcMain.on('downloadFinished', (e, ...args) => {
const dock = require('./dock')
dock.downloadFinished(...args)
})
@@ -70,7 +66,7 @@ function init () {
* Player Events
*/
ipc.on('onPlayerOpen', function () {
ipcMain.on('onPlayerOpen', function () {
const powerSaveBlocker = require('./power-save-blocker')
const shortcuts = require('./shortcuts')
const thumbar = require('./thumbar')
@@ -81,14 +77,14 @@ function init () {
thumbar.enable()
})
ipc.on('onPlayerUpdate', function (e, ...args) {
ipcMain.on('onPlayerUpdate', function (e, ...args) {
const thumbar = require('./thumbar')
menu.onPlayerUpdate(...args)
thumbar.onPlayerUpdate(...args)
})
ipc.on('onPlayerClose', function () {
ipcMain.on('onPlayerClose', function () {
const powerSaveBlocker = require('./power-save-blocker')
const shortcuts = require('./shortcuts')
const thumbar = require('./thumbar')
@@ -99,7 +95,7 @@ function init () {
thumbar.disable()
})
ipc.on('onPlayerPlay', function () {
ipcMain.on('onPlayerPlay', function () {
const powerSaveBlocker = require('./power-save-blocker')
const thumbar = require('./thumbar')
@@ -107,7 +103,7 @@ function init () {
thumbar.onPlayerPlay()
})
ipc.on('onPlayerPause', function () {
ipcMain.on('onPlayerPause', function () {
const powerSaveBlocker = require('./power-save-blocker')
const thumbar = require('./thumbar')
@@ -119,7 +115,7 @@ function init () {
* Folder Watcher Events
*/
ipc.on('startFolderWatcher', function () {
ipcMain.on('startFolderWatcher', function () {
if (!modules.folderWatcher) {
log('IPC ERR: folderWatcher module is not defined.')
return
@@ -128,7 +124,7 @@ function init () {
modules.folderWatcher.start()
})
ipc.on('stopFolderWatcher', function () {
ipcMain.on('stopFolderWatcher', function () {
if (!modules.folderWatcher) {
log('IPC ERR: folderWatcher module is not defined.')
return
@@ -141,15 +137,15 @@ function init () {
* Shell
*/
ipc.on('openPath', (e, ...args) => {
ipcMain.on('openPath', (e, ...args) => {
const shell = require('./shell')
shell.openPath(...args)
})
ipc.on('showItemInFolder', (e, ...args) => {
ipcMain.on('showItemInFolder', (e, ...args) => {
const shell = require('./shell')
shell.showItemInFolder(...args)
})
ipc.on('moveItemToTrash', (e, ...args) => {
ipcMain.on('moveItemToTrash', (e, ...args) => {
const shell = require('./shell')
shell.moveItemToTrash(...args)
})
@@ -158,7 +154,7 @@ function init () {
* File handlers
*/
ipc.on('setDefaultFileHandler', (e, flag) => {
ipcMain.on('setDefaultFileHandler', (e, flag) => {
const handlers = require('./handlers')
if (flag) handlers.install()
@@ -169,7 +165,7 @@ function init () {
* Auto start on login
*/
ipc.on('setStartup', (e, flag) => {
ipcMain.on('setStartup', (e, flag) => {
const startup = require('./startup')
if (flag) startup.install()
@@ -182,19 +178,19 @@ function init () {
const main = windows.main
ipc.on('setAspectRatio', (e, ...args) => main.setAspectRatio(...args))
ipc.on('setBounds', (e, ...args) => main.setBounds(...args))
ipc.on('setProgress', (e, ...args) => main.setProgress(...args))
ipc.on('setTitle', (e, ...args) => main.setTitle(...args))
ipc.on('show', () => main.show())
ipc.on('toggleFullScreen', (e, ...args) => main.toggleFullScreen(...args))
ipc.on('setAllowNav', (e, ...args) => menu.setAllowNav(...args))
ipcMain.on('setAspectRatio', (e, ...args) => main.setAspectRatio(...args))
ipcMain.on('setBounds', (e, ...args) => main.setBounds(...args))
ipcMain.on('setProgress', (e, ...args) => main.setProgress(...args))
ipcMain.on('setTitle', (e, ...args) => main.setTitle(...args))
ipcMain.on('show', () => main.show())
ipcMain.on('toggleFullScreen', (e, ...args) => main.toggleFullScreen(...args))
ipcMain.on('setAllowNav', (e, ...args) => menu.setAllowNav(...args))
/**
* External Media Player
*/
ipc.on('checkForExternalPlayer', function (e, path) {
ipcMain.on('checkForExternalPlayer', function (e, path) {
const externalPlayer = require('./external-player')
externalPlayer.checkInstall(path, function (err) {
@@ -202,7 +198,7 @@ function init () {
})
})
ipc.on('openExternalPlayer', (e, ...args) => {
ipcMain.on('openExternalPlayer', (e, ...args) => {
const externalPlayer = require('./external-player')
const thumbar = require('./thumbar')
@@ -211,7 +207,7 @@ function init () {
externalPlayer.spawn(...args)
})
ipc.on('quitExternalPlayer', () => {
ipcMain.on('quitExternalPlayer', () => {
const externalPlayer = require('./external-player')
externalPlayer.kill()
})
@@ -220,8 +216,8 @@ function init () {
* Message passing
*/
const oldEmit = ipc.emit
ipc.emit = function (name, e, ...args) {
const oldEmit = ipcMain.emit
ipcMain.emit = function (name, e, ...args) {
// Relay messages between the main window and the WebTorrent hidden window
if (name.startsWith('wt-') && !app.isQuitting) {
if (e.sender.browserWindowOptions.title === 'webtorrent-hidden-window') {
@@ -244,6 +240,6 @@ function init () {
}
// Emit all other events normally
oldEmit.call(ipc, name, e, ...args)
oldEmit.call(ipcMain, name, e, ...args)
}
}

View File

@@ -8,11 +8,9 @@ module.exports.error = error
* where they can be viewed in Developer Tools.
*/
const electron = require('electron')
const { app } = require('electron')
const windows = require('./windows')
const app = electron.app
function log (...args) {
if (app.ipcReady) {
windows.main.send('log', ...args)

View File

@@ -8,9 +8,7 @@ module.exports = {
onToggleFullScreen
}
const electron = require('electron')
const app = electron.app
const { app, Menu } = require('electron')
const config = require('../config')
const windows = require('./windows')
@@ -18,8 +16,8 @@ const windows = require('./windows')
let menu = null
function init () {
menu = electron.Menu.buildFromTemplate(getMenuTemplate())
electron.Menu.setApplicationMenu(menu)
menu = Menu.buildFromTemplate(getMenuTemplate())
Menu.setApplicationMenu(menu)
}
function togglePlaybackControls (flag) {

View File

@@ -3,7 +3,7 @@ module.exports = {
disable
}
const electron = require('electron')
const { powerSaveBlocker } = require('electron')
const log = require('./log')
let blockId = 0
@@ -13,11 +13,11 @@ let blockId = 0
* display.
*/
function enable () {
if (electron.powerSaveBlocker.isStarted(blockId)) {
if (powerSaveBlocker.isStarted(blockId)) {
// If a power saver block already exists, do nothing.
return
}
blockId = electron.powerSaveBlocker.start('prevent-display-sleep')
blockId = powerSaveBlocker.start('prevent-display-sleep')
log(`powerSaveBlocker.enable: ${blockId}`)
}
@@ -25,10 +25,10 @@ function enable () {
* Stop blocking the system from entering low-power mode.
*/
function disable () {
if (!electron.powerSaveBlocker.isStarted(blockId)) {
if (!powerSaveBlocker.isStarted(blockId)) {
// If a power saver block does not exist, do nothing.
return
}
electron.powerSaveBlocker.stop(blockId)
powerSaveBlocker.stop(blockId)
log(`powerSaveBlocker.disable: ${blockId}`)
}

View File

@@ -5,7 +5,7 @@ module.exports = {
moveItemToTrash
}
const electron = require('electron')
const { shell } = require('electron')
const log = require('./log')
/**
@@ -13,15 +13,16 @@ const log = require('./log')
*/
function openExternal (url) {
log(`openExternal: ${url}`)
electron.shell.openExternal(url)
shell.openExternal(url)
}
/**
* Open the given file in the desktops default manner.
*/
function openPath (path) {
log(`openPath: ${path}`)
electron.shell.openPath(path)
shell.openPath(path)
}
/**
@@ -29,7 +30,7 @@ function openPath (path) {
*/
function showItemInFolder (path) {
log(`showItemInFolder: ${path}`)
electron.shell.showItemInFolder(path)
shell.showItemInFolder(path)
}
/**
@@ -37,5 +38,5 @@ function showItemInFolder (path) {
*/
function moveItemToTrash (path) {
log(`moveItemToTrash: ${path}`)
electron.shell.moveItemToTrash(path)
shell.moveItemToTrash(path)
}

View File

@@ -3,20 +3,20 @@ module.exports = {
enable
}
const electron = require('electron')
const { globalShortcut } = require('electron')
const windows = require('./windows')
function enable () {
// Register play/pause media key, available on some keyboards.
electron.globalShortcut.register(
globalShortcut.register(
'MediaPlayPause',
() => windows.main.dispatch('playPause')
)
electron.globalShortcut.register(
globalShortcut.register(
'MediaNextTrack',
() => windows.main.dispatch('nextTrack')
)
electron.globalShortcut.register(
globalShortcut.register(
'MediaPreviousTrack',
() => windows.main.dispatch('previousTrack')
)
@@ -24,7 +24,7 @@ function enable () {
function disable () {
// Return the media key to the OS, so other apps can use it.
electron.globalShortcut.unregister('MediaPlayPause')
electron.globalShortcut.unregister('MediaNextTrack')
electron.globalShortcut.unregister('MediaPreviousTrack')
globalShortcut.unregister('MediaPlayPause')
globalShortcut.unregister('MediaNextTrack')
globalShortcut.unregister('MediaPreviousTrack')
}

View File

@@ -2,150 +2,39 @@ module.exports = {
handleEvent
}
const cp = require('child_process')
const electron = require('electron')
const fs = require('fs')
const os = require('os')
const path = require('path')
const { app } = require('electron')
const app = electron.app
const path = require('path')
const spawn = require('child_process').spawn
const handlers = require('./handlers')
const EXE_NAME = path.basename(process.execPath)
const UPDATE_EXE = path.join(process.execPath, '..', '..', 'Update.exe')
function handleEvent (cmd) {
if (cmd === '--squirrel-install') {
// App was installed. Install desktop/start menu shortcuts.
createShortcuts(function () {
// Ensure user sees install splash screen so they realize that Setup.exe actually
// installed an application and isn't the application itself.
setTimeout(function () {
app.quit()
}, 3000)
})
return true
}
const run = function (args, done) {
spawn(UPDATE_EXE, args, { detached: true })
.on('close', done)
}
if (cmd === '--squirrel-updated') {
// App was updated. (Called on new version of app)
updateShortcuts(function () {
app.quit()
})
function handleEvent (cmd) {
if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') {
run([`--createShortcut=${EXE_NAME}`], app.quit)
return true
}
if (cmd === '--squirrel-uninstall') {
// App was just uninstalled. Undo anything we did in the --squirrel-install and
// --squirrel-updated handlers
// Uninstall .torrent file and magnet link handlers
handlers.uninstall()
// Remove desktop/start menu shortcuts.
// HACK: add a callback to handlers.uninstall() so we can remove this setTimeout
setTimeout(function () {
removeShortcuts(function () {
app.quit()
})
}, 1000)
run([`--removeShortcut=${EXE_NAME}`], app.quit)
return true
}
if (cmd === '--squirrel-obsolete') {
// App will be updated. (Called on outgoing version of app)
app.quit()
return true
}
if (cmd === '--squirrel-firstrun') {
// App is running for the first time. Do not quit, allow startup to continue.
return false
}
return false
}
/**
* Spawn a command and invoke the callback when it completes with an error and
* the output from standard out.
*/
function spawn (command, args, cb) {
let stdout = ''
let error = null
let child = null
try {
child = cp.spawn(command, args)
} catch (err) {
// Spawn can throw an error
process.nextTick(function () {
cb(error, stdout)
})
return
}
child.stdout.on('data', function (data) {
stdout += data
})
child.on('error', function (processError) {
error = processError
})
child.on('close', function (code, signal) {
if (code !== 0 && !error) error = new Error('Command failed: #{signal || code}')
if (error) error.stdout = stdout
cb(error, stdout)
})
}
/**
* Spawn the Squirrel `Update.exe` command with the given arguments and invoke
* the callback when the command completes.
*/
function spawnUpdate (args, cb) {
spawn(UPDATE_EXE, args, cb)
}
/**
* Create desktop and start menu shortcuts using the Squirrel `Update.exe`
* command.
*/
function createShortcuts (cb) {
spawnUpdate(['--createShortcut', EXE_NAME], cb)
}
/**
* Update desktop and start menu shortcuts using the Squirrel `Update.exe`
* command.
*/
function updateShortcuts (cb) {
const homeDir = os.homedir()
if (homeDir) {
const desktopShortcutPath = path.join(homeDir, 'Desktop', 'WebTorrent.lnk')
// If the desktop shortcut was deleted by the user, then keep it deleted.
fs.access(desktopShortcutPath, function (err) {
const desktopShortcutExists = !err
createShortcuts(function () {
if (desktopShortcutExists) {
cb()
} else {
// Remove the unwanted desktop shortcut that was recreated
fs.unlink(desktopShortcutPath, cb)
}
})
})
} else {
createShortcuts(cb)
}
}
/**
* Remove desktop and start menu shortcuts using the Squirrel `Update.exe`
* command.
*/
function removeShortcuts (cb) {
spawnUpdate(['--removeShortcut', EXE_NAME], cb)
}

View File

@@ -4,9 +4,7 @@ module.exports = {
setWindowFocus
}
const electron = require('electron')
const app = electron.app
const { app, Tray, Menu } = require('electron')
const config = require('../config')
const windows = require('./windows')
@@ -67,7 +65,7 @@ function checkLinuxTraySupport (cb) {
}
function createTray () {
tray = new electron.Tray(getIconPath())
tray = new Tray(getIconPath())
// On Windows, left click opens the app, right click opens the context menu.
// On Linux, any click (left or right) opens the context menu.
@@ -78,7 +76,7 @@ function createTray () {
}
function updateTrayMenu () {
const contextMenu = electron.Menu.buildFromTemplate(getMenuTemplate())
const contextMenu = Menu.buildFromTemplate(getMenuTemplate())
tray.setContextMenu(contextMenu)
}

View File

@@ -2,7 +2,7 @@ module.exports = {
init
}
const electron = require('electron')
const { autoUpdater } = require('electron')
const get = require('simple-get')
const config = require('../config')
@@ -47,31 +47,31 @@ function onResponse (err, res, data) {
}
function initDarwinWin32 () {
electron.autoUpdater.on(
autoUpdater.on(
'error',
(err) => log.error(`Update error: ${err.message}`)
)
electron.autoUpdater.on(
autoUpdater.on(
'checking-for-update',
() => log('Checking for update')
)
electron.autoUpdater.on(
autoUpdater.on(
'update-available',
() => log('Update available')
)
electron.autoUpdater.on(
autoUpdater.on(
'update-not-available',
() => log('No update available')
)
electron.autoUpdater.on(
autoUpdater.on(
'update-downloaded',
(e, notes, name, date, url) => log(`Update downloaded: ${name}: ${url}`)
)
electron.autoUpdater.setFeedURL({ url: AUTO_UPDATE_URL })
electron.autoUpdater.checkForUpdates()
autoUpdater.setFeedURL({ url: AUTO_UPDATE_URL })
autoUpdater.checkForUpdates()
}

View File

@@ -2,9 +2,7 @@ module.exports = {
init
}
const electron = require('electron')
const app = electron.app
const { app } = require('electron')
/**
* Add a user task menu to the app icon on right-click. (Windows)

View File

@@ -4,14 +4,14 @@ const about = module.exports = {
}
const config = require('../../config')
const electron = require('electron')
const { BrowserWindow } = require('electron')
function init () {
if (about.win) {
return about.win.show()
}
const win = about.win = new electron.BrowserWindow({
const win = about.win = new BrowserWindow({
backgroundColor: '#ECECEC',
center: true,
fullscreen: false,
@@ -26,7 +26,9 @@ function init () {
useContentSize: true,
webPreferences: {
nodeIntegration: true,
enableBlinkFeatures: 'AudioVideoTracks'
enableBlinkFeatures: 'AudioVideoTracks',
enableRemoteModule: true,
backgroundThrottling: false
},
width: 300
})

View File

@@ -14,11 +14,9 @@ const main = module.exports = {
win: null
}
const electron = require('electron')
const { app, BrowserWindow, screen } = require('electron')
const debounce = require('debounce')
const app = electron.app
const config = require('../../config')
const log = require('../log')
const menu = require('../menu')
@@ -30,7 +28,7 @@ function init (state, options) {
const initialBounds = Object.assign(config.WINDOW_INITIAL_BOUNDS, state.saved.bounds)
const win = main.win = new electron.BrowserWindow({
const win = main.win = new BrowserWindow({
backgroundColor: '#282828',
darkTheme: true, // Forces dark theme (GTK+3)
height: initialBounds.height,
@@ -44,7 +42,9 @@ function init (state, options) {
width: initialBounds.width,
webPreferences: {
nodeIntegration: true,
enableBlinkFeatures: 'AudioVideoTracks'
enableBlinkFeatures: 'AudioVideoTracks',
enableRemoteModule: true,
backgroundThrottling: false
},
x: initialBounds.x,
y: initialBounds.y
@@ -160,7 +160,7 @@ function setBounds (bounds, maximize) {
log(`setBounds: setting bounds to ${JSON.stringify(bounds)}`)
if (bounds.x === null && bounds.y === null) {
// X and Y not specified? By default, center on current screen
const scr = electron.screen.getDisplayMatching(main.win.getBounds())
const scr = screen.getDisplayMatching(main.win.getBounds())
bounds.x = Math.round(scr.bounds.x + (scr.bounds.width / 2) - (bounds.width / 2))
bounds.y = Math.round(scr.bounds.y + (scr.bounds.height / 2) - (bounds.height / 2))
log(`setBounds: centered to ${JSON.stringify(bounds)}`)

View File

@@ -6,12 +6,12 @@ const webtorrent = module.exports = {
win: null
}
const electron = require('electron')
const { app, BrowserWindow } = require('electron')
const config = require('../../config')
function init () {
const win = webtorrent.win = new electron.BrowserWindow({
const win = webtorrent.win = new BrowserWindow({
backgroundColor: '#1E1E1E',
center: true,
fullscreen: false,
@@ -26,7 +26,9 @@ function init () {
useContentSize: true,
webPreferences: {
nodeIntegration: true,
enableBlinkFeatures: 'AudioVideoTracks'
enableBlinkFeatures: 'AudioVideoTracks',
enableRemoteModule: true,
backgroundThrottling: false
},
width: 150
})
@@ -35,7 +37,7 @@ function init () {
// Prevent killing the WebTorrent process
win.on('close', function (e) {
if (electron.app.isQuitting) {
if (app.isQuitting) {
return
}
e.preventDefault()

View File

@@ -1,12 +1,10 @@
const path = require('path')
const colors = require('material-ui/styles/colors')
const electron = require('electron')
const { remote } = require('electron')
const React = require('react')
const PropTypes = require('prop-types')
const remote = electron.remote
const RaisedButton = require('material-ui/RaisedButton').default
const TextField = require('material-ui/TextField').default

View File

@@ -1,5 +1,5 @@
const React = require('react')
const electron = require('electron')
const { shell } = require('electron')
const ModalOKCancel = require('./modal-ok-cancel')
const { dispatcher } = require('../lib/dispatcher')
@@ -36,7 +36,7 @@ module.exports = class UnsupportedMediaModal extends React.Component {
}
onInstall () {
electron.shell.openExternal('http://www.videolan.org/vlc/')
shell.openExternal('http://www.videolan.org/vlc/')
// TODO: dcposch send a dispatch rather than modifying state directly
const state = this.props.state

View File

@@ -1,5 +1,5 @@
const React = require('react')
const electron = require('electron')
const { shell } = require('electron')
const ModalOKCancel = require('./modal-ok-cancel')
const { dispatch } = require('../lib/dispatcher')
@@ -25,7 +25,7 @@ module.exports = class UpdateAvailableModal extends React.Component {
function handleShow () {
// TODO: use the GitHub urls from config.js
electron.shell.openExternal('https://github.com/webtorrent/webtorrent-desktop/releases')
shell.openExternal('https://github.com/webtorrent/webtorrent-desktop/releases')
dispatch('exitModal')
}

View File

@@ -1,4 +1,4 @@
const electron = require('electron')
const { ipcRenderer } = require('electron')
const path = require('path')
const Cast = require('../lib/cast')
@@ -11,8 +11,6 @@ const TorrentSummary = require('../lib/torrent-summary')
const Playlist = require('../lib/playlist')
const State = require('../lib/state')
const ipcRenderer = electron.ipcRenderer
// Controls playback of torrents and files within torrents
// both local (<video>,<audio>,external player) and remote (cast)
module.exports = class PlaybackController {
@@ -158,6 +156,20 @@ module.exports = class PlaybackController {
else this.state.playing.jumpToTime = time
}
// Show video preview
preview (x) {
if (!Number.isFinite(x)) {
console.error('Tried to preview a non-finite position ' + x)
return console.trace()
}
this.state.playing.previewXCoord = x
}
// Hide video preview
clearPreview () {
this.state.playing.previewXCoord = null
}
// Change playback speed. 1 = faster, -1 = slower
// Playback speed ranges from 16 (fast forward) to 1 (normal playback)
// to 0.25 (quarter-speed playback), then goes to -0.25, -0.5, -1, -2, etc
@@ -270,8 +282,10 @@ module.exports = class PlaybackController {
state.playing.infoHash = infoHash
state.playing.fileIndex = index
state.playing.fileName = fileSummary.name
state.playing.type = TorrentPlayer.isVideo(fileSummary) ? 'video'
: TorrentPlayer.isAudio(fileSummary) ? 'audio'
state.playing.type = TorrentPlayer.isVideo(fileSummary)
? 'video'
: TorrentPlayer.isAudio(fileSummary)
? 'audio'
: 'other'
// pick up where we left off

View File

@@ -1,5 +1,5 @@
const { dispatch } = require('../lib/dispatcher')
const ipcRenderer = require('electron').ipcRenderer
const { ipcRenderer } = require('electron')
// Controls the Preferences screen
module.exports = class PrefsController {

View File

@@ -1,10 +1,8 @@
const electron = require('electron')
const { remote } = require('electron')
const fs = require('fs')
const path = require('path')
const parallel = require('run-parallel')
const remote = electron.remote
const { dispatch } = require('../lib/dispatcher')
module.exports = class SubtitlesController {

View File

@@ -1,5 +1,5 @@
const path = require('path')
const ipcRenderer = require('electron').ipcRenderer
const { ipcRenderer } = require('electron')
const TorrentSummary = require('../lib/torrent-summary')
const sound = require('../lib/sound')

View File

@@ -1,14 +1,12 @@
const fs = require('fs')
const path = require('path')
const electron = require('electron')
const { ipcRenderer, remote, clipboard } = require('electron')
const { dispatch } = require('../lib/dispatcher')
const { TorrentKeyNotFoundError } = require('../lib/errors')
const sound = require('../lib/sound')
const TorrentSummary = require('../lib/torrent-summary')
const ipcRenderer = electron.ipcRenderer
const instantIoRegex = /^(https:\/\/)?instant\.io\/#/
// Controls the torrent list: creating, adding, deleting, & manipulating torrents
@@ -160,7 +158,7 @@ module.exports = class TorrentListController {
.filter((torrent) => { // We're interested in active torrents only.
return (['downloading', 'seeding'].indexOf(torrent.status) !== -1)
})
.map((torrent) => { // Pause all active torrents except the one that started playing.
.forEach((torrent) => { // Pause all active torrents except the one that started playing.
if (infoHash === torrent.infoHash) return
// Pause torrent without playing sounds.
@@ -175,7 +173,7 @@ module.exports = class TorrentListController {
resumePausedTorrents () {
console.log('Playback Priority: resuming paused torrents')
if (!this.state.saved.torrentsToResume || !this.state.saved.torrentsToResume.length) return
this.state.saved.torrentsToResume.map((infoHash) => {
this.state.saved.torrentsToResume.forEach((infoHash) => {
this.toggleTorrent(infoHash)
})
@@ -249,59 +247,59 @@ module.exports = class TorrentListController {
openTorrentContextMenu (infoHash) {
const torrentSummary = TorrentSummary.getByKey(this.state, infoHash)
const menu = new electron.remote.Menu()
const menu = new remote.Menu()
menu.append(new electron.remote.MenuItem({
menu.append(new remote.MenuItem({
label: 'Remove From List',
click: () => dispatch('confirmDeleteTorrent', torrentSummary.infoHash, false)
}))
menu.append(new electron.remote.MenuItem({
menu.append(new remote.MenuItem({
label: 'Remove Data File',
click: () => dispatch('confirmDeleteTorrent', torrentSummary.infoHash, true)
}))
menu.append(new electron.remote.MenuItem({
menu.append(new remote.MenuItem({
type: 'separator'
}))
if (torrentSummary.files) {
menu.append(new electron.remote.MenuItem({
menu.append(new remote.MenuItem({
label: process.platform === 'darwin' ? 'Show in Finder' : 'Show in Folder',
click: () => showItemInFolder(torrentSummary)
}))
menu.append(new electron.remote.MenuItem({
menu.append(new remote.MenuItem({
type: 'separator'
}))
}
menu.append(new electron.remote.MenuItem({
menu.append(new remote.MenuItem({
label: 'Copy Magnet Link to Clipboard',
click: () => electron.clipboard.writeText(torrentSummary.magnetURI)
click: () => clipboard.writeText(torrentSummary.magnetURI)
}))
menu.append(new electron.remote.MenuItem({
menu.append(new remote.MenuItem({
label: 'Copy Instant.io Link to Clipboard',
click: () => electron.clipboard.writeText(`https://instant.io/#${torrentSummary.infoHash}`)
click: () => clipboard.writeText(`https://instant.io/#${torrentSummary.infoHash}`)
}))
menu.append(new electron.remote.MenuItem({
menu.append(new remote.MenuItem({
label: 'Save Torrent File As...',
click: () => dispatch('saveTorrentFileAs', torrentSummary.torrentKey),
enabled: torrentSummary.torrentFileName != null
}))
menu.append(new electron.remote.MenuItem({
menu.append(new remote.MenuItem({
type: 'separator'
}))
const sortedByName = this.state.saved.prefs.sortByName
menu.append(new electron.remote.MenuItem({
menu.append(new remote.MenuItem({
label: `${sortedByName ? '✓ ' : ''}Sort by Name`,
click: () => dispatch('updatePreferences', 'sortByName', !sortedByName)
}))
menu.popup({ window: electron.remote.getCurrentWindow() })
menu.popup({ window: remote.getCurrentWindow() })
}
// Takes a torrentSummary or torrentKey
@@ -311,7 +309,7 @@ module.exports = class TorrentListController {
if (!torrentSummary) throw new TorrentKeyNotFoundError(torrentKey)
const downloadPath = this.state.saved.prefs.downloadPath
const newFileName = path.parse(torrentSummary.name).name + '.torrent'
const win = electron.remote.getCurrentWindow()
const win = remote.getCurrentWindow()
const opts = {
title: 'Save Torrent File',
defaultPath: path.join(downloadPath, newFileName),
@@ -322,7 +320,7 @@ module.exports = class TorrentListController {
buttonLabel: 'Save'
}
const savePath = electron.remote.dialog.showSaveDialogSync(win, opts)
const savePath = remote.dialog.showSaveDialogSync(win, opts)
if (!savePath) return // They clicked Cancel
console.log('Saving torrent ' + torrentKey + ' to ' + savePath)

View File

@@ -5,7 +5,7 @@ const mediaExtensions = {
'.ogg', '.opus', '.spx', '.wma', '.wav', '.wv', '.wvp'],
video: [
'.avi', '.mp4', '.m4v', '.webm', '.mov', '.mkv', '.mpg', '.mpeg',
'.ogv', '.webm', '.wmv'],
'.ogv', '.webm', '.wmv', '.m2ts'],
image: ['.gif', '.jpg', '.jpeg', '.png']
}

View File

@@ -7,7 +7,7 @@ module.exports = {
logPlayAttempt
}
const electron = require('electron')
const { remote } = require('electron')
const config = require('../../config')
@@ -74,7 +74,7 @@ function reset () {
// Track screen resolution
function getScreenInfo () {
return electron.remote.screen.getAllDisplays().map((screen) => ({
return remote.screen.getAllDisplays().map((screen) => ({
width: screen.size.width,
height: screen.size.height,
scaleFactor: screen.scaleFactor

View File

@@ -166,7 +166,8 @@ function torrentPosterFromVideo (torrent, cb) {
function onSeeked () {
video.removeEventListener('seeked', onSeeked)
const buf = captureFrame(video)
const frame = captureFrame(video)
const buf = frame && frame.image
// unload video element
video.pause()

View File

@@ -14,9 +14,6 @@ Module.prototype.require = function (id) {
console.time('init')
const crashReporter = require('../crash-reporter')
crashReporter.init()
// Perf optimization: Start asynchronously read on config file before all the
// blocking require() calls below.
@@ -133,7 +130,10 @@ function onState (err, _state) {
resumeTorrents()
// Initialize ReactDOM
app = ReactDOM.render(<App state={state} />, document.querySelector('#body'))
ReactDOM.render(
<App state={state} ref={elem => { app = elem }} />,
document.querySelector('#body')
)
// Calling update() updates the UI given the current state
// Do this at least once a second to give every file in every torrentSummary
@@ -277,6 +277,8 @@ const dispatchHandlers = {
previousTrack: () => controllers.playback().previousTrack(),
skip: (time) => controllers.playback().skip(time),
skipTo: (time) => controllers.playback().skipTo(time),
preview: (x) => controllers.playback().preview(x),
clearPreview: () => controllers.playback().clearPreview(),
changePlaybackRate: (dir) => controllers.playback().changePlaybackRate(dir),
changeVolume: (delta) => controllers.playback().changeVolume(delta),
setVolume: (vol) => controllers.playback().setVolume(vol),
@@ -524,6 +526,9 @@ function onPaste (e) {
}
function onKeydown (e) {
// prevent event fire on user input elements
if (editableHtmlTags.has(e.target.tagName.toLowerCase())) return
const key = e.key
if (key === 'ArrowLeft') {

View File

@@ -1,5 +1,5 @@
const React = require('react')
const Bitfield = require('bitfield')
const BitField = require('bitfield').default
const prettyBytes = require('prettier-bytes')
const TorrentSummary = require('../lib/torrent-summary')
@@ -427,22 +427,77 @@ function renderCastScreen (state) {
const isStarting = state.playing.location.endsWith('-pending')
const castName = state.playing.castName
const fileName = state.getPlayingFileSummary().name || ''
let castStatus
if (isCast && isStarting) castStatus = 'Connecting to ' + castName + '...'
else if (isCast && !isStarting) castStatus = 'Connected to ' + castName
else castStatus = ''
const prog = state.getPlayingTorrentSummary().progress || {}
// Show a nice title image, if possible
const style = {
backgroundImage: cssBackgroundImagePoster(state)
}
function renderEta (total, downloaded) {
const missing = (total || 0) - (downloaded || 0)
const downloadSpeed = prog.downloadSpeed || 0
if (downloadSpeed === 0 || missing === 0) return
const rawEta = missing / downloadSpeed
const hours = Math.floor(rawEta / 3600) % 24
const minutes = Math.floor(rawEta / 60) % 60
const seconds = Math.floor(rawEta % 60)
const hoursStr = hours ? hours + 'h' : ''
const minutesStr = (hours || minutes) ? minutes + 'm' : ''
const secondsStr = seconds + 's'
return (<span>{hoursStr} {minutesStr} {secondsStr} remaining</span>)
}
function renderDownloadProgress () {
if (!prog.files) return
const fileProg = prog.files[state.playing.fileIndex]
const fileProgress = fileProg.numPiecesPresent / fileProg.numPieces
const fileLength = state.getPlayingFileSummary().length
const fileDownloaded = fileProgress * fileLength
const progress = Math.round(100 * fileProgress)
const total = prettyBytes(fileLength)
const completed = prettyBytes(fileDownloaded)
const downloadSpeed = prettyBytes(prog.downloadSpeed || 0)
const uploadSpeed = prettyBytes(prog.uploadSpeed || 0)
let sizes
if (fileProgress < 1) {
sizes = <span> | {completed} / {total}</span>
} else {
sizes = <span> | {completed}</span>
}
return (
<div key='download-progress'>
<span className='progress'>{progress}% downloaded {sizes}</span>
<br />
<span>↓ {downloadSpeed}/s ↑ {uploadSpeed}/s | {prog.numPeers || 0} peer(s)</span>
<br />
{renderEta(fileLength, fileDownloaded)}
</div>
)
}
return (
<div key='cast' className='letterbox' style={style}>
<div className='cast-screen'>
<i className='icon'>{castIcon}</i>
<div key='type' className='cast-type'>{castType}</div>
<div key='status' className='cast-status'>{castStatus}</div>
<div key='name' className='name'>{fileName}</div>
{renderDownloadProgress()}
</div>
</div>
)
@@ -536,6 +591,8 @@ function renderPlayerControls (state) {
const nextClass = Playlist.hasNext(state) ? '' : 'disabled'
const elements = [
renderPreview(state),
<div key='playback-bar' className='playback-bar'>
{renderLoadingBar(state)}
<div
@@ -547,6 +604,8 @@ function renderPlayerControls (state) {
key='scrub-bar'
className='scrub-bar'
draggable
onMouseMove={handleScrubPreview}
onMouseOut={clearPreview}
onDragStart={handleDragStart}
onClick={handleScrub}
onDrag={handleScrub}
@@ -655,10 +714,14 @@ function renderPlayerControls (state) {
// Render volume slider
const volume = state.playing.volume
const volumeIcon = 'volume_' + (
volume === 0 ? 'off'
: volume < 0.3 ? 'mute'
: volume < 0.6 ? 'down'
: 'up')
volume === 0
? 'off'
: volume < 0.3
? 'mute'
: volume < 0.6
? 'down'
: 'up'
)
const volumeStyle = {
background: '-webkit-gradient(linear, left top, right top, ' +
'color-stop(' + (volume * 100) + '%, #eee), ' +
@@ -722,6 +785,19 @@ function renderPlayerControls (state) {
}
}
// Handles a scrub hover (preview another position in the video)
function handleScrubPreview (e) {
// Only show for videos
if (!e.clientX || state.playing.type !== 'video') return
dispatch('mediaMouseMoved')
dispatch('preview', e.clientX)
}
function clearPreview (e) {
if (state.playing.type !== 'video') return
dispatch('clearPreview')
}
// Handles a click or drag to scrub (jump to another position in the video)
function handleScrub (e) {
if (!e.clientX) return
@@ -760,6 +836,56 @@ function renderPlayerControls (state) {
}
}
function renderPreview (state) {
const { previewXCoord = null } = state.playing
// Calculate time from x-coord as fraction of track width
const windowWidth = document.querySelector('body').clientWidth
const fraction = previewXCoord / windowWidth
const time = fraction * state.playing.duration /* seconds */
const height = 70
let width = 0
const previewEl = document.querySelector('video#preview')
if (previewEl !== null && previewXCoord !== null) {
previewEl.currentTime = time
// Auto adjust width to maintain video aspect ratio
width = Math.floor((previewEl.videoWidth / previewEl.videoHeight) * height)
}
// Center preview window on mouse cursor,
// while avoiding falling off the left or right edges
const xPos = Math.min(Math.max(previewXCoord - (width / 2), 5), windowWidth - width - 5)
return (
<div
key='preview' style={{
position: 'absolute',
bottom: 50,
left: xPos,
display: previewXCoord == null && 'none' // Hide preview when XCoord unset
}}
>
<div style={{ width, height, backgroundColor: 'black' }}>
<video
src={Playlist.getCurrentLocalURL(state)}
id='preview'
style={{ border: '1px solid lightgrey', borderRadius: 2 }}
/>
</div>
<p
style={{
textAlign: 'center', margin: 5, textShadow: '0 0 2px rgba(0,0,0,.5)', color: '#eee'
}}
>
{formatTime(time, state.playing.duration)}
</p>
</div>
)
}
// Renders the loading bar. Shows which parts of the torrent are loaded, which
// can be 'spongey' / non-contiguous
function renderLoadingBar (state) {
@@ -779,7 +905,7 @@ function renderLoadingBar (state) {
const parts = []
let lastPiecePresent = false
for (let i = fileProg.startPiece; i <= fileProg.endPiece; i++) {
const partPresent = Bitfield.prototype.get.call(prog.bitfield, i)
const partPresent = BitField.prototype.get.call(prog.bitfield, i)
if (partPresent && !lastPiecePresent) {
parts.push({ start: i - fileProg.startPiece, count: 1 })
} else if (partPresent) {

View File

@@ -5,24 +5,17 @@ console.time('init')
const crypto = require('crypto')
const util = require('util')
const defaultAnnounceList = require('create-torrent').announceList
const electron = require('electron')
const { ipcRenderer } = require('electron')
const fs = require('fs')
const mm = require('music-metadata')
const networkAddress = require('network-address')
const path = require('path')
const WebTorrent = require('webtorrent')
const crashReporter = require('../crash-reporter')
const config = require('../config')
const { TorrentKeyNotFoundError } = require('./lib/errors')
const torrentPoster = require('./lib/torrent-poster')
// Report when the process crashes
crashReporter.init()
// Send & receive messages from the main window
const ipc = electron.ipcRenderer
// Force use of webtorrent trackers on all torrents
global.WEBTORRENT_ANNOUNCE = defaultAnnounceList
.map((arr) => arr[0])
@@ -59,7 +52,7 @@ const PEER_ID = Buffer.from(VERSION_PREFIX + crypto.randomBytes(9).toString('bas
// Connect to the WebTorrent and BitTorrent networks. WebTorrent Desktop is a hybrid
// client, as explained here: https://webtorrent.io/faq
let client = window.client = new WebTorrent({ peerId: PEER_ID })
let client = window.client = new WebTorrent({ peerId: PEER_ID, utp: true })
// WebTorrent-to-HTTP streaming sever
let server = null
@@ -72,29 +65,29 @@ init()
function init () {
listenToClientEvents()
ipc.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))
ipc.on('wt-stop-torrenting', (e, infoHash) =>
ipcRenderer.on('wt-stop-torrenting', (e, infoHash) =>
stopTorrenting(infoHash))
ipc.on('wt-create-torrent', (e, torrentKey, options) =>
ipcRenderer.on('wt-create-torrent', (e, torrentKey, options) =>
createTorrent(torrentKey, options))
ipc.on('wt-save-torrent-file', (e, torrentKey) =>
ipcRenderer.on('wt-save-torrent-file', (e, torrentKey) =>
saveTorrentFile(torrentKey))
ipc.on('wt-generate-torrent-poster', (e, torrentKey) =>
ipcRenderer.on('wt-generate-torrent-poster', (e, torrentKey) =>
generateTorrentPoster(torrentKey))
ipc.on('wt-get-audio-metadata', (e, infoHash, index) =>
ipcRenderer.on('wt-get-audio-metadata', (e, infoHash, index) =>
getAudioMetadata(infoHash, index))
ipc.on('wt-start-server', (e, infoHash) =>
ipcRenderer.on('wt-start-server', (e, infoHash) =>
startServer(infoHash))
ipc.on('wt-stop-server', (e) =>
ipcRenderer.on('wt-stop-server', (e) =>
stopServer())
ipc.on('wt-select-files', (e, infoHash, selections) =>
ipcRenderer.on('wt-select-files', (e, infoHash, selections) =>
selectFiles(infoHash, selections))
ipc.send('ipcReadyWebTorrent')
ipcRenderer.send('ipcReadyWebTorrent')
window.addEventListener('error', (e) =>
ipc.send('wt-uncaught-error', { message: e.error.message, stack: e.error.stack }),
ipcRenderer.send('wt-uncaught-error', { message: e.error.message, stack: e.error.stack }),
true)
setInterval(updateTorrentProgress, 1000)
@@ -102,8 +95,8 @@ function init () {
}
function listenToClientEvents () {
client.on('warning', (err) => ipc.send('wt-warning', null, err.message))
client.on('error', (err) => ipc.send('wt-error', null, err.message))
client.on('warning', (err) => ipcRenderer.send('wt-warning', null, err.message))
client.on('error', (err) => ipcRenderer.send('wt-error', null, err.message))
}
// Starts a given TorrentID, which can be an infohash, magnet URI, etc.
@@ -137,44 +130,44 @@ function createTorrent (torrentKey, options) {
const torrent = client.seed(paths, options)
torrent.key = torrentKey
addTorrentEvents(torrent)
ipc.send('wt-new-torrent')
ipcRenderer.send('wt-new-torrent')
}
function addTorrentEvents (torrent) {
torrent.on('warning', (err) =>
ipc.send('wt-warning', torrent.key, err.message))
ipcRenderer.send('wt-warning', torrent.key, err.message))
torrent.on('error', (err) =>
ipc.send('wt-error', torrent.key, err.message))
ipcRenderer.send('wt-error', torrent.key, err.message))
torrent.on('infoHash', () =>
ipc.send('wt-parsed', torrent.key, torrent.infoHash, torrent.magnetURI))
ipcRenderer.send('wt-parsed', torrent.key, torrent.infoHash, torrent.magnetURI))
torrent.on('metadata', torrentMetadata)
torrent.on('ready', torrentReady)
torrent.on('done', torrentDone)
function torrentMetadata () {
const info = getTorrentInfo(torrent)
ipc.send('wt-metadata', torrent.key, info)
ipcRenderer.send('wt-metadata', torrent.key, info)
updateTorrentProgress()
}
function torrentReady () {
const info = getTorrentInfo(torrent)
ipc.send('wt-ready', torrent.key, info)
ipc.send('wt-ready-' + torrent.infoHash, torrent.key, info)
ipcRenderer.send('wt-ready', torrent.key, info)
ipcRenderer.send('wt-ready-' + torrent.infoHash, torrent.key, info)
updateTorrentProgress()
}
function torrentDone () {
const info = getTorrentInfo(torrent)
ipc.send('wt-done', torrent.key, info)
ipcRenderer.send('wt-done', torrent.key, info)
updateTorrentProgress()
torrent.getFileModtimes(function (err, fileModtimes) {
if (err) return onError(err)
ipc.send('wt-file-modtimes', torrent.key, fileModtimes)
ipcRenderer.send('wt-file-modtimes', torrent.key, fileModtimes)
})
}
}
@@ -211,7 +204,7 @@ function saveTorrentFile (torrentKey) {
const fileName = torrent.infoHash + '.torrent'
if (!err) {
// We've already saved the file
return ipc.send('wt-file-saved', torrentKey, fileName)
return ipcRenderer.send('wt-file-saved', torrentKey, fileName)
}
// Otherwise, save the .torrent file, under the app config folder
@@ -219,7 +212,7 @@ function saveTorrentFile (torrentKey) {
fs.writeFile(torrentPath, torrent.torrentFile, function (err) {
if (err) return console.log('error saving torrent file %s: %o', torrentPath, err)
console.log('saved torrent file %s', torrentPath)
return ipc.send('wt-file-saved', torrentKey, fileName)
return ipcRenderer.send('wt-file-saved', torrentKey, fileName)
})
})
})
@@ -239,7 +232,7 @@ function generateTorrentPoster (torrentKey) {
fs.writeFile(posterFilePath, buf, function (err) {
if (err) return console.log('error saving poster: %o', err)
// show the poster
ipc.send('wt-poster', torrentKey, posterFileName)
ipcRenderer.send('wt-poster', torrentKey, posterFileName)
})
})
})
@@ -251,7 +244,7 @@ function updateTorrentProgress () {
if (prevProgress && util.isDeepStrictEqual(progress, prevProgress)) {
return /* don't send heavy object if it hasn't changed */
}
ipc.send('wt-progress', progress)
ipcRenderer.send('wt-progress', progress)
prevProgress = progress
}
@@ -321,8 +314,8 @@ function startServerFromReadyTorrent (torrent, cb) {
networkAddress: networkAddress()
}
ipc.send('wt-server-running', info)
ipc.send('wt-server-' + torrent.infoHash, info)
ipcRenderer.send('wt-server-running', info)
ipcRenderer.send('wt-server-' + torrent.infoHash, info)
})
}
@@ -340,14 +333,17 @@ function getAudioMetadata (infoHash, index) {
// Set initial matadata to display the filename first.
const metadata = { title: file.name }
ipc.send('wt-audio-metadata', infoHash, index, metadata)
ipcRenderer.send('wt-audio-metadata', infoHash, index, metadata)
const options = {
native: false,
skipCovers: true,
fileSize: file.length,
observer: event => {
ipc.send('wt-audio-metadata', infoHash, index, event.metadata)
ipcRenderer.send('wt-audio-metadata', infoHash, index, {
common: metadata.common,
format: metadata.format
})
}
}
const onMetadata = file.done
@@ -359,7 +355,7 @@ function getAudioMetadata (infoHash, index) {
onMetadata
.then(
metadata => {
ipc.send('wt-audio-metadata', infoHash, index, metadata)
ipcRenderer.send('wt-audio-metadata', infoHash, index, metadata)
console.log(`metadata for file='${file.name}' completed.`)
},
err => {

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,5 @@
[Desktop Entry]
Type=Application
<% if (version) { %>Version=<%= version %><% } %>
Name=<%= productName %>
<% if (genericName) { %>GenericName=<%= genericName %><% } %>
<% if (description) { %>Comment=<%= description %><% } %>
@@ -11,7 +10,7 @@ Actions=CreateNewTorrent;OpenTorrentFile;OpenTorrentAddress;
<% if (mimeType && mimeType.length) { %>MimeType=<%= mimeType.join(';') %>;<% } %>
<% if (categories && categories.length) { %>Categories=<%= categories.join(';') %>;<% } %>
StartupNotify=true
<% if (name) { %>StartupWMClass=<%= name %> <% } %>
StartupWMClass=<%= productName %>
[Desktop Action CreateNewTorrent]
Name=Create New Torrent...

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -558,6 +558,13 @@ body.drag .app::after {
width: 100%;
}
.player .name {
font-size: 20px;
font-weight: bold;
line-height: 1.5em;
margin-bottom: 6px;
}
/*
* PLAYER CONTROLS
*/

Binary file not shown.

Binary file not shown.

Binary file not shown.