1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge branch 'master' into polyfill-lint

This commit is contained in:
Julien Machiels 2020-04-10 06:28:59 +02:00 committed by GitHub
commit acbe7730b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
84 changed files with 1172 additions and 809 deletions

View file

@ -16,7 +16,7 @@ define(["events", "globalize", "dom", "date-fns", "dfnshelper", "userSettings",
html += '<i class="listItemIcon material-icons" style="width:2em!important;height:2em!important;padding:0;color:transparent;background-color:' + color + ";background-image:url('" + apiClient.getUserImageUrl(entry.UserId, {
type: "Primary",
tag: entry.UserPrimaryImageTag
}) + "');background-repeat:no-repeat;background-position:center center;background-size: cover;\">dvr</i>"
}) + "');background-repeat:no-repeat;background-position:center center;background-size: cover;\">dvr</i>";
} else {
html += '<i class="listItemIcon material-icons" style="background-color:' + color + '">' + icon + '</i>';
}

View file

@ -579,8 +579,8 @@ define(['loading', 'globalize', 'events', 'viewManager', 'layoutManager', 'skinM
function showDirect(path) {
return new Promise(function(resolve, reject) {
resolveOnNextShow = resolve, page.show(baseUrl()+path)
})
resolveOnNextShow = resolve, page.show(baseUrl()+path);
});
}
function show(path, options) {

View file

@ -279,8 +279,8 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
features.push("screensaver");
webSettings.enableMultiServer().then(enabled => {
if (enabled) features.push("multiserver")
})
if (enabled) features.push("multiserver");
});
if (!browser.orsay && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || supportsCue())) {
features.push("subtitleappearancesettings");
@ -383,7 +383,7 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings"], f
return window.NativeShell.AppHost.getDefaultLayout();
}
return getDefaultLayout()
return getDefaultLayout();
},
getDeviceProfile: getDeviceProfile,
init: function () {

View file

@ -52,5 +52,5 @@ define(["connectionManager"], function (connectionManager) {
currentSlideshow = null;
}
};
}
};
});

View file

@ -188,9 +188,9 @@ define(['events'], function (events) {
return apiClient.getEndpointInfo().then(function (endpoint) {
if (endpoint.IsInNetwork) {
return apiClient.getPublicSystemInfo().then(function (info) {
var localAddress = info.LocalAddress
var localAddress = info.LocalAddress;
if (!localAddress) {
console.debug("No valid local address returned, defaulting to external one")
console.debug("No valid local address returned, defaulting to external one");
localAddress = serverAddress;
}
addToCache(serverAddress, localAddress);

View file

@ -7,11 +7,11 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
systemInfo = info;
return info;
}
)
);
}
function onDialogClosed() {
loading.hide()
loading.hide();
}
function refreshDirectoryBrowser(page, path, fileOptions, updatePathOnError) {
@ -24,7 +24,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
var promises = [];
if ("Network" === path) {
promises.push(ApiClient.getNetworkDevices())
promises.push(ApiClient.getNetworkDevices());
} else {
if (path) {
promises.push(ApiClient.getDirectoryContents(path, fileOptions));
@ -101,7 +101,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
html += Globalize.translate("MessageDirectoryPickerLinuxInstruction");
html += "<br/>";
}
html += "</div>"
html += "</div>";
}
html += '<form style="margin:auto;">';
html += '<div class="inputContainer" style="display: flex; align-items: center;">';
@ -144,13 +144,13 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
function alertText(text) {
alertTextWithOptions({
text: text
})
});
}
function alertTextWithOptions(options) {
require(["alert"], function(alert) {
alert(options)
})
alert(options);
});
}
function validatePath(path, validateWriteable, apiClient) {
@ -171,12 +171,12 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
if (validateWriteable) {
alertText(Globalize.translate("WriteAccessRequired"));
} else {
alertText(Globalize.translate("PathNotFound"))
alertText(Globalize.translate("PathNotFound"));
}
return Promise.reject()
return Promise.reject();
}
}
return Promise.resolve()
return Promise.resolve();
});
}
@ -188,7 +188,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
if (lnkPath.classList.contains("lnkFile")) {
content.querySelector("#txtDirectoryPickerPath").value = path;
} else {
refreshDirectoryBrowser(content, path, fileOptions, true)
refreshDirectoryBrowser(content, path, fileOptions, true);
}
}
});
@ -275,7 +275,7 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
dlg.addEventListener("close", onDialogClosed);
dialogHelper.open(dlg);
dlg.querySelector(".btnCloseDialog").addEventListener("click", function() {
dialogHelper.close(dlg)
dialogHelper.close(dlg);
});
currentDialog = dlg;
dlg.querySelector("#txtDirectoryPickerPath").value = initialPath;
@ -293,9 +293,9 @@ define(['loading', 'dialogHelper', 'dom', 'listViewStyle', 'emby-input', 'paper-
if (currentDialog) {
dialogHelper.close(currentDialog);
}
}
};
}
var systemInfo;
return directoryBrowser
return directoryBrowser;
});

View file

