From 6bb1cf3554839b6605834686431c1788833099df Mon Sep 17 00:00:00 2001
From: redSpoutnik <15638041+redSpoutnik@users.noreply.github.com>
Date: Fri, 8 May 2020 21:25:23 +0200
Subject: [PATCH 1/6] Feature: manually add subtitle
---
.../subtitleeditor/subtitleeditor.js | 30 +++
.../subtitleeditor.template.html | 1 +
src/components/subtitleuploader/style.css | 11 +
.../subtitleuploader/subtitleuploader.js | 194 ++++++++++++++++++
.../subtitleuploader.template.html | 45 ++++
src/scripts/site.js | 1 +
6 files changed, 282 insertions(+)
create mode 100644 src/components/subtitleuploader/style.css
create mode 100644 src/components/subtitleuploader/subtitleuploader.js
create mode 100644 src/components/subtitleuploader/subtitleuploader.template.html
diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js
index e9bcc0bfca..4513d1d9d9 100644
--- a/src/components/subtitleeditor/subtitleeditor.js
+++ b/src/components/subtitleeditor/subtitleeditor.js
@@ -347,6 +347,34 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings',
}
}
+ function onOpenUploadMenu(e) {
+
+ var context = dom.parentWithClass(e.target, 'subtitleEditorDialog');
+ var selectLanguage = context.querySelector('#selectLanguage');
+ var apiClient = connectionManager.getApiClient(currentItem.ServerId);
+
+ require(['subtitleUploader'], function (subtitleUploader) {
+
+ subtitleUploader.show({
+
+ languages: {
+ list: selectLanguage.innerHTML,
+ value: selectLanguage.value
+ },
+ itemId: currentItem.Id,
+ serverId: currentItem.ServerId
+
+ }).then(function (hasChanged) {
+
+ if (hasChanged) {
+ hasChanges = true;
+ reload(context, apiClient, currentItem.Id);
+ }
+ });
+ });
+
+ }
+
function onSearchSubmit(e) {
var form = this;
@@ -454,6 +482,8 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings',
dlg.querySelector('.subtitleSearchForm').addEventListener('submit', onSearchSubmit);
+ dlg.querySelector('.btnOpenUploadMenu').addEventListener('click', onOpenUploadMenu);
+
var btnSubmit = dlg.querySelector('.btnSubmit');
if (layoutManager.tv) {
diff --git a/src/components/subtitleeditor/subtitleeditor.template.html b/src/components/subtitleeditor/subtitleeditor.template.html
index 7471972f59..b01942c995 100644
--- a/src/components/subtitleeditor/subtitleeditor.template.html
+++ b/src/components/subtitleeditor/subtitleeditor.template.html
@@ -18,6 +18,7 @@
+
diff --git a/src/components/subtitleuploader/style.css b/src/components/subtitleuploader/style.css
new file mode 100644
index 0000000000..c9d5eb980d
--- /dev/null
+++ b/src/components/subtitleuploader/style.css
@@ -0,0 +1,11 @@
+.subtitleEditor-dropZone {
+ border: 0.2em dashed currentcolor;
+ border-radius: 0.25em;
+
+ text-align: center;
+ position: relative;
+ height: 12em;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
diff --git a/src/components/subtitleuploader/subtitleuploader.js b/src/components/subtitleuploader/subtitleuploader.js
new file mode 100644
index 0000000000..bf3a8ca4b3
--- /dev/null
+++ b/src/components/subtitleuploader/subtitleuploader.js
@@ -0,0 +1,194 @@
+define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', 'layoutManager', 'globalize', 'require', 'emby-button', 'emby-select', 'formDialogStyle', 'css!./style'], function (dialogHelper, connectionManager, dom, loading, scrollHelper, layoutManager, globalize, require) {
+ 'use strict';
+
+ var currentItemId;
+ var currentServerId;
+ var currentFile;
+ var hasChanges = false;
+
+ function onFileReaderError(evt) {
+
+ loading.hide();
+
+ switch (evt.target.error.code) {
+ case evt.target.error.NOT_FOUND_ERR:
+ require(['toast'], function (toast) {
+ toast(globalize.translate('MessageFileReadError'));
+ });
+ break;
+ case evt.target.error.ABORT_ERR:
+ break; // noop
+ default:
+ require(['toast'], function (toast) {
+ toast(globalize.translate('MessageFileReadError'));
+ });
+ break;
+ }
+ }
+
+ function isValidSubtitleFile(file) {
+ return file && ['.sub', '.srt', '.vtt', '.ass', '.ssa']
+ .some(function(ext) {
+ return file.name.endsWith(ext);
+ });
+ }
+
+ function setFiles(page, files) {
+
+ var file = files[0];
+
+ if (!isValidSubtitleFile(file)) {
+ page.querySelector('#subtitleOutput').innerHTML = '';
+ page.querySelector('#fldUpload').classList.add('hide');
+ page.querySelector('#labelDropSubtitle').classList.remove('hide');
+ currentFile = null;
+ return;
+ }
+
+ currentFile = file;
+
+ var reader = new FileReader();
+
+ reader.onerror = onFileReaderError;
+ reader.onloadstart = function () {
+ page.querySelector('#fldUpload').classList.add('hide');
+ };
+ reader.onabort = function () {
+ loading.hide();
+ console.debug('File read cancelled');
+ };
+
+ // Closure to capture the file information.
+ reader.onload = (function (theFile) {
+ return function () {
+
+ // Render thumbnail.
+ var html = 'subtitles' + escape(theFile.name) + '';
+
+ page.querySelector('#subtitleOutput').innerHTML = html;
+ page.querySelector('#fldUpload').classList.remove('hide');
+ page.querySelector('#labelDropSubtitle').classList.add('hide');
+
+ };
+ })(file);
+
+ // Read in the subtitle file as a data URL.
+ reader.readAsDataURL(file);
+ }
+
+ function onSubmit(e) {
+
+ var file = currentFile;
+
+ if (!isValidSubtitleFile(file)) {
+ require(['toast'], function (toast) {
+ toast(globalize.translate('MessageSubtitleFileTypeAllowed'));
+ });
+ e.preventDefault();
+ return false;
+ }
+
+ loading.show();
+
+ var dlg = dom.parentWithClass(this, 'dialog');
+ var language = dlg.querySelector('#selectLanguage').value;
+ var isForced = dlg.querySelector('#chkIsForced').checked;
+
+ connectionManager.getApiClient(currentServerId).uploadItemSubtitle(currentItemId, language, isForced, file).then(function () {
+
+ dlg.querySelector('#uploadSubtitle').value = '';
+ loading.hide();
+ hasChanges = true;
+ dialogHelper.close(dlg);
+ });
+
+ e.preventDefault();
+ return false;
+ }
+
+ function initEditor(page) {
+
+ page.querySelector('.uploadSubtitleForm').addEventListener('submit', onSubmit);
+
+ page.querySelector('#uploadSubtitle').addEventListener('change', function () {
+ setFiles(page, this.files);
+ });
+
+ page.querySelector('.btnBrowse').addEventListener('click', function () {
+ page.querySelector('#uploadSubtitle').click();
+ });
+ }
+
+ function showEditor(options, resolve, reject) {
+
+ options = options || {};
+
+ require(['text!./subtitleuploader.template.html'], function (template) {
+
+ currentItemId = options.itemId;
+ currentServerId = options.serverId;
+
+ var dialogOptions = {
+ removeOnClose: true,
+ scrollY: false
+ };
+
+ if (layoutManager.tv) {
+ dialogOptions.size = 'fullscreen';
+ } else {
+ dialogOptions.size = 'small';
+ }
+
+ var dlg = dialogHelper.createDialog(dialogOptions);
+
+ dlg.classList.add('formDialog');
+ dlg.classList.add('subtitleUploaderDialog');
+
+ dlg.innerHTML = globalize.translateDocument(template, 'core');
+
+ if (layoutManager.tv) {
+ scrollHelper.centerFocus.on(dlg, false);
+ }
+
+ // Has to be assigned a z-index after the call to .open()
+ dlg.addEventListener('close', function () {
+
+ if (layoutManager.tv) {
+ scrollHelper.centerFocus.off(dlg, false);
+ }
+
+ loading.hide();
+ resolve(hasChanges);
+ });
+
+ dialogHelper.open(dlg);
+
+ initEditor(dlg);
+
+ var selectLanguage = dlg.querySelector('#selectLanguage');
+
+ if (options.languages) {
+
+ selectLanguage.innerHTML = options.languages.list || null;
+ selectLanguage.value = options.languages.value || null;
+ }
+
+ dlg.querySelector('.btnCancel').addEventListener('click', function () {
+
+ dialogHelper.close(dlg);
+ });
+ });
+ }
+
+ return {
+ show: function (options) {
+
+ return new Promise(function (resolve, reject) {
+
+ hasChanges = false;
+
+ showEditor(options, resolve, reject);
+ });
+ }
+ };
+});
diff --git a/src/components/subtitleuploader/subtitleuploader.template.html b/src/components/subtitleuploader/subtitleuploader.template.html
new file mode 100644
index 0000000000..ef09775cdd
--- /dev/null
+++ b/src/components/subtitleuploader/subtitleuploader.template.html
@@ -0,0 +1,45 @@
+
+
+
diff --git a/src/scripts/site.js b/src/scripts/site.js
index c00169d224..d3a47031bb 100644
--- a/src/scripts/site.js
+++ b/src/scripts/site.js
@@ -799,6 +799,7 @@ var AppInfo = {};
define('recordingButton', [componentsPath + '/recordingcreator/recordingbutton'], returnFirstDependency);
define('recordingHelper', [componentsPath + '/recordingcreator/recordinghelper'], returnFirstDependency);
define('subtitleEditor', [componentsPath + '/subtitleeditor/subtitleeditor'], returnFirstDependency);
+ define('subtitleUploader', [componentsPath + '/subtitleuploader/subtitleuploader'], returnFirstDependency);
define('subtitleSync', [componentsPath + '/subtitlesync/subtitlesync'], returnFirstDependency);
define('itemIdentifier', [componentsPath + '/itemidentifier/itemidentifier'], returnFirstDependency);
define('itemMediaInfo', [componentsPath + '/itemMediaInfo/itemMediaInfo'], returnFirstDependency);
From 64da797e78e33e11eec8f087dcb2ec7dcb26dcce Mon Sep 17 00:00:00 2001
From: redSpoutnik <15638041+redSpoutnik@users.noreply.github.com>
Date: Sat, 16 May 2020 15:16:18 +0200
Subject: [PATCH 2/6] fix code smells
---
.../subtitleeditor/subtitleeditor.js | 6 +++---
.../subtitleuploader/subtitleuploader.js | 21 ++++++-------------
.../subtitleuploader.template.html | 4 ++--
3 files changed, 11 insertions(+), 20 deletions(-)
diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js
index 4513d1d9d9..350b95d669 100644
--- a/src/components/subtitleeditor/subtitleeditor.js
+++ b/src/components/subtitleeditor/subtitleeditor.js
@@ -349,8 +349,8 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings',
function onOpenUploadMenu(e) {
- var context = dom.parentWithClass(e.target, 'subtitleEditorDialog');
- var selectLanguage = context.querySelector('#selectLanguage');
+ var dialog = dom.parentWithClass(e.target, 'subtitleEditorDialog');
+ var selectLanguage = dialog.querySelector('#selectLanguage');
var apiClient = connectionManager.getApiClient(currentItem.ServerId);
require(['subtitleUploader'], function (subtitleUploader) {
@@ -368,7 +368,7 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings',
if (hasChanged) {
hasChanges = true;
- reload(context, apiClient, currentItem.Id);
+ reload(dialog, apiClient, currentItem.Id);
}
});
});
diff --git a/src/components/subtitleuploader/subtitleuploader.js b/src/components/subtitleuploader/subtitleuploader.js
index bf3a8ca4b3..09e45ba5d4 100644
--- a/src/components/subtitleuploader/subtitleuploader.js
+++ b/src/components/subtitleuploader/subtitleuploader.js
@@ -10,19 +10,11 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
loading.hide();
- switch (evt.target.error.code) {
- case evt.target.error.NOT_FOUND_ERR:
- require(['toast'], function (toast) {
- toast(globalize.translate('MessageFileReadError'));
- });
- break;
- case evt.target.error.ABORT_ERR:
- break; // noop
- default:
- require(['toast'], function (toast) {
- toast(globalize.translate('MessageFileReadError'));
- });
- break;
+ var error = evt.target.error;
+ if (error.code !== error.ABORT_ERR) {
+ require(['toast'], function (toast) {
+ toast(globalize.translate('MessageFileReadError'));
+ });
}
}
@@ -85,7 +77,7 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
toast(globalize.translate('MessageSubtitleFileTypeAllowed'));
});
e.preventDefault();
- return false;
+ return;
}
loading.show();
@@ -103,7 +95,6 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
});
e.preventDefault();
- return false;
}
function initEditor(page) {
diff --git a/src/components/subtitleuploader/subtitleuploader.template.html b/src/components/subtitleuploader/subtitleuploader.template.html
index ef09775cdd..3f4944de57 100644
--- a/src/components/subtitleuploader/subtitleuploader.template.html
+++ b/src/components/subtitleuploader/subtitleuploader.template.html
@@ -1,5 +1,5 @@
From 11099fc41e9085f80641f3a7d3eca657f5cf2528 Mon Sep 17 00:00:00 2001
From: redSpoutnik <15638041+redSpoutnik@users.noreply.github.com>
Date: Sat, 16 May 2020 15:42:39 +0200
Subject: [PATCH 3/6] remove block padding
---
.../subtitleeditor/subtitleeditor.js | 6 ------
.../subtitleuploader/subtitleuploader.js | 18 ------------------
2 files changed, 24 deletions(-)
diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js
index 350b95d669..553255f1ad 100644
--- a/src/components/subtitleeditor/subtitleeditor.js
+++ b/src/components/subtitleeditor/subtitleeditor.js
@@ -348,31 +348,25 @@ define(['dialogHelper', 'require', 'layoutManager', 'globalize', 'userSettings',
}
function onOpenUploadMenu(e) {
-
var dialog = dom.parentWithClass(e.target, 'subtitleEditorDialog');
var selectLanguage = dialog.querySelector('#selectLanguage');
var apiClient = connectionManager.getApiClient(currentItem.ServerId);
require(['subtitleUploader'], function (subtitleUploader) {
-
subtitleUploader.show({
-
languages: {
list: selectLanguage.innerHTML,
value: selectLanguage.value
},
itemId: currentItem.Id,
serverId: currentItem.ServerId
-
}).then(function (hasChanged) {
-
if (hasChanged) {
hasChanges = true;
reload(dialog, apiClient, currentItem.Id);
}
});
});
-
}
function onSearchSubmit(e) {
diff --git a/src/components/subtitleuploader/subtitleuploader.js b/src/components/subtitleuploader/subtitleuploader.js
index 09e45ba5d4..9b9be4c753 100644
--- a/src/components/subtitleuploader/subtitleuploader.js
+++ b/src/components/subtitleuploader/subtitleuploader.js
@@ -7,7 +7,6 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
var hasChanges = false;
function onFileReaderError(evt) {
-
loading.hide();
var error = evt.target.error;
@@ -26,7 +25,6 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
}
function setFiles(page, files) {
-
var file = files[0];
if (!isValidSubtitleFile(file)) {
@@ -53,14 +51,12 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
// Closure to capture the file information.
reader.onload = (function (theFile) {
return function () {
-
// Render thumbnail.
var html = 'subtitles' + escape(theFile.name) + '';
page.querySelector('#subtitleOutput').innerHTML = html;
page.querySelector('#fldUpload').classList.remove('hide');
page.querySelector('#labelDropSubtitle').classList.add('hide');
-
};
})(file);
@@ -69,7 +65,6 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
}
function onSubmit(e) {
-
var file = currentFile;
if (!isValidSubtitleFile(file)) {
@@ -87,7 +82,6 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
var isForced = dlg.querySelector('#chkIsForced').checked;
connectionManager.getApiClient(currentServerId).uploadItemSubtitle(currentItemId, language, isForced, file).then(function () {
-
dlg.querySelector('#uploadSubtitle').value = '';
loading.hide();
hasChanges = true;
@@ -98,24 +92,19 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
}
function initEditor(page) {
-
page.querySelector('.uploadSubtitleForm').addEventListener('submit', onSubmit);
-
page.querySelector('#uploadSubtitle').addEventListener('change', function () {
setFiles(page, this.files);
});
-
page.querySelector('.btnBrowse').addEventListener('click', function () {
page.querySelector('#uploadSubtitle').click();
});
}
function showEditor(options, resolve, reject) {
-
options = options || {};
require(['text!./subtitleuploader.template.html'], function (template) {
-
currentItemId = options.itemId;
currentServerId = options.serverId;
@@ -143,11 +132,9 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
// Has to be assigned a z-index after the call to .open()
dlg.addEventListener('close', function () {
-
if (layoutManager.tv) {
scrollHelper.centerFocus.off(dlg, false);
}
-
loading.hide();
resolve(hasChanges);
});
@@ -159,13 +146,11 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
var selectLanguage = dlg.querySelector('#selectLanguage');
if (options.languages) {
-
selectLanguage.innerHTML = options.languages.list || null;
selectLanguage.value = options.languages.value || null;
}
dlg.querySelector('.btnCancel').addEventListener('click', function () {
-
dialogHelper.close(dlg);
});
});
@@ -173,11 +158,8 @@ define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', '
return {
show: function (options) {
-
return new Promise(function (resolve, reject) {
-
hasChanges = false;
-
showEditor(options, resolve, reject);
});
}
From b4e420df8f23259bf5b9becb095fa39b84d783b7 Mon Sep 17 00:00:00 2001
From: redSpoutnik <15638041+redSpoutnik@users.noreply.github.com>
Date: Sat, 16 May 2020 17:25:50 +0200
Subject: [PATCH 4/6] es6 migration
---
package.json | 1 +
.../subtitleuploader/subtitleuploader.js | 323 +++++++++---------
2 files changed, 167 insertions(+), 157 deletions(-)
diff --git a/package.json b/package.json
index 1e7ebfd0cd..61b67829b2 100644
--- a/package.json
+++ b/package.json
@@ -97,6 +97,7 @@
"src/components/playback/mediasession.js",
"src/components/sanatizefilename.js",
"src/components/scrollManager.js",
+ "src/components/subtitleuploader/subtitleuploader.js",
"src/scripts/dfnshelper.js",
"src/scripts/dom.js",
"src/scripts/filesystem.js",
diff --git a/src/components/subtitleuploader/subtitleuploader.js b/src/components/subtitleuploader/subtitleuploader.js
index 9b9be4c753..e631978881 100644
--- a/src/components/subtitleuploader/subtitleuploader.js
+++ b/src/components/subtitleuploader/subtitleuploader.js
@@ -1,167 +1,176 @@
-define(['dialogHelper', 'connectionManager', 'dom', 'loading', 'scrollHelper', 'layoutManager', 'globalize', 'require', 'emby-button', 'emby-select', 'formDialogStyle', 'css!./style'], function (dialogHelper, connectionManager, dom, loading, scrollHelper, layoutManager, globalize, require) {
- 'use strict';
+import dialogHelper from 'dialogHelper';
+import connectionManager from 'connectionManager';
+import dom from 'dom';
+import loading from 'loading';
+import scrollHelper from 'scrollHelper';
+import layoutManager from 'layoutManager';
+import globalize from 'globalize';
+import template from 'text!./subtitleuploader.template.html';
+import 'require';
+import 'emby-button';
+import 'emby-select';
+import 'formDialogStyle';
+import 'css!./style';
- var currentItemId;
- var currentServerId;
- var currentFile;
- var hasChanges = false;
+var currentItemId;
+var currentServerId;
+var currentFile;
+var hasChanges = false;
- function onFileReaderError(evt) {
- loading.hide();
+function onFileReaderError(evt) {
+ loading.hide();
- var error = evt.target.error;
- if (error.code !== error.ABORT_ERR) {
- require(['toast'], function (toast) {
- toast(globalize.translate('MessageFileReadError'));
- });
- }
- }
-
- function isValidSubtitleFile(file) {
- return file && ['.sub', '.srt', '.vtt', '.ass', '.ssa']
- .some(function(ext) {
- return file.name.endsWith(ext);
- });
- }
-
- function setFiles(page, files) {
- var file = files[0];
-
- if (!isValidSubtitleFile(file)) {
- page.querySelector('#subtitleOutput').innerHTML = '';
- page.querySelector('#fldUpload').classList.add('hide');
- page.querySelector('#labelDropSubtitle').classList.remove('hide');
- currentFile = null;
- return;
- }
-
- currentFile = file;
-
- var reader = new FileReader();
-
- reader.onerror = onFileReaderError;
- reader.onloadstart = function () {
- page.querySelector('#fldUpload').classList.add('hide');
- };
- reader.onabort = function () {
- loading.hide();
- console.debug('File read cancelled');
- };
-
- // Closure to capture the file information.
- reader.onload = (function (theFile) {
- return function () {
- // Render thumbnail.
- var html = 'subtitles' + escape(theFile.name) + '';
-
- page.querySelector('#subtitleOutput').innerHTML = html;
- page.querySelector('#fldUpload').classList.remove('hide');
- page.querySelector('#labelDropSubtitle').classList.add('hide');
- };
- })(file);
-
- // Read in the subtitle file as a data URL.
- reader.readAsDataURL(file);
- }
-
- function onSubmit(e) {
- var file = currentFile;
-
- if (!isValidSubtitleFile(file)) {
- require(['toast'], function (toast) {
- toast(globalize.translate('MessageSubtitleFileTypeAllowed'));
- });
- e.preventDefault();
- return;
- }
-
- loading.show();
-
- var dlg = dom.parentWithClass(this, 'dialog');
- var language = dlg.querySelector('#selectLanguage').value;
- var isForced = dlg.querySelector('#chkIsForced').checked;
-
- connectionManager.getApiClient(currentServerId).uploadItemSubtitle(currentItemId, language, isForced, file).then(function () {
- dlg.querySelector('#uploadSubtitle').value = '';
- loading.hide();
- hasChanges = true;
- dialogHelper.close(dlg);
- });
-
- e.preventDefault();
- }
-
- function initEditor(page) {
- page.querySelector('.uploadSubtitleForm').addEventListener('submit', onSubmit);
- page.querySelector('#uploadSubtitle').addEventListener('change', function () {
- setFiles(page, this.files);
- });
- page.querySelector('.btnBrowse').addEventListener('click', function () {
- page.querySelector('#uploadSubtitle').click();
+ const error = evt.target.error;
+ if (error.code !== error.ABORT_ERR) {
+ require(['toast'], function (toast) {
+ toast(globalize.translate('MessageFileReadError'));
});
}
+}
- function showEditor(options, resolve, reject) {
- options = options || {};
-
- require(['text!./subtitleuploader.template.html'], function (template) {
- currentItemId = options.itemId;
- currentServerId = options.serverId;
-
- var dialogOptions = {
- removeOnClose: true,
- scrollY: false
- };
-
- if (layoutManager.tv) {
- dialogOptions.size = 'fullscreen';
- } else {
- dialogOptions.size = 'small';
- }
-
- var dlg = dialogHelper.createDialog(dialogOptions);
-
- dlg.classList.add('formDialog');
- dlg.classList.add('subtitleUploaderDialog');
-
- dlg.innerHTML = globalize.translateDocument(template, 'core');
-
- if (layoutManager.tv) {
- scrollHelper.centerFocus.on(dlg, false);
- }
-
- // Has to be assigned a z-index after the call to .open()
- dlg.addEventListener('close', function () {
- if (layoutManager.tv) {
- scrollHelper.centerFocus.off(dlg, false);
- }
- loading.hide();
- resolve(hasChanges);
- });
-
- dialogHelper.open(dlg);
-
- initEditor(dlg);
-
- var selectLanguage = dlg.querySelector('#selectLanguage');
-
- if (options.languages) {
- selectLanguage.innerHTML = options.languages.list || null;
- selectLanguage.value = options.languages.value || null;
- }
-
- dlg.querySelector('.btnCancel').addEventListener('click', function () {
- dialogHelper.close(dlg);
- });
+function isValidSubtitleFile(file) {
+ return file && ['.sub', '.srt', '.vtt', '.ass', '.ssa']
+ .some(function(ext) {
+ return file.name.endsWith(ext);
});
+}
+
+function setFiles(page, files) {
+ const file = files[0];
+
+ if (!isValidSubtitleFile(file)) {
+ page.querySelector('#subtitleOutput').innerHTML = '';
+ page.querySelector('#fldUpload').classList.add('hide');
+ page.querySelector('#labelDropSubtitle').classList.remove('hide');
+ currentFile = null;
+ return;
}
- return {
- show: function (options) {
- return new Promise(function (resolve, reject) {
- hasChanges = false;
- showEditor(options, resolve, reject);
- });
- }
+ currentFile = file;
+
+ const reader = new FileReader();
+
+ reader.onerror = onFileReaderError;
+ reader.onloadstart = function () {
+ page.querySelector('#fldUpload').classList.add('hide');
};
-});
+ reader.onabort = function () {
+ loading.hide();
+ console.debug('File read cancelled');
+ };
+
+ // Closure to capture the file information.
+ reader.onload = (function (theFile) {
+ return function () {
+ // Render file.
+ const html = 'subtitles' + escape(theFile.name) + '';
+
+ page.querySelector('#subtitleOutput').innerHTML = html;
+ page.querySelector('#fldUpload').classList.remove('hide');
+ page.querySelector('#labelDropSubtitle').classList.add('hide');
+ };
+ })(file);
+
+ // Read in the subtitle file as a data URL.
+ reader.readAsDataURL(file);
+}
+
+function onSubmit(e) {
+ const file = currentFile;
+
+ if (!isValidSubtitleFile(file)) {
+ require(['toast'], function (toast) {
+ toast(globalize.translate('MessageSubtitleFileTypeAllowed'));
+ });
+ e.preventDefault();
+ return;
+ }
+
+ loading.show();
+
+ const dlg = dom.parentWithClass(this, 'dialog');
+ const language = dlg.querySelector('#selectLanguage').value;
+ const isForced = dlg.querySelector('#chkIsForced').checked;
+
+ connectionManager.getApiClient(currentServerId).uploadItemSubtitle(currentItemId, language, isForced, file).then(function () {
+ dlg.querySelector('#uploadSubtitle').value = '';
+ loading.hide();
+ hasChanges = true;
+ dialogHelper.close(dlg);
+ });
+
+ e.preventDefault();
+}
+
+function initEditor(page) {
+ page.querySelector('.uploadSubtitleForm').addEventListener('submit', onSubmit);
+ page.querySelector('#uploadSubtitle').addEventListener('change', function () {
+ setFiles(page, this.files);
+ });
+ page.querySelector('.btnBrowse').addEventListener('click', function () {
+ page.querySelector('#uploadSubtitle').click();
+ });
+}
+
+function showEditor(options, resolve, reject) {
+ options = options || {};
+ currentItemId = options.itemId;
+ currentServerId = options.serverId;
+
+ const dialogOptions = {
+ removeOnClose: true,
+ scrollY: false
+ };
+
+ if (layoutManager.tv) {
+ dialogOptions.size = 'fullscreen';
+ } else {
+ dialogOptions.size = 'small';
+ }
+
+ const dlg = dialogHelper.createDialog(dialogOptions);
+
+ dlg.classList.add('formDialog');
+ dlg.classList.add('subtitleUploaderDialog');
+
+ dlg.innerHTML = globalize.translateDocument(template, 'core');
+
+ if (layoutManager.tv) {
+ scrollHelper.centerFocus.on(dlg, false);
+ }
+
+ // Has to be assigned a z-index after the call to .open()
+ dlg.addEventListener('close', function () {
+ if (layoutManager.tv) {
+ scrollHelper.centerFocus.off(dlg, false);
+ }
+ loading.hide();
+ resolve(hasChanges);
+ });
+
+ dialogHelper.open(dlg);
+
+ initEditor(dlg);
+
+ const selectLanguage = dlg.querySelector('#selectLanguage');
+
+ if (options.languages) {
+ selectLanguage.innerHTML = options.languages.list || null;
+ selectLanguage.value = options.languages.value || null;
+ }
+
+ dlg.querySelector('.btnCancel').addEventListener('click', function () {
+ dialogHelper.close(dlg);
+ });
+}
+
+export function show(options) {
+ return new Promise(function (resolve, reject) {
+ hasChanges = false;
+ showEditor(options, resolve, reject);
+ });
+}
+
+export default {
+ show: show
+};
From 7613dcfc1d863b450c5b482cdb50660850e4c9fc Mon Sep 17 00:00:00 2001
From: redSpoutnik <15638041+redSpoutnik@users.noreply.github.com>
Date: Sat, 16 May 2020 18:02:14 +0200
Subject: [PATCH 5/6] Add subtitleUploader fr and en-us strings
---
src/strings/en-us.json | 4 ++++
src/strings/fr.json | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/src/strings/en-us.json b/src/strings/en-us.json
index 2014f2d611..683e97c676 100644
--- a/src/strings/en-us.json
+++ b/src/strings/en-us.json
@@ -301,6 +301,7 @@
"HeaderAddToCollection": "Add to Collection",
"HeaderAddToPlaylist": "Add to Playlist",
"HeaderAddUpdateImage": "Add/Update Image",
+ "HeaderAddUpdateSubtitle": "Add/Update Subtitle",
"HeaderAddUser": "Add User",
"HeaderAdditionalParts": "Additional Parts",
"HeaderAdmin": "Admin",
@@ -505,6 +506,7 @@
"HeaderTypeText": "Enter Text",
"HeaderUpcomingOnTV": "Upcoming On TV",
"HeaderUploadImage": "Upload Image",
+ "HeaderUploadSubtitle": "Upload Subtitle",
"HeaderUser": "User",
"HeaderUsers": "Users",
"HeaderVideoQuality": "Video Quality",
@@ -625,6 +627,7 @@
"LabelDropImageHere": "Drop image here, or click to browse.",
"LabelDroppedFrames": "Dropped frames:",
"LabelDropShadow": "Drop shadow:",
+ "LabelDropSubtitleHere": "Drop subtitle here, or click to browse.",
"LabelDynamicExternalId": "{0} Id:",
"LabelEasyPinCode": "Easy pin code:",
"LabelEmbedAlbumArtDidl": "Embed album art in Didl",
@@ -684,6 +687,7 @@
"LabelInNetworkSignInWithEasyPassword": "Enable in-network sign in with my easy pin code",
"LabelInNetworkSignInWithEasyPasswordHelp": "Use the easy pin code to sign in to clients within your local network. Your regular password will only be needed away from home. If the pin code is left blank, you won't need a password within your home network.",
"LabelInternetQuality": "Internet quality:",
+ "LabelIsForced": "Forced",
"LabelKeepUpTo": "Keep up to:",
"LabelKidsCategories": "Children's categories:",
"LabelKodiMetadataDateFormat": "Release date format:",
diff --git a/src/strings/fr.json b/src/strings/fr.json
index 3f1d22c75a..625a15f3b3 100644
--- a/src/strings/fr.json
+++ b/src/strings/fr.json
@@ -271,6 +271,7 @@
"HeaderAddToCollection": "Ajouter à la collection",
"HeaderAddToPlaylist": "Ajouter à la liste de lecture",
"HeaderAddUpdateImage": "Ajouter/Mettre à jour une image",
+ "HeaderAddUpdateSubtitle": "Ajouter/Mettre à jour des sous-titres",
"HeaderAddUser": "Ajouter un utilisateur",
"HeaderAdditionalParts": "Parties additionelles",
"HeaderAdmin": "Administrateur",
@@ -457,6 +458,7 @@
"HeaderTypeText": "Entrer texte",
"HeaderUpcomingOnTV": "Prochainement à la TV",
"HeaderUploadImage": "Envoyer une image",
+ "HeaderUploadSubtitle": "Envoyer des sous-titres",
"HeaderUser": "Utilisateur",
"HeaderUsers": "Utilisateurs",
"HeaderVideoQuality": "Qualité vidéo",
@@ -564,6 +566,7 @@
"LabelDownloadLanguages": "Téléchargement des langues :",
"LabelDropImageHere": "Faites glisser l'image ici, ou cliquez pour parcourir vos fichiers.",
"LabelDropShadow": "Ombre portée :",
+ "LabelDropSubtitleHere": "Faites glisser les sous-tires ici, ou cliquez pour parcourir vos fichiers.",
"LabelDynamicExternalId": "ID {0} :",
"LabelEasyPinCode": "Code Easy PIN :",
"LabelEmbedAlbumArtDidl": "Intégrer les images d'album dans le DIDL",
@@ -620,6 +623,7 @@
"LabelInNetworkSignInWithEasyPassword": "Activer l'authentification simplifiée dans les réseaux domestiques avec mon code Easy PIN",
"LabelInNetworkSignInWithEasyPasswordHelp": "Utilisez votre code Easy PIN pour vous connecter aux applications depuis l'intérieur de votre réseau local. Votre mot de passe habituel ne sera requis que depuis l'extérieur. Si le code PIN n'est pas défini, vous n'aurez pas besoin de mot de passe depuis l'intérieur de votre réseau local.",
"LabelInternetQuality": "Qualité d'internet :",
+ "LabelIsForced": "Forcés",
"LabelKeepUpTo": "Garder jusqu'à :",
"LabelKidsCategories": "Catégories jeunesse :",
"LabelKodiMetadataDateFormat": "Format de la date de sortie :",
From 9e28d2d4cc0a42042dc0ad49c9c4e3b9944d7cf2 Mon Sep 17 00:00:00 2001
From: cameron clark
Date: Sat, 21 Nov 2020 21:08:51 +0000
Subject: [PATCH 6/6] remove require
---
.../subtitleeditor/subtitleeditor.js | 56 ++++++++-----------
.../subtitleuploader/subtitleuploader.js | 46 +++++++--------
2 files changed, 45 insertions(+), 57 deletions(-)
diff --git a/src/components/subtitleeditor/subtitleeditor.js b/src/components/subtitleeditor/subtitleeditor.js
index 48de1ff5cd..980a5ef735 100644
--- a/src/components/subtitleeditor/subtitleeditor.js
+++ b/src/components/subtitleeditor/subtitleeditor.js
@@ -270,36 +270,6 @@ function reload(context, apiClient, itemId) {
context.querySelector('.pathValue').innerHTML = '';
context.querySelector('.originalFile').classList.add('hide');
}
- }
-
- function onOpenUploadMenu(e) {
- var dialog = dom.parentWithClass(e.target, 'subtitleEditorDialog');
- var selectLanguage = dialog.querySelector('#selectLanguage');
- var apiClient = connectionManager.getApiClient(currentItem.ServerId);
-
- require(['subtitleUploader'], function (subtitleUploader) {
- subtitleUploader.show({
- languages: {
- list: selectLanguage.innerHTML,
- value: selectLanguage.value
- },
- itemId: currentItem.Id,
- serverId: currentItem.ServerId
- }).then(function (hasChanged) {
- if (hasChanged) {
- hasChanges = true;
- reload(dialog, apiClient, currentItem.Id);
- }
- });
- });
- }
-
- function onSearchSubmit(e) {
- var form = this;
-
- var lang = form.querySelector('#selectLanguage', form).value;
-
- searchForSubtitles(dom.parentWithClass(form, 'formDialogContent'), lang);
loading.hide();
}
@@ -382,6 +352,28 @@ function centerFocus(elem, horiz, on) {
});
}
+function onOpenUploadMenu(e) {
+ const dialog = dom.parentWithClass(e.target, 'subtitleEditorDialog');
+ const selectLanguage = dialog.querySelector('#selectLanguage');
+ const apiClient = ServerConnections.getApiClient(currentItem.ServerId);
+
+ import('../subtitleuploader/subtitleuploader').then(({default: subtitleUploader}) => {
+ subtitleUploader.show({
+ languages: {
+ list: selectLanguage.innerHTML,
+ value: selectLanguage.value
+ },
+ itemId: currentItem.Id,
+ serverId: currentItem.ServerId
+ }).then(function (hasChanged) {
+ if (hasChanged) {
+ hasChanges = true;
+ reload(dialog, apiClient, currentItem.Id);
+ }
+ });
+ });
+}
+
function showEditorInternal(itemId, serverId, template) {
hasChanges = false;
@@ -400,8 +392,6 @@ function showEditorInternal(itemId, serverId, template) {
const dlg = dialogHelper.createDialog(dialogOptions);
- dlg.querySelector('.btnOpenUploadMenu').addEventListener('click', onOpenUploadMenu);
-
dlg.classList.add('formDialog');
dlg.classList.add('subtitleEditorDialog');
@@ -411,6 +401,8 @@ function showEditorInternal(itemId, serverId, template) {
dlg.querySelector('.subtitleSearchForm').addEventListener('submit', onSearchSubmit);
+ dlg.querySelector('.btnOpenUploadMenu').addEventListener('click', onOpenUploadMenu);
+
const btnSubmit = dlg.querySelector('.btnSubmit');
if (layoutManager.tv) {
diff --git a/src/components/subtitleuploader/subtitleuploader.js b/src/components/subtitleuploader/subtitleuploader.js
index e631978881..1c9b8cfb24 100644
--- a/src/components/subtitleuploader/subtitleuploader.js
+++ b/src/components/subtitleuploader/subtitleuploader.js
@@ -1,30 +1,28 @@
-import dialogHelper from 'dialogHelper';
-import connectionManager from 'connectionManager';
-import dom from 'dom';
-import loading from 'loading';
-import scrollHelper from 'scrollHelper';
-import layoutManager from 'layoutManager';
-import globalize from 'globalize';
-import template from 'text!./subtitleuploader.template.html';
-import 'require';
-import 'emby-button';
-import 'emby-select';
-import 'formDialogStyle';
-import 'css!./style';
+import dialogHelper from '../../components/dialogHelper/dialogHelper';
+import ServerConnections from '../ServerConnections';
+import dom from '../../scripts/dom';
+import loading from '../../components/loading/loading';
+import scrollHelper from '../../libraries/scroller';
+import layoutManager from '../layoutManager';
+import globalize from '../../scripts/globalize';
+import template from './subtitleuploader.template.html';
+import toast from '../toast/toast';
+import '../../elements/emby-button/emby-button';
+import '../../elements/emby-select/emby-select';
+import '../formdialog.css';
+import './style.css';
-var currentItemId;
-var currentServerId;
-var currentFile;
-var hasChanges = false;
+let currentItemId;
+let currentServerId;
+let currentFile;
+let hasChanges = false;
function onFileReaderError(evt) {
loading.hide();
const error = evt.target.error;
if (error.code !== error.ABORT_ERR) {
- require(['toast'], function (toast) {
- toast(globalize.translate('MessageFileReadError'));
- });
+ toast(globalize.translate('MessageFileReadError'));
}
}
@@ -79,9 +77,7 @@ function onSubmit(e) {
const file = currentFile;
if (!isValidSubtitleFile(file)) {
- require(['toast'], function (toast) {
- toast(globalize.translate('MessageSubtitleFileTypeAllowed'));
- });
+ toast(globalize.translate('MessageSubtitleFileTypeAllowed'));
e.preventDefault();
return;
}
@@ -92,7 +88,7 @@ function onSubmit(e) {
const language = dlg.querySelector('#selectLanguage').value;
const isForced = dlg.querySelector('#chkIsForced').checked;
- connectionManager.getApiClient(currentServerId).uploadItemSubtitle(currentItemId, language, isForced, file).then(function () {
+ ServerConnections.getApiClient(currentServerId).uploadItemSubtitle(currentItemId, language, isForced, file).then(function () {
dlg.querySelector('#uploadSubtitle').value = '';
loading.hide();
hasChanges = true;
@@ -133,7 +129,7 @@ function showEditor(options, resolve, reject) {
dlg.classList.add('formDialog');
dlg.classList.add('subtitleUploaderDialog');
- dlg.innerHTML = globalize.translateDocument(template, 'core');
+ dlg.innerHTML = globalize.translateHtml(template, 'core');
if (layoutManager.tv) {
scrollHelper.centerFocus.on(dlg, false);