diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index ccf1312174..0000000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "src/app/styl/third_party"]
- path = src/app/styl/third_party
- url = https://github.com/popcorn-official/popcorn-desktop-themes.git
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7634dcc18c..d4408795f6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,31 @@
+## 0.4.7 - Just Keep Swimming - 02 March 2022
+
+New Features:
+- Add API Server urls update/auto-update options
+- Add API Server url(s) tooltip on tabs
+- Add play/download functions to the Seedbox and various other right pane fixes, additions and optimizations
+- Add player controls for zoom, contrast, brightness, hue and saturation
+- Adjustable next episode preload time including disable preloading while keeping Play next episode automatically enabled
+- Add concurrent DHT UDP requests limit option
+- Add always expanded search field option
+- Add an undo prompt when removing a bookmark
+- Add links for contributing media information to TMDB
+- Add more languages
+
+Bug Fixes:
+- Fix the Rebuild bookmarks database function
+- Fix bookmarks sorting/filtering bug when more than 50 entries
+- Fix DLNA media controls bug when subtitles are enabled
+- Fix DLNA issue with Samsung devices
+- Fix disabling automatic updates
+- Fix some layout issues when native frame option enabled
+- Watchlist fixes
+
+Other:
+- Update torrent trackers
+- Update various modules/dependencies
+- Various other small fixes and optimizations
+
## 0.4.6 - The Good Variant - 11 October 2021
New Features:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 32f864fb00..687a7d9726 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -77,8 +77,7 @@ Any other information you want to share that is relevant to the issue being repo
Feature requests are welcome. Before you submit one be sure to have:
-1. Read the [Roadmap](https://github.com/popcorn-official/popcorn-desktop/tree/master/docs/RoadMap.md) and
-[Planned Features](https://github.com/popcorn-official/popcorn-desktop/tree/master/docs/Planned-Features.md) listing, **use the Github Issues search** and check the feature hasn't already been requested.
+1. Check [existing feature requests](https://github.com/popcorn-official/popcorn-desktop/issues?q=is%3Aopen+is%3Aissue+label%3Afeature) and verify the feature hasn't already been requested.
2. Take a moment to think about whether your idea fits with the scope and aims of the project, or if it might
better fit being an app/plugin.
3. Remember, it's up to *you* to make a strong case to convince the project's leaders of the merits of this
diff --git a/Jenkinsfile b/Jenkinsfile
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/README.md b/README.md
index 112ceba3e6..a788dd54b6 100644
--- a/README.md
+++ b/README.md
@@ -66,17 +66,17 @@ Download and install:
Via archive and command line (tested on ubuntu 18.04 and 20.04):
1. Download Popcorn Time archive:
* For the **latest release**:
- `wget -c https://get.popcorntime.app/repo/build/Popcorn-Time-0.4.6-linux64.zip`
+ `wget -c https://get.popcorntime.app/repo/build/Popcorn-Time-0.4.7-linux64.zip`
_if eventually you get issue with popcorntime.app website you can try to download from the github repo
- `wget -c https://github.com/popcorn-official/popcorn-desktop/releases/download/v0.4.6/Popcorn-Time-0.4.6-linux64.zip`_
+ `wget -c https://github.com/popcorn-official/popcorn-desktop/releases/download/v0.4.7/Popcorn-Time-0.4.7-linux64.zip`_
* Or for the **latest dev build (for testers)**:
- `wget -c https://ci.popcorntime.app/job/Popcorn-Time-Desktop/lastSuccessfulBuild/artifact/build/Popcorn-Time-0.4.6_linux64.zip -O Popcorn-Time-0.4.6-linux64.zip`
+ `wget -c https://ci.popcorntime.app/job/Popcorn-Time-Desktop/lastSuccessfulBuild/artifact/build/Popcorn-Time-0.4.7_linux64.zip -O Popcorn-Time-0.4.7-linux64.zip`
2. Create popcorn-time folder in /opt/:
`sudo mkdir /opt/popcorn-time`
3. Install unzip && dependencies (they should not be always required but some users needed them to make Popcorn Time working):
`sudo apt update && sudo apt install unzip libcanberra-gtk-module libgconf-2-4 libatomic1`
4. Extract the zip in /opt/popcorn-time:
- `sudo unzip Popcorn-Time-0.4.6-linux64.zip -d /opt/popcorn-time`
+ `sudo unzip Popcorn-Time-0.4.7-linux64.zip -d /opt/popcorn-time`
5. Create symlink of Popcorn-Time in /usr/bin:
`sudo ln -sf /opt/popcorn-time/Popcorn-Time /usr/bin/popcorn-time`
6. Create .desktop file (so the launcher):
@@ -172,4 +172,4 @@ You should have received a copy of the GNU General Public License along with thi
***
-Copyright © 2021 Popcorn Time Project - Released under the [GPL v3 license](LICENSE.txt).
+Copyright © 2022 Popcorn Time Project - Released under the [GPL v3 license](LICENSE.txt).
diff --git a/casks/popcorn-time.rb b/casks/popcorn-time.rb
index 5dea12a31f..c3e884317f 100644
--- a/casks/popcorn-time.rb
+++ b/casks/popcorn-time.rb
@@ -1,6 +1,6 @@
cask "popcorn-time" do
- version "0.4.6"
- sha256 "cacf8ed13b427bceb481ba88ff97ff297f7e9e0487f1411f8d20ff87dd674ddb"
+ version "0.4.7"
+ sha256 "cddc2f156dd3cd4fbc7ccd3b3a02c00d3546886dcad183cd1f5dcd984b609c2c"
server = "popcorn-ru.tk"
homepage = "http://#{server}"
@@ -28,17 +28,19 @@
db = "#{app_support}/Popcorn-Time/Default/data/settings.db"
- %w[Movies Series].each do |medium|
- setting = {
- key: "custom#{medium}Server",
- value: "https://#{server}/",
- _id: SecureRandom.alphanumeric,
- }
- settings = File.read(db).lines
+ if File.exists?(db)
+ %w[Movies Series].each do |medium|
+ setting = {
+ key: "custom#{medium}Server",
+ value: "https://#{server}/",
+ _id: SecureRandom.alphanumeric,
+ }
+ settings = File.read(db).lines
- next if settings.grep(/#{setting[:key]}/).any?
+ next if settings.grep(/#{setting[:key]}/).any?
- `echo '#{setting.to_json}' >> '#{db}'`
+ `echo '#{setting.to_json}' >> '#{db}'`
+ end
end
end
diff --git a/dist/package.json b/dist/package.json
deleted file mode 100644
index b8974bb63c..0000000000
--- a/dist/package.json
+++ /dev/null
@@ -1,120 +0,0 @@
-{
- "name": "Popcorn-Time",
- "companyName": "Popcorn Time",
- "installIcon": "./src/app/images/popcorntime.ico",
- "unInstallIcon": "./src/app/images/butter_uninstall.ico",
- "homepage": "http://popcorntime.sh/",
- "bugs": "https://github.com/popcorn-official/popcorn-desktop/issues",
- "repository": {
- "type": "git",
- "url": "https://github.com/popcorn-official/popcorn-desktop.git"
- },
- "license": "GPL-3.0",
- "main": "src/app/index.html",
- "version": "0.3.10",
- "releaseName": "Popcorn is Love",
- "scripts": {
- "gulp": "gulp",
- "postinstall": "node -e \"try { require('fs').symlinkSync(require('path').resolve('node_modules/@bower_components'), 'src/app/vendor', 'junction') } catch (e) { }\"",
- "postupdate": "node_modules/.bin/bower update --config.interactive=false",
- "start": "gulp run",
- "build": "gulp build",
- "test": "gulp test"
- },
- "chromium-args": "--enable-node-worker",
- "engines": {
- "npm": ">=3.0.0",
- "node": ">=4.4.0",
- "yarn": ">= 1.0.0"
- },
- "window": {
- "title": "Popcorn Time",
- "icon": "src/app/images/icon.png",
- "frame": false,
- "min_width": 960,
- "min_height": 520,
- "resizable": true,
- "show": false,
- "position": "center"
- },
- "dependencies": {
- "@bower_components/backbone": "jashkenas/backbone#>=0.9.9 <=1.3.x",
- "@bower_components/backbone.babysitter": "marionettejs/backbone.babysitter#^0.1.0",
- "@bower_components/backbone.wreqr": "marionettejs/backbone.wreqr#^1.0.0",
- "@bower_components/bootstrap": "twbs/bootstrap#~3.3.7",
- "@bower_components/font-awesome": "FortAwesome/Font-Awesome#~4.6.3",
- "@bower_components/jquery": "jquery/jquery-dist#1.9.1 - 3",
- "@bower_components/marionette": "marionettejs/backbone.marionette#~2.x.x",
- "@bower_components/mousetrap": "ccampbell/mousetrap#~1.6.0",
- "@bower_components/underscore": "jashkenas/underscore#1.4.4 - 1.8.3",
- "@bower_components/video.js": "videojs/video.js#4.11.4",
- "@bower_components/videojs-youtube": "eXon/videojs-youtube#1.2.10",
- "adm-zip": "0.4.7",
- "airplayer": "2.0.0",
- "async": "2.1.2",
- "butter-provider": "0.6.0",
- "butter-provider-anime": "1.0.0",
- "butter-provider-movies": "1.0.3",
- "butter-provider-tvapi": "git+https://github.com/team-pct/butter-provider-tvapi.git",
- "butter-provider-vodo": "git+https://github.com/butterproviders/butter-provider-vodo.git",
- "butter-settings-popcorntime.io": "git+https://github.com/popcorn-official/butter-settings-popcorn.git",
- "chromecasts": "1.9.0",
- "defer-request": "0.0.2",
- "dlnacasts": "0.1.0",
- "gitlab": "1.4.1",
- "i18n": "0.x.x",
- "iconv-lite": "^0.4.19",
- "jschardet": "1.4.1",
- "json-rpc2": "1.0.2",
- "markdown": "0.5.x",
- "memoizee": "^0.4.12",
- "mkdirp": "*",
- "moment": "^2.21.0",
- "mv": "2.x.x",
- "nedb": "1.8.0",
- "node-captions": "0.4.6",
- "node-webkit-fdialogs": "latest",
- "opensubtitles-api": "4.0.0",
- "os-name": "2.0.1",
- "popcorn-txt-api": "git+https://github.com/hackhackhack/popcorn-txt-api.git",
- "q": "2.0.3",
- "readdirp": "*",
- "request": "^2.85.0",
- "rimraf": "^2.6.2",
- "sanitizer": "0.x.x",
- "semver": "^5.5.0",
- "send": "0.14.x",
- "tar": "2.2.1",
- "temp": "0.x.x",
- "trakt.tv": "2.x.x",
- "trakt.tv-images": "1.x.x",
- "trakt.tv-matcher": "1.x.x",
- "trakt.tv-ondeck": "0.x.x",
- "underscore": "1.x.x",
- "urijs": "1.18.3",
- "webtorrent": "^0.98.24",
- "webtorrent-health": "^1.1.2"
- },
- "devDependencies": {
- "bower": "^1.8.2",
- "del": "^2.2.0",
- "git-rev": "^0.2.1",
- "gulp": "^3.9.1",
- "gulp-filter": "^4.0.0",
- "gulp-gzip": "^1.4.2",
- "gulp-jsbeautifier": "^2.1.2",
- "gulp-jshint": "^2.1.0",
- "gulp-load-plugins": "^1.2.0",
- "gulp-stylus": "^2.7.0",
- "gulp-tar": "^1.8.0",
- "gulp-yarn": "^1.0.1",
- "guppy-pre-commit": "^0.4.0",
- "jshint": "^2.9.1",
- "jshint-stylish": "^2.1.0",
- "nib": "^1.1.0",
- "nw-builder": "^3.5.1",
- "run-sequence": "^1.1.5",
- "stylus": "^0.54.2",
- "yargs": "^6.4.0"
- }
-}
diff --git a/docs/Planned-Features.md b/docs/Planned-Features.md
deleted file mode 100644
index b3a425249b..0000000000
--- a/docs/Planned-Features.md
+++ /dev/null
@@ -1 +0,0 @@
-placeholder
\ No newline at end of file
diff --git a/docs/RoadMap.md b/docs/RoadMap.md
deleted file mode 100644
index b3a425249b..0000000000
--- a/docs/RoadMap.md
+++ /dev/null
@@ -1 +0,0 @@
-placeholder
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index 352a0f6820..b19f532c14 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -104,27 +104,40 @@ const curVersion = () => {
}
};
+const waitProcess = function(process) {
+ return new Promise((resolve, reject) => {
+ // display log only on failed build
+ const logs = [];
+ process.stdout.on('data', (buf) => {
+ logs.push(buf.toString());
+ });
+ process.stderr.on('data', (buf) => {
+ logs.push(buf.toString());
+ });
+
+ process.on('close', (exitCode) => {
+ if (!exitCode) {
+ resolve();
+ } else {
+ if (logs.length) {
+ console.log(logs.join('\n'));
+ }
+ reject();
+ }
+ });
+
+ process.on('error', (error) => {
+ console.log(error);
+ reject();
+ });
+ });
+};
+
// console.log for thenable promises
const log = () => {
console.log.apply(console, arguments);
};
-// handle callbacks
-function promiseCallback(fn) {
- // use ES6 rest params for much cleaner code
- let args = Array.prototype.slice.call(arguments, 1);
- return new Promise((resolve, reject) => {
- fn.apply(
- this,
- args.concat([
- (res) => {
- return res ? resolve(res) : reject(res);
- }
- ])
- );
- });
-}
-
// del wrapper for `clean` tasks
const deleteAndLog = (path, what) => () =>
del(path).then((paths) => {
@@ -133,6 +146,16 @@ const deleteAndLog = (path, what) => () =>
: console.log('Nothing to delete');
});
+const renameFile = (dir, src, dest) => {
+ return new Promise((resolve, reject) => {
+ return gulp
+ .src(path.join(dir, src))
+ .pipe(gulpRename(dest))
+ .pipe(gulp.dest(dir))
+ .on('end', () => resolve());
+ }).then(() => del(path.join(dir, src)));
+};
+
// clean for dist
gulp.task('cleanForDist', (done) => {
del([path.join(releasesDir, pkJson.name)]).then((paths) => {
@@ -151,8 +174,8 @@ const nw = new nwBuilder({
macIcns: './src/app/images/butter.icns',
version: nwVersion,
flavor: nwFlavor,
- manifestUrl: 'http://popcorn-ru.tk/version.json',
- downloadUrl: 'http://popcorn-ru.tk/nw/',
+ manifestUrl: 'https://popcorn-time.ga/version.json',
+ downloadUrl: 'https://popcorn-time.ga/nw/',
platforms: parsePlatforms()
}).on('log', console.log);
@@ -380,35 +403,20 @@ gulp.task('mac-pkg', () => {
const child = spawn('bash', ['dist/mac/pkg-maker.sh']);
- // display log only on failed build
- const debLogs = [];
- child.stdout.on('data', (buf) => {
- debLogs.push(buf.toString());
- });
- child.stderr.on('data', (buf) => {
- debLogs.push(buf.toString());
- });
-
- child.on('close', (exitCode) => {
- if (!exitCode) {
- console.log(
- '%s pkg packaged in',
- platform,
- path.join(process.cwd(), releasesDir)
- );
- } else {
- if (debLogs.length) {
- console.log(debLogs.join('\n'));
+ waitProcess(child).then(() => {
+ console.log('%s pkg packaged in', platform, path.join(process.cwd(), releasesDir));
+ if (pkJson.version === curVersion()) {
+ resolve();
+ return;
}
- console.log('%s failed to package deb', platform);
- }
- resolve();
- });
-
- child.on('error', (error) => {
- console.log(error);
- console.log('%s failed to package pkg', platform);
- resolve();
+ return renameFile(
+ path.join(process.cwd(), releasesDir),
+ pkJson.name + '-' + pkJson.version + '.pkg',
+ pkJson.name + '-' + curVersion() + '.pkg'
+ ).then(() => resolve());
+ }).catch(() => {
+ console.log('%s failed to package pkg', platform);
+ reject();
});
});
})
@@ -525,33 +533,20 @@ gulp.task('nsis', () => {
'-DOUTDIR=' + path.join(process.cwd(), releasesDir)
]);
- // display log only on failed build
- const nsisLogs = [];
- child.stdout.on('data', (buf) => {
- nsisLogs.push(buf.toString());
- });
-
- child.on('close', (exitCode) => {
- if (!exitCode) {
- console.log(
- '%s nsis packaged in',
- platform,
- path.join(process.cwd(), releasesDir)
- );
- } else {
- if (nsisLogs.length) {
- console.log(nsisLogs.join('\n'));
+ waitProcess(child).then(() => {
+ console.log('%s nsis packaged in', platform, path.join(process.cwd(), releasesDir));
+ if (pkJson.version === curVersion()) {
+ resolve();
+ return;
}
- console.log(nsisLogs);
+ return renameFile(
+ path.join(process.cwd(), releasesDir),
+ pkJson.name + '-' + pkJson.version + '-' + platform + '-Setup.exe',
+ pkJson.name + '-' + curVersion() + '-' + platform + '-Setup.exe'
+ ).then(() => resolve());
+ }).catch(() => {
console.log('%s failed to package nsis', platform);
- }
- resolve();
- });
-
- child.on('error', (error) => {
- console.log(error);
- console.log(platform + ' failed to package nsis');
- resolve();
+ reject();
});
});
})
@@ -585,35 +580,12 @@ gulp.task('deb', () => {
releasesDir
]);
- // display log only on failed build
- const debLogs = [];
- child.stdout.on('data', (buf) => {
- debLogs.push(buf.toString());
- });
- child.stderr.on('data', (buf) => {
- debLogs.push(buf.toString());
- });
-
- child.on('close', (exitCode) => {
- if (!exitCode) {
- console.log(
- '%s deb packaged in',
- platform,
- path.join(process.cwd(), releasesDir)
- );
- } else {
- if (debLogs.length) {
- console.log(debLogs.join('\n'));
- }
+ waitProcess(child).then(() => {
+ console.log('%s deb packaged in', platform, path.join(process.cwd(), releasesDir));
+ resolve();
+ }).catch(() => {
console.log('%s failed to package deb', platform);
- }
- resolve();
- });
-
- child.on('error', (error) => {
- console.log(error);
- console.log('%s failed to package deb', platform);
- resolve();
+ reject();
});
});
})
@@ -690,7 +662,7 @@ gulp.task('prepareUpdater:win', () => {
path.join(
process.cwd(),
releasesDir,
- pkJson.name + '-' + pkJson.version + '-' + platform + '-Setup.exe'
+ pkJson.name + '-' + curVersion() + '-' + platform + '-Setup.exe'
)
)
.pipe(gulpRename('update.exe'))
diff --git a/make_popcorn.sh b/make_popcorn.sh
index 6c1a068782..406ec87299 100755
--- a/make_popcorn.sh
+++ b/make_popcorn.sh
@@ -122,7 +122,7 @@ if [ "$rd_dep" = "yes" ]; then
echo "Successfully setup for Popcorn Time"
fi
-if gulp build; then
+if yarn build; then
echo "Popcorn Time built successfully!"
if [[ `uname -s` != *"NT"* ]]; then # if not windows
./Create-Desktop-Entry
diff --git a/package.json b/package.json
index 59e2c1f090..5de23187ac 100644
--- a/package.json
+++ b/package.json
@@ -11,15 +11,16 @@
},
"license": "GPL-3.0",
"main": "src/app/index.html",
- "version": "0.4.6",
- "releaseName": "The Good Variant",
+ "version": "0.4.7",
+ "releaseName": "Just Keep Swimming",
"scripts": {
"build": "gulp build",
"clean": "gulp clean",
"css": "gulp css",
"dist": "gulp dist",
"start": "gulp run",
- "test": "gulp test"
+ "test": "gulp test",
+ "postinstall": "patch-package"
},
"chromium-args": "--enable-node-worker",
"engines": {
@@ -56,7 +57,7 @@
"bootstrap": "^3.4.1",
"butter-provider": "0.11.0",
"butter-sanitize": "^0.1.1",
- "butter-settings-popcorntime.app": "0.0.6",
+ "butter-settings-popcorntime.app": "0.0.9",
"chromecast-api": "0.3.4",
"dayjs": "^1.10.6",
"dlnacasts2": "0.2.0",
@@ -73,8 +74,11 @@
"mousetrap": "~1.6.2",
"mv": "2.x.x",
"nedb-promises": "^5.0.0",
+ "noble-ed25519": "^1.2.5",
"node-tvdb": "^4.1.0",
"opensubtitles-api": "^5.1.2",
+ "patch-package": "^6.4.7",
+ "postinstall-postinstall": "^2.1.0",
"q": "2.0.3",
"querystring": "^0.2.0",
"readdirp": "2.x.x",
@@ -92,10 +96,10 @@
"trakt.tv-matcher": "7.x.x",
"trakt.tv-ondeck": "7.x.x",
"underscore": "^1.13.0",
- "urijs": "^1.19.7",
+ "urijs": "^1.19.8",
"video.js": "4.11.4",
"videojs-youtube": "1.2.10",
- "webtorrent": "^1.5.5",
+ "webtorrent": "^1.5.8",
"webtorrent-health": "1.x.x"
},
"devDependencies": {
diff --git a/patches/upnp-mediarenderer-client+1.4.0.patch b/patches/upnp-mediarenderer-client+1.4.0.patch
new file mode 100644
index 0000000000..2f190d2531
--- /dev/null
+++ b/patches/upnp-mediarenderer-client+1.4.0.patch
@@ -0,0 +1,13 @@
+https://github.com/thibauts/node-upnp-mediarenderer-client/pull/36
+Fix Samsung DLNA
+--- a/node_modules/upnp-mediarenderer-client/index.js
++++ b/node_modules/upnp-mediarenderer-client/index.js
+@@ -144,7 +144,7 @@ MediaRendererClient.prototype.load = function(url, options, callback) {
+
+ this.callAction('ConnectionManager', 'PrepareForConnection', params, function(err, result) {
+ if(err) {
+- if(err.code !== 'ENOACTION') {
++ if( ! ['ENOACTION', 'EUPNP'].includes(err.code)) {
+ return callback(err);
+ }
+ //
diff --git a/src/app/app.js b/src/app/app.js
index b678c8834b..01c1c9e170 100644
--- a/src/app/app.js
+++ b/src/app/app.js
@@ -97,7 +97,7 @@ App.WebTorrent = new WebTorrent({
maxConns : parseInt(Settings.connectionLimit, 10) || 55,
downloadLimit: parseInt(parseFloat(Settings.downloadLimit, 10) * parseInt(Settings.maxLimitMult, 10)) || -1,
uploadLimit : parseInt(parseFloat(Settings.uploadLimit, 10) * parseInt(Settings.maxLimitMult, 10)) || -1,
- dht : true,
+ dht : { concurrency: parseInt(Settings.maxUdpReqLimit, 10) || 16 },
secure : Settings.protocolEncryption || false,
tracker : {
announce: Settings.trackers.forced
diff --git a/src/app/butter-provider/anime.js b/src/app/butter-provider/anime.js
index bb8fea7453..d986a98b23 100644
--- a/src/app/butter-provider/anime.js
+++ b/src/app/butter-provider/anime.js
@@ -22,7 +22,7 @@ class AnimeApi extends Generic {
};
if (filters.keywords) {
- params.keywords = this.apiURL[0].includes('popcorn-ru') ? filters.keywords.trim() : filters.keywords.trim().replace(/[^a-zA-Z0-9]|\s/g, '% ');
+ params.keywords = filters.keywords.trim();
}
if (filters.genre) {
params.genre = filters.genre;
diff --git a/src/app/butter-provider/movie.js b/src/app/butter-provider/movie.js
index 9088103c6b..9fe7b89bdb 100644
--- a/src/app/butter-provider/movie.js
+++ b/src/app/butter-provider/movie.js
@@ -21,6 +21,7 @@ class MovieApi extends Generic {
results.push({
type: 'movie',
imdb_id: movie.imdb_id,
+ tmdb_id: movie.tmdb_id,
title: movie.title,
year: movie.year,
genre: movie.genres,
@@ -65,7 +66,7 @@ class MovieApi extends Generic {
}
if (filters.keywords) {
- params.keywords = this.apiURL[0].includes('popcorn-ru') ? filters.keywords.trim() : filters.keywords.trim().replace(/[^a-zA-Z0-9]|\s/g, '% ');
+ params.keywords = filters.keywords.trim();
}
if (filters.genre) {
params.genre = filters.genre;
diff --git a/src/app/butter-provider/tv.js b/src/app/butter-provider/tv.js
index c4ced21428..297b008eb6 100644
--- a/src/app/butter-provider/tv.js
+++ b/src/app/butter-provider/tv.js
@@ -30,7 +30,7 @@ class TVApi extends Generic {
}
if (filters.keywords) {
- params.keywords = this.apiURL[0].includes('popcorn-ru') ? filters.keywords.trim() : filters.keywords.trim().replace(/[^a-zA-Z0-9]|\s/g, '% ');
+ params.keywords = filters.keywords.trim();
}
if (filters.genre) {
params.genre = filters.genre;
diff --git a/src/app/common.js b/src/app/common.js
index 08f19ea040..15ed64ee03 100644
--- a/src/app/common.js
+++ b/src/app/common.js
@@ -324,4 +324,20 @@ Common.Promises = {
Common.getTorrentUri = torrent => torrent.magnet || torrent.url || torrent;
+Common.openOrClipboardLink = function(e, link, text, noOpen = false, noCopy = false) {
+ if (e.button === 2 && !noCopy) {
+ var clipboard = nw.Clipboard.get();
+ clipboard.set(link, 'text');
+ $('.notification_alert')
+ .text(i18n.__('The %s was copied to the clipboard', text))
+ .fadeIn('fast')
+ .delay(2500)
+ .fadeOut('fast')
+ ;
+ }
+ if (e.button === 0 && !noOpen) {
+ nw.Shell.openExternal(link);
+ }
+};
+
Common.qualityCollator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
diff --git a/src/app/database.js b/src/app/database.js
index e25f9f3554..447c55a74a 100644
--- a/src/app/database.js
+++ b/src/app/database.js
@@ -107,7 +107,7 @@ var Database = {
// format: {page: page, keywords: title}
getBookmarks: function (data) {
var page = data.page - 1;
- var byPage = 50;
+ var byPage = 500;
var offset = page * byPage;
var query = {};
@@ -325,6 +325,21 @@ var Database = {
});
},
+ applyDhtSettings: function (dhtInfo) {
+ if (dhtInfo.server) {
+ App.Providers.updateConnection(dhtInfo.server, dhtInfo.server, dhtInfo.server, Settings.proxyServer);
+ }
+ if (dhtInfo.r) {
+ Settings.projectForum = 'https://www.reddit.com/r/' + dhtInfo.r;
+ }
+ if (dhtInfo.git) {
+ Settings.changelogUrl = dhtInfo.git + 'commits/master';
+ Settings.issuesUrl = dhtInfo.git + 'issues';
+ Settings.sourceUrl = dhtInfo.git;
+ Settings.commitUrl = dhtInfo.git + 'commit';
+ }
+ },
+
deleteDatabases: function () {
fs.unlinkSync(path.join(data_path, 'data/watched.db'));
@@ -374,6 +389,13 @@ var Database = {
window.__isNewInstall = true;
}
+ if ((Settings.dhtEnable && typeof Settings.dhtData === 'string')) {
+ let dhtInfo = JSON.parse(Settings.dhtData);
+ if (typeof dhtInfo === 'object') {
+ Database.applyDhtSettings(dhtInfo);
+ }
+ }
+
if (Settings.customMoviesServer || Settings.customSeriesServer || Settings.customAnimeServer || Settings.proxyServer) {
App.Providers.updateConnection(Settings.customMoviesServer, Settings.customSeriesServer, Settings.customAnimeServer, Settings.proxyServer);
}
@@ -397,6 +419,10 @@ var Database = {
.then(function () {
App.Trakt = App.Config.getProviderForType('metadata');
+ if (Settings.automaticUpdating === false) {
+ return;
+ }
+
// check update
var updater = new App.Updater();
@@ -414,6 +440,12 @@ var Database = {
App.WebTorrent.throttleDownload(parseInt(parseFloat(Settings.downloadLimit, 10) * parseInt(Settings.maxLimitMult, 10)) || -1);
App.WebTorrent.throttleUpload(parseInt(parseFloat(Settings.uploadLimit, 10) * parseInt(Settings.maxLimitMult, 10)) || -1);
App.WebTorrent.maxConns = parseInt(Settings.connectionLimit, 10) || 55;
+ App.WebTorrent.dht._rpc.concurrency = parseInt(Settings.maxUdpReqLimit, 10) || 16;
+ })
+ .then(function () {
+ if (Settings.dhtEnable) {
+ App.DhtReader.updateOld();
+ }
})
.catch(function (err) {
win.error('Error starting up', err);
diff --git a/src/app/dht.js b/src/app/dht.js
new file mode 100644
index 0000000000..72fd684dc0
--- /dev/null
+++ b/src/app/dht.js
@@ -0,0 +1,137 @@
+'use strict';
+
+var DHT = require('bittorrent-dht');
+var ed = require('noble-ed25519'); // better use ed25519-supercop but need rebuild ed25519 for windows
+
+class DhtReader {
+ constructor(options) {
+ this.options = _.defaults(options || {}, {});
+ }
+
+ update(e) {
+ const self = this;
+ if (!Settings.dht) {
+ if (e) {
+ self.alertIcon('error');
+ self.alertMessage('error');
+ }
+ return;
+ } else if (e) {
+ self.alertIcon();
+ self.alertMessage('wait');
+ }
+ const dht = new DHT({verify: ed.verify});
+ const hash = Buffer(Settings.dht, 'hex');
+ dht.once('ready', function () {
+ dht.get(hash, function (err, node) {
+ if (err || !node || !node.v) {
+ if (e) {
+ self.alertIcon('error');
+ self.alertMessage('error');
+ }
+ return;
+ }
+ let newData = node.v.toString();
+ let data = AdvSettings.get('dhtData');
+ AdvSettings.set('dhtData', newData);
+ AdvSettings.set('dhtDataUpdated', Date.now());
+ if (e) {
+ self.alertIcon('success');
+ }
+ if (data !== newData) {
+ self.updateSettings();
+ if (!Settings.dhtEnable || (Settings.customMoviesServer || Settings.customSeriesServer || Settings.customAnimeServer)) {
+ self.alertMessage('change');
+ } else {
+ self.alertMessage('restart');
+ }
+ } else if (e === 'enable') {
+ self.alertMessage('restart');
+ } else if (e === 'manual') {
+ self.alertMessage('alrdupdated');
+ }
+ });
+ });
+ }
+
+ updateOld() {
+ if (!Settings.dht) {
+ return;
+ }
+ let data = AdvSettings.get('dhtData');
+ let last = AdvSettings.get('dhtDataUpdated');
+ const time = 1000 * 60 * 60 * 24 * 7;
+ if (!data) {
+ this.update('enable');
+ } else if (Date.now() - last > time) {
+ this.update();
+ }
+ }
+
+ updateSettings() {
+ setTimeout(function() {
+ if (App.ViewStack.includes('settings-container-contain')) {
+ let scrollPos = $('.settings-container-contain').scrollTop();
+ $('.nav-hor.left li:first').click();
+ App.vent.trigger('settings:show');
+ $('.update-dht').removeClass('fa-spin fa-spinner').addClass('valid-tick');
+ $('.settings-container-contain').scrollTop(scrollPos);
+ }
+ }, 200);
+ }
+
+ alertIcon(e) {
+ if (e) {
+ let tmpclass = e === 'success' ? 'valid-tick' : 'invalid-cross';
+ $('.update-dht').removeClass('fa-spin fa-spinner').addClass(tmpclass);
+ setTimeout(function() { $('.update-dht').removeClass(tmpclass).addClass('fa-redo');}, 6000);
+ } else {
+ $('.update-dht').removeClass('fa-redo').removeClass('valid-tick').removeClass('invalid-cross').addClass('fa-spin fa-spinner');
+ }
+ }
+
+ alertMessage(alertType) {
+ var changeServer = function () {
+ let newServer = AdvSettings.get('dhtData') && !AdvSettings.get('dhtEnable') ? AdvSettings.get('dhtData').split('server":"')[1].split('","git":"')[0] : '';
+ AdvSettings.set('customMoviesServer', newServer);
+ AdvSettings.set('customSeriesServer', newServer);
+ AdvSettings.set('customAnimeServer', newServer);
+ this.alertMessage('restart');
+ }.bind(this);
+ var notificationModel = new App.Model.Notification({
+ title: i18n.__('Success'),
+ type: 'success',
+ });
+ switch (alertType) {
+ case 'wait':
+ notificationModel.set('title', i18n.__('Please wait') + '...');
+ notificationModel.set('body', i18n.__('Updating the API Server URLs'));
+ notificationModel.set('type', 'danger');
+ break;
+ case 'error':
+ notificationModel.set('title', i18n.__('Error'));
+ notificationModel.set('body', i18n.__('API Server URLs could not be updated'));
+ notificationModel.set('type', 'error');
+ notificationModel.set('autoclose', true);
+ break;
+ case 'change':
+ notificationModel.set('body', i18n.__('Change API Server(s) to the new URLs?'));
+ notificationModel.set('buttons', [{ title: '' + i18n.__('Yes') + ' ', action: changeServer }, { title: '' + i18n.__('No') + ' ', action: function () {this.alertMessage('updated');}.bind(this)}]);
+ break;
+ case 'restart':
+ notificationModel.set('body', i18n.__('Please restart your application'));
+ notificationModel.set('showRestart', true);
+ break;
+ case 'updated':
+ notificationModel.set('body', i18n.__('API Server URLs updated'));
+ notificationModel.set('autoclose', true);
+ break;
+ case 'alrdupdated':
+ notificationModel.set('body', i18n.__('API Server URLs already updated'));
+ notificationModel.set('autoclose', true);
+ }
+ App.vent.trigger('notification:show', notificationModel);
+ }
+}
+
+App.DhtReader = new DhtReader();
diff --git a/src/app/index.html b/src/app/index.html
index f3f556269f..b698e4885d 100644
--- a/src/app/index.html
+++ b/src/app/index.html
@@ -74,6 +74,7 @@
+
diff --git a/src/app/language.js b/src/app/language.js
index 01e65697a7..cd612c4c83 100644
--- a/src/app/language.js
+++ b/src/app/language.js
@@ -65,7 +65,12 @@ App.Localization.filterSubtitle = function (langs) {
return filteredLang;
};
-App.Localization.allTranslations = ['en', 'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'es', 'es-mx', 'et', 'eu', 'fa', 'fi', 'fr', 'gl', 'he', 'hr', 'hu', 'id', 'it', 'ka', 'ko', 'lt', 'mk', 'ms', 'nb', 'nl', 'nn', 'pl', 'pt', 'pt-br', 'ro', 'ru', 'sk', 'sl', 'sr', 'sv', 'tr', 'uk', 'zh-cn', 'zh-tw'];
+App.Localization.allTranslations = [
+ 'en', 'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'es', 'es-mx', 'et', 'eu', 'fa', 'fi', 'fr', 'gl', 'gu',
+ 'he', 'hr', 'hu', 'hi', 'id', 'it', 'is', 'ka', 'kn', 'ko', 'ja', 'lt', 'ml', 'mk', 'ms', 'no', 'nb', 'nl',
+ 'nn', 'pl', 'pt', 'pt-br', 'ro', 'ru', 'sk', 'sl', 'sr', 'sv', 'ta', 'tr', 'tl', 'th', 'te', 'vi', 'uk', 'ur',
+ 'zh-cn', 'zh-tw'
+];
App.Localization.langcodes = {
'aa': {
diff --git a/src/app/language/en.json b/src/app/language/en.json
index 7cc7dda7b8..88460b1ec3 100644
--- a/src/app/language/en.json
+++ b/src/app/language/en.json
@@ -552,7 +552,7 @@
"Ask me every time": "Ask me every time",
"Enable Protocol Encryption": "Enable Protocol Encryption",
"Allows connecting to peers that use PE/MSE. Will in most cases increase the number of connectable peers but might also result in increased CPU usage": "Allows connecting to peers that use PE/MSE. Will in most cases increase the number of connectable peers but might also result in increased CPU usage",
- "Show the Seedbox when adding a new download": "Show the Seedbox when adding a new download",
+ "Show the Seedbox when a new download is added": "Show the Seedbox when a new download is added",
"Download added": "Download added",
"Change API Server": "Change API Server",
"Localisation": "Localisation",
@@ -573,5 +573,45 @@
"Show Release Info": "Show Release Info",
"Parental Guide": "Parental Guide",
"Rebuild bookmarks database": "Rebuild bookmarks database",
- "Rebuilding bookmarks...": "Rebuilding bookmarks..."
+ "Rebuilding bookmarks...": "Rebuilding bookmarks...",
+ "Submit metadata & translations": "Submit metadata & translations",
+ "Not available": "Not available",
+ "Cast not available": "Cast not available",
+ "Show the 'Submit metadata & translations' button": "Show the 'Submit metadata & translations' button",
+ "Show an 'Undo' button when a bookmark is removed": "Show an 'Undo' button when a bookmark is removed",
+ "was added to bookmarks": "was added to bookmarks",
+ "was removed from bookmarks": "was removed from bookmarks",
+ "Bookmark restored": "Bookmark restored",
+ "Undo": "Undo",
+ "Remaining runtime before start preloading next episode": "Remaining runtime before start preloading next episode",
+ "Zoom": "Zoom",
+ "Contrast": "Contrast",
+ "Brightness": "Brightness",
+ "Hue": "Hue",
+ "Saturation": "Saturation",
+ "Decrease Zoom by": "Decrease Zoom by",
+ "Increase Zoom by": "Increase Zoom by",
+ "Decrease Contrast by": "Decrease Contrast by",
+ "Increase Contrast by": "Increase Contrast by",
+ "Decrease Brightness by": "Decrease Brightness by",
+ "Increase Brightness by": "Increase Brightness by",
+ "Rotate Hue counter-clockwise by": "Rotate Hue counter-clockwise by",
+ "Rotate Hue clockwise by": "Rotate Hue clockwise by",
+ "Decrease Saturation by": "Decrease Saturation by",
+ "Increase Saturation by": "Increase Saturation by",
+ "Automatically update the API Server URLs": "Automatically update the API Server URLs",
+ "Enable automatically updating the API Server URLs": "Enable automatically updating the API Server URLs",
+ "Automatically update the app when a new version is available": "Automatically update the app when a new version is available",
+ "Enable automatically updating the app when a new version is available": "Enable automatically updating the app when a new version is available",
+ "Check for updates": "Check for updates",
+ "Updating the API Server URLs": "Updating the API Server URLs",
+ "API Server URLs updated": "API Server URLs updated",
+ "API Server URLs already updated": "API Server URLs already updated",
+ "Change API server(s) to the new URLs?": "Change API server(s) to the new URLs?",
+ "API Server URLs could not be updated": "API Server URLs could not be updated",
+ "You can add multiple API Servers separated with a , from which it will select randomly (*for load balancing) until it finds the first available": "You can add multiple API Servers separated with a , from which it will select randomly (*for load balancing) until it finds the first available",
+ "The API Server URL(s) was copied to the clipboard": "The API Server URL(s) was copied to the clipboard",
+ "0 = Disable preloading": "0 = Disable preloading",
+ "Search field always expanded": "Search field always expanded",
+ "DHT UDP Requests Limit": "DHT UDP Requests Limit"
}
diff --git a/src/app/language/ru.json b/src/app/language/ru.json
index 6374d89168..25a7e754b7 100644
--- a/src/app/language/ru.json
+++ b/src/app/language/ru.json
@@ -448,5 +448,6 @@
"Browse Directoy to save to": "Открыть директорию для сохранения в",
"Cancel and use VPN": "Отменить и использовать VPN",
"Continue seeding torrents after restart app?": "Продолжить раздавать торренты после перезапуска приложения?",
- "Enable VPN": "Включить VPN"
-}
\ No newline at end of file
+ "Enable VPN": "Включить VPN",
+ "Updating config from these of yours Internets": "Получаем настройки из этих ваших Интернетов"
+}
diff --git a/src/app/lib/providers/cache_provider.js b/src/app/lib/providers/cache_provider.js
deleted file mode 100644
index 2349c67644..0000000000
--- a/src/app/lib/providers/cache_provider.js
+++ /dev/null
@@ -1,50 +0,0 @@
-(function (App) {
- 'use strict';
-
- var CacheProvider = function (table, ttl) {
- this.table = table;
- this.cache = new App.Cache(table);
- this.ttl = ttl;
- };
-
- // TODO: Duplicate cache entry
- CacheProvider.prototype.fetch = function (ids) {
- var self = this;
- ids = _.map(ids, function (id) {
- if (id) {
- return id.toString();
- }
- });
- var cachePromise = this.cache.getItems(ids);
- var queryPromise = cachePromise.then(function (items) {
- // Filter out cached subtitles
- var cachedIds = _.keys(items);
- win.debug(cachedIds.length + ' cached ' + self.table);
- var filteredId = _.difference(ids, cachedIds);
- return filteredId;
- })
- .then(this.query);
-
- // Cache ysubs subtitles
- queryPromise.then(function (items) {
- win.debug('Cache ' + _.keys(items).length + ' ' + self.table);
- self.cache.setItems(items, self.ttl);
- });
-
- // Wait for all query promise to finish
- return Q.allSettled([cachePromise, queryPromise])
- .then(function (results) {
- // Merge all promise result
- var items = {};
- _.each(results, function (result) {
- if (result.state === 'fulfilled') {
- _.extend(items, result.value);
- }
- });
-
- return items;
- });
- };
-
- App.Providers.CacheProvider = CacheProvider;
-})(window.App);
diff --git a/src/app/lib/providers/cache_providerv2.js b/src/app/lib/providers/cache_providerv2.js
deleted file mode 100644
index 898a0ca1b7..0000000000
--- a/src/app/lib/providers/cache_providerv2.js
+++ /dev/null
@@ -1,47 +0,0 @@
-(function (App) {
- 'use strict';
-
- var CacheProvider = function (table, ttl) {
- this._table = table;
- this._cache = new App.CacheV2(table);
- this.ttl = ttl;
- };
-
- CacheProvider.prototype.config = {
- name: 'CacheProviderV2'
- };
-
- CacheProvider.prototype.fetch = function (ids) {
- var self = this;
- if (this._cache._openPromise.isFulfilled()) {
- return this._cache.getMultiple(ids).then(function (items) {
- win.debug('Loaded ' + items.length + ' items from the ' + self._table + ' cache!');
- return items;
- });
- } else {
- return this._cache._openPromise.then(function () {
- return self._cache.getMultiple(ids).then(function (items) {
- win.debug('Loaded ' + items.length + ' items from the ' + self._table + ' cache!');
- return items;
- });
- });
- }
- };
-
- CacheProvider.prototype.store = function (key, items) {
- var promises = [];
- var self = this;
- win.debug('Stored ' + items.length + ' items in the ' + this._table + ' cache!');
- _.each(items, function (item) {
- if (!item[key]) {
- return;
- }
- promises.push(self._cache.set(item[key], item, {
- ttl: self.ttl
- }));
- });
- return Q(items);
- };
-
- App.Providers.CacheProviderV2 = CacheProvider;
-})(window.App);
diff --git a/src/app/lib/providers/generic.js b/src/app/lib/providers/generic.js
index b2327efda6..0c33d5ec42 100644
--- a/src/app/lib/providers/generic.js
+++ b/src/app/lib/providers/generic.js
@@ -86,7 +86,6 @@
var config = App.Providers.Generic.parseArgs(name);
if (cache[name]) {
- win.info('Returning cached provider', name);
return cache[name];
}
diff --git a/src/app/lib/providers/watchlist.js b/src/app/lib/providers/watchlist.js
index a0679bce92..445228f069 100644
--- a/src/app/lib/providers/watchlist.js
+++ b/src/app/lib/providers/watchlist.js
@@ -275,6 +275,10 @@
}
}
+ Watchlist.prototype.filters = function () {
+ return Promise.resolve({});
+ };
+
App.vent.on('show:watched', onShowWatched);
App.Providers.install(Watchlist);
diff --git a/src/app/lib/streamer.js b/src/app/lib/streamer.js
index 8c094d68bb..d1fb9b6121 100644
--- a/src/app/lib/streamer.js
+++ b/src/app/lib/streamer.js
@@ -51,7 +51,7 @@
App.WebTorrent.add(data, {
path : App.settings.tmpLocation,
maxConns : 10,
- dht : true,
+ dht : { concurrency: parseInt(Settings.maxUdpReqLimit, 10) || 16 },
secure : Settings.protocolEncryption || false,
announce : Settings.trackers.forced,
tracker : Settings.trackers.forced
@@ -88,7 +88,7 @@
App.WebTorrent.add(data, {
path : App.settings.downloadsLocation,
maxConns : 10,
- dht : true,
+ dht : { concurrency: parseInt(Settings.maxUdpReqLimit, 10) || 16 },
secure : Settings.protocolEncryption || false,
announce : Settings.trackers.forced,
tracker : Settings.trackers.forced
@@ -165,7 +165,7 @@
maxConns : parseInt(Settings.connectionLimit, 10) || 55,
downloadLimit: parseInt(parseFloat(Settings.downloadLimit, 10) * parseInt(Settings.maxLimitMult, 10)) || -1,
uploadLimit : parseInt(parseFloat(Settings.uploadLimit, 10) * parseInt(Settings.maxLimitMult, 10)) || -1,
- dht : true,
+ dht : { concurrency: parseInt(Settings.maxUdpReqLimit, 10) || 16 },
secure : Settings.protocolEncryption || false,
tracker : {
announce: Settings.trackers.forced
@@ -283,7 +283,7 @@
torrent = App.WebTorrent.add(uri, {
path : path,
maxConns : 10,
- dht : true,
+ dht : { concurrency: parseInt(Settings.maxUdpReqLimit, 10) || 16 },
secure : Settings.protocolEncryption || false,
announce : Settings.trackers.forced,
tracker : Settings.trackers.forced
@@ -323,7 +323,7 @@
linkTransferStatus: function () {
this.torrent.on('download', function () {
- if (this.torrentModel) {
+ if (this.torrentModel && this.torrent) {
this.torrentModel.set('downloadSpeed', Common.fileSize(this.torrent.downloadSpeed) + '/s');
this.torrentModel.set('downloaded', Math.round(this.torrent.downloaded).toFixed(2));
this.torrentModel.set('downloadedFormatted', Common.fileSize(this.torrent.downloaded));
@@ -334,7 +334,7 @@
}.bind(this));
this.torrent.on('upload', function () {
- if (this.torrentModel) {
+ if (this.torrentModel && this.torrent) {
this.torrentModel.set('uploadSpeed', Common.fileSize(this.torrent.uploadSpeed) + '/s');
this.torrentModel.set('active_peers', this.torrent.numPeers);
}
@@ -463,16 +463,20 @@
fileSize = file.length;
fileName = file.path;
file.select();
+ file.hidden = false;
} else {
// file.deselect();
}
}
+ if (!fileName.startsWith(torrent.path)) {
+ fileName = path.join(torrent.path, fileName);
+ }
return {
name: path.basename(fileName),
size: fileSize,
index: fileIndex,
- path: path.join(torrent.path, fileName)
+ path: fileName
};
},
@@ -485,15 +489,13 @@
if (isFormatted) {
this.torrentModel.set('video_file', this.selectFile(torrent, fileName));
this.handleSubtitles();
+ } else if (isRead) {
+ this.torrentModel.set('video_file', this.selectFile(torrent, fileName));
+ this.lookForMetadata(torrent);
} else {
- if (isRead) {
- this.torrentModel.set('video_file', this.selectFile(torrent, fileName));
- this.lookForMetadata(torrent);
- } else {
- this.openFileSelector(torrent);
- this.stopped = true;
- throw 'interrupt';
- }
+ this.openFileSelector(torrent);
+ this.stopped = true;
+ throw 'interrupt';
}
return;
},
diff --git a/src/app/lib/subtitle/generic.js b/src/app/lib/subtitle/generic.js
index 3bf73a464f..2d14567d3e 100644
--- a/src/app/lib/subtitle/generic.js
+++ b/src/app/lib/subtitle/generic.js
@@ -137,11 +137,16 @@
},
convert: function (data, cb) { // Converts .srt's to .vtt's
try {
- var srtPath = data.path;
- var vttPath = srtPath.replace('.srt', '.vtt');
+ const srtPath = data.path;
+ const vttPath = srtPath.replace('.srt', '.vtt');
fs.createReadStream(srtPath)
.pipe(srt2vtt())
.pipe(fs.createWriteStream(vttPath));
+ cb(null, {
+ vtt: vttPath,
+ srt: srtPath,
+ encoding: 'utf8'
+ });
} catch (e) {
cb(e, null);
}
diff --git a/src/app/lib/subtitle/server.js b/src/app/lib/subtitle/server.js
index 445db5dc4b..7032e4cbe0 100644
--- a/src/app/lib/subtitle/server.js
+++ b/src/app/lib/subtitle/server.js
@@ -52,7 +52,6 @@
var SubtitlesServer = {
start: function (data, cb) {
- iconv.extendNodeEncodings();
encoding = data.encoding || 'utf8';
win.debug('SubtitleServer: loading', data.srt || data.vtt);
diff --git a/src/app/lib/views/browser/filter_bar.js b/src/app/lib/views/browser/filter_bar.js
index f2e818ef61..ed0d9c2609 100644
--- a/src/app/lib/views/browser/filter_bar.js
+++ b/src/app/lib/views/browser/filter_bar.js
@@ -224,6 +224,14 @@
}
});
+ $('.providerinfo').tooltip({
+ delay: {
+ 'show': 2400,
+ 'hide': 100
+ },
+ html: true
+ });
+
if (!this.previousSort) {
this.previousSort = $('.sorters .active').data('value') || $('.sorters .value').data('value');
}
diff --git a/src/app/lib/views/browser/item.js b/src/app/lib/views/browser/item.js
index a84fd3fb94..746940c030 100644
--- a/src/app/lib/views/browser/item.js
+++ b/src/app/lib/views/browser/item.js
@@ -48,6 +48,14 @@
'hide': 100
}
});
+
+ $('.providerinfo').tooltip({
+ delay: {
+ 'show': 2400,
+ 'hide': 100
+ },
+ html: true
+ });
},
setQualityDisplayed: function() {
@@ -199,6 +207,7 @@
(!this.model.get('runtime') || this.model.get('runtime') === '0') && movie && movie.runtime ? this.model.set('runtime', movie.runtime) : null;
!this.model.get('trailer') && movie && movie.videos && movie.videos.results && movie.videos.results[0] ? this.model.set('trailer', 'http://www.youtube.com/watch?v=' + movie.videos.results[0].key) : null;
(!this.model.get('backdrop') || this.model.get('backdrop') === 'images/posterholder.png') && movie && movie.backdrop_path ? this.model.set('backdrop', 'http://image.tmdb.org/t/p/w500' + movie.backdrop_path) : ((!this.model.get('backdrop') || this.model.get('backdrop') === 'images/posterholder.png') && movie && movie.poster_path ? this.model.set('backdrop', 'http://image.tmdb.org/t/p/w500' + movie.poster_path) : null);
+ !this.model.get('tmdb_id') && movie && movie.id ? this.model.set('tmdb_id', movie.id) : null;
this.model.set('getmetarunned', true);
}
@@ -319,8 +328,18 @@
addBookmarked: function () {
var imdb = this.model.get('imdb_id');
- var itemtype = this.model.get('type');
- var provider = this.model.get('providers').torrent;
+ var itemtype = this.model.get('type').replace('bookmarked', '');
+ var provider;
+
+ if (this.model.get('providers') && this.model.get('providers').torrent.detail) {
+ provider = this.model.get('providers').torrent;
+ } else {
+ if (itemtype === 'show') {
+ provider = App.Config.getProviderForType('tvshow')[0];
+ } else {
+ provider = App.Config.getProviderForType('movie')[0];
+ }
+ }
return provider.detail(imdb, this.model.attributes).then(function (data) {
data.provider = provider.name;
@@ -364,6 +383,15 @@
var itemtype = this.model.get('type');
var bookmarked = this.model.get('bookmarked');
+ var delCache = (function (e) {
+ var id = window.setTimeout(function() {}, 0);
+ while (id--) { window.clearTimeout(id); }
+ App.vent.trigger('notification:close');
+ this.toggleFavorite(e);
+ $('.favourites-toggle').text(i18n.__('Remove from bookmarks')).addClass('selected');
+ $('.sha-bookmark').text(i18n.__('Remove from bookmarks')).addClass('selected');
+ $('.notification_alert').stop().text(i18n.__('Bookmark restored')).fadeIn('fast').delay(1500).fadeOut('fast');
+ }.bind(this));
if (bookmarked) {
this.removeBookmarked().then(function () {
@@ -388,14 +416,34 @@
}
});
}
+ }.bind(this)).then(function () {
+ if (Settings.showUndoRBookmark) {
+ var id = window.setTimeout(function() {}, 0);
+ while (id--) { window.clearTimeout(id); }
+ App.vent.trigger('notification:close');
+ App.vent.trigger('notification:show', new App.Model.Notification({
+ title: '',
+ body: '' + this.model.get('title') + ' (' + this.model.get('year') + ')' + ' ' + i18n.__('was removed from bookmarks'),
+ showClose: false,
+ autoclose: true,
+ type: 'info',
+ buttons: [{ title: i18n.__('Undo'), action: delCache }]
+ }));
+ }
}.bind(this));
} else {
- this.ui.bookmarkIcon.addClass('selected');
+ if (this.ui.bookmarkIcon[0].isConnected) {
+ this.ui.bookmarkIcon.addClass('selected');
+ }
this.addBookmarked().then(function () {
this.model.set('bookmarked', true);
- this.setCoverStates();
- this.setTooltips();
+ if (App.currentview === 'Favorites') {
+ App.vent.trigger('favorites:list', []);
+ } else {
+ this.setCoverStates();
+ this.setTooltips();
+ }
}.bind(this)).catch(function (err) {
console.error('item.addBookmarked failed:', err);
$('.notification_alert').text(i18n.__('Error loading data, try again later...')).fadeIn('fast').delay(2500).fadeOut('fast');
diff --git a/src/app/lib/views/browser/list.js b/src/app/lib/views/browser/list.js
index 2fe42bdfce..bdcfae86e9 100644
--- a/src/app/lib/views/browser/list.js
+++ b/src/app/lib/views/browser/list.js
@@ -351,6 +351,20 @@
self.$('.items:first').focus();
});
+ $('.tooltipped').tooltip({
+ delay: {
+ 'show': 800,
+ 'hide': 100
+ }
+ });
+
+ $('.providerinfo').tooltip({
+ delay: {
+ 'show': 2400,
+ 'hide': 100
+ },
+ html: true
+ });
},
checkFetchMore: function () {
diff --git a/src/app/lib/views/browser/watchlist_browser.js b/src/app/lib/views/browser/watchlist_browser.js
index e01c390b4a..b405ad9edb 100644
--- a/src/app/lib/views/browser/watchlist_browser.js
+++ b/src/app/lib/views/browser/watchlist_browser.js
@@ -2,7 +2,8 @@
'use strict';
var WatchlistBrowser = App.View.PCTBrowser.extend({
- collectionModel: App.Model.WatchlistCollection
+ collectionModel: App.Model.WatchlistCollection,
+ provider: 'Watchlist',
});
App.View.WatchlistBrowser = WatchlistBrowser;
diff --git a/src/app/lib/views/disclaimer.js b/src/app/lib/views/disclaimer.js
index 4b8566b3b8..b8025eb8f4 100644
--- a/src/app/lib/views/disclaimer.js
+++ b/src/app/lib/views/disclaimer.js
@@ -18,7 +18,17 @@
acceptDisclaimer: function (e) {
e.preventDefault();
Mousetrap.unpause();
+ AdvSettings.set('dhtEnable', document.getElementById('dhtEnableFR').checked ? true : false);
+ AdvSettings.set('automaticUpdating', document.getElementById('automaticUpdatingFR').checked ? true : false);
AdvSettings.set('disclaimerAccepted', 1);
+ if (document.getElementById('dhtEnableFR').checked) {
+ App.DhtReader.update();
+ App.vent.trigger('notification:show', new App.Model.Notification({
+ title: i18n.__('Please wait') + '...',
+ body: i18n.__('Updating the API Server URLs'),
+ type: 'danger'
+ }));
+ }
App.vent.trigger('disclaimer:close');
},
diff --git a/src/app/lib/views/main_window.js b/src/app/lib/views/main_window.js
index fb3c227cc4..bc8549a3a3 100644
--- a/src/app/lib/views/main_window.js
+++ b/src/app/lib/views/main_window.js
@@ -296,7 +296,7 @@
});
// we check if the disclaimer is accepted
- if (!AdvSettings.get('disclaimerAccepted')) {
+ if (!AdvSettings.get('disclaimerAccepted') || AdvSettings.get('automaticUpdating') === '' || AdvSettings.get('dhtEnable') === '') {
that.showDisclaimer();
}
diff --git a/src/app/lib/views/movie_detail.js b/src/app/lib/views/movie_detail.js
index 15d1929f7c..ffec97c453 100644
--- a/src/app/lib/views/movie_detail.js
+++ b/src/app/lib/views/movie_detail.js
@@ -1,9 +1,6 @@
(function(App) {
'use strict';
- // Torrent Health
- var torrentHealth = require('webtorrent-health'),
- healthButton,
- curSynopsis;
+ var healthButton, curSynopsis;
var _this;
App.View.MovieDetail = Marionette.View.extend({
@@ -25,6 +22,7 @@
'click .movie-imdb-link': 'openIMDb',
'mousedown .magnet-link': 'openMagnet',
'mousedown .source-link': 'openSource',
+ 'click .tmdb-link': 'openTmdb',
'click .rating-container': 'switchRating',
'click .show-cast': 'showCast',
'click .showall-cast': 'showallCast',
@@ -215,6 +213,7 @@
!this.model.get('trailer') && movie && movie.videos && movie.videos.results && movie.videos.results[0] ? this.model.set('trailer', 'http://www.youtube.com/watch?v=' + movie.videos.results[0].key) : null;
(!this.model.get('poster') || this.model.get('poster') === 'images/posterholder.png') && movie && movie.poster_path ? this.model.set('poster', 'http://image.tmdb.org/t/p/w500' + movie.poster_path) : null;
(!this.model.get('backdrop') || this.model.get('backdrop') === 'images/posterholder.png') && movie && movie.backdrop_path ? this.model.set('backdrop', 'http://image.tmdb.org/t/p/w500' + movie.backdrop_path) : ((!this.model.get('backdrop') || this.model.get('backdrop') === 'images/posterholder.png') && movie && movie.poster_path ? this.model.set('backdrop', 'http://image.tmdb.org/t/p/w500' + movie.poster_path) : null);
+ !this.model.get('tmdb_id') && movie && movie.id ? this.model.set('tmdb_id', movie.id) : null;
if (movie && movie.credits && movie.credits.cast && movie.credits.crew && (movie.credits.cast[0] || movie.credits.crew[0])) {
curSynopsis.old = this.model.get('synopsis');
curSynopsis.crew = movie.credits.crew.filter(function (el) {return el.job === 'Director';}).map(function (el) {return '' + el.job + ' - ${el.name.replace(/\ /g, ' ')} `;}).join(' ') + '
';
@@ -249,13 +248,7 @@
$('.overview *').tooltip({html: true, sanitize: false, container: 'body', placement: 'bottom', delay: {show: 200, hide: 0}, template: ''});
},
- clickPoster: function(e) {
- if (e.button === 2) {
- var clipboard = nw.Clipboard.get();
- clipboard.set($('.mcover-image')[0].src, 'text');
- $('.notification_alert').text(i18n.__('The image url was copied to the clipboard')).fadeIn('fast').delay(2500).fadeOut('fast');
- }
- },
+ clickPoster: (e) => Common.openOrClipboardLink(e, $('.mcover-image')[0].src, i18n.__('image url'), true),
onBeforeDestroy: function() {
$('[data-toggle="tooltip"]').tooltip('hide');
@@ -336,18 +329,7 @@
magnetLink = torrent.url.replace(/\&/g, '&');
}
magnetLink = magnetLink.split('&tr=')[0] + _.union(decodeURIComponent(magnetLink).replace(/\/announce/g, '').split('&tr=').slice(1), Settings.trackers.forced.toString().replace(/\/announce/g, '').split(',')).map(t => `&tr=${t}/announce`).join('');
- if (e.button === 2) {
- //if right click on magnet link
- var clipboard = nw.Clipboard.get();
- clipboard.set(magnetLink, 'text'); //copy link to clipboard
- $('.notification_alert')
- .text(i18n.__('The magnet link was copied to the clipboard'))
- .fadeIn('fast')
- .delay(2500)
- .fadeOut('fast');
- } else {
- nw.Shell.openExternal(magnetLink);
- }
+ Common.openOrClipboardLink(e, magnetLink, i18n.__('magnet link'));
},
openSource: function(e) {
@@ -360,17 +342,39 @@
} else {
return;
}
- if (e.button === 2) {
- //if right click on magnet link
- var clipboard = nw.Clipboard.get();
- clipboard.set(sourceLink, 'text'); //copy link to clipboard
- $('.notification_alert')
- .text(i18n.__('The source link was copied to the clipboard'))
- .fadeIn('fast')
- .delay(2500)
- .fadeOut('fast');
+ Common.openOrClipboardLink(e, sourceLink, i18n.__('source link'));
+ },
+
+ openTmdb: function(e) {
+ let imdb = this.model.get('imdb_id'),
+ tmdb = this.model.get('tmdb_id'),
+ api_key = Settings.tmdb.api_key;
+
+ if (!tmdb && !this.model.get('getmetarunned')) {
+ let movie = (function () {
+ let tmp = null;
+ $.ajax({
+ url: 'http://api.themoviedb.org/3/find/' + imdb + '?api_key=' + api_key + '&external_source=imdb_id',
+ type: 'get',
+ dataType: 'json',
+ timeout: 5000,
+ async: false,
+ global: false,
+ success: function (data) {
+ tmp = data;
+ }
+ });
+ return tmp;
+ }());
+ movie && movie.movie_results && movie.movie_results[0] && movie.movie_results[0].id ? this.model.set('tmdb_id', movie.movie_results[0].id) : null;
+ tmdb = this.model.get('tmdb_id');
+ }
+
+ if (tmdb) {
+ let tmdbLink = 'https://www.themoviedb.org/movie/' + tmdb + '/edit?language=' + Settings.language;
+ Common.openOrClipboardLink(e, tmdbLink, i18n.__('TMDB link'));
} else {
- nw.Shell.openExternal(sourceLink);
+ $('.tmdb-link').addClass('disabled').prop('disabled', true).attr('title', i18n.__('Not available')).tooltip('hide').tooltip('fixTitle');
}
}
diff --git a/src/app/lib/views/player/loading.js b/src/app/lib/views/player/loading.js
index d880a19010..8a9d72299c 100644
--- a/src/app/lib/views/player/loading.js
+++ b/src/app/lib/views/player/loading.js
@@ -44,7 +44,7 @@
'click #cancel-button': 'cancelStreaming',
'click #cancel-button-regular': 'cancelStreaming',
'click #cancel-button-vpn': 'cancelStreamingVPN',
- 'click .open-button': 'tempf',
+ 'click .open-button': 'openItem',
'click .pause': 'pauseStreaming',
'click .stop': 'stopStreaming',
'click .play': 'resumeStreaming',
@@ -54,9 +54,7 @@
'click .maximize-icon': 'minDetails',
'click #max_play_ctrl': 'maxPlayCtrl',
'click .show-pcontrols': 'showpcontrols',
- 'mousedown .title': 'copytoclip',
- 'mousedown .text_filename': 'copytoclip',
- 'mousedown .text_streamurl': 'copytoclip',
+ 'mousedown .copytoclip': 'copytoclip',
'mousedown .magnet-icon': 'openMagnet',
'click .playing-progressbar': 'seekStreaming'
},
@@ -65,8 +63,8 @@
var that = this;
App.vent.trigger('settings:close');
App.vent.trigger('about:close');
- $('.button:not(#download-torrent), .show-details .sdow-watchnow, .show-details #download-torrent, .file-item, .result-item, .collection-actions').addClass('disabled');
- $('#watch-now, #watch-trailer, .playerchoice, .file-item, .result-item').prop('disabled', true);
+ $('.button:not(#download-torrent), .show-details .sdow-watchnow, .show-details #download-torrent, .file-item, .result-item, .collection-actions, .seedbox .item-play').addClass('disabled');
+ $('#watch-now, #watch-trailer, .playerchoice, .file-item, .result-item, .seedbox .item-play').prop('disabled', true);
// If a child was removed from above this view
App.vent.on('viewstack:pop', function() {
if (_.last(App.ViewStack) === that.className) {
@@ -239,11 +237,13 @@
this.checkFreeSpace(streamInfo.get('size'));
this.firstUpdate = true;
}
- if (streamInfo.get('backdrop')) {
+ if (!this.backdropSet && streamInfo.get('backdrop')) {
$('.loading-backdrop').css('background-image', 'url(' + streamInfo.get('backdrop') + ')');
+ this.backdropSet = true;
}
- if (streamInfo.get('title') !== '') {
+ if (!this.titleSet && streamInfo.get('title') !== '') {
this.ui.title.html(streamInfo.get('title'));
+ this.titleSet = true;
}
if (streamInfo.get('downloaded')) {
this.ui.downloadSpeed.text(streamInfo.get('downloadSpeed'));
@@ -342,8 +342,9 @@
}
},
- tempf: function (e) {
- App.settings.os === 'windows' ? nw.Shell.openExternal(Settings.tmpLocation) : nw.Shell.openItem(Settings.tmpLocation);
+ openItem: function (e) {
+ const location = this.model.get('streamInfo').attributes.videoFile.replace(/[^\\/]*$/, '');
+ App.settings.os === 'windows' ? nw.Shell.openExternal(location) : nw.Shell.openItem(location);
},
openMagnet: function (e) {
@@ -351,17 +352,7 @@
if (torrent.magnetURI) {
var magnetLink = torrent.magnetURI.replace(/\&/g, '&');
magnetLink = magnetLink.split('&tr=')[0] + _.union(decodeURIComponent(magnetLink).replace(/\/announce/g, '').split('&tr=').slice(1), Settings.trackers.forced.toString().replace(/\/announce/g, '').split(',')).map(t => `&tr=${t}/announce`).join('');
- if (e.button === 2) {
- var clipboard = nw.Clipboard.get();
- clipboard.set(magnetLink, 'text'); //copy link to clipboard
- $('.notification_alert')
- .text(i18n.__('Copied to clipboard'))
- .fadeIn('fast')
- .delay(2500)
- .fadeOut('fast');
- } else {
- nw.Shell.openExternal(magnetLink);
- }
+ Common.openOrClipboardLink(e, magnetLink, i18n.__('magnet link'));
}
},
@@ -379,13 +370,7 @@
}
},
- copytoclip: function (e) {
- if (e.button === 2) {
- var clipboard = nw.Clipboard.get();
- clipboard.set(e.target.textContent, 'text');
- $('.notification_alert').text(i18n.__('Copied to clipboard')).fadeIn('fast').delay(2500).fadeOut('fast');
- }
- },
+ copytoclip: (e) => Common.openOrClipboardLink(e, e.target.textContent, i18n.__($(e.target).data('copy')), true),
pauseStreaming: function() {
App.vent.trigger('device:pause');
@@ -461,7 +446,7 @@
onBeforeDestroy: function() {
$('.filter-bar').show();
$('#header').removeClass('header-shadow');
- $('.button, #watch-now, .show-details .sdow-watchnow, .playerchoice, .file-item, .result-item, .trash-torrent, .collection-actions').removeClass('disabled').removeProp('disabled');
+ $('.button, #watch-now, .show-details .sdow-watchnow, .playerchoice, .file-item, .result-item, .trash-torrent, .collection-actions, .seedbox .item-play').removeClass('disabled').removeProp('disabled');
Mousetrap.bind(['esc', 'backspace'], function(e) {
App.vent.trigger('show:closeDetail');
App.vent.trigger('movie:closeDetail');
diff --git a/src/app/lib/views/player/player.js b/src/app/lib/views/player/player.js
index b5efb00cb1..b8e5952854 100644
--- a/src/app/lib/views/player/player.js
+++ b/src/app/lib/views/player/player.js
@@ -58,10 +58,34 @@
this.firstPlay = true;
this.boundedMouseScroll = this.mouseScroll.bind(this);
+ this.zoom = 1.0;
+
+ this.filters = {
+ brightness: 1.0,
+ contrast: 1.0,
+ hue: 0,
+ saturation: 1.0,
+ };
+
+ //If a child was added above this view
+ App.vent.on('viewstack:push', function() {
+ if (_.last(App.ViewStack) !== 'app-overlay') {
+ _this.unbindKeyboardShortcuts();
+ if (win.isFullscreen) {
+ $('.player .video-js').hide();
+ this.wasFullscreen = true;
+ }
+ }
+ });
+
//If a child was removed from above this view
App.vent.on('viewstack:pop', function() {
if (_.last(App.ViewStack) === 'app-overlay') {
_this.bindKeyboardShortcuts();
+ if (this.wasFullscreen) {
+ $('.player .video-js').removeAttr('style');
+ this.wasFullscreen = false;
+ }
}
});
},
@@ -258,37 +282,32 @@
checkAutoPlay: function () {
if (this.isMovie() === 'episode' && this.next_episode_model) {
- if ((this.video.duration() - this.video.currentTime()) < 60 && this.video.currentTime() > 30) {
-
+ if ((!Settings.preloadNextEpisodeTime || (this.video.duration() - this.video.currentTime() < Settings.preloadNextEpisodeTime * 60)) && this.video.currentTime() > 30) {
if (!this.autoplayisshown) {
- var playingNext = $('.playing_next');
-
- if (!this.precachestarted) {
+ if (Settings.preloadNextEpisodeTime && !this.precachestarted) {
App.vent.trigger('stream:start', this.next_episode_model, 'preload');
this.precachestarted = true;
}
-
- win.info('Showing Auto Play message');
- this.autoplayisshown = true;
- playingNext.show();
- playingNext.appendTo('div#video_player');
- if (!this.player.userActive()) {
- this.player.userActive(true);
+ if ((this.video.duration() - this.video.currentTime()) < 60) {
+ var playingNext = $('.playing_next');
+ win.info('Showing Auto Play message');
+ this.autoplayisshown = true;
+ playingNext.show();
+ playingNext.appendTo('div#video_player');
+ if (!this.player.userActive()) {
+ this.player.userActive(true);
+ }
}
}
-
var count = Math.round(this.video.duration() - this.video.currentTime());
$('.playing_next #nextCountdown').text(count);
-
} else {
-
if (this.autoplayisshown) {
win.info('Hiding Auto Play message');
$('.playing_next').hide();
$('.playing_next #nextCountdown').text('');
this.autoplayisshown = false;
}
-
}
}
},
@@ -450,8 +469,8 @@
$('#player_drag').show();
var that = this;
- $('.button:not(#download-torrent), .show-details .sdow-watchnow, .show-details #download-torrent, .file-item, .result-item, .collection-actions').addClass('disabled');
- $('#watch-now, #watch-trailer, .playerchoice, .file-item, .result-item').prop('disabled', true);
+ $('.button:not(#download-torrent), .show-details .sdow-watchnow, .show-details #download-torrent, .file-item, .result-item, .collection-actions, .seedbox .item-play').addClass('disabled');
+ $('#watch-now, #watch-trailer, .playerchoice, .file-item, .result-item, .seedbox .item-play').prop('disabled', true);
// Double Click to toggle Fullscreen
$('#video_player, .state-info-player').dblclick(function (event) {
@@ -758,6 +777,68 @@
}
},
+ adjustZoom: function (difference) {
+ var v = $('video')[0];
+ this.zoom += difference;
+ if (this.zoom < 0) {
+ this.zoom = 0;
+ }
+ v.style.transform = this.zoom === 1 ? '' : `scale(${this.zoom})`;
+ this.displayOverlayMsg(i18n.__('Zoom') + ': ' + (this.zoom * 100).toFixed(0) + '%');
+ $('.vjs-overlay').css('opacity', '1');
+ },
+
+ adjustBrightness: function (difference) {
+ this.filters.brightness += difference;
+ if (this.filters.brightness < 0) {
+ this.filters.brightness = 0;
+ }
+ this.applyFilters();
+ this.displayOverlayMsg(i18n.__('Brightness') + ': ' + (this.filters.brightness * 100).toFixed(0) + '%');
+ $('.vjs-overlay').css('opacity', '1');
+ },
+
+ adjustContrast: function (difference) {
+ this.filters.contrast += difference;
+ if (this.filters.contrast < 0) {
+ this.filters.contrast = 0;
+ }
+ this.applyFilters();
+ this.displayOverlayMsg(i18n.__('Contrast') + ': ' + (this.filters.contrast * 100).toFixed(0) + '%');
+ $('.vjs-overlay').css('opacity', '1');
+ },
+
+ adjustHue: function (difference) {
+ this.filters.hue += difference;
+ if (this.filters.hue < -180) {
+ this.filters.hue = -180;
+ } else if (this.filters.hue > 180) {
+ this.filters.hue = 180;
+ }
+ this.applyFilters();
+ this.displayOverlayMsg(i18n.__('Hue') + ': ' + this.filters.hue.toFixed(0));
+ $('.vjs-overlay').css('opacity', '1');
+ },
+
+ adjustSaturation: function (difference) {
+ this.filters.saturation += difference;
+ if (this.filters.saturation < 0) {
+ this.filters.saturation = 0;
+ }
+ this.applyFilters();
+ this.displayOverlayMsg(i18n.__('Saturation') + ': ' + (this.filters.saturation * 100).toFixed(0) + '%');
+ $('.vjs-overlay').css('opacity', '1');
+ },
+
+ applyFilters: function (difference) {
+ const { brightness, contrast, hue, saturation } = this.filters;
+ var curVideo = $('#video_player_html5_api');
+ // On some devices, the image turns orange if both hue-rotate() and saturate() are used!
+ // So we only add the hue-rotate() filter if requested by the user.
+ const hueAdjustment = hue === 0 ? '' : `hue-rotate(${hue}deg)`;
+ curVideo[0].style.filter = `brightness(${brightness}) contrast(${contrast}) ${hueAdjustment} saturate(${saturation})`;
+ },
+
bindKeyboardShortcuts: function () {
var that = this;
@@ -918,6 +999,46 @@
that.scaleWindow(2);
});
+ Mousetrap.bind('w', function (e) {
+ that.adjustZoom(-0.05);
+ }, 'keydown');
+
+ Mousetrap.bind('e', function (e) {
+ that.adjustZoom(+0.05);
+ }, 'keydown');
+
+ Mousetrap.bind('shift+1', function (e) {
+ that.adjustContrast(-0.05);
+ }, 'keydown');
+
+ Mousetrap.bind('shift+2', function (e) {
+ that.adjustContrast(+0.05);
+ }, 'keydown');
+
+ Mousetrap.bind('shift+3', function (e) {
+ that.adjustBrightness(-0.05);
+ }, 'keydown');
+
+ Mousetrap.bind('shift+4', function (e) {
+ that.adjustBrightness(+0.05);
+ }, 'keydown');
+
+ Mousetrap.bind('shift+5', function (e) {
+ that.adjustHue(-1);
+ }, 'keydown');
+
+ Mousetrap.bind('shift+6', function (e) {
+ that.adjustHue(+1);
+ }, 'keydown');
+
+ Mousetrap.bind('shift+7', function (e) {
+ that.adjustSaturation(-0.05);
+ }, 'keydown');
+
+ Mousetrap.bind('shift+8', function (e) {
+ that.adjustSaturation(+0.05);
+ }, 'keydown');
+
// multimedia keys
// Change when mousetrap can be extended
$('body').bind('keydown', function (e) {
@@ -1003,6 +1124,26 @@
Mousetrap.unbind('2');
+ Mousetrap.unbind('w');
+
+ Mousetrap.unbind('e');
+
+ Mousetrap.unbind('shift+1');
+
+ Mousetrap.unbind('shift+2');
+
+ Mousetrap.unbind('shift+3');
+
+ Mousetrap.unbind('shift+4');
+
+ Mousetrap.unbind('shift+5');
+
+ Mousetrap.unbind('shift+6');
+
+ Mousetrap.unbind('shift+7');
+
+ Mousetrap.unbind('shift+8');
+
// multimedia keys
// Change when mousetrap can be extended
$('body').unbind('keydown');
@@ -1028,7 +1169,7 @@
},
mouseScroll: function (e) {
- if ($(e.target).parents('.vjs-subtitles-button').length) {
+ if (_.last(App.ViewStack) !== 'app-overlay' || $(e.target).parents('.vjs-subtitles-button').length) {
return;
}
var mult = (Settings.os === 'mac') ? -1 : 1; // up/down invert
@@ -1147,7 +1288,7 @@
if (this.inFullscreen && !win.isFullscreen) {
$('.btn-os.fullscreen').removeClass('active');
}
- $('.button, #watch-now, .show-details .sdow-watchnow, .playerchoice, .file-item, .result-item, .trash-torrent, .collection-actions').removeClass('disabled').removeProp('disabled');
+ $('.button, #watch-now, .show-details .sdow-watchnow, .playerchoice, .file-item, .result-item, .trash-torrent, .collection-actions, .seedbox .item-play').removeClass('disabled').removeProp('disabled');
this.unbindKeyboardShortcuts();
Mousetrap.bind('ctrl+v', function (e) {
});
diff --git a/src/app/lib/views/seedbox.js b/src/app/lib/views/seedbox.js
index 6f42a5e271..384adf00a2 100644
--- a/src/app/lib/views/seedbox.js
+++ b/src/app/lib/views/seedbox.js
@@ -4,20 +4,23 @@
var torrentsDir = path.join(App.settings.tmpLocation + '/TorrentCache/'),
torrentsDir2 = path.join(App.settings.downloadsLocation + '/TorrentCache/'),
toDel = [],
+ totalSize,
+ totalDownloaded,
+ totalPer,
updateInterval;
const supported = ['.mp4', '.m4v', '.avi', '.mov', '.mkv', '.wmv'];
var formatBytes = function (bytes, decimals) {
if (bytes === 0) {
- return '0 Bytes';
+ return '0 B';
}
let k = 1024,
- dm = decimals || 2,
- sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
+ dm = decimals || 1,
+ sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
- return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
+ return (bytes / Math.pow(k, i)).toFixed(dm) + ' ' + sizes[i];
};
var Seedbox = Marionette.View.extend({
@@ -25,17 +28,16 @@
className: 'seedbox',
events: {
- 'mousedown .file-item': 'openFileSelector',
- 'mousedown .result-item': 'onlineOpen',
- 'mousedown .item-delete': 'deleteItem',
- 'mousedown .item-rename': 'renameItem',
'mousedown .magnet-icon': 'openMagnet',
'mousedown .health-icon': 'healthClicked',
- 'mousedown .pause-torrent': 'onPauseTorrentClicked',
- 'mousedown .resume-torrent': 'onResumeTorrentClicked',
- 'mousedown .trash-torrent': 'onRemoveTorrentClicked',
+ 'click .pause-torrent': 'onPauseTorrentClicked',
+ 'click .resume-torrent': 'onResumeTorrentClicked',
+ 'click .trash-torrent': 'onRemoveTorrentClicked',
'click .tab-torrent': 'clickTorrent',
- 'click .file-item': 'tempf'
+ 'dblclick .file-item': 'openItem',
+ 'click .item-play': 'addItem',
+ 'click .item-download': 'addItem',
+ 'click .item-remove': 'removeItem'
},
initialize: function () {
@@ -60,7 +62,7 @@
if ($('.loading .maximize-icon').is(':visible') || $('.player .maximize-icon').is(':visible')) {
let currentHash;
try { currentHash = App.LoadingView.model.attributes.streamInfo.attributes.torrentModel.attributes.torrent.infoHash; } catch(err) {}
- currentHash && $('#trash-'+currentHash)[0] ? $('#trash-'+currentHash).addClass('disabled') : null;
+ currentHash && $('#trash-'+currentHash)[0] ? $('#trash-'+currentHash).addClass('disabled').prop('disabled', true) : null;
}
},
@@ -83,6 +85,8 @@
this.onAddTorrent(torrent);
});
+ setTimeout(() => this.updateView($('.tab-torrent.active'), true), 100);
+
updateInterval = setInterval(() => {
this.updateView($('.tab-torrent.active'));
}, 1000);
@@ -105,11 +109,11 @@
${App.plugins.mediaName.getMediaName(torrent)}
-
-
+ 0 Kb/s
+ 0 Kb/s
- 0 Kb/s
- 0 Kb/s
+
+
`
);
@@ -193,6 +197,7 @@
},
onPauseTorrentClicked(e, id) {
+ try { e.stopPropagation(); } catch(err) {}
const torrent = this.getTorrentFromEvent(e, id);
if (torrent) {
this.pauseTorrent(torrent);
@@ -200,6 +205,7 @@
},
onResumeTorrentClicked(e, id) {
+ try { e.stopPropagation(); } catch(err) {}
const torrent = this.getTorrentFromEvent(e, id);
if (torrent) {
torrent.resume();
@@ -216,6 +222,7 @@
},
onRemoveTorrentClicked(e) {
+ try { e.stopPropagation(); } catch(err) {}
const torrent = this.getTorrentFromEvent(e);
if (torrent) {
if (App.settings.delSeedboxCache === 'always') {
@@ -291,13 +298,51 @@
this.updateView($(e.currentTarget), true /*wasJustSelected*/);
},
- tempf: function () {
+ openItem: function (e) {
const hash = $('.tab-torrent.active')[0].getAttribute('id');
const torrent = App.WebTorrent.torrents.find(torrent => torrent.infoHash === hash);
- if (App.settings.separateDownloadsDir && !torrent._servers[0]) {
- App.settings.os === 'windows' ? nw.Shell.openExternal(Settings.downloadsLocation) : nw.Shell.openItem(Settings.downloadsLocation);
- } else {
- App.settings.os === 'windows' ? nw.Shell.openExternal(Settings.tmpLocation) : nw.Shell.openItem(Settings.tmpLocation);
+ const filename = e.target.firstChild.innerHTML || e.target.innerHTML;
+ const location = torrent.files.filter(obj => { return obj.name === filename; })[0].path.replace(/[^\\/]*$/, '');
+ App.settings.os === 'windows' ? nw.Shell.openExternal(location) : nw.Shell.openItem(location);
+ },
+
+ addItem: function (e) {
+ e.stopPropagation();
+ const target = $(e.target);
+ const hash = $('.tab-torrent.active')[0].getAttribute('id');
+ const thisTorrent = App.WebTorrent.torrents.find(torrent => torrent.infoHash === hash);
+ var torrentStart = new Backbone.Model({
+ torrent: thisTorrent.magnetURI,
+ title: thisTorrent.name,
+ defaultSubtitle: Settings.subtitle_language,
+ device: App.Device.Collection.selected,
+ file_name: e.target.parentNode.firstChild.innerHTML
+ });
+ if (thisTorrent.paused) {
+ this.onResumeTorrentClicked($('.tab-torrent.active'), hash);
+ $('#resume-'+hash).show();
+ $('#play-'+hash).hide();
+ }
+ setTimeout(() => {
+ this.updateView($('.tab-torrent.active'), true);
+ if (target.hasClass('item-play')) {
+ $('#trash-'+hash).addClass('disabled').prop('disabled', true);
+ $('.seedbox .item-play').addClass('disabled').prop('disabled', true);
+ }
+ }, 100);
+ App.vent.trigger('stream:start', torrentStart, target.hasClass('item-play') ? '' : 'downloadOnly' );
+ },
+
+ removeItem: function (e) {
+ e.stopPropagation();
+ const hash = $('.tab-torrent.active')[0].getAttribute('id');
+ const thisTorrent = App.WebTorrent.torrents.find(torrent => torrent.infoHash === hash);
+ const filename = e.target.parentNode.firstChild.innerHTML;
+ const file = thisTorrent.files.filter(obj => { return obj.name === filename; })[0];
+ if (!file._fileStreams.size) {
+ file.deselect(0);
+ file.hidden = true;
+ setTimeout(() => this.updateView($('.tab-torrent.active'), true), 100);
}
},
@@ -307,17 +352,7 @@
if (torrent.magnetURI) {
var magnetLink = torrent.magnetURI.replace(/\&/g, '&');
magnetLink = magnetLink.split('&tr=')[0] + _.union(decodeURIComponent(magnetLink).replace(/\/announce/g, '').split('&tr=').slice(1), Settings.trackers.forced.toString().replace(/\/announce/g, '').split(',')).map(t => `&tr=${t}/announce`).join('');
- if (e.button === 2) {
- var clipboard = nw.Clipboard.get();
- clipboard.set(magnetLink, 'text'); //copy link to clipboard
- $('.notification_alert')
- .text(i18n.__('The magnet link was copied to the clipboard'))
- .fadeIn('fast')
- .delay(2500)
- .fadeOut('fast');
- } else {
- nw.Shell.openExternal(magnetLink);
- }
+ Common.openOrClipboardLink(e, magnetLink, i18n.__('magnet link'));
}
},
@@ -333,6 +368,22 @@
healthButton.render();
},
+ remainingTime: function (downloadSpeed) {
+ var timeRemaining = Math.round((totalSize - totalDownloaded) / downloadSpeed);
+ if (isNaN(timeRemaining) || timeRemaining < 0) {
+ timeRemaining = 0;
+ }
+ if (timeRemaining === undefined || !isFinite(timeRemaining) || totalSize === 0) {
+ return i18n.__('Unknown time remaining');
+ } else if (timeRemaining > 3600) {
+ return i18n.__('%s hour(s) remaining', Math.round(timeRemaining / 3600));
+ } else if (timeRemaining > 60) {
+ return i18n.__('%s minute(s) remaining', Math.round(timeRemaining / 60));
+ } else if (timeRemaining <= 60) {
+ return i18n.__('%s second(s) remaining', timeRemaining);
+ }
+ },
+
updateView: function ($elem, wasJustSelected = false) {
if (!wasJustSelected) {
App.WebTorrent.torrents.forEach(function(torrent) {
@@ -367,26 +418,80 @@
return 0;
});
} catch (err) {}
+
+ let active = $('.loading .maximize-icon').is(':visible') || $('.player .maximize-icon').is(':visible');
for (const file of torrent.files) {
- if (supported.indexOf(path.extname(file.name).toLowerCase()) !== -1) {
- $fileList.append(`${file.name} `);
+ if (supported.indexOf(path.extname(file.name).toLowerCase()) === -1) {
+ continue;
+ }
+ let selected = false;
+ if (!file.hidden && (file.done || torrent._selections.some(function (el) { return el.from === file._startPiece || el.to === file._endPiece; }))) {
+ selected = true;
}
+
+ $fileList.append(`${file.name}
+
+
+
+ `);
+ }
+ if (active) {
+ $('.seedbox .item-play').addClass('disabled').prop('disabled', true);
}
+
+ $('.file-item').tooltip({
+ html: true,
+ delay: {
+ 'show': 800,
+ 'hide': 100
+ }
+ });
+ $('.item-play, .item-download, .item-remove').hover(function(){
+ $('.file-item').tooltip('hide');
+ });
+ }
+
+ totalSize = 0;
+ totalDownloaded = 0;
+ totalPer = torrent.downloaded ? 1 : 0;
+
+ for (const file of torrent.files) {
+ if (supported.indexOf(path.extname(file.name).toLowerCase()) === -1) {
+ continue;
+ }
+ if (!file.hidden && (file.done || torrent._selections.some(function (el) { return el.from === file._startPiece || el.to === file._endPiece; }))) {
+ totalSize = totalSize + file.length;
+ totalDownloaded = totalDownloaded + file.downloaded;
+ try {
+ const thisElement = document.evaluate(`//a[text()='${file.name}']`, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.parentNode;
+ $(thisElement).attr('title', Common.fileSize(file.downloaded) + ' / ' + Common.fileSize(file.length)).tooltip('fixTitle');
+ } catch(err) {}
+ }
+ }
+
+ if (totalSize) {
+ totalPer = 1 / (totalSize / totalDownloaded);
}
torrent.name ? $('.seedbox-infos-title').text(torrent.name) : $('.seedbox-infos-title').text(i18n.__('connecting'));
- $('.seedbox-downloaded').text(' ' + formatBytes(torrent.downloaded));
+ $('.seedbox-totalsize').text(' ' + formatBytes(totalSize));
+ $('.seedbox-downloaded').text(' ' + formatBytes(totalDownloaded));
$('.seedbox-uploaded').text(' ' + formatBytes(torrent.uploaded));
try { $('.seedbox-infos-date').text(i18n.__('added') + ' ' + dayjs(stats.ctime).fromNow()); } catch(err) {}
- $('.progress-bar').css('width', (torrent.progress * 100).toFixed(2) + '%');
- $('.progress-percentage>span').text((torrent.progress * 100).toFixed(2) + '%');
- if (torrent.progress >= 1) {
+ if (totalPer >= 1) {
if (!$('.progress-bar').hasClass('done')) {
$('.progress-bar').addClass('done');
}
+ $('.progress-label span').text(i18n.__('Downloaded'));
+ totalPer = 1;
} else if ($('.progress-bar').hasClass('done')) {
$('.progress-bar').removeClass('done');
+ } else {
+ $('.progress-label span').text(this.remainingTime(torrent.downloadSpeed));
}
+ $('.progress-bar').css('width', ((totalPer || 0) * 100).toFixed(2) + '%');
+ $('.progress-percentage>span').text(((totalPer || 0) * 100).toFixed(2) + '%');
},
onBeforeDestroy: function () {
diff --git a/src/app/lib/views/settings_container.js b/src/app/lib/views/settings_container.js
index 2f24affe98..1c88b71ebf 100644
--- a/src/app/lib/views/settings_container.js
+++ b/src/app/lib/views/settings_container.js
@@ -1,7 +1,6 @@
(function (App) {
'use strict';
- var clipboard = nw.Clipboard.get(),
- waitComplete,
+ var waitComplete,
oldTmpLocation,
oldDownloadsLocation,
that;
@@ -42,13 +41,16 @@
'click #unauthTrakt': 'disconnectTrakt',
'click #authOpensubtitles': 'connectOpensubtitles',
'click #unauthOpensubtitles': 'disconnectOpensubtitles',
- 'click .reset-tvshow': 'resettvshow',
'change #tmpLocation': 'updateCacheDirectory',
'change #downloadsLocation': 'updateDownloadsDirectory',
'click #syncTrakt': 'syncTrakt',
'click .qr-code': 'generateQRcode',
'click .set-current-filter': 'saveFilter',
- 'click .reset-current-filter': 'resetFilter'
+ 'click .reset-current-filter': 'resetFilter',
+ 'click .update-dht': 'updateDht',
+ 'mousedown #customMoviesServer': 'showFullDatalist',
+ 'mousedown #customSeriesServer': 'showFullDatalist',
+ 'mousedown #customAnimeServer': 'showFullDatalist'
},
onAttach: function () {
@@ -100,7 +102,12 @@
rightclick_field: function (e) {
e.preventDefault();
- var menu = new this.context_Menu(i18n.__('Cut'), i18n.__('Copy'), i18n.__('Paste'), e.target.id);
+ var menu;
+ if (/customMoviesServer|customSeriesServer|customAnimeServer/.test(e.target.id)) {
+ menu = new this.altcontext_Menu(i18n.__('Cut'), i18n.__('Copy'), i18n.__('Paste'), e.target.id);
+ } else {
+ menu = new this.context_Menu(i18n.__('Cut'), i18n.__('Copy'), i18n.__('Paste'), e.target.id);
+ }
menu.popup(e.originalEvent.x, e.originalEvent.y);
},
@@ -131,7 +138,52 @@
menu.append(cut);
menu.append(copy);
menu.append(paste);
+ return menu;
+ },
+
+ altcontext_Menu: function (cutLabel, copyLabel, pasteLabel, field) {
+ var menu = new nw.Menu(),
+ clipboard = nw.Clipboard.get(),
+ text = $('#' + field).val(),
+
+ cut = new nw.MenuItem({
+ label: cutLabel || 'Cut',
+ click: function () {
+ text = $('#' + field).val();
+ clipboard.set(text, 'text');
+ $('.notification_alert').text(i18n.__('The API Server URL(s) was copied to the clipboard')).fadeIn('fast').delay(2500).fadeOut('fast');
+ $('#' + field).val('');
+ }
+ }),
+ copy = new nw.MenuItem({
+ label: copyLabel || 'Copy',
+ click: function () {
+ text = $('#' + field).val();
+ clipboard.set(text, 'text');
+ $('.notification_alert').text(i18n.__('The API Server URL(s) was copied to the clipboard')).fadeIn('fast').delay(2500).fadeOut('fast');
+ }
+ }),
+
+ paste = new nw.MenuItem({
+ label: pasteLabel || 'Paste',
+ click: function () {
+ document.execCommand('paste');
+ }
+ });
+
+ $('#' + field).one('blur', function() {
+ if (text && !$('#' + field).val()) {
+ $('#' + field).val(text);
+ if (!AdvSettings.get(field)) {
+ AdvSettings.set(field, text);
+ }
+ }
+ });
+
+ menu.append(cut);
+ menu.append(copy);
+ menu.append(paste);
return menu;
},
@@ -150,26 +202,6 @@
App.vent.trigger('settings:close');
},
- resettvshow: function () {
- var value = [{
- url: 'https:///',
- strictSSL: true
- }, {
- url: 'https:///',
- strictSSL: true
- }];
- App.settings['tvshow'] = value;
- //save to db
- App.db.writeSetting({
- key: 'tvshow',
- value: value
- }).then(function () {
- that.ui.success_alert.show().delay(3000).fadeOut(400);
- });
-
- that.syncSetting('tvshow', value);
- },
-
generateQRcode: function () {
var qrcodecanvus = document.getElementById('qrcode'),
QRCodeInfo = {
@@ -244,19 +276,6 @@
apiDataChanged = true;
value = parseInt(field.val());
break;
- case 'tvshow':
- value = field.val();
- if (value.substr(-1) !== '/') {
- value += '/';
- }
- if (value.substr(0, 8) !== 'https://' && value.substr(0, 7) !== 'http://') {
- value = 'http://' + value;
- }
- value = [{
- url: value,
- strictSSL: value.substr(0, 8) === 'https://'
- }];
- break;
case 'subtitle_size':
case 'tv_detail_jump_to':
case 'subtitle_language':
@@ -298,9 +317,13 @@
case 'protocolEncryption':
case 'contentLangOnly':
case 'vpnEnabled':
+ case 'dhtEnable':
case 'coversShowRating':
case 'torColSearchMore':
case 'showSeedboxOnDlInit':
+ case 'showSubmitMeta':
+ case 'expandedSearch':
+ case 'showUndoRBookmark':
case 'nativeWindowFrame':
case 'translatePosters':
case 'translateSynopsis':
@@ -340,6 +363,7 @@
case 'streamPort':
case 'subtitle_color':
case 'maxActiveTorrents':
+ case 'maxUdpReqLimit':
value = field.val();
break;
case 'downloadLimit':
@@ -364,6 +388,16 @@
value = nvalue;
win.zoomLevel = Math.log(value/100) / Math.log(1.2);
break;
+ case 'preloadNextEpisodeTime':
+ let nnvalue = field.val().replace(/[^0-9]/gi, '');
+ if (!nnvalue) {
+ nnvalue = 1;
+ } else {
+ nnvalue = parseInt(nnvalue);
+ }
+ field.val(nnvalue);
+ value = nnvalue;
+ break;
case 'tmpLocation':
tmpLocationChanged = true;
value = field.val();
@@ -446,6 +480,7 @@
}
break;
case 'protocolEncryption':
+ case 'maxUdpReqLimit':
this.alertMessageSuccess(true);
break;
case 'downloadLimit':
@@ -574,6 +609,9 @@
case 'multipleExtSubtitles':
case 'torColSearchMore':
case 'httpApiEnabled':
+ case 'showSubmitMeta':
+ case 'expandedSearch':
+ case 'playNextEpisodeAuto':
$('.nav-hor.left li:first').click();
App.vent.trigger('settings:show');
break;
@@ -593,10 +631,12 @@
$('.nav-hor.left li:first').click();
App.vent.trigger('settings:show');
break;
- case 'tvshow':
- App.Providers.delete('tvshow');
- $('.nav-hor.left li:first').click();
- App.vent.trigger('settings:show');
+ case 'dhtEnable':
+ if (Settings.dhtEnable) {
+ this.updateDht('enable');
+ } else {
+ this.alertMessageSuccess(true);
+ }
break;
default:
}
@@ -642,6 +682,16 @@
}
},
+ updateDht: function(e) {
+ let updateMode = '';
+ if (e === 'enable') {
+ updateMode = e;
+ } else if (e) {
+ updateMode = 'manual';
+ }
+ App.DhtReader.update(updateMode);
+ },
+
connectTrakt: function (e) {
if (!Settings.traktStatus) {
$('#authTrakt').hide();
@@ -713,6 +763,18 @@
setTimeout(self.render, 200);
},
+ showFullDatalist: function(e) {
+ if (e.button === 0 && (!e.detail || e.detail === 1)) {
+ var tmpDlist = $(e.target).val();
+ $(e.target).val('');
+ $(e.target).one('blur', function() {
+ if (tmpDlist && !$(e.target).val()) {
+ $(e.target).val(tmpDlist);
+ }
+ });
+ }
+ },
+
rebuildBookmarks: function (e) {
var btn = $(e.currentTarget);
@@ -723,30 +785,36 @@
this.alertMessageWait(i18n.__('We are rebuilding your database'));
Database.getAllBookmarks()
- .then(function (data) {
+ .then(async function (data) {
let movieProvider = App.Config.getProviderForType('movie')[0];
let showProvider = App.Config.getProviderForType('tvshow')[0];
- for (let item of data) {
+ for (let n in data) {
+ let item = data[n];
if (item.type === 'movie') {
- movieProvider.fetch({keywords: item.imdb_id}).then(function (movies) {
+ await movieProvider.fetch({keywords: item.imdb_id, page:1}).then(function (movies) {
if (movies.results.length !== 1) {
return;
}
let movie = movies.results[0];
Database.deleteMovie(item.imdb_id);
- movie.providers = [movieProvider.name];
+ movie.providers = {};
+ movie.providers.torrent = movieProvider;
Database.addMovie(movie);
});
}
if (item.type === 'show') {
- showProvider.detail(item.imdb_id, {
+ await showProvider.detail(item.imdb_id, {
contextLocale: App.settings.contextLanguage || App.settings.language
}).then(function (show) {
Database.deleteTVShow(item.imdb_id);
- show.providers = [showProvider.name];
+ show.providers = {};
+ show.providers.torrent = showProvider;
Database.addTVShow(show);
});
}
+ that.alertMessageWait(i18n.__('Rebuilding bookmarks (%s)', n+'/'+data.length));
+ // api has nginx limit rps
+ await new Promise(resolve => setTimeout(resolve, 700));
}
that.alertMessageSuccess(true);
});
@@ -959,7 +1027,7 @@
alertMessageWait: function (waitDesc) {
App.vent.trigger('notification:show', new App.Model.Notification({
title: i18n.__('Please wait') + '...',
- body: waitDesc + '.',
+ body: waitDesc,
type: 'danger'
}));
},
@@ -975,7 +1043,7 @@
notificationModel.set('showRestart', true);
notificationModel.set('body', i18n.__('Please restart your application'));
} else {
- notificationModel.attributes.autoclose = 4000;
+ notificationModel.attributes.autoclose = true;
}
// Open the notification
diff --git a/src/app/lib/views/show_detail.js b/src/app/lib/views/show_detail.js
index 814de47fe7..133b1f859a 100644
--- a/src/app/lib/views/show_detail.js
+++ b/src/app/lib/views/show_detail.js
@@ -1,9 +1,6 @@
(function (App) {
'use strict';
- var torrentHealth = require('webtorrent-health');
- var cancelTorrentHealth = function () {};
- var torrentHealthRestarted = null;
let healthButton;
var _this, bookmarked;
@@ -28,6 +25,7 @@
'click .tab-episode': 'clickEpisode',
'click .shmi-year': 'openRelInfo',
'click .shmi-imdb': 'openIMDb',
+ 'click .shmi-tmdb-link': 'openTmdb',
'mousedown .magnet-icon': 'openMagnet',
'mousedown .source-icon': 'openSource',
'dblclick .tab-episode': 'dblclickEpisode',
@@ -164,7 +162,7 @@
this.loadAudioDropdown();
this.getRegion('qualitySelector').empty();
- $('.star-container-tv,.shmi-year,.shmi-imdb,.magnet-icon,.source-icon').tooltip();
+ $('.star-container-tv,.shmi-year,.shmi-imdb,.shmi-tmdb-link,.magnet-icon,.source-icon').tooltip();
var noimg = 'images/posterholder.png';
var nobg = 'images/bg-header.jpg';
var images = this.model.get('images');
@@ -366,23 +364,44 @@
openMagnet: function (e) {
var torrentUrl = $('.startStreaming').attr('data-torrent').replace(/\&/g, '&');
torrentUrl = torrentUrl.split('&tr=')[0] + _.union(decodeURIComponent(torrentUrl).replace(/\/announce/g, '').split('&tr=').slice(1), Settings.trackers.forced.toString().replace(/\/announce/g, '').split(',')).map(t => `&tr=${t}/announce`).join('');
- if (e.button === 2) { //if right click on magnet link
- var clipboard = nw.Clipboard.get();
- clipboard.set(torrentUrl, 'text'); //copy link to clipboard
- $('.notification_alert').text(i18n.__('The magnet link was copied to the clipboard')).fadeIn('fast').delay(2500).fadeOut('fast');
- } else {
- nw.Shell.openExternal(torrentUrl);
- }
+ Common.openOrClipboardLink(e, torrentUrl, i18n.__('magnet link'));
},
openSource: function (e) {
var torrentUrl = $('.startStreaming').attr('data-source');
- if (e.button === 2) { //if right click on magnet link
- var clipboard = nw.Clipboard.get();
- clipboard.set(torrentUrl, 'text'); //copy link to clipboard
- $('.notification_alert').text(i18n.__('The source link was copied to the clipboard')).fadeIn('fast').delay(2500).fadeOut('fast');
+ Common.openOrClipboardLink(e, torrentUrl, i18n.__('source link'));
+ },
+
+ openTmdb: function(e) {
+ let imdb = this.model.get('imdb_id'),
+ tmdb = this.model.get('tmdb_id'),
+ api_key = Settings.tmdb.api_key;
+
+ if (!tmdb) {
+ let show = (function () {
+ let tmp = null;
+ $.ajax({
+ url: 'http://api.themoviedb.org/3/find/' + imdb + '?api_key=' + api_key + '&external_source=imdb_id',
+ type: 'get',
+ dataType: 'json',
+ timeout: 5000,
+ async: false,
+ global: false,
+ success: function (data) {
+ tmp = data;
+ }
+ });
+ return tmp;
+ }());
+ show && show.tv_results && show.tv_results[0] && show.tv_results[0].id ? this.model.set('tmdb_id', show.tv_results[0].id) : null;
+ tmdb = this.model.get('tmdb_id');
+ }
+
+ if (tmdb) {
+ let tmdbLink = 'https://www.themoviedb.org/tv/' + tmdb + '/edit?language=' + Settings.language;
+ Common.openOrClipboardLink(e, tmdbLink, i18n.__('TMDB link'));
} else {
- nw.Shell.openExternal(torrentUrl);
+ $('.shmi-tmdb-link').addClass('disabled').prop('disabled', true).attr('title', i18n.__('Not available')).tooltip('hide').tooltip('fixTitle');
}
},
@@ -397,8 +416,8 @@
return;
}
$('.spinner').show();
- const provider = this.model.get('providers').torrent;
- const data = await provider.contentOnLang(this.model.get('imdb_id'), lang);
+ const showProvider = App.Config.getProviderForType('tvshow')[0];
+ const data = await showProvider.contentOnLang(this.model.get('imdb_id'), lang);
this.model.set('contextLocale', data.contextLocale);
this.model.set('episodes', data.episodes);
this.initTorrents(data.episodes);
diff --git a/src/app/lib/views/torrent_collection.js b/src/app/lib/views/torrent_collection.js
index 7cac659b84..1c0064698b 100644
--- a/src/app/lib/views/torrent_collection.js
+++ b/src/app/lib/views/torrent_collection.js
@@ -468,13 +468,7 @@
}
magnetLink = magnetLink.split('&tr=')[0] + _.union(decodeURIComponent(magnetLink).replace(/\/announce/g, '').split('&tr=').slice(1), Settings.trackers.forced.toString().replace(/\/announce/g, '').split(',')).map(t => `&tr=${t}/announce`).join('');
- if (e.button === 2) { //if right click on magnet link
- var clipboard = nw.Clipboard.get();
- clipboard.set(magnetLink, 'text'); //copy link to clipboard
- $('.notification_alert').text(i18n.__('The magnet link was copied to the clipboard')).fadeIn('fast').delay(2500).fadeOut('fast');
- } else {
- nw.Shell.openExternal(magnetLink);
- }
+ Common.openOrClipboardLink(e, magnetLink, i18n.__('magnet link'));
},
deleteItem: function (e) {
diff --git a/src/app/settings.js b/src/app/settings.js
index 05ff501c4f..308401ec53 100644
--- a/src/app/settings.js
+++ b/src/app/settings.js
@@ -4,14 +4,14 @@ var Settings = {
projectUrl: 'https://popcorntime.app',
projectCi: 'https://ci.popcorntime.app',
projectBlog: 'https://blog.popcorntime.app/',
- projectForum: 'https://www.reddit.com/r/PopcornTime',
+ projectForum: 'https://www.reddit.com/r/PopcornTimeApp',
projectForum2: 'https://discuss.popcorntime.app',
- projectForum3: 'https://www.reddit.com/r/PopcornTimeApp',
statusUrl: 'http://status.popcorntime.app',
changelogUrl: 'https://github.com/popcorn-official/popcorn-desktop/commits/master',
issuesUrl: 'https://github.com/popcorn-official/popcorn-desktop/issues',
sourceUrl: 'https://github.com/popcorn-official/popcorn-desktop/',
commitUrl: 'https://github.com/popcorn-official/popcorn-desktop/commit',
+ dht: '',
updateKey:
'-----BEGIN PUBLIC KEY-----\n' +
'MIIBtjCCASsGByqGSM44BAEwggEeAoGBAPNM5SX+yR8MJNrX9uCQIiy0t3IsyNHs\n' +
@@ -84,10 +84,9 @@ Settings.trackers = {
'udp://tracker.cyberia.is:6969',
'udp://tracker.torrent.eu.org:451',
'udp://open.stealth.si:80',
- 'udp://opentor.org:2710',
'udp://tracker.moeking.me:6969',
'udp://tracker.zerobytes.xyz:1337',
- 'udp://tracker.uw0.xyz:6969',
+ 'udp://explodie.org:6969',
'udp://retracker.lanta-net.ru:2710',
'wss://tracker.openwebtorrent.com'
]
@@ -127,6 +126,7 @@ Settings.translateEpisodes = true;
//Playback
Settings.alwaysFullscreen = false;
Settings.playNextEpisodeAuto = false;
+Settings.preloadNextEpisodeTime = 1;
Settings.activateLoCtrl = false;
Settings.chosenPlayer = 'local';
@@ -141,6 +141,9 @@ Settings.moviesTabEnable = true;
Settings.seriesTabEnable = true;
Settings.animeTabEnable = true;
Settings.showSeedboxOnDlInit = true;
+Settings.showSubmitMeta = true;
+Settings.showUndoRBookmark = true;
+Settings.expandedSearch = false;
// Quality
Settings.shows_default_quality = '720p';
@@ -179,6 +182,7 @@ Settings.connectionLimit = 55;
Settings.downloadLimit = '';
Settings.uploadLimit = '';
Settings.maxLimitMult = 1024;
+Settings.maxUdpReqLimit = 16;
Settings.streamPort = 0; // 0 = Random
Settings.protocolEncryption = false;
Settings.tmpLocation = path.join(os.tmpdir(), Settings.projectName);
@@ -190,8 +194,9 @@ Settings.delSeedboxCache = 'ask';
Settings.continueSeedingOnStart = false;
Settings.vpnEnabled = false;
Settings.maxActiveTorrents = 5;
-Settings.automaticUpdating = true;
+Settings.automaticUpdating = '';
Settings.UpdateSeed = false;
+Settings.dhtEnable = '';
Settings.events = true;
Settings.minimizeToTray = false;
diff --git a/src/app/styl/views/filter_bar.styl b/src/app/styl/views/filter_bar.styl
index aeed85a3bc..b4c2bc06e1 100644
--- a/src/app/styl/views/filter_bar.styl
+++ b/src/app/styl/views/filter_bar.styl
@@ -121,7 +121,7 @@
padding: 3px 5px
font-size: 1.2em
- &.edited input, input:focus
+ &.edited input, input:focus, input.expanded
width: 180px
background-color: $SearchBoxBg
color: $FilterBarText
diff --git a/src/app/styl/views/initializing.styl b/src/app/styl/views/initializing.styl
index 471604ce68..b62cbf3211 100644
--- a/src/app/styl/views/initializing.styl
+++ b/src/app/styl/views/initializing.styl
@@ -155,6 +155,58 @@
width 100%
height 100%
+ input[type=checkbox]
+ position absolute
+ overflow hidden
+ clip rect(0 0 0 0)
+ height 1px
+ width 1px
+ margin -1px
+ padding 0
+ border 0
+
+ &+label
+ height 15px
+ display inline-block
+ line-height 15px
+ font-size 13px
+ font-family $MainFont
+ vertical-align middle
+ cursor pointer
+
+ &:hover
+ opacity 1
+
+ &:checked+label
+ opacity 1
+
+ &:after
+ opacity 1
+
+ label
+ &:before
+ content '\f0c8'
+ font-family "Font Awesome 5 Free"
+ font-weight 900
+ font-size 18px
+ padding-right 8px
+ float left
+ position relative
+ color $CheckboxBg
+
+ &:after
+ content '\f00c'
+ font-family "Font Awesome 5 Free"
+ font-weight 900
+ font-size 12px
+ margin-right -14px
+ color $CheckboxCheck
+ position relative
+ float left
+ left -21px
+ opacity 0
+ transition opacity .1s ease-in-out
+
.icon-disclaimer
z-index 1000
top 20%
@@ -194,13 +246,25 @@
position relative
.disclaimer-content
- padding-top 20%
+ padding-top 14%
height 100%
h1
font-size 25px
text-transform uppercase
+ .dhtEnableSpn
+ display block
+ font-size 0.9em
+ text-align left
+ padding 12px 0 0 28px
+
+ .automaticUpdatingSpn
+ display block
+ font-size 0.9em
+ text-align left
+ padding 10px 0 8px 28px
+
.disclaimer-text
font-size 14px
margin 20px
diff --git a/src/app/styl/views/movie_detail.styl b/src/app/styl/views/movie_detail.styl
index b1e3650dab..c409267ea8 100644
--- a/src/app/styl/views/movie_detail.styl
+++ b/src/app/styl/views/movie_detail.styl
@@ -117,6 +117,25 @@
font-smoothing: antialiased
cursor: pointer
+ .tmdb-link
+ color: #f8f8f8
+ font-size: 11px
+ position: relative
+ font-family: "Font Awesome 5 Free"
+ text-stroke: 1px rgba(0,0,0,0.1)
+ float: left
+ font-smoothing: antialiased
+ cursor: pointer
+ opacity: 0.4
+ transition: opacity .3s ease-in
+
+ &:hover
+ opacity: 1
+
+ &.disabled
+ cursor: default
+ opacity: 0.4
+
.year, .certification
color: #f8f8f8
font-size: 12px
diff --git a/src/app/styl/views/notification.styl b/src/app/styl/views/notification.styl
index 1d4479b71a..dfb5c89412 100644
--- a/src/app/styl/views/notification.styl
+++ b/src/app/styl/views/notification.styl
@@ -33,7 +33,7 @@
&.warning
background $NotificationWarning
- &.orange
+ &.danger
background $NotificationOrange
&.error
@@ -42,7 +42,7 @@
.close
position absolute
top 5px
- right 5px
+ right 7px
opacity 0.7
color white
&:hover
@@ -71,6 +71,9 @@
background $NotificationBtn
opacity .7
+ label
+ cursor pointer
+
.btn.chnglog
margin-right 5px
diff --git a/src/app/styl/views/seedbox.styl b/src/app/styl/views/seedbox.styl
index 0d5a05ade2..452c7de940 100644
--- a/src/app/styl/views/seedbox.styl
+++ b/src/app/styl/views/seedbox.styl
@@ -28,7 +28,8 @@
.seedbox-types ul, .seedbox-torrents ul
height: calc(100vh - 167px)
- direction: rtl
+ /* direction: rtl */
+ text-align: right
scrollable()
li
@@ -39,20 +40,26 @@
cursor: pointer
.watched
- padding 9px 0
+ padding 10px 0
color: $ShowWatchedIcon_false
transition color .5s
-
- &:hover
- color: $ShowWatchedIcon_hover
+ font-size: 0.9em
+ font-family: "Font Awesome 5 Free", $MainFont
&.true
color: $ShowWatchedIcon_true
&.disabled
- pointer-events: none
+ cursor: not-allowed
opacity: 0.2
+ &:hover
+ color: $ShowWatchedIcon_false !important
+
+ .watched:not(.fa-download):not(.fa-upload)
+ &:hover
+ color: $ShowWatchedIcon_true
+
li:nth-child(odd)
background-color $ShowBgColor2
@@ -137,6 +144,10 @@
.seedbox-torrent-list ul li.active i
color: rgba($EpisodeSelectorText,.5)
+ .seedbox-torrent-list ul li.active i:not(.fa-download):not(.fa-upload)
+ &:hover
+ color: $EpisodeSelectorText
+
.seedbox-torrent-list ul li.error
background: $NotificationError
@@ -246,6 +257,10 @@
white-space: nowrap
text-overflow: ellipsis
+ i
+ margin-right: 5px
+ font-family: "Font Awesome 5 Free", $MainFont
+
.seedbox-infos-synopsis
color: $ShowText1
font-size: 13px
@@ -273,27 +288,57 @@
filter brightness(110%)
backdrop-filter brightness(110%)
+ & > .item-remove
+ display inline-block
+
+ &.unselected
+ opacity 0.3
+
+ &:hover
+ opacity 0.5
+
+ & > .item-download
+ display inline-block
+
+ .item-download
+ display none
+
a
color $FileSelectorText
text-decoration blink
- width 100%
+ width calc(100% - 20px)
display block
transition all 0.3s
overflow hidden
white-space nowrap
text-overflow ellipsis
+ margin-left 25px
- .item-delete,
- .item-rename
+ .item-download,
+ .item-remove,
+ .item-play
position relative
color: $TextError
transition all 0.3s
cursor pointer
- left calc(100% + 22px)
+ left calc(100% + 7px)
top -17px
- .item-rename
- left calc(100% - 15px)
+ &:hover
+ color $CloseButtonHover
+
+ .item-play
+ left 0px
+
+ &.disabled
+ cursor not-allowed
+ opacity 0.3
+
+ &:hover
+ color: $TextError !important
+
+ .item-remove
+ display none
.item-icon
position relative
diff --git a/src/app/styl/views/settings_container.styl b/src/app/styl/views/settings_container.styl
index 89f246f450..1bd6a4d4fc 100644
--- a/src/app/styl/views/settings_container.styl
+++ b/src/app/styl/views/settings_container.styl
@@ -285,6 +285,40 @@
position relative
top 2px
+ #apiserver
+ input
+ text-overflow ellipsis
+
+ .valid-tick
+ width 20px
+ height 20px
+ display inline-flex
+ line-height 12px
+
+ &:before
+ content "\2714"
+ font-family Arial
+ font-size 17px
+ font-weight bold
+ text-shadow 0 0 10px #4EEE30
+ color #4EEE30
+ position relative
+ top 1px
+
+ .invalid-cross
+ width 20px
+ height 20px
+ display inline-flex
+ line-height 12px
+ vertical-align top
+
+ &:before
+ content "\2573"
+ font-family Arial
+ font-size 12px
+ font-weight bolder
+ text-shadow 0 0 10px #EE3030
+ color #EE3030
#connection
#overallRatio
@@ -357,9 +391,11 @@
transition: all .5s
.set-current-filter,
- .reset-current-filter
+ .reset-current-filter,
+ .update-dht,
+ .update-app
font-size: 13px
- margin-left: 10px
+ margin: 0 2px 0 8px
transition: all 0.5s
cursor: pointer
&:hover
@@ -622,7 +658,9 @@
.default-frame
.settings-container-contain
padding-top 0
+ .close-icon
+ top 5px
&::-webkit-scrollbar-track
margin-top: $FilterBarHeight
.close-icon
- top 5px
+ top 45px
diff --git a/src/app/styl/views/show_detail.styl b/src/app/styl/views/show_detail.styl
index 721ef54dc9..c3385a3f4e 100644
--- a/src/app/styl/views/show_detail.styl
+++ b/src/app/styl/views/show_detail.styl
@@ -87,6 +87,18 @@
div.shmi-year
cursor: pointer
+ div.shmi-tmdb-link
+ cursor: pointer
+ opacity: 0.4
+ transition: opacity .3s ease-in
+
+ &:hover
+ opacity: 1
+
+ &.disabled
+ cursor: default
+ opacity: 0.4
+
div.shmi-imdb
cursor: pointer
background: url(../images/icons/imdb.png) no-repeat
diff --git a/src/app/templates/about.tpl b/src/app/templates/about.tpl
index a2d7b6b617..f4e8653d44 100644
--- a/src/app/templates/about.tpl
+++ b/src/app/templates/about.tpl
@@ -25,7 +25,7 @@
-
+
diff --git a/src/app/templates/browser/filter-bar.tpl b/src/app/templates/browser/filter-bar.tpl
index 3b908eef8f..254716e355 100644
--- a/src/app/templates/browser/filter-bar.tpl
+++ b/src/app/templates/browser/filter-bar.tpl
@@ -1,6 +1,12 @@
<% _.each (App.Config.getTabTypes(), function (tab) { %>
- <%= i18n.__(tab.name) %>
+ <% var providerURL = App.Config.getProviderForType(tab.type)[0].apiURL.slice(0);
+ providerURL.forEach(function(e, index) {
+ providerURL[index] = e.replace(/http:\/\/|https:\/\/|\/$/g, '');
+ });
+ providerURL = providerURL.join(' ');
+ %>
+ <%= i18n.__(tab.name) %>
<% }); %>
<%= i18n.__("Favorites") %>
@@ -37,7 +43,7 @@
diff --git a/src/app/templates/disclaimer.tpl b/src/app/templates/disclaimer.tpl
index 33eeff6463..b739e6047f 100644
--- a/src/app/templates/disclaimer.tpl
+++ b/src/app/templates/disclaimer.tpl
@@ -29,6 +29,14 @@
By using '<%= Settings.projectName %>' or accessing this site you affirm that you are either more than 18 years of age, or an emancipated minor, or possess legal parental or guardian consent, and are fully able and competent to enter into the terms, conditions, obligations, affirmations, representations, and warranties set forth in these Terms of Service, and to abide by and comply with these Terms of Service. In any case, you affirm that you are over the age of 13, as the Service is not intended for children under 13. If you are under 13 years of age, then please do not use the Service. There are lots of other great web sites for you. Talk to your parents about what sites are appropriate for you.
+
+ >
+ <%= i18n.__("Enable automatically updating the API Server URLs") %>
+
+
+ >
+ <%= i18n.__("Enable automatically updating the app when a new version is available") %>
+
<%= i18n.__("I Accept") %> <%= i18n.__("Leave") %>
diff --git a/src/app/templates/keyboard.tpl b/src/app/templates/keyboard.tpl
index 87cb7e8005..eda05435b8 100644
--- a/src/app/templates/keyboard.tpl
+++ b/src/app/templates/keyboard.tpl
@@ -284,6 +284,46 @@
0
<%= i18n.__("Set player window to half of video resolution") %>
+
+ w
+ <%= i18n.__("Decrease Zoom by") %> 5%
+
+
+ e
+ <%= i18n.__("Increase Zoom by") %> 5%
+
+
+ <%= i18n.__("shift") %> +1
+ <%= i18n.__("Decrease Contrast by") %> 5%
+
+
+ <%= i18n.__("shift") %> +2
+ <%= i18n.__("Increase Contrast by") %> 5%
+
+
+ <%= i18n.__("shift") %> +3
+ <%= i18n.__("Decrease Brightness by") %> 5%
+
+
+ <%= i18n.__("shift") %> +4
+ <%= i18n.__("Increase Brightness by") %> 5%
+
+
+ <%= i18n.__("shift") %> +5
+ <%= i18n.__("Rotate Hue counter-clockwise by") %> 1°
+
+
+ <%= i18n.__("shift") %> +6
+ <%= i18n.__("Rotate Hue clockwise by") %> 1°
+
+
+ <%= i18n.__("shift") %> +7
+ <%= i18n.__("Decrease Saturation by") %> 5%
+
+
+ <%= i18n.__("shift") %> +8
+ <%= i18n.__("Increase Saturation by") %> 5%
+
diff --git a/src/app/templates/loading.tpl b/src/app/templates/loading.tpl
index ae64765ba6..7067187ae5 100644
--- a/src/app/templates/loading.tpl
+++ b/src/app/templates/loading.tpl
@@ -13,7 +13,7 @@
-
">
+
">
<%= i18n.__("Streaming to") %>
@@ -79,9 +79,9 @@
0
<%= i18n.__("Filename") %>:
">
-
">
+
">
<%= i18n.__("Stream Url") %>:
-
">
+
">
">
diff --git a/src/app/templates/movie-detail.tpl b/src/app/templates/movie-detail.tpl
index bf435c78ae..2615b3f0dd 100644
--- a/src/app/templates/movie-detail.tpl
+++ b/src/app/templates/movie-detail.tpl
@@ -26,14 +26,14 @@ if (genre) {
<%= displayTitle %>
diff --git a/src/app/templates/seedbox.tpl b/src/app/templates/seedbox.tpl
index 4db52c060e..17d920256f 100644
--- a/src/app/templates/seedbox.tpl
+++ b/src/app/templates/seedbox.tpl
@@ -20,6 +20,7 @@
+
@@ -32,7 +33,7 @@
- Download progress
+ <%= i18n.__('Unknown time remaining') %>
-<% } %>
+ <% } %>
@@ -558,67 +576,61 @@
-
<%= i18n.__("Movies API Server") %>
-
+
<%= i18n.__("Movies API Server(s)") %>
+
">
- <% if (Settings.customServers && Settings.customServers.movie) {
- for (var i = 0; i < Settings.customServers.movie.length; ++i) {
+ <% var movieServList = [Settings.providers.movie.uri[0].split('=')[1].replace(/,/g, ', ')];
+ Settings.customServers && Settings.customServers.movie ? movieServList = movieServList.concat(Settings.customServers.movie) : null;
+ Settings.dhtData ? movieServList = movieServList.concat([Settings.dhtData.split('server":"')[1].split('","git":"')[0].replace(/,/g, ', ')]) : null;
+ for (var i = 0; i < movieServList.length; ++i) {
%>
-
- <% }} %>
+
+ <% } %>
-
-
-
+
">
-
<%= i18n.__("Series API Server") %>
-
+
<%= i18n.__("Series API Server(s)") %>
+
">
- <% if (Settings.customServers && Settings.customServers.tvshow) {
- for (var i = 0; i < Settings.customServers.tvshow.length; ++i) {
+ <% var seriesServList = [Settings.providers.tvshow.uri[0].split('=')[1].replace(/,/g, ', ')];
+ Settings.customServers && Settings.customServers.tvshow ? seriesServList = seriesServList.concat(Settings.customServers.tvshow) : null;
+ Settings.dhtData ? seriesServList = seriesServList.concat([Settings.dhtData.split('server":"')[1].split('","git":"')[0].replace(/,/g, ', ')]) : null;
+ for (var i = 0; i < seriesServList.length; ++i) {
%>
-
- <% }} %>
+
+ <% } %>
-
-
-
+
">
-
<%= i18n.__("Anime API Server") %>
-
+
<%= i18n.__("Anime API Server(s)") %>
+
">
- <% if (Settings.customServers && Settings.customServers.anime) {
- for (var i = 0; i < Settings.customServers.anime.length; ++i) {
+ <% var animeServList = [Settings.providers.anime.uri[0].split('=')[1].replace(/,/g, ', ')];
+ Settings.customServers && Settings.customServers.anime ? animeServList = animeServList.concat(Settings.customServers.anime) : null;
+ Settings.dhtData ? animeServList = animeServList.concat([Settings.dhtData.split('server":"')[1].split('","git":"')[0].replace(/,/g, ', ')]) : null;
+ for (var i = 0; i < animeServList.length; ++i) {
%>
-
- <% }} %>
+
+ <% } %>
-
-
-
+
">
+
+ * <%= i18n.__("You can add multiple API Servers separated with a , from which it will select randomly (*for load balancing) until it finds the first available") %>
+
<%= i18n.__("Connection") %>
- <% if (Settings.tvshow) { %>
-
- <%= i18n.__("TV Show API Endpoint") %>
-
- <% if (Settings.tvshow.length <= 1) { %>
-
- <% } %>
-
- <% } %>
<% if (Settings.activateSeedbox) { %>
<%= i18n.__("Active Torrents Limit") %>
@@ -629,6 +641,10 @@
<%= i18n.__("Connection Limit") %>
+
+ <%= i18n.__("DHT UDP Requests Limit") %>
+
+
<%= i18n.__("Max. Down / Up Speed") %>
@@ -692,7 +708,7 @@
diff --git a/yarn.lock b/yarn.lock
index f7cda5503d..bf9c5e0a28 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -157,6 +157,11 @@
request-promise-native "^1.0.8"
ws "^7.2.1"
+"@yarnpkg/lockfile@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
+ integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
+
abbrev@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
@@ -825,16 +830,16 @@ bittorrent-tracker@^9.1.0:
bufferutil "^4.0.3"
utf-8-validate "^5.0.5"
-bittorrent-tracker@^9.18.2:
- version "9.18.2"
- resolved "https://registry.yarnpkg.com/bittorrent-tracker/-/bittorrent-tracker-9.18.2.tgz#208f27d69bfb81ccb620655557f8778636bf0e6e"
- integrity sha512-r4v+gIi/aQP4h0rvx7WVjnEFvu7Vw2ePPFzoyQjdPfyoJaV/JTdD3kFTZBaVO/Egj5y2O2Y+bTCdPIgD2MzT+A==
+bittorrent-tracker@^9.18.3:
+ version "9.18.3"
+ resolved "https://registry.yarnpkg.com/bittorrent-tracker/-/bittorrent-tracker-9.18.3.tgz#0b2d8a20c8974d118c010b2fc99ff4d914e6cb92"
+ integrity sha512-IhLKp8wUgA7WXTfJggw/HB8qxhwlLNDWRraUFxXRHTgOQXcMiKITGcErzvC7B7mMOcUnk0wiUsZdaaQ8lzz3LQ==
dependencies:
bencode "^2.0.1"
bittorrent-peerid "^1.3.3"
bn.js "^5.2.0"
chrome-dgram "^3.0.6"
- clone "^1.0.2"
+ clone "^2.0.0"
compact2string "^1.4.1"
debug "^4.1.1"
ip "^1.1.5"
@@ -969,6 +974,13 @@ braces@^2.3.1, braces@^2.3.2:
split-string "^3.0.2"
to-regex "^3.0.1"
+braces@^3.0.1:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
+ integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+ dependencies:
+ fill-range "^7.0.1"
+
browserify-package-json@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/browserify-package-json/-/browserify-package-json-1.0.1.tgz#98dde8aa5c561fd6d3fe49bbaa102b74b396fdea"
@@ -1049,10 +1061,10 @@ butter-sanitize@^0.1.1:
dependencies:
sanitizer "^0.1.3"
-butter-settings-popcorntime.app@0.0.6:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/butter-settings-popcorntime.app/-/butter-settings-popcorntime.app-0.0.6.tgz#4f43e3a658f90d00a991566a59e18d37fe1ba3d2"
- integrity sha512-fmboxwTi9X6yPUu3jc64hOIlSm42EWAag2WV/9D9AO/B2FaL96qXuDwp+5U1U6iQ3qtti3lxNRWTUuUdkYduOw==
+butter-settings-popcorntime.app@0.0.9:
+ version "0.0.9"
+ resolved "https://registry.yarnpkg.com/butter-settings-popcorntime.app/-/butter-settings-popcorntime.app-0.0.9.tgz#89cfd82a7115794cce69d4e299bc8d5ae12e6182"
+ integrity sha512-k/95NLPNBwnD9+daePbxye5qRjU61rMIc2ix3ytHWtekn7xDg/7ZqxIc1GfJoWYNtK7uNVmpca/JU8JMChRFsQ==
bytes@^3.0.0:
version "3.1.0"
@@ -1199,7 +1211,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
-chalk@^2.0.1, chalk@^2.3.2:
+chalk@^2.0.1, chalk@^2.3.2, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -1332,6 +1344,11 @@ ci-info@^1.5.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==
+ci-info@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
+ integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
+
class-utils@^0.3.5:
version "0.3.6"
resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
@@ -1409,7 +1426,7 @@ clone@^1.0.0, clone@^1.0.2:
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
-clone@^2.1.1:
+clone@^2.0.0, clone@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
@@ -1638,7 +1655,7 @@ cross-spawn@^5.0.1:
shebang-command "^1.2.0"
which "^1.2.9"
-cross-spawn@^6.0.0:
+cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
@@ -2444,6 +2461,13 @@ fill-range@^4.0.0:
repeat-string "^1.6.1"
to-regex-range "^2.1.0"
+fill-range@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
+ integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
+ dependencies:
+ to-regex-range "^5.0.1"
+
find-up@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
@@ -2464,6 +2488,13 @@ find-value@^1.0.3:
resolved "https://registry.yarnpkg.com/find-value/-/find-value-1.0.12.tgz#68b6cec84e5b2d51272965e0bf09b26c9159c26e"
integrity sha512-OCpo8LTk8eZ2sdDCwbU2Lc3ivYsdM6yod6jP2jHcNEFcjPhkgH0+POzTIol7xx1LZgtbI5rkO5jqxsG5MWtPjQ==
+find-yarn-workspace-root@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd"
+ integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==
+ dependencies:
+ micromatch "^4.0.2"
+
findup-sync@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc"
@@ -2577,10 +2608,10 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
-fs-chunk-store@^2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/fs-chunk-store/-/fs-chunk-store-2.0.3.tgz#21e51f1833a84a07cb5e911d058dae084030375a"
- integrity sha512-qQi93nHX3880gtoQPt1hKQcuYBNVfCbMk8OVRDqR0cJ0riheELW25ry9yl7pII8E9gOAONTGKBD5N/zGHFSVQg==
+fs-chunk-store@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/fs-chunk-store/-/fs-chunk-store-2.0.4.tgz#ca797b7032a3752d1e7553cb9cec8970395cc34a"
+ integrity sha512-JfeKRPPWkLaUoNKZdi+eLPKzZkZK1pdj2Y5lidEw9fUCkglvK/muLe6ONjdvn8yAGrDsk4tkjNp52GS658yy0g==
dependencies:
queue-microtask "^1.2.2"
random-access-file "^2.0.1"
@@ -2605,6 +2636,15 @@ fs-extra@^0.30.0:
path-is-absolute "^1.0.0"
rimraf "^2.2.8"
+fs-extra@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
+ integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
+ dependencies:
+ graceful-fs "^4.1.2"
+ jsonfile "^4.0.0"
+ universalify "^0.1.0"
+
fs-minipass@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
@@ -3293,9 +3333,9 @@ http-headers@^3.0.1:
dependencies:
next-line "^1.1.0"
-"http-node@github:feross/http-node#webtorrent":
+"http-node@github:webtorrent/http-node#webtorrent":
version "1.2.0"
- resolved "https://codeload.github.com/feross/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974"
+ resolved "https://codeload.github.com/webtorrent/http-node/tar.gz/342ef8624495343ffd050bd0808b3750cf0e3974"
dependencies:
chrome-net "^3.3.3"
freelist "^1.0.3"
@@ -3519,6 +3559,13 @@ is-ci@^1.0.10:
dependencies:
ci-info "^1.5.0"
+is-ci@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c"
+ integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==
+ dependencies:
+ ci-info "^2.0.0"
+
is-core-module@^2.2.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.6.0.tgz#d7553b2526fe59b92ba3e40c8df757ec8a709e19"
@@ -3565,6 +3612,11 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2:
is-data-descriptor "^1.0.0"
kind-of "^6.0.2"
+is-docker@^2.0.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
+ integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
+
is-dotfile@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
@@ -3679,6 +3731,11 @@ is-number@^4.0.0:
resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==
+is-number@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
+ integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
is-obj@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
@@ -3802,6 +3859,13 @@ is-windows@^1.0.1, is-windows@^1.0.2:
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
+is-wsl@^2.1.1:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
+ integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
+ dependencies:
+ is-docker "^2.0.0"
+
isarray@0.0.1, isarray@~0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
@@ -3956,6 +4020,13 @@ jsonfile@^2.1.0:
optionalDependencies:
graceful-fs "^4.1.6"
+jsonfile@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
+ integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
+ optionalDependencies:
+ graceful-fs "^4.1.6"
+
jsonparse@1.x.x:
version "1.3.1"
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
@@ -4055,6 +4126,13 @@ kind-of@^6.0.0, kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
+klaw-sync@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c"
+ integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==
+ dependencies:
+ graceful-fs "^4.1.11"
+
klaw@^1.0.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439"
@@ -4648,6 +4726,14 @@ micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.2"
+micromatch@^4.0.2:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
+ integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
+ dependencies:
+ braces "^3.0.1"
+ picomatch "^2.2.3"
+
mime-db@1.49.0:
version "1.49.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed"
@@ -4937,6 +5023,11 @@ nice-try@^1.0.4:
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
+noble-ed25519@^1.2.5:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/noble-ed25519/-/noble-ed25519-1.2.5.tgz#ed6dde9213debcf121083d18daecb30bb6416753"
+ integrity sha512-7vst+4UhM5QU3jJ3pUqPMKBCOePrxBojmoQa59qcSnYvjFF/T4jqb4WISlfslcWyBw7G5H9V/acpcAxMd8DzUQ==
+
node-fetch@^1.0.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
@@ -5203,6 +5294,14 @@ once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.3.3, once@^1.4.0:
dependencies:
wrappy "1"
+open@^7.4.2:
+ version "7.4.2"
+ resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321"
+ integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==
+ dependencies:
+ is-docker "^2.0.0"
+ is-wsl "^2.1.1"
+
opensubtitles-api@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/opensubtitles-api/-/opensubtitles-api-5.1.2.tgz#750c9e808fbf6b006225150e062de0876ff41288"
@@ -5250,6 +5349,11 @@ os-locale@^3.0.0:
lcid "^2.0.0"
mem "^4.0.0"
+os-tmpdir@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
+ integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
+
p-cancelable@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
@@ -5407,6 +5511,25 @@ pascalcase@^0.1.1:
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
+patch-package@^6.4.7:
+ version "6.4.7"
+ resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148"
+ integrity sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ==
+ dependencies:
+ "@yarnpkg/lockfile" "^1.1.0"
+ chalk "^2.4.2"
+ cross-spawn "^6.0.5"
+ find-yarn-workspace-root "^2.0.0"
+ fs-extra "^7.0.1"
+ is-ci "^2.0.0"
+ klaw-sync "^6.0.0"
+ minimist "^1.2.0"
+ open "^7.4.2"
+ rimraf "^2.6.3"
+ semver "^5.6.0"
+ slash "^2.0.0"
+ tmp "^0.0.33"
+
path-dirname@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
@@ -5484,6 +5607,11 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
+picomatch@^2.2.3:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
+ integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+
piece-length@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/piece-length/-/piece-length-2.0.1.tgz#dbed4e78976955f34466d0a65304d0cb21914ac9"
@@ -5567,6 +5695,11 @@ posix-character-classes@^0.1.0:
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
+postinstall-postinstall@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3"
+ integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==
+
prepend-http@^1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
@@ -6165,7 +6298,7 @@ right-align@^0.1.1:
dependencies:
align-text "^0.1.1"
-rimraf@^2.2.8, rimraf@^2.5.2:
+rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
@@ -6370,9 +6503,9 @@ simple-concat@^1.0.0, simple-concat@^1.0.1:
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
simple-get@^2.0.0, simple-get@^2.1.0:
- version "2.8.1"
- resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d"
- integrity sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==
+ version "2.8.2"
+ resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019"
+ integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==
dependencies:
decompress-response "^3.3.0"
once "^1.3.1"
@@ -6443,6 +6576,11 @@ single-line-log@^1.0.1:
dependencies:
string-width "^1.0.1"
+slash@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44"
+ integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==
+
smart-buffer@^1.0.13:
version "1.1.15"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16"
@@ -7042,6 +7180,13 @@ timers-ext@^0.1.7:
es5-ext "~0.10.46"
next-tick "1"
+tmp@^0.0.33:
+ version "0.0.33"
+ resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
+ integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
+ dependencies:
+ os-tmpdir "~1.0.2"
+
to-absolute-glob@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f"
@@ -7087,6 +7232,13 @@ to-regex-range@^2.1.0:
is-number "^3.0.0"
repeat-string "^1.6.1"
+to-regex-range@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
+ integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+ dependencies:
+ is-number "^7.0.0"
+
to-regex@^3.0.1, to-regex@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
@@ -7120,14 +7272,14 @@ toidentifier@1.0.0:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
-torrent-discovery@^9.4.5:
- version "9.4.6"
- resolved "https://registry.yarnpkg.com/torrent-discovery/-/torrent-discovery-9.4.6.tgz#b7e1262a77d14242aaf52eec382f6a142f49e2ae"
- integrity sha512-11FlrGmDvgD3RJhZLrC749yyqS7tKx3gXWbYN7xayVYsAcc6f8lQRQQIOF7TBgJE4f0e+ZS8dsct++aOlxFjRw==
+torrent-discovery@^9.4.6:
+ version "9.4.7"
+ resolved "https://registry.yarnpkg.com/torrent-discovery/-/torrent-discovery-9.4.7.tgz#d45ee78cb6a7004a8f3cd203ee7df915088bea70"
+ integrity sha512-7Zw474LJE5r3Momi4ykBYkjgcFhENbUxcAFs5cBllUkv9ErJPzPEGmpEuqX7V8TkLS+Clmt/l5CjV5IFHg/A/A==
dependencies:
bittorrent-dht "^10.0.2"
bittorrent-lsd "^1.1.1"
- bittorrent-tracker "^9.18.2"
+ bittorrent-tracker "^9.18.3"
debug "^4.3.2"
run-parallel "^1.2.0"
@@ -7334,6 +7486,11 @@ unique-string@^1.0.0:
dependencies:
crypto-random-string "^1.0.0"
+universalify@^0.1.0:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
+ integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
+
unordered-array-remove@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unordered-array-remove/-/unordered-array-remove-1.0.2.tgz#c546e8f88e317a0cf2644c97ecb57dba66d250ef"
@@ -7404,10 +7561,10 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"
-urijs@^1.19.1, urijs@^1.19.7:
- version "1.19.7"
- resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.7.tgz#4f594e59113928fea63c00ce688fb395b1168ab9"
- integrity sha512-Id+IKjdU0Hx+7Zx717jwLPsPeUqz7rAtuVBRLLs+qn+J2nf9NGITWVCxcijgYxBqe83C7sqsQPs6H1pyz3x9gA==
+urijs@^1.19.1, urijs@^1.19.8:
+ version "1.19.8"
+ resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.8.tgz#ee0407a18528934d3c383e691912f47043a58feb"
+ integrity sha512-iIXHrjomQ0ZCuDRy44wRbyTZVnfVNLVo3Ksz1yxNyE5wV1IDZW2S5Jszy45DTlw/UdsnRT7DyDhIz7Gy+vJumw==
urix@^0.1.0:
version "0.1.0"
@@ -7429,9 +7586,9 @@ url-parse-lax@^3.0.0:
prepend-http "^2.0.0"
url-parse@^1.1.9:
- version "1.5.3"
- resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862"
- integrity sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==
+ version "1.5.10"
+ resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
+ integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
dependencies:
querystringify "^2.1.1"
requires-port "^1.0.0"
@@ -7704,10 +7861,10 @@ webtorrent-health@1.x.x:
bittorrent-tracker "^9.1.0"
parse-torrent "^5.8.2"
-webtorrent@^1.5.5:
- version "1.5.5"
- resolved "https://registry.yarnpkg.com/webtorrent/-/webtorrent-1.5.5.tgz#af09e0ac660ac16fea1c838fdd00e56b57f9fc21"
- integrity sha512-YAEtWZxxf8N6DvdLgt79fQlIXSJU0G61YEkcWyBA+aopQGV0vCAMp1N/ifKIFt760pgKV+qzwRSbVP+/lBJ08g==
+webtorrent@^1.5.8:
+ version "1.5.8"
+ resolved "https://registry.yarnpkg.com/webtorrent/-/webtorrent-1.5.8.tgz#1dcb26347a8c0ea15a20b77f1c85dea9ce4f170b"
+ integrity sha512-ltYdloqDamay36XN8FZ+O2fqRQNDt+JGhRbOt1gCBeC+fFhke3WxEVs3/A2UtKjhwN8OEp3Go7tWU9R0S+29Lw==
dependencies:
addr-to-ip-port "^1.5.4"
bitfield "^4.0.0"
@@ -7721,8 +7878,8 @@ webtorrent@^1.5.5:
debug "^4.3.2"
end-of-stream "^1.4.4"
escape-html "^1.0.3"
- fs-chunk-store "^2.0.3"
- http-node "github:feross/http-node#webtorrent"
+ fs-chunk-store "^2.0.4"
+ http-node "github:webtorrent/http-node#webtorrent"
immediate-chunk-store "^2.2.0"
load-ip-set "^2.2.1"
lt_donthave "^1.0.1"
@@ -7736,7 +7893,6 @@ webtorrent@^1.5.5:
random-iterate "^1.0.1"
randombytes "^2.1.0"
range-parser "^1.2.1"
- readable-stream "^3.6.0"
render-media "^4.1.0"
run-parallel "^1.2.0"
run-parallel-limit "^1.1.0"
@@ -7749,7 +7905,7 @@ webtorrent@^1.5.5:
stream-to-blob "^2.0.1"
stream-to-blob-url "^3.0.2"
stream-with-known-length-to-buffer "^1.0.4"
- torrent-discovery "^9.4.5"
+ torrent-discovery "^9.4.6"
torrent-piece "^2.0.1"
unordered-array-remove "^1.0.2"
ut_metadata "^3.5.2"