@ -186,6 +186,8 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', '
context.querySelector('#selectLanguage').value = userSettings.language() || '';
context.querySelector('.selectDateTimeLocale').value = userSettings.dateTimeLocale() || '';
context.querySelector('#txtLibraryPageSize').value = userSettings.libraryPageSize();
selectDashboardTheme.value = userSettings.dashboardTheme() || '';
selectTheme.value = userSettings.theme() || '';
@ -215,6 +217,8 @@ define(['require', 'browser', 'layoutManager', 'appSettings', 'pluginManager', '
userSettingsInstance.soundEffects(context.querySelector('.selectSoundEffects').value);
userSettingsInstance.screensaver(context.querySelector('.selectScreensaver').value);
userSettingsInstance.libraryPageSize(context.querySelector('#txtLibraryPageSize').value);
userSettingsInstance.skin(context.querySelector('.selectSkin').value);
userSettingsInstance.enableFastFadein(context.querySelector('#chkFadein').checked);

View file

@ -143,6 +143,11 @@
<select is="emby-select" class="selectSoundEffects" label="${LabelSoundEffects}"></select>
</div>
<div class="inputContainer inputContainer-withDescription fldFadein">
<input is="emby-input" type="number" id="txtLibraryPageSize" pattern="[0-9]*" required="required" min="0" max="1000" step="1" label="${LabelLibraryPageSize}" />
<div class="fieldDescription">${LabelLibraryPageSizeHelp}</div>
</div>
<div class="checkboxContainer checkboxContainer-withDescription fldFadein">
<label>
<input type="checkbox" is="emby-checkbox" id="chkFadein" />

View file

@ -1,4 +1,4 @@
import multiDownload from "multi-download"
import multiDownload from "multi-download";
export function download(items) {

View file

@ -64,18 +64,18 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
} else {
var noLibDescription;
if (user['Policy'] && user['Policy']['IsAdministrator']) {
noLibDescription = Globalize.translate("NoCreatedLibraries", '<a id="button-createLibrary" class="button-link">', '</a>')
noLibDescription = Globalize.translate("NoCreatedLibraries", '<a id="button-createLibrary" class="button-link">', '</a>');
} else {
noLibDescription = Globalize.translate("AskAdminToCreateLibrary");
}
html += '<div class="centerMessage padded-left padded-right">';
html += '<h2>' + Globalize.translate("MessageNothingHere") + '</h2>';
html += '<p>' + noLibDescription + '</p>'
html += '<p>' + noLibDescription + '</p>';
html += '</div>';
elem.innerHTML = html;
var createNowLink = elem.querySelector("#button-createLibrary")
var createNowLink = elem.querySelector("#button-createLibrary");
if (createNowLink) {
createNowLink.addEventListener("click", function () {
Dashboard.navigate("library.html");
@ -640,7 +640,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
if (enableScrollX()) {
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">'
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">';
} else {
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">';
}
@ -714,7 +714,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
if (enableScrollX()) {
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="videoplayback,markplayed">'
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x" data-monitor="videoplayback,markplayed">';
} else {
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x" data-monitor="videoplayback,markplayed">';
}
@ -786,7 +786,7 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
if (enableScrollX()) {
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">';
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">'
html += '<div is="emby-itemscontainer" class="itemsContainer scrollSlider focuscontainer-x">';
} else {
html += '<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right vertical-wrap focuscontainer-x">';
}

View file

@ -171,13 +171,29 @@ define(['appSettings', 'browser', 'events'], function (appSettings, browser, eve
// Appending #t=xxx to the query string doesn't seem to work with HLS
// For plain video files, not all browsers support it either
var delay = browser.safari ? 2500 : 0;
if (delay) {
setTimeout(function () {
setCurrentTimeIfNeeded(element, seconds);
}, delay);
} else {
if (element.duration >= seconds) {
// media is ready, seek immediately
setCurrentTimeIfNeeded(element, seconds);
} else {
// update video player position when media is ready to be sought
var events = ["durationchange", "loadeddata", "play", "loadedmetadata"];
var onMediaChange = function(e) {
if (element.currentTime === 0 && element.duration >= seconds) {
// seek only when video position is exactly zero,
// as this is true only if video hasn't started yet or
// user rewound to the very beginning
// (but rewinding cannot happen as the first event with media of non-empty duration)
console.debug(`seeking to ${seconds} on ${e.type} event`);
setCurrentTimeIfNeeded(element, seconds);
events.map(function(name) {
element.removeEventListener(name, onMediaChange);
});
}
};
events.map(function (name) {
element.addEventListener(name, onMediaChange);
});
}
}
}

View file

@ -116,8 +116,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
});
}
function normalizeTrackEventText(text) {
return text.replace(/\\N/gi, '\n');
function normalizeTrackEventText(text, useHtml) {
var result = text.replace(/\\N/gi, '\n').replace(/\r/gi, '');
return useHtml ? result.replace(/\n/gi, '<br>') : result;
}
function setTracks(elem, tracks, item, mediaSource) {
@ -567,19 +568,19 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
self.resetSubtitleOffset = function() {
currentTrackOffset = 0;
showTrackOffset = false;
}
};
self.enableShowingSubtitleOffset = function() {
showTrackOffset = true;
}
};
self.disableShowingSubtitleOffset = function() {
showTrackOffset = false;
}
};
self.isShowingSubtitleOffsetEnabled = function() {
return showTrackOffset;
}
};
function getTextTrack() {
var videoElement = self._mediaElement;
@ -651,7 +652,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
self.getSubtitleOffset = function() {
return currentTrackOffset;
}
};
function isAudioStreamSupported(stream, deviceProfile) {
@ -1019,7 +1020,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
xhr.onerror = function (e) {
reject(e);
decrementFetchQueue();
}
};
xhr.send();
});
@ -1209,7 +1210,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
data.TrackEvents.forEach(function (trackEvent) {
var trackCueObject = window.VTTCue || window.TextTrackCue;
var cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text));
var cue = new trackCueObject(trackEvent.StartPositionTicks / 10000000, trackEvent.EndPositionTicks / 10000000, normalizeTrackEventText(trackEvent.Text, false));
trackElement.addCue(cue);
});
@ -1250,8 +1251,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
}
if (selectedTrackEvent && selectedTrackEvent.Text) {
subtitleTextElement.innerHTML = normalizeTrackEventText(selectedTrackEvent.Text);
subtitleTextElement.innerHTML = normalizeTrackEventText(selectedTrackEvent.Text, true);
subtitleTextElement.classList.remove('hide');
} else {
@ -1428,11 +1428,11 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
}
if (browser.safari || browser.iOS || browser.iPad) {
list.push('AirPlay')
list.push('AirPlay');
}
list.push('SetBrightness');
list.push("SetAspectRatio")
list.push("SetAspectRatio");
return list;
}
@ -1555,11 +1555,11 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
if (video) {
if (isEnabled) {
video.requestAirPlay().catch(function(err) {
console.error("Error requesting AirPlay", err)
console.error("Error requesting AirPlay", err);
});
} else {
document.exitAirPLay().catch(function(err) {
console.error("Error exiting AirPlay", err)
console.error("Error exiting AirPlay", err);
});
}
}
@ -1692,12 +1692,12 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
var mediaElement = this._mediaElement;
if (mediaElement) {
if ("auto" === val) {
mediaElement.style.removeProperty("object-fit")
mediaElement.style.removeProperty("object-fit");
} else {
mediaElement.style["object-fit"] = val
mediaElement.style["object-fit"] = val;
}
}
this._currentAspectRatio = val
this._currentAspectRatio = val;
};
HtmlVideoPlayer.prototype.getAspectRatio = function () {
@ -1714,7 +1714,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
}, {
name: "Fill",
id: "fill"
}]
}];
};
HtmlVideoPlayer.prototype.togglePictureInPicture = function () {

View file

@ -116,7 +116,7 @@ define(["dialogHelper", "require", "layoutManager", "globalize", "userSettings",
}
function createAttribute(label, value) {
return '<span class="mediaInfoLabel">' + label + '</span><span class="mediaInfoAttribute">' + value + "</span>"
return '<span class="mediaInfoLabel">' + label + '</span><span class="mediaInfoAttribute">' + value + "</span>";
}
function showMediaInfoMore(itemId, serverId, template) {

View file

@ -36,7 +36,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
html += "<option value='" + culture.TwoLetterISORegionName + "'>" + culture.DisplayName + "</option>";
}
select.innerHTML = html;
})
});
}
function populateRefreshInterval(select) {
@ -120,7 +120,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
html += plugin.Name;
html += "</h3>";
html += "</div>";
i > 0 ? html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_up"></i></button>' : plugins.length > 1 && (html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_down"></i></button>'), html += "</div>"
i > 0 ? html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonUp") + '" class="btnSortableMoveUp btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_up"></i></button>' : plugins.length > 1 && (html += '<button type="button" is="paper-icon-button-light" title="' + globalize.translate("ButtonDown") + '" class="btnSortableMoveDown btnSortable" data-pluginindex="' + i + '"><i class="material-icons keyboard_arrow_down"></i></button>'), html += "</div>";
}
html += "</div>";
html += '<div class="fieldDescription">' + globalize.translate("LabelMetadataDownloadersHelp") + "</div>";
@ -265,10 +265,10 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
renderMetadataFetchers(parent, availableOptions, {});
renderSubtitleFetchers(parent, availableOptions, {});
renderImageFetchers(parent, availableOptions, {});
availableOptions.SubtitleFetchers.length ? parent.querySelector(".subtitleDownloadSettings").classList.remove("hide") : parent.querySelector(".subtitleDownloadSettings").classList.add("hide")
availableOptions.SubtitleFetchers.length ? parent.querySelector(".subtitleDownloadSettings").classList.remove("hide") : parent.querySelector(".subtitleDownloadSettings").classList.add("hide");
}).catch(function() {
return Promise.resolve();
})
});
}
function adjustSortableListElement(elem) {
@ -296,8 +296,8 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
Type: type
}, currentLibraryOptions.TypeOptions.push(typeOptions));
var availableOptions = getTypeOptions(currentAvailableOptions || {}, type);
(new ImageOptionsEditor).show(type, typeOptions, availableOptions)
})
(new ImageOptionsEditor).show(type, typeOptions, availableOptions);
});
}
function onImageFetchersContainerClick(e) {
@ -315,12 +315,12 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
var list = dom.parentWithClass(li, "paperList");
if (btnSortable.classList.contains("btnSortableMoveDown")) {
var next = li.nextSibling;
next && (li.parentNode.removeChild(li), next.parentNode.insertBefore(li, next.nextSibling))
next && (li.parentNode.removeChild(li), next.parentNode.insertBefore(li, next.nextSibling));
} else {
var prev = li.previousSibling;
prev && (li.parentNode.removeChild(li), prev.parentNode.insertBefore(li, prev))
prev && (li.parentNode.removeChild(li), prev.parentNode.insertBefore(li, prev));
}
Array.prototype.forEach.call(list.querySelectorAll(".sortableOption"), adjustSortableListElement)
Array.prototype.forEach.call(list.querySelectorAll(".sortableOption"), adjustSortableListElement);
}
}
@ -407,13 +407,13 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
function setSubtitleFetchersIntoOptions(parent, options) {
options.DisabledSubtitleFetchers = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll(".chkSubtitleFetcher"), function(elem) {
return !elem.checked
return !elem.checked;
}), function(elem) {
return elem.getAttribute("data-pluginname")
return elem.getAttribute("data-pluginname");
});
options.SubtitleFetcherOrder = Array.prototype.map.call(parent.querySelectorAll(".subtitleFetcherItem"), function(elem) {
return elem.getAttribute("data-pluginname")
return elem.getAttribute("data-pluginname");
});
}
@ -455,13 +455,13 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
}
typeOptions.ImageFetchers = Array.prototype.map.call(Array.prototype.filter.call(section.querySelectorAll(".chkImageFetcher"), function(elem) {
return elem.checked
return elem.checked;
}), function(elem) {
return elem.getAttribute("data-pluginname")
return elem.getAttribute("data-pluginname");
});
typeOptions.ImageFetcherOrder = Array.prototype.map.call(section.querySelectorAll(".imageFetcherItem"), function(elem) {
return elem.getAttribute("data-pluginname")
return elem.getAttribute("data-pluginname");
});
}
}
@ -505,20 +505,20 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
SaveSubtitlesWithMedia: parent.querySelector("#chkSaveSubtitlesLocally").checked,
RequirePerfectSubtitleMatch: parent.querySelector("#chkRequirePerfectMatch").checked,
MetadataSavers: Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll(".chkMetadataSaver"), function(elem) {
return elem.checked
return elem.checked;
}), function(elem) {
return elem.getAttribute("data-pluginname")
return elem.getAttribute("data-pluginname");
}),
TypeOptions: []
};
options.LocalMetadataReaderOrder = Array.prototype.map.call(parent.querySelectorAll(".localReaderOption"), function(elem) {
return elem.getAttribute("data-pluginname")
return elem.getAttribute("data-pluginname");
});
options.SubtitleDownloadLanguages = Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll(".chkSubtitleLanguage"), function(elem) {
return elem.checked
return elem.checked;
}), function(elem) {
return elem.getAttribute("data-lang")
return elem.getAttribute("data-lang");
});
setSubtitleFetchersIntoOptions(parent, options);
setMetadataFetchersIntoOptions(parent, options);
@ -531,7 +531,7 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
function getOrderedPlugins(plugins, configuredOrder) {
plugins = plugins.slice(0);
plugins.sort(function(a, b) {
return a = configuredOrder.indexOf(a.Name), b = configuredOrder.indexOf(b.Name), a < b ? -1 : a > b ? 1 : 0
return a = configuredOrder.indexOf(a.Name), b = configuredOrder.indexOf(b.Name), a < b ? -1 : a > b ? 1 : 0;
});
return plugins;
}
@ -558,10 +558,10 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
parent.querySelector("#chkSkipIfAudioTrackPresent").checked = options.SkipSubtitlesIfAudioTrackMatches;
parent.querySelector("#chkRequirePerfectMatch").checked = options.RequirePerfectSubtitleMatch;
Array.prototype.forEach.call(parent.querySelectorAll(".chkMetadataSaver"), function(elem) {
elem.checked = options.MetadataSavers ? -1 !== options.MetadataSavers.indexOf(elem.getAttribute("data-pluginname")) : "true" === elem.getAttribute("data-defaultenabled")
elem.checked = options.MetadataSavers ? -1 !== options.MetadataSavers.indexOf(elem.getAttribute("data-pluginname")) : "true" === elem.getAttribute("data-defaultenabled");
});
Array.prototype.forEach.call(parent.querySelectorAll(".chkSubtitleLanguage"), function(elem) {
elem.checked = !!options.SubtitleDownloadLanguages && -1 !== options.SubtitleDownloadLanguages.indexOf(elem.getAttribute("data-lang"))
elem.checked = !!options.SubtitleDownloadLanguages && -1 !== options.SubtitleDownloadLanguages.indexOf(elem.getAttribute("data-lang"));
});
renderMetadataReaders(parent, getOrderedPlugins(parent.availableOptions.MetadataReaders, options.LocalMetadataReaderOrder || []));
renderMetadataFetchers(parent, parent.availableOptions, options);
@ -578,5 +578,5 @@ define(["globalize", "dom", "emby-checkbox", "emby-select", "emby-input"], funct
getLibraryOptions: getLibraryOptions,
setLibraryOptions: setLibraryOptions,
setAdvancedVisible: setAdvancedVisible
}
};
});

View file

@ -188,5 +188,5 @@ define(["pluginManager"], function (pluginManager) {
}
}
};
}
};
});

View file

@ -1633,29 +1633,29 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
self.supportSubtitleOffset = function(player) {
player = player || self._currentPlayer;
return player && 'setSubtitleOffset' in player;
}
};
self.enableShowingSubtitleOffset = function(player) {
player = player || self._currentPlayer;
player.enableShowingSubtitleOffset();
}
};
self.disableShowingSubtitleOffset = function(player) {
player = player || self._currentPlayer;
if (player.disableShowingSubtitleOffset) {
player.disableShowingSubtitleOffset();
}
}
};
self.isShowingSubtitleOffsetEnabled = function(player) {
player = player || self._currentPlayer;
return player.isShowingSubtitleOffsetEnabled();
}
};
self.isSubtitleStreamExternal = function(index, player) {
var stream = getSubtitleStream(player, index);
return stream ? getDeliveryMethod(stream) === 'External' : false;
}
};
self.setSubtitleOffset = function (value, player) {
player = player || self._currentPlayer;
@ -1669,12 +1669,12 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla
if (player.getSubtitleOffset) {
return player.getSubtitleOffset();
}
}
};
self.canHandleOffsetOnCurrentSubtitle = function(player) {
var index = self.getSubtitleStreamIndex(player);
return index !== -1 && self.isSubtitleStreamExternal(index, player);
}
};
self.seek = function (ticks, player) {

View file

@ -1,8 +1,18 @@
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'browser', 'apphost', 'loading', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputManager, connectionManager, layoutManager, focusManager, browser, appHost, loading) {
/**
* Image viewer component
* @module components/slideshow/slideshow
*/
define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'focusManager', 'browser', 'apphost', 'css!./style', 'material-icons', 'paper-icon-button-light'], function (dialogHelper, inputManager, connectionManager, layoutManager, focusManager, browser, appHost) {
'use strict';
/**
* Retrieves an item's image URL from the API.
* @param {object|string} item - Item used to generate the image URL.
* @param {object} options - Options of the image.
* @param {object} apiClient - API client instance used to retrieve the image.
* @returns {null|string} URL of the item's image.
*/
function getImageUrl(item, options, apiClient) {
options = options || {};
options.type = options.type || "Primary";
@ -11,7 +21,6 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
if (item.ImageTags && item.ImageTags[options.type]) {
options.tag = item.ImageTags[options.type];
return apiClient.getScaledImageUrl(item.Id, options);
}
@ -27,8 +36,14 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
return null;
}
/**
* Retrieves a backdrop's image URL from the API.
* @param {object} item - Item used to generate the image URL.
* @param {object} options - Options of the image.
* @param {object} apiClient - API client instance used to retrieve the image.
* @returns {null|string} URL of the item's backdrop.
*/
function getBackdropImageUrl(item, options, apiClient) {
options = options || {};
options.type = options.type || "Backdrop";
@ -46,19 +61,19 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
return null;
}
function getImgUrl(item, original) {
/**
* Dispatches a request for an item's image to its respective handler.
* @param {object} item - Item used to generate the image URL.
* @returns {string} URL of the item's image.
*/
function getImgUrl(item) {
var apiClient = connectionManager.getApiClient(item.ServerId);
var imageOptions = {};
if (!original) {
imageOptions.maxWidth = screen.availWidth;
}
if (item.BackdropImageTags && item.BackdropImageTags.length) {
return getBackdropImageUrl(item, imageOptions, apiClient);
} else {
if (item.MediaType === 'Photo' && original) {
if (item.MediaType === 'Photo') {
return apiClient.getItemDownloadUrl(item.Id);
}
imageOptions.type = "Primary";
@ -66,15 +81,25 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
}
/**
* Generates a button using the specified icon, classes and properties.
* @param {string} icon - Name of the material icon on the button
* @param {string} cssClass - CSS classes to assign to the button
* @param {boolean} canFocus - Flag to set the tabindex attribute on the button to -1.
* @param {boolean} autoFocus - Flag to set the autofocus attribute on the button.
* @returns {string} The HTML markup of the button.
*/
function getIcon(icon, cssClass, canFocus, autoFocus) {
var tabIndex = canFocus ? '' : ' tabindex="-1"';
autoFocus = autoFocus ? ' autofocus' : '';
return '<button is="paper-icon-button-light" class="autoSize ' + cssClass + '"' + tabIndex + autoFocus + '><i class="material-icons slideshowButtonIcon ' + icon + '"></i></button>';
}
/**
* Sets the viewport meta tag to enable or disable scaling by the user.
* @param {boolean} scalable - Flag to set the scalability of the viewport.
*/
function setUserScalable(scalable) {
try {
appHost.setUserScalable(scalable);
} catch (err) {
@ -83,23 +108,31 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
return function (options) {
var self = this;
/** Initialized instance of Swiper. */
var swiperInstance;
var dlg;
var currentTimeout;
var currentIntervalMs;
/** Initialized instance of the dialog containing the Swiper instance. */
var dialog;
/** Options of the slideshow components */
var currentOptions;
var currentIndex;
/** ID of the timeout used to hide the OSD. */
var hideTimeout;
/** Last coordinates of the mouse pointer. */
var lastMouseMoveData;
/** Visibility status of the OSD. */
var _osdOpen = false;
// small hack since this is not possible anyway
if (browser.chromecast) {
options.interactive = false;
}
// Use autoplay on Chromecast since it is non-interactive.
options.interactive = !browser.chromecast;
/**
* Creates the HTML markup for the dialog and the OSD.
* @param {Object} options - Options used to create the dialog and slideshow.
*/
function createElements(options) {
currentOptions = options;
dlg = dialogHelper.createDialog({
dialog = dialogHelper.createDialog({
exitAnimationDuration: options.interactive ? 400 : 800,
size: 'fullscreen',
autoFocus: false,
@ -108,17 +141,15 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
removeOnClose: true
});
dlg.classList.add('slideshowDialog');
dialog.classList.add('slideshowDialog');
var html = '';
if (options.interactive) {
html += '<div class="slideshowSwiperContainer"><div class="swiper-wrapper"></div></div>';
if (options.interactive && !layoutManager.tv) {
var actionButtonsOnTop = layoutManager.mobile;
html += '<div>';
html += '<div class="slideshowSwiperContainer"><div class="swiper-wrapper"></div></div>';
html += getIcon('keyboard_arrow_left', 'btnSlideshowPrevious slideshowButton hide-mouse-idle-tv', false);
html += getIcon('keyboard_arrow_right', 'btnSlideshowNext slideshowButton hide-mouse-idle-tv', false);
@ -137,7 +168,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
if (!actionButtonsOnTop) {
html += '<div class="slideshowBottomBar hide">';
html += getIcon('pause', 'btnSlideshowPause slideshowButton', true, true);
html += getIcon('play_arrow', 'btnSlideshowPause slideshowButton', true, true);
if (appHost.supports('filedownload')) {
html += getIcon('file_download', 'btnDownload slideshowButton', true);
}
@ -148,33 +179,28 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
html += '</div>';
}
html += '</div>';
} else {
html += '<div class="slideshowImage"></div><h1 class="slideshowImageText"></h1>';
}
dlg.innerHTML = html;
dialog.innerHTML = html;
if (options.interactive) {
dlg.querySelector('.btnSlideshowExit').addEventListener('click', function (e) {
dialogHelper.close(dlg);
if (options.interactive && !layoutManager.tv) {
dialog.querySelector('.btnSlideshowExit').addEventListener('click', function (e) {
dialogHelper.close(dialog);
});
dlg.querySelector('.btnSlideshowNext').addEventListener('click', nextImage);
dlg.querySelector('.btnSlideshowPrevious').addEventListener('click', previousImage);
var btnPause = dlg.querySelector('.btnSlideshowPause');
var btnPause = dialog.querySelector('.btnSlideshowPause');
if (btnPause) {
btnPause.addEventListener('click', playPause);
}
var btnDownload = dlg.querySelector('.btnDownload');
var btnDownload = dialog.querySelector('.btnDownload');
if (btnDownload) {
btnDownload.addEventListener('click', download);
}
var btnShare = dlg.querySelector('.btnShare');
var btnShare = dialog.querySelector('.btnShare');
if (btnShare) {
btnShare.addEventListener('click', share);
}
@ -182,78 +208,104 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
setUserScalable(true);
dialogHelper.open(dlg).then(function () {
dialogHelper.open(dialog).then(function () {
setUserScalable(false);
stopInterval();
});
inputManager.on(window, onInputCommand);
document.addEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove);
dlg.addEventListener('close', onDialogClosed);
dialog.addEventListener('close', onDialogClosed);
if (options.interactive) {
loadSwiper(dlg);
}
loadSwiper(dialog, options);
}
/**
* Handles OSD changes when the autoplay is started.
*/
function onAutoplayStart() {
var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i');
var btnSlideshowPause = dialog.querySelector('.btnSlideshowPause i');
if (btnSlideshowPause) {
btnSlideshowPause.classList.remove("play_arrow");
btnSlideshowPause.classList.add("pause");
btnSlideshowPause.classList.replace("play_arrow", "pause");
}
}
/**
* Handles OSD changes when the autoplay is stopped.
*/
function onAutoplayStop() {
var btnSlideshowPause = dlg.querySelector('.btnSlideshowPause i');
var btnSlideshowPause = dialog.querySelector('.btnSlideshowPause i');
if (btnSlideshowPause) {
btnSlideshowPause.classList.remove("pause");
btnSlideshowPause.classList.add("play_arrow");
btnSlideshowPause.classList.replace("pause", "play_arrow");
}
}
function loadSwiper(dlg) {
/**
* Initializes the Swiper instance and binds the relevant events.
* @param {HTMLElement} dialog - Element containing the dialog.
* @param {Object} options - Options used to initialize the Swiper instance.
*/
function loadSwiper(dialog, options) {
var slides;
if (currentOptions.slides) {
dlg.querySelector('.swiper-wrapper').innerHTML = currentOptions.slides.map(getSwiperSlideHtmlFromSlide).join('');
slides = currentOptions.slides;
} else {
dlg.querySelector('.swiper-wrapper').innerHTML = currentOptions.items.map(getSwiperSlideHtmlFromItem).join('');
slides = currentOptions.items;
}
require(['swiper'], function (Swiper) {
swiperInstance = new Swiper(dlg.querySelector('.slideshowSwiperContainer'), {
// Optional parameters
swiperInstance = new Swiper(dialog.querySelector('.slideshowSwiperContainer'), {
direction: 'horizontal',
loop: options.loop !== false,
autoplay: {
delay: options.interval || 8000
// Loop is disabled due to the virtual slides option not supporting it.
loop: false,
autoplay: !options.interactive,
keyboard: {
enabled: true
},
// Disable preloading of all images
preloadImages: false,
// Enable lazy loading
lazy: true,
loadPrevNext: true,
disableOnInteraction: false,
preloadImages: true,
slidesPerView: 1,
slidesPerColumn: 1,
initialSlide: options.startIndex || 0,
speed: 240
speed: 240,
navigation: {
nextEl: '.btnSlideshowNext',
prevEl: '.btnSlideshowPrevious'
},
// Virtual slides reduce memory consumption for large libraries while allowing preloading of images;
virtual: {
slides: slides,
cache: true,
renderSlide: getSwiperSlideHtml,
addSlidesBefore: 1,
addSlidesAfter: 1
}
});
swiperInstance.on('autoplayStart', onAutoplayStart);
swiperInstance.on('autoplayStop', onAutoplayStop);
if (layoutManager.mobile) {
pause();
} else {
play();
}
});
}
function getSwiperSlideHtmlFromItem(item) {
/**
* Renders the HTML markup of a slide for an item or a slide.
* @param {Object} item - The item used to render the slide.
* @param {number} index - The index of the item in the Swiper instance.
* @returns {string} The HTML markup of the slide.
*/
function getSwiperSlideHtml(item, index) {
if (currentOptions.slides) {
return getSwiperSlideHtmlFromSlide(item);
} else {
return getSwiperSlideHtmlFromItem(item);
}
}
/**
* Renders the HTML markup of a slide for an item.
* @param {Object} item - Item used to generate the slide.
* @returns {string} The HTML markup of the slide.
*/
function getSwiperSlideHtmlFromItem(item) {
return getSwiperSlideHtmlFromSlide({
imageUrl: getImgUrl(item),
originalImage: getImgUrl(item, true),
@ -264,11 +316,17 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
});
}
/**
* Renders the HTML markup of a slide for a slide object.
* @param {Object} item - Slide object used to generate the slide.
* @returns {string} The HTML markup of the slide.
*/
function getSwiperSlideHtmlFromSlide(item) {
var html = '';
html += '<div class="swiper-slide" data-imageurl="' + item.imageUrl + '" data-original="' + item.originalImage + '" data-itemid="' + item.Id + '" data-serverid="' + item.ServerId + '">';
html += '<img data-src="' + item.imageUrl + '" class="swiper-lazy swiper-slide-img">';
html += '<div class="swiper-slide" data-original="' + item.originalImage + '" data-itemid="' + item.Id + '" data-serverid="' + item.ServerId + '">';
html += '<div class="slider-zoom-container">';
html += '<img src="' + item.originalImage + '" class="swiper-slide-img">';
html += '</div>';
if (item.title || item.subtitle) {
html += '<div class="slideText">';
html += '<div class="slideTextInner">';
@ -290,42 +348,18 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
return html;
}
function previousImage() {
if (swiperInstance) {
swiperInstance.slidePrev();
} else {
stopInterval();
showNextImage(currentIndex - 1);
}
}
function nextImage() {
if (swiperInstance) {
if (options.loop === false) {
if (swiperInstance.activeIndex >= swiperInstance.slides.length - 1) {
dialogHelper.close(dlg);
return;
}
}
swiperInstance.slideNext();
} else {
stopInterval();
showNextImage(currentIndex + 1);
}
}
/**
* Fetches the information of the currently displayed slide.
* @returns {null|{itemId: string, shareUrl: string, serverId: string, url: string}} Object containing the information of the currently displayed slide.
*/
function getCurrentImageInfo() {
if (swiperInstance) {
var slide = document.querySelector('.swiper-slide-active');
if (slide) {
return {
url: slide.getAttribute('data-original'),
shareUrl: slide.getAttribute('data-imageurl'),
shareUrl: slide.getAttribute('data-original'),
itemId: slide.getAttribute('data-itemid'),
serverId: slide.getAttribute('data-serverid')
};
@ -336,8 +370,10 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
}
/**
* Starts a download for the currently displayed slide.
*/
function download() {
var imageInfo = getCurrentImageInfo();
require(['fileDownloader'], function (fileDownloader) {
@ -345,8 +381,10 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
});
}
/**
* Shares the currently displayed slide using the browser's built-in sharing feature.
*/
function share() {
var imageInfo = getCurrentImageInfo();
navigator.share({
@ -354,20 +392,29 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
});
}
/**
* Starts the autoplay feature of the Swiper instance.
*/
function play() {
if (swiperInstance.autoplay) {
swiperInstance.autoplay.start();
}
}
/**
* Pauses the autoplay feature of the Swiper instance;
*/
function pause() {
if (swiperInstance.autoplay) {
swiperInstance.autoplay.stop();
}
}
/**
* Toggles the autoplay feature of the Swiper instance.
*/
function playPause() {
var paused = !dlg.querySelector('.btnSlideshowPause i').classList.contains("pause");
var paused = !dialog.querySelector('.btnSlideshowPause i').classList.contains("pause");
if (paused) {
play();
} else {
@ -375,8 +422,10 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
}
/**
* Closes the dialog and destroys the Swiper instance.
*/
function onDialogClosed() {
var swiper = swiperInstance;
if (swiper) {
swiper.destroy(true, true);
@ -387,53 +436,38 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
document.removeEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove);
}
function startInterval(options) {
currentOptions = options;
stopInterval();
createElements(options);
if (!options.interactive) {
currentIntervalMs = options.interval || 11000;
showNextImage(options.startIndex || 0, true);
}
}
var _osdOpen = false;
function isOsdOpen() {
return _osdOpen;
}
function getOsdBottom() {
return dlg.querySelector('.slideshowBottomBar');
}
/**
* Shows the OSD.
*/
function showOsd() {
var bottom = getOsdBottom();
var bottom = dialog.querySelector('.slideshowBottomBar');
if (bottom) {
slideUpToShow(bottom);
startHideTimer();
}
}
/**
* Hides the OSD.
*/
function hideOsd() {
var bottom = getOsdBottom();
var bottom = dialog.querySelector('.slideshowBottomBar');
if (bottom) {
slideDownToHide(bottom);
}
}
var hideTimeout;
/**
* Starts the timer used to automatically hide the OSD.
*/
function startHideTimer() {
stopHideTimer();
hideTimeout = setTimeout(hideOsd, 4000);
hideTimeout = setTimeout(hideOsd, 3000);
}
/**
* Stops the timer used to automatically hide the OSD.
*/
function stopHideTimer() {
if (hideTimeout) {
clearTimeout(hideTimeout);
@ -441,71 +475,76 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
}
function slideUpToShow(elem) {
if (!elem.classList.contains('hide')) {
/**
* Shows the OSD by sliding it into view.
* @param {HTMLElement} element - Element containing the OSD.
*/
function slideUpToShow(element) {
if (!element.classList.contains('hide')) {
return;
}
_osdOpen = true;
elem.classList.remove('hide');
element.classList.remove('hide');
var onFinish = function () {
focusManager.focus(elem.querySelector('.btnSlideshowPause'));
focusManager.focus(element.querySelector('.btnSlideshowPause'));
};
if (!elem.animate) {
if (!element.animate) {
onFinish();
return;
}
requestAnimationFrame(function () {
var keyframes = [
{ transform: 'translate3d(0,' + elem.offsetHeight + 'px,0)', opacity: '.3', offset: 0 },
{ transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 0 },
{ transform: 'translate3d(0,0,0)', opacity: '1', offset: 1 }
];
var timing = { duration: 300, iterations: 1, easing: 'ease-out' };
elem.animate(keyframes, timing).onfinish = onFinish;
element.animate(keyframes, timing).onfinish = onFinish;
});
}
function slideDownToHide(elem) {
if (elem.classList.contains('hide')) {
/**
* Hides the OSD by sliding it out of view.
* @param {HTMLElement} element - Element containing the OSD.
*/
function slideDownToHide(element) {
if (element.classList.contains('hide')) {
return;
}
var onFinish = function () {
elem.classList.add('hide');
element.classList.add('hide');
_osdOpen = false;
};
if (!elem.animate) {
if (!element.animate) {
onFinish();
return;
}
requestAnimationFrame(function () {
var keyframes = [
{ transform: 'translate3d(0,0,0)', opacity: '1', offset: 0 },
{ transform: 'translate3d(0,' + elem.offsetHeight + 'px,0)', opacity: '.3', offset: 1 }
{ transform: 'translate3d(0,' + element.offsetHeight + 'px,0)', opacity: '.3', offset: 1 }
];
var timing = { duration: 300, iterations: 1, easing: 'ease-out' };
elem.animate(keyframes, timing).onfinish = onFinish;
element.animate(keyframes, timing).onfinish = onFinish;
});
}
var lastMouseMoveData;
function onPointerMove(e) {
var pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
/**
* Shows the OSD when moving the mouse pointer or touching the screen.
* @param {Event} event - Pointer movement event.
*/
function onPointerMove(event) {
var pointerType = event.pointerType || (layoutManager.mobile ? 'touch' : 'mouse');
if (pointerType === 'mouse') {
var eventX = e.screenX || 0;
var eventY = e.screenY || 0;
var eventX = event.screenX || 0;
var eventY = event.screenY || 0;
var obj = lastMouseMoveData;
if (!obj) {
@ -528,125 +567,46 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
}
}
function onInputCommand(e) {
switch (e.detail.command) {
case 'left':
if (!isOsdOpen()) {
e.preventDefault();
e.stopPropagation();
previousImage();
}
break;
case 'right':
if (!isOsdOpen()) {
e.preventDefault();
e.stopPropagation();
nextImage();
}
break;
/**
* Dispatches keyboard inputs to their proper handlers.
* @param {Event} event - Keyboard input event.
*/
function onInputCommand(event) {
switch (event.detail.command) {
case 'up':
case 'down':
case 'select':
case 'menu':
case 'info':
case 'play':
case 'playpause':
case 'pause':
showOsd();
break;
case 'play':
play();
break;
case 'pause':
pause();
break;
case 'playpause':
playPause();
break;
default:
break;
}
}
function showNextImage(index, skipPreload) {
index = Math.max(0, index);
if (index >= currentOptions.items.length) {
index = 0;
}
currentIndex = index;
var options = currentOptions;
var items = options.items;
var item = items[index];
var imgUrl = getImgUrl(item);
var onSrcLoaded = function () {
var cardImageContainer = dlg.querySelector('.slideshowImage');
var newCardImageContainer = document.createElement('div');
newCardImageContainer.className = cardImageContainer.className;
if (options.cover) {
newCardImageContainer.classList.add('slideshowImage-cover');
}
newCardImageContainer.style.backgroundImage = "url('" + imgUrl + "')";
newCardImageContainer.classList.add('hide');
cardImageContainer.parentNode.appendChild(newCardImageContainer);
if (options.showTitle) {
dlg.querySelector('.slideshowImageText').innerHTML = item.Name;
} else {
dlg.querySelector('.slideshowImageText').innerHTML = '';
}
newCardImageContainer.classList.remove('hide');
var onAnimationFinished = function () {
var parentNode = cardImageContainer.parentNode;
if (parentNode) {
parentNode.removeChild(cardImageContainer);
}
};
if (newCardImageContainer.animate) {
var keyframes = [
{ opacity: '0', offset: 0 },
{ opacity: '1', offset: 1 }
];
var timing = { duration: 1200, iterations: 1 };
newCardImageContainer.animate(keyframes, timing).onfinish = onAnimationFinished;
} else {
onAnimationFinished();
}
stopInterval();
currentTimeout = setTimeout(function () {
showNextImage(index + 1, true);
}, currentIntervalMs);
};
if (!skipPreload) {
var img = new Image();
img.onload = onSrcLoaded;
img.src = imgUrl;
} else {
onSrcLoaded();
}
}
function stopInterval() {
if (currentTimeout) {
clearTimeout(currentTimeout);
currentTimeout = null;
}
}
/**
* Shows the slideshow component.
*/
self.show = function () {
startInterval(options);
createElements(options);
};
/**
* Hides the slideshow element.
*/
self.hide = function () {
var dialog = dlg;
var dialog = dialog;
if (dialog) {
dialogHelper.close(dialog);
}
};

View file

@ -30,7 +30,7 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
subtitleSyncTextField.updateOffset = function(offset) {
this.textContent = offset + "s";
}
};
subtitleSyncTextField.addEventListener("keypress", function(event) {
@ -66,7 +66,7 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
subtitleSyncSlider.updateOffset = function(percent) {
// default value is 0s = 50%
this.value = percent === undefined ? 50 : percent;
}
};
subtitleSyncSlider.addEventListener("change", function () {
// set new offset
@ -132,7 +132,7 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
elem.parentNode.removeChild(elem);
this.element = null;
}
}
};
SubtitleSync.prototype.toggle = function(action) {
@ -166,7 +166,7 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html',
}
/* eslint-enable no-fallthrough */
}
}
};
return SubtitleSync;
});