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 fix-#518

This commit is contained in:
Joshua M. Boniface 2019-10-23 11:37:49 -04:00 committed by GitHub
commit 5a4498dca1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 1666 additions and 513 deletions

View file

@ -28,6 +28,8 @@
- [lewazo](https://github.com/lewazo) - [lewazo](https://github.com/lewazo)
- [Raghu Saxena](https://github.com/ckcr4lyf) - [Raghu Saxena](https://github.com/ckcr4lyf)
- [Nickbert7](https://github.com/Nickbert7) - [Nickbert7](https://github.com/Nickbert7)
- [ferferga](https://github.com/ferferga)
- [bilde2910](https://github.com/bilde2910)
- [Daniel Hartung](https://github.com/dhartung) - [Daniel Hartung](https://github.com/dhartung)
# Emby Contributors # Emby Contributors

View file

@ -17,14 +17,14 @@
}, },
"dependencies": { "dependencies": {
"flv.js": "^1.5.0", "flv.js": "^1.5.0",
"jstree": "^3.3.7",
"jquery": "^3.4.1",
"hls.js": "^0.12.4", "hls.js": "^0.12.4",
"howler": "^2.1.2", "howler": "^2.1.2",
"jquery": "^3.4.1",
"jstree": "^3.3.7",
"libjass": "^0.11.0",
"shaka-player": "^2.5.5", "shaka-player": "^2.5.5",
"swiper": "^4.5.0",
"sortablejs": "^1.9.0", "sortablejs": "^1.9.0",
"libjass": "^0.11.0" "swiper": "^3.4.2"
}, },
"scripts": { "scripts": {
"serve": "webpack-dev-server --config webpack.dev.js --open", "serve": "webpack-dev-server --config webpack.dev.js --open",

View file

@ -13,8 +13,7 @@ define(["events", "globalize", "dom", "datetime", "userSettings", "serverNotific
if (entry.UserId && entry.UserPrimaryImageTag) { if (entry.UserId && entry.UserPrimaryImageTag) {
html += '<i class="listItemIcon md-icon" style="width:2em!important;height:2em!important;padding:0;color:transparent;background-color:' + color + ";background-image:url('" + apiClient.getUserImageUrl(entry.UserId, { html += '<i class="listItemIcon md-icon" style="width:2em!important;height:2em!important;padding:0;color:transparent;background-color:' + color + ";background-image:url('" + apiClient.getUserImageUrl(entry.UserId, {
type: "Primary", type: "Primary",
tag: entry.UserPrimaryImageTag, tag: entry.UserPrimaryImageTag
height: 40
}) + "');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 { } else {
html += '<i class="listItemIcon md-icon" style="background-color:' + color + '">' + icon + '</i>'; html += '<i class="listItemIcon md-icon" style="background-color:' + color + '">' + icon + '</i>';

View file

@ -173,19 +173,6 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
currentLoadingBackdrop = instance; currentLoadingBackdrop = instance;
} }
var standardWidths = [480, 720, 1280, 1440, 1920];
function getBackdropMaxWidth() {
var width = dom.getWindowSize().innerWidth;
var roundScreenTo = 100;
if (standardWidths.indexOf(width) !== -1) {
return width;
}
width = Math.floor(width / roundScreenTo) * roundScreenTo;
return Math.min(width, 1920);
}
function getItemImageUrls(item, imageOptions) { function getItemImageUrls(item, imageOptions) {
imageOptions = imageOptions || {}; imageOptions = imageOptions || {};
@ -195,7 +182,6 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
return apiClient.getScaledImageUrl(item.BackdropItemId || item.Id, Object.assign(imageOptions, { return apiClient.getScaledImageUrl(item.BackdropItemId || item.Id, Object.assign(imageOptions, {
type: "Backdrop", type: "Backdrop",
tag: imgTag, tag: imgTag,
maxWidth: getBackdropMaxWidth(),
index: index index: index
})); }));
}); });
@ -206,7 +192,6 @@ define(['browser', 'connectionManager', 'playbackManager', 'dom', 'css!./style']
return apiClient.getScaledImageUrl(item.ParentBackdropItemId, Object.assign(imageOptions, { return apiClient.getScaledImageUrl(item.ParentBackdropItemId, Object.assign(imageOptions, {
type: "Backdrop", type: "Backdrop",
tag: imgTag, tag: imgTag,
maxWidth: getBackdropMaxWidth(),
index: index index: index
})); }));
}); });

View file

@ -232,9 +232,10 @@ button {
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background-size: contain; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center bottom; background-position: center;
border: none;
} }
.cardImage-img { .cardImage-img {

View file

@ -471,7 +471,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, { imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Thumb", type: "Thumb",
maxWidth: width,
tag: item.ImageTags.Thumb tag: item.ImageTags.Thumb
}); });
@ -479,7 +478,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, { imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Banner", type: "Banner",
maxWidth: width,
tag: item.ImageTags.Banner tag: item.ImageTags.Banner
}); });
@ -487,7 +485,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, { imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Disc", type: "Disc",
maxWidth: width,
tag: item.ImageTags.Disc tag: item.ImageTags.Disc
}); });
@ -495,7 +492,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, { imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Logo", type: "Logo",
maxWidth: width,
tag: item.ImageTags.Logo tag: item.ImageTags.Logo
}); });
@ -503,7 +499,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentLogoItemId, { imgUrl = apiClient.getScaledImageUrl(item.ParentLogoItemId, {
type: "Logo", type: "Logo",
maxWidth: width,
tag: item.ParentLogoImageTag tag: item.ParentLogoImageTag
}); });
@ -511,7 +506,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, { imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
type: "Thumb", type: "Thumb",
maxWidth: width,
tag: item.SeriesThumbImageTag tag: item.SeriesThumbImageTag
}); });
@ -519,7 +513,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, { imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, {
type: "Thumb", type: "Thumb",
maxWidth: width,
tag: item.ParentThumbImageTag tag: item.ParentThumbImageTag
}); });
@ -527,7 +520,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, { imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Backdrop", type: "Backdrop",
maxWidth: width,
tag: item.BackdropImageTags[0] tag: item.BackdropImageTags[0]
}); });
@ -537,7 +529,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, { imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
type: "Backdrop", type: "Backdrop",
maxWidth: width,
tag: item.ParentBackdropImageTags[0] tag: item.ParentBackdropImageTags[0]
}); });
@ -547,8 +538,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, { imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Primary", type: "Primary",
maxHeight: height,
maxWidth: width,
tag: item.ImageTags.Primary tag: item.ImageTags.Primary
}); });
@ -569,8 +558,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.PrimaryImageItemId || item.Id || item.ItemId, { imgUrl = apiClient.getScaledImageUrl(item.PrimaryImageItemId || item.Id || item.ItemId, {
type: "Primary", type: "Primary",
maxHeight: height,
maxWidth: width,
tag: item.PrimaryImageTag tag: item.PrimaryImageTag
}); });
@ -589,7 +576,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, { imgUrl = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, {
type: "Primary", type: "Primary",
maxWidth: width,
tag: item.ParentPrimaryImageTag tag: item.ParentPrimaryImageTag
}); });
} }
@ -597,7 +583,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, { imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
type: "Primary", type: "Primary",
maxWidth: width,
tag: item.SeriesPrimaryImageTag tag: item.SeriesPrimaryImageTag
}); });
} }
@ -607,8 +592,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.AlbumId, { imgUrl = apiClient.getScaledImageUrl(item.AlbumId, {
type: "Primary", type: "Primary",
maxHeight: height,
maxWidth: width,
tag: item.AlbumPrimaryImageTag tag: item.AlbumPrimaryImageTag
}); });
@ -623,7 +606,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, { imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Thumb", type: "Thumb",
maxWidth: width,
tag: item.ImageTags.Thumb tag: item.ImageTags.Thumb
}); });
@ -632,7 +614,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, { imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Backdrop", type: "Backdrop",
maxWidth: width,
tag: item.BackdropImageTags[0] tag: item.BackdropImageTags[0]
}); });
@ -640,7 +621,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.Id, { imgUrl = apiClient.getScaledImageUrl(item.Id, {
type: "Thumb", type: "Thumb",
maxWidth: width,
tag: item.ImageTags.Thumb tag: item.ImageTags.Thumb
}); });
@ -648,7 +628,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.SeriesId, { imgUrl = apiClient.getScaledImageUrl(item.SeriesId, {
type: "Thumb", type: "Thumb",
maxWidth: width,
tag: item.SeriesThumbImageTag tag: item.SeriesThumbImageTag
}); });
@ -656,7 +635,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, { imgUrl = apiClient.getScaledImageUrl(item.ParentThumbItemId, {
type: "Thumb", type: "Thumb",
maxWidth: width,
tag: item.ParentThumbImageTag tag: item.ParentThumbImageTag
}); });
@ -664,7 +642,6 @@ define(['datetime', 'imageLoader', 'connectionManager', 'itemHelper', 'focusMana
imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, { imgUrl = apiClient.getScaledImageUrl(item.ParentBackdropItemId, {
type: "Backdrop", type: "Backdrop",
maxWidth: width,
tag: item.ParentBackdropImageTags[0] tag: item.ParentBackdropImageTags[0]
}); });

View file

@ -147,15 +147,14 @@
vertical-align: middle; vertical-align: middle;
} }
.paper-icon-button-light > img { .paper-icon-button-light > div {
width: 1.72em;
/* Can't use 100% height or it will stretch past the boundaries in safari */
/*height: 100%;*/
max-height: 100%; max-height: 100%;
/* Make sure its on top of the ripple */ transform: scale(1.8);
position: relative; position: relative;
z-index: 1; z-index: 1;
vertical-align: middle; vertical-align: middle;
display: inline;
margin: 0 auto;
} }
.emby-button-foreground { .emby-button-foreground {

View file

@ -560,31 +560,31 @@ define(['connectionManager', 'cardBuilder', 'appSettings', 'dom', 'apphost', 'la
if (enableScrollX()) { if (enableScrollX()) {
html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true" data-scrollbuttons="false">'; html += '<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-mousewheel="false" data-centerfocus="true" data-scrollbuttons="false">';
html += '<div class="padded-left padded-right padded-top padded-bottom scrollSlider focuscontainer-x">'; html += '<div class="padded-top padded-bottom scrollSlider focuscontainer-x">';
} else { } else {
html += '<div class="padded-left padded-right padded-top padded-bottom focuscontainer-x">'; html += '<div class="padded-top padded-bottom focuscontainer-x">';
} }
html += '<a style="margin-left:.8em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', { html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', {
serverId: apiClient.serverId(), serverId: apiClient.serverId(),
section: 'programs' section: 'programs'
}) + '" class="raised"><span>' + globalize.translate('Programs') + '</span></a>'; }) + '" class="raised"><span>' + globalize.translate('Programs') + '</span></a>';
html += '<a style="margin-left:.5em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', { html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', {
serverId: apiClient.serverId(), serverId: apiClient.serverId(),
section: 'guide' section: 'guide'
}) + '" class="raised"><span>' + globalize.translate('Guide') + '</span></a>'; }) + '" class="raised"><span>' + globalize.translate('Guide') + '</span></a>';
html += '<a style="margin-left:.5em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('recordedtv', { html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl('recordedtv', {
serverId: apiClient.serverId() serverId: apiClient.serverId()
}) + '" class="raised"><span>' + globalize.translate('Recordings') + '</span></a>'; }) + '" class="raised"><span>' + globalize.translate('Recordings') + '</span></a>';
html += '<a style="margin-left:.5em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', { html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', {
serverId: apiClient.serverId(), serverId: apiClient.serverId(),
section: 'dvrschedule' section: 'dvrschedule'
}) + '" class="raised"><span>' + globalize.translate('Schedule') + '</span></a>'; }) + '" class="raised"><span>' + globalize.translate('Schedule') + '</span></a>';
html += '<a style="margin-left:.5em;margin-right:0;" is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', { html += '<a is="emby-linkbutton" href="' + appRouter.getRouteUrl('livetv', {
serverId: apiClient.serverId(), serverId: apiClient.serverId(),
section: 'seriesrecording' section: 'seriesrecording'
}) + '" class="raised"><span>' + globalize.translate('Series') + '</span></a>'; }) + '" class="raised"><span>' + globalize.translate('Series') + '</span></a>';

View file

@ -1,5 +1,5 @@
define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter', 'playbackManager', 'loading', 'appSettings', 'browser', 'actionsheet'], function (appHost, globalize, connectionManager, itemHelper, appRouter, playbackManager, loading, appSettings, browser, actionsheet) { define(["apphost", "globalize", "connectionManager", "itemHelper", "appRouter", "playbackManager", "loading", "appSettings", "browser", "actionsheet"], function (appHost, globalize, connectionManager, itemHelper, appRouter, playbackManager, loading, appSettings, browser, actionsheet) {
'use strict'; "use strict";
function getCommands(options) { function getCommands(options) {
var item = options.item; var item = options.item;
@ -9,18 +9,20 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
var user = options.user; var user = options.user;
var commands = []; var commands = [];
if (canPlay && item.MediaType !== 'Photo') { if (canPlay && item.MediaType !== "Photo") {
if (options.play !== false) { if (options.play !== false) {
commands.push({ commands.push({
name: globalize.translate('Play'), name: globalize.translate("Play"),
id: 'resume' id: "resume",
icon: "play_arrow"
}); });
} }
if (options.playAllFromHere && item.Type !== 'Program' && item.Type !== 'TvChannel') { if (options.playAllFromHere && item.Type !== "Program" && item.Type !== "TvChannel") {
commands.push({ commands.push({
name: globalize.translate('PlayAllFromHere'), name: globalize.translate("PlayAllFromHere"),
id: 'playallfromhere' id: "playallfromhere",
icon: "play_arrow"
}); });
} }
} }
@ -28,22 +30,24 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
if (playbackManager.canQueue(item)) { if (playbackManager.canQueue(item)) {
if (options.queue !== false) { if (options.queue !== false) {
commands.push({ commands.push({
name: globalize.translate('AddToPlayQueue'), name: globalize.translate("AddToPlayQueue"),
id: 'queue' id: "queue",
icon: "playlist_add"
}); });
} }
if (options.queue !== false) { if (options.queue !== false) {
commands.push({ commands.push({
name: globalize.translate('PlayNext'), name: globalize.translate("PlayNext"),
id: 'queuenext' id: "queuenext",
icon: "playlist_add"
}); });
} }
//if (options.queueAllFromHere) { //if (options.queueAllFromHere) {
// commands.push({ // commands.push({
// name: globalize.translate('QueueAllFromHere'), // name: globalize.translate("QueueAllFromHere"),
// id: 'queueallfromhere' // id: "queueallfromhere"
// }); // });
//} //}
} }
@ -51,11 +55,12 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
if (item.IsFolder || item.Type === "MusicArtist" || item.Type === "MusicGenre") { if (item.IsFolder || item.Type === "MusicArtist" || item.Type === "MusicGenre") {
if (item.CollectionType !== 'livetv') { if (item.CollectionType !== "livetv") {
if (options.shuffle !== false) { if (options.shuffle !== false) {
commands.push({ commands.push({
name: globalize.translate('Shuffle'), name: globalize.translate("Shuffle"),
id: 'shuffle' id: "shuffle",
icon: "shuffle"
}); });
} }
} }
@ -64,8 +69,9 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
if (item.MediaType === "Audio" || item.Type === "MusicAlbum" || item.Type === "MusicArtist" || item.Type === "MusicGenre") { if (item.MediaType === "Audio" || item.Type === "MusicAlbum" || item.Type === "MusicArtist" || item.Type === "MusicGenre") {
if (options.instantMix !== false && !itemHelper.isLocalItem(item)) { if (options.instantMix !== false && !itemHelper.isLocalItem(item)) {
commands.push({ commands.push({
name: globalize.translate('InstantMix'), name: globalize.translate("InstantMix"),
id: 'instantmix' id: "instantmix",
icon: "shuffle"
}); });
} }
} }
@ -79,75 +85,91 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
if (!restrictOptions) { if (!restrictOptions) {
if (itemHelper.supportsAddingToCollection(item)) { if (itemHelper.supportsAddingToCollection(item)) {
commands.push({ commands.push({
name: globalize.translate('AddToCollection'), name: globalize.translate("AddToCollection"),
id: 'addtocollection' id: "addtocollection",
icon: "playlist_add"
}); });
} }
if (itemHelper.supportsAddingToPlaylist(item)) { if (itemHelper.supportsAddingToPlaylist(item)) {
commands.push({ commands.push({
name: globalize.translate('AddToPlaylist'), name: globalize.translate("AddToPlaylist"),
id: 'addtoplaylist' id: "addtoplaylist",
icon: "playlist_add"
}); });
} }
} }
if ((item.Type === 'Timer') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) { if ((item.Type === "Timer") && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
commands.push({ commands.push({
name: globalize.translate('CancelRecording'), name: globalize.translate("CancelRecording"),
id: 'canceltimer' id: "canceltimer",
icon: "cancel"
}); });
} }
if ((item.Type === 'Recording' && item.Status === 'InProgress') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) { if ((item.Type === "Recording" && item.Status === "InProgress") && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
commands.push({ commands.push({
name: globalize.translate('CancelRecording'), name: globalize.translate("CancelRecording"),
id: 'canceltimer' id: "canceltimer",
icon: "cancel"
}); });
} }
if ((item.Type === 'SeriesTimer') && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) { if ((item.Type === "SeriesTimer") && user.Policy.EnableLiveTvManagement && options.cancelTimer !== false) {
commands.push({ commands.push({
name: globalize.translate('CancelSeries'), name: globalize.translate("CancelSeries"),
id: 'cancelseriestimer' id: "cancelseriestimer",
icon: "cancel"
}); });
} }
if (item.CanDelete && options.deleteItem !== false) { if (item.CanDelete && options.deleteItem !== false) {
if (item.Type === 'Playlist' || item.Type === 'BoxSet') { if (item.Type === "Playlist" || item.Type === "BoxSet") {
commands.push({ commands.push({
name: globalize.translate('Delete'), name: globalize.translate("Delete"),
id: 'delete' id: "delete",
icon: "delete"
}); });
} else { } else {
commands.push({ commands.push({
name: globalize.translate('DeleteMedia'), name: globalize.translate("DeleteMedia"),
id: 'delete' id: "delete",
icon: "delete"
}); });
} }
} }
// Books are promoted to major download Button and therefor excluded in the context menu // Books are promoted to major download Button and therefor excluded in the context menu
if ((item.CanDownload && appHost.supports('filedownload')) && item.Type !== "Book") { if ((item.CanDownload && appHost.supports("filedownload")) && item.Type !== "Book") {
commands.push({ commands.push({
name: globalize.translate('Download'), name: globalize.translate("Download"),
id: 'download' id: "download",
icon: "file_download"
}); });
commands.push({ commands.push({
name: globalize.translate('CopyStreamURL'), name: globalize.translate("CopyStreamURL"),
id: 'copy-stream' id: "copy-stream",
icon: "content_copy"
});
}
if (commands.length) {
commands.push({
divider: true
}); });
} }
var canEdit = itemHelper.canEdit(user, item); var canEdit = itemHelper.canEdit(user, item);
if (canEdit) { if (canEdit) {
if (options.edit !== false && item.Type !== 'SeriesTimer') { if (options.edit !== false && item.Type !== "SeriesTimer") {
var text = (item.Type === 'Timer' || item.Type === 'SeriesTimer') ? globalize.translate('Edit') : globalize.translate('EditMetadata'); var text = (item.Type === "Timer" || item.Type === "SeriesTimer") ? globalize.translate("Edit") : globalize.translate("EditMetadata");
commands.push({ commands.push({
name: text, name: text,
id: 'edit' id: "edit",
icon: "edit"
}); });
} }
} }
@ -155,18 +177,20 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
if (itemHelper.canEditImages(user, item)) { if (itemHelper.canEditImages(user, item)) {
if (options.editImages !== false) { if (options.editImages !== false) {
commands.push({ commands.push({
name: globalize.translate('EditImages'), name: globalize.translate("EditImages"),
id: 'editimages' id: "editimages",
icon: "edit"
}); });
} }
} }
if (canEdit) { if (canEdit) {
if (item.MediaType === 'Video' && item.Type !== 'TvChannel' && item.Type !== 'Program' && item.LocationType !== 'Virtual' && !(item.Type === 'Recording' && item.Status !== 'Completed')) { if (item.MediaType === "Video" && item.Type !== "TvChannel" && item.Type !== "Program" && item.LocationType !== "Virtual" && !(item.Type === "Recording" && item.Status !== "Completed")) {
if (options.editSubtitles !== false) { if (options.editSubtitles !== false) {
commands.push({ commands.push({
name: globalize.translate('EditSubtitles'), name: globalize.translate("EditSubtitles"),
id: 'editsubtitles' id: "editsubtitles",
icon: "closed_caption"
}); });
} }
} }
@ -175,8 +199,9 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
if (options.identify !== false) { if (options.identify !== false) {
if (itemHelper.canIdentify(user, item)) { if (itemHelper.canIdentify(user, item)) {
commands.push({ commands.push({
name: globalize.translate('Identify'), name: globalize.translate("Identify"),
id: 'identify' id: "identify",
icon: "edit"
}); });
} }
} }
@ -184,48 +209,54 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
if (item.MediaSources) { if (item.MediaSources) {
if (options.moremediainfo !== false) { if (options.moremediainfo !== false) {
commands.push({ commands.push({
name: globalize.translate('MoreMediaInfo'), name: globalize.translate("MoreMediaInfo"),
id: 'moremediainfo' id: "moremediainfo",
icon: "info"
}); });
} }
} }
if (item.Type === 'Program' && options.record !== false) { if (item.Type === "Program" && options.record !== false) {
if (item.TimerId) { if (item.TimerId) {
commands.push({ commands.push({
name: Globalize.translate('ManageRecording'), name: Globalize.translate("ManageRecording"),
id: 'record' id: "record",
icon: "fiber_manual_record"
}); });
} }
} }
if (item.Type === 'Program' && options.record !== false) { if (item.Type === "Program" && options.record !== false) {
if (!item.TimerId) { if (!item.TimerId) {
commands.push({ commands.push({
name: Globalize.translate('Record'), name: Globalize.translate("Record"),
id: 'record' id: "record",
icon: "fiber_manual_record"
}); });
} }
} }
if (itemHelper.canRefreshMetadata(item, user)) { if (itemHelper.canRefreshMetadata(item, user)) {
commands.push({ commands.push({
name: globalize.translate('RefreshMetadata'), name: globalize.translate("RefreshMetadata"),
id: 'refresh' id: "refresh",
icon: "refresh"
}); });
} }
if (item.PlaylistItemId && options.playlistId) { if (item.PlaylistItemId && options.playlistId) {
commands.push({ commands.push({
name: globalize.translate('RemoveFromPlaylist'), name: globalize.translate("RemoveFromPlaylist"),
id: 'removefromplaylist' id: "removefromplaylist",
icon: "remove"
}); });
} }
if (options.collectionId) { if (options.collectionId) {
commands.push({ commands.push({
name: globalize.translate('RemoveFromCollection'), name: globalize.translate("RemoveFromCollection"),
id: 'removefromcollection' id: "removefromcollection",
icon: "remove"
}); });
} }
@ -233,8 +264,9 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
if (options.share === true) { if (options.share === true) {
if (itemHelper.canShare(item, user)) { if (itemHelper.canShare(item, user)) {
commands.push({ commands.push({
name: globalize.translate('Share'), name: globalize.translate("Share"),
id: 'share' id: "share",
icon: "share"
}); });
} }
} }
@ -243,23 +275,26 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
if (options.sync !== false) { if (options.sync !== false) {
if (itemHelper.canSync(user, item)) { if (itemHelper.canSync(user, item)) {
commands.push({ commands.push({
name: globalize.translate('Sync'), name: globalize.translate("Sync"),
id: 'sync' id: "sync",
icon: "sync"
}); });
} }
} }
if (options.openAlbum !== false && item.AlbumId && item.MediaType !== 'Photo') { if (options.openAlbum !== false && item.AlbumId && item.MediaType !== "Photo") {
commands.push({ commands.push({
name: Globalize.translate('ViewAlbum'), name: Globalize.translate("ViewAlbum"),
id: 'album' id: "album",
icon: "album"
}); });
} }
if (options.openArtist !== false && item.ArtistItems && item.ArtistItems.length) { if (options.openArtist !== false && item.ArtistItems && item.ArtistItems.length) {
commands.push({ commands.push({
name: Globalize.translate('ViewArtist'), name: Globalize.translate("ViewArtist"),
id: 'artist' id: "artist",
icon: "person"
}); });
} }
@ -283,24 +318,24 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
switch (id) { switch (id) {
case 'addtocollection': case "addtocollection":
require(['collectionEditor'], function (collectionEditor) { require(["collectionEditor"], function (collectionEditor) {
new collectionEditor().show({ new collectionEditor().show({
items: [itemId], items: [itemId],
serverId: serverId serverId: serverId
}).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); }).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
}); });
break; break;
case 'addtoplaylist': case "addtoplaylist":
require(['playlistEditor'], function (playlistEditor) { require(["playlistEditor"], function (playlistEditor) {
new playlistEditor().show({ new playlistEditor().show({
items: [itemId], items: [itemId],
serverId: serverId serverId: serverId
}).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); }).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
}); });
break; break;
case 'download': case "download":
require(['fileDownloader'], function (fileDownloader) { require(["fileDownloader"], function (fileDownloader) {
var downloadHref = apiClient.getItemDownloadUrl(itemId); var downloadHref = apiClient.getItemDownloadUrl(itemId);
fileDownloader.download([{ fileDownloader.download([{
url: downloadHref, url: downloadHref,
@ -310,7 +345,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
getResolveFunction(getResolveFunction(resolve, id), id)(); getResolveFunction(getResolveFunction(resolve, id), id)();
}); });
break; break;
case 'copy-stream': case "copy-stream":
var downloadHref = apiClient.getItemDownloadUrl(itemId); var downloadHref = apiClient.getItemDownloadUrl(itemId);
var textArea = document.createElement("textarea"); var textArea = document.createElement("textarea");
textArea.value = downloadHref; textArea.value = downloadHref;
@ -318,10 +353,10 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
textArea.focus(); textArea.focus();
textArea.select(); textArea.select();
try { try {
document.execCommand('copy'); document.execCommand("copy");
require(['toast'], function (toast) { require(["toast"], function (toast) {
toast(globalize.translate('CopyStreamURLSuccess')); toast(globalize.translate("CopyStreamURLSuccess"));
}); });
} catch (err) { } catch (err) {
console.error("Failed to copy to clipboard"); console.error("Failed to copy to clipboard");
@ -330,118 +365,118 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
document.body.removeChild(textArea); document.body.removeChild(textArea);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'editsubtitles': case "editsubtitles":
require(['subtitleEditor'], function (subtitleEditor) { require(["subtitleEditor"], function (subtitleEditor) {
subtitleEditor.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); subtitleEditor.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
}); });
break; break;
case 'edit': case "edit":
editItem(apiClient, item).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); editItem(apiClient, item).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
break; break;
case 'editimages': case "editimages":
require(['imageEditor'], function (imageEditor) { require(["imageEditor"], function (imageEditor) {
imageEditor.show({ imageEditor.show({
itemId: itemId, itemId: itemId,
serverId: serverId serverId: serverId
}).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); }).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
}); });
break; break;
case 'identify': case "identify":
require(['itemIdentifier'], function (itemIdentifier) { require(["itemIdentifier"], function (itemIdentifier) {
itemIdentifier.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); itemIdentifier.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
}); });
break; break;
case 'moremediainfo': case "moremediainfo":
require(['itemMediaInfo'], function (itemMediaInfo) { require(["itemMediaInfo"], function (itemMediaInfo) {
itemMediaInfo.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); itemMediaInfo.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
}); });
break; break;
case 'refresh': case "refresh":
refresh(apiClient, item); refresh(apiClient, item);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'open': case "open":
appRouter.showItem(item); appRouter.showItem(item);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'play': case "play":
play(item, false); play(item, false);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'resume': case "resume":
play(item, true); play(item, true);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'queue': case "queue":
play(item, false, true); play(item, false, true);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'queuenext': case "queuenext":
play(item, false, true, true); play(item, false, true, true);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'record': case "record":
require(['recordingCreator'], function (recordingCreator) { require(["recordingCreator"], function (recordingCreator) {
recordingCreator.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); recordingCreator.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id));
}); });
break; break;
case 'shuffle': case "shuffle":
playbackManager.shuffle(item); playbackManager.shuffle(item);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'instantmix': case "instantmix":
playbackManager.instantMix(item); playbackManager.instantMix(item);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'delete': case "delete":
deleteItem(apiClient, item).then(getResolveFunction(resolve, id, true, true), getResolveFunction(resolve, id)); deleteItem(apiClient, item).then(getResolveFunction(resolve, id, true, true), getResolveFunction(resolve, id));
break; break;
case 'share': case "share":
navigator.share({ navigator.share({
title: item.Name, title: item.Name,
text: item.Overview, text: item.Overview,
url: "https://github.com/jellyfin/jellyfin" url: "https://github.com/jellyfin/jellyfin"
}); });
break; break;
case 'album': case "album":
appRouter.showItem(item.AlbumId, item.ServerId); appRouter.showItem(item.AlbumId, item.ServerId);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'artist': case "artist":
appRouter.showItem(item.ArtistItems[0].Id, item.ServerId); appRouter.showItem(item.ArtistItems[0].Id, item.ServerId);
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'playallfromhere': case "playallfromhere":
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'queueallfromhere': case "queueallfromhere":
getResolveFunction(resolve, id)(); getResolveFunction(resolve, id)();
break; break;
case 'removefromplaylist': case "removefromplaylist":
apiClient.ajax({ apiClient.ajax({
url: apiClient.getUrl('Playlists/' + options.playlistId + '/Items', { url: apiClient.getUrl("Playlists/" + options.playlistId + "/Items", {
EntryIds: [item.PlaylistItemId].join(',') EntryIds: [item.PlaylistItemId].join(",")
}), }),
type: 'DELETE' type: "DELETE"
}).then(function () { }).then(function () {
getResolveFunction(resolve, id, true)(); getResolveFunction(resolve, id, true)();
}); });
break; break;
case 'removefromcollection': case "removefromcollection":
apiClient.ajax({ apiClient.ajax({
type: "DELETE", type: "DELETE",
url: apiClient.getUrl("Collections/" + options.collectionId + "/Items", { url: apiClient.getUrl("Collections/" + options.collectionId + "/Items", {
Ids: [item.Id].join(',') Ids: [item.Id].join(",")
}) })
}).then(function () { }).then(function () {
getResolveFunction(resolve, id, true)(); getResolveFunction(resolve, id, true)();
}); });
break; break;
case 'canceltimer': case "canceltimer":
deleteTimer(apiClient, item, resolve, id); deleteTimer(apiClient, item, resolve, id);
break; break;
case 'cancelseriestimer': case "cancelseriestimer":
deleteSeriesTimer(apiClient, item, resolve, id); deleteSeriesTimer(apiClient, item, resolve, id);
break; break;
default: default:
@ -452,7 +487,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
} }
function deleteTimer(apiClient, item, resolve, command) { function deleteTimer(apiClient, item, resolve, command) {
require(['recordingHelper'], function (recordingHelper) { require(["recordingHelper"], function (recordingHelper) {
var timerId = item.TimerId || item.Id; var timerId = item.TimerId || item.Id;
recordingHelper.cancelTimerWithConfirmation(timerId, item.ServerId).then(function () { recordingHelper.cancelTimerWithConfirmation(timerId, item.ServerId).then(function () {
getResolveFunction(resolve, command, true)(); getResolveFunction(resolve, command, true)();
@ -461,7 +496,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
} }
function deleteSeriesTimer(apiClient, item, resolve, command) { function deleteSeriesTimer(apiClient, item, resolve, command) {
require(['recordingHelper'], function (recordingHelper) { require(["recordingHelper"], function (recordingHelper) {
recordingHelper.cancelSeriesTimerWithConfirmation(item.Id, item.ServerId).then(function () { recordingHelper.cancelSeriesTimerWithConfirmation(item.Id, item.ServerId).then(function () {
getResolveFunction(resolve, command, true)(); getResolveFunction(resolve, command, true)();
}); });
@ -469,14 +504,14 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
} }
function play(item, resume, queue, queueNext) { function play(item, resume, queue, queueNext) {
var method = queue ? (queueNext ? 'queueNext' : 'queue') : 'play'; var method = queue ? (queueNext ? "queueNext" : "queue") : "play";
var startPosition = 0; var startPosition = 0;
if (resume && item.UserData && item.UserData.PlaybackPositionTicks) { if (resume && item.UserData && item.UserData.PlaybackPositionTicks) {
startPosition = item.UserData.PlaybackPositionTicks; startPosition = item.UserData.PlaybackPositionTicks;
} }
if (item.Type === 'Program') { if (item.Type === "Program") {
playbackManager[method]({ playbackManager[method]({
ids: [item.ChannelId], ids: [item.ChannelId],
startPositionTicks: startPosition, startPositionTicks: startPosition,
@ -494,16 +529,16 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
var serverId = apiClient.serverInfo().Id; var serverId = apiClient.serverInfo().Id;
if (item.Type === 'Timer') { if (item.Type === "Timer") {
require(['recordingEditor'], function (recordingEditor) { require(["recordingEditor"], function (recordingEditor) {
recordingEditor.show(item.Id, serverId).then(resolve, reject); recordingEditor.show(item.Id, serverId).then(resolve, reject);
}); });
} else if (item.Type === 'SeriesTimer') { } else if (item.Type === "SeriesTimer") {
require(['seriesRecordingEditor'], function (recordingEditor) { require(["seriesRecordingEditor"], function (recordingEditor) {
recordingEditor.show(item.Id, serverId).then(resolve, reject); recordingEditor.show(item.Id, serverId).then(resolve, reject);
}); });
} else { } else {
require(['metadataEditor'], function (metadataEditor) { require(["metadataEditor"], function (metadataEditor) {
metadataEditor.show(item.Id, serverId).then(resolve, reject); metadataEditor.show(item.Id, serverId).then(resolve, reject);
}); });
} }
@ -512,7 +547,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
function deleteItem(apiClient, item) { function deleteItem(apiClient, item) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
require(['deleteHelper'], function (deleteHelper) { require(["deleteHelper"], function (deleteHelper) {
deleteHelper.deleteItem({ deleteHelper.deleteItem({
item: item, item: item,
navigate: false navigate: false
@ -524,11 +559,11 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
} }
function refresh(apiClient, item) { function refresh(apiClient, item) {
require(['refreshDialog'], function (refreshDialog) { require(["refreshDialog"], function (refreshDialog) {
new refreshDialog({ new refreshDialog({
itemIds: [item.Id], itemIds: [item.Id],
serverId: apiClient.serverInfo().Id, serverId: apiClient.serverInfo().Id,
mode: item.Type === 'CollectionFolder' ? 'scan' : null mode: item.Type === "CollectionFolder" ? "scan" : null
}).show(); }).show();
}); });
} }
@ -542,7 +577,7 @@ define(['apphost', 'globalize', 'connectionManager', 'itemHelper', 'appRouter',
return actionsheet.show({ return actionsheet.show({
items: commands, items: commands,
positionTo: options.positionTo, positionTo: options.positionTo,
resolveOnClick: ['share'] resolveOnClick: ["share"]
}).then(function (id) { }).then(function (id) {
return executeCommand(options.item, id, options); return executeCommand(options.item, id, options);
}); });

View file

@ -511,7 +511,9 @@ define(["browser", "datetime", "backdrop", "libraryBrowser", "listView", "imageL
function getSaveablePlaylistItems() { function getSaveablePlaylistItems() {
return getPlaylistItems(currentPlayer).then(function (items) { return getPlaylistItems(currentPlayer).then(function (items) {
return i.Id && i.ServerId return items.filter(function (i) {
return i.Id && i.ServerId;
});
}); });
} }

View file

@ -207,7 +207,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f
dlg.querySelector('.swiper-wrapper').innerHTML = currentOptions.items.map(getSwiperSlideHtmlFromItem).join(''); dlg.querySelector('.swiper-wrapper').innerHTML = currentOptions.items.map(getSwiperSlideHtmlFromItem).join('');
} }
require(['swiper'], function (swiper) { require(['swiper'], function (Swiper) {
swiperInstance = new Swiper(dlg.querySelector('.slideshowSwiperContainer'), { swiperInstance = new Swiper(dlg.querySelector('.slideshowSwiperContainer'), {
// Optional parameters // Optional parameters

View file

@ -304,7 +304,7 @@ define(["datetime", "events", "itemHelper", "serverNotifications", "dom", "globa
html += "</div>"; html += "</div>";
html += '<div class="flex align-items-center justify-content-center">'; html += '<div class="flex align-items-center justify-content-center">';
var userImage = DashboardPage.getUserImage(session); var userImage = DashboardPage.getUserImage(session);
html += userImage ? '<img style="height:1.71em;border-radius:50px;margin-right:.5em;" src="' + userImage + '" />' : '<div style="height:1.71em;"></div>'; html += userImage ? '<div class="activitylogUserPhoto" style="background-image:url(\'' + userImage + "');\"></div>" : '<div style="height:1.71em;"></div>';
html += '<div class="sessionUserName">'; html += '<div class="sessionUserName">';
html += DashboardPage.getUsersHtml(session); html += DashboardPage.getUsersHtml(session);
html += "</div>"; html += "</div>";

View file

@ -429,31 +429,24 @@ define(["loading", "appRouter", "layoutManager", "connectionManager", "cardBuild
detectRatio = !1; detectRatio = !1;
imageTags.Primary ? (url = apiClient.getScaledImageUrl(item.Id, { imageTags.Primary ? (url = apiClient.getScaledImageUrl(item.Id, {
type: "Primary", type: "Primary",
maxHeight: 460,
tag: item.ImageTags.Primary tag: item.ImageTags.Primary
}), detectRatio = !0) : item.BackdropImageTags && item.BackdropImageTags.length ? (url = apiClient.getScaledImageUrl(item.Id, { }), detectRatio = !0) : item.BackdropImageTags && item.BackdropImageTags.length ? (url = apiClient.getScaledImageUrl(item.Id, {
type: "Backdrop", type: "Backdrop",
maxHeight: 360,
tag: item.BackdropImageTags[0] tag: item.BackdropImageTags[0]
}), shape = "thumb") : imageTags.Thumb ? (url = apiClient.getScaledImageUrl(item.Id, { }), shape = "thumb") : imageTags.Thumb ? (url = apiClient.getScaledImageUrl(item.Id, {
type: "Thumb", type: "Thumb",
maxHeight: 360,
tag: item.ImageTags.Thumb tag: item.ImageTags.Thumb
}), shape = "thumb") : imageTags.Disc ? (url = apiClient.getScaledImageUrl(item.Id, { }), shape = "thumb") : imageTags.Disc ? (url = apiClient.getScaledImageUrl(item.Id, {
type: "Disc", type: "Disc",
maxHeight: 360,
tag: item.ImageTags.Disc tag: item.ImageTags.Disc
}), shape = "square") : item.AlbumId && item.AlbumPrimaryImageTag ? (url = apiClient.getScaledImageUrl(item.AlbumId, { }), shape = "square") : item.AlbumId && item.AlbumPrimaryImageTag ? (url = apiClient.getScaledImageUrl(item.AlbumId, {
type: "Primary", type: "Primary",
maxHeight: 360,
tag: item.AlbumPrimaryImageTag tag: item.AlbumPrimaryImageTag
}), shape = "square") : item.SeriesId && item.SeriesPrimaryImageTag ? url = apiClient.getScaledImageUrl(item.SeriesId, { }), shape = "square") : item.SeriesId && item.SeriesPrimaryImageTag ? url = apiClient.getScaledImageUrl(item.SeriesId, {
type: "Primary", type: "Primary",
maxHeight: 360,
tag: item.SeriesPrimaryImageTag tag: item.SeriesPrimaryImageTag
}) : item.ParentPrimaryImageItemId && item.ParentPrimaryImageTag && (url = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, { }) : item.ParentPrimaryImageItemId && item.ParentPrimaryImageTag && (url = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, {
type: "Primary", type: "Primary",
maxHeight: 360,
tag: item.ParentPrimaryImageTag tag: item.ParentPrimaryImageTag
})), html += '<div style="position:relative;">', editable && (html += "<a class='itemDetailGalleryLink' is='emby-linkbutton' style='display:block;padding:2px;margin:0;' href='#'>"), detectRatio && item.PrimaryImageAspectRatio && (item.PrimaryImageAspectRatio >= 1.48 ? shape = "thumb" : item.PrimaryImageAspectRatio >= .85 && item.PrimaryImageAspectRatio <= 1.34 && (shape = "square")), html += "<img class='itemDetailImage lazy' src='data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' />", editable && (html += "</a>"); })), html += '<div style="position:relative;">', editable && (html += "<a class='itemDetailGalleryLink' is='emby-linkbutton' style='display:block;padding:2px;margin:0;' href='#'>"), detectRatio && item.PrimaryImageAspectRatio && (item.PrimaryImageAspectRatio >= 1.48 ? shape = "thumb" : item.PrimaryImageAspectRatio >= .85 && item.PrimaryImageAspectRatio <= 1.34 && (shape = "square")), html += "<img class='itemDetailImage lazy' src='data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' />", editable && (html += "</a>");
var progressHtml = item.IsFolder || !item.UserData ? "" : indicators.getProgressBarHtml(item); var progressHtml = item.IsFolder || !item.UserData ? "" : indicators.getProgressBarHtml(item);

View file

@ -11,14 +11,13 @@ define(["controllers/userpasswordpage", "loading", "libraryMenu", "apphost", "em
var imageUrl = "img/logindefault.png"; var imageUrl = "img/logindefault.png";
if (user.PrimaryImageTag) { if (user.PrimaryImageTag) {
imageUrl = ApiClient.getUserImageUrl(user.Id, { imageUrl = ApiClient.getUserImageUrl(user.Id, {
height: 200,
tag: user.PrimaryImageTag, tag: user.PrimaryImageTag,
type: "Primary" type: "Primary"
}); });
} }
var userImage = page.querySelector("#image"); var userImage = page.querySelector("#image");
userImage.src = imageUrl; userImage.style.backgroundImage = "url(" + imageUrl + ")";
Dashboard.getCurrentUser().then(function (loggedInUser) { Dashboard.getCurrentUser().then(function (loggedInUser) {
if (user.PrimaryImageTag) { if (user.PrimaryImageTag) {
@ -71,7 +70,7 @@ define(["controllers/userpasswordpage", "loading", "libraryMenu", "apphost", "em
reader.onerror = onFileReaderError; reader.onerror = onFileReaderError;
reader.onabort = onFileReaderAbort; reader.onabort = onFileReaderAbort;
reader.onload = function (evt) { reader.onload = function (evt) {
userImage.src = evt.target.result; userImage.style.backgroundImage = "url(" + evt.target.result + ")";
var userId = getParameterByName("userId"); var userId = getParameterByName("userId");
ApiClient.uploadUserImage(userId, "Primary", file).then(function () { ApiClient.uploadUserImage(userId, "Primary", file).then(function () {
loading.hide(); loading.hide();

View file

@ -252,6 +252,16 @@ div[data-role=controlgroup] a.ui-btn-active {
width: 100% !important width: 100% !important
} }
.activitylogUserPhoto {
height:1.71em;
width:1.71em;
border-radius:100%;
margin-right:.5em;
background-size:cover;
background-repeat:no-repeat;
background-position:center;
}
@media all and (min-width:40em) { @media all and (min-width:40em) {
.activeSession { .activeSession {
width: 100% !important width: 100% !important

View file

@ -67,9 +67,12 @@
display: inline-block display: inline-block
} }
.headerUserButtonRound img { .headerUserButtonRound div {
-webkit-border-radius: 100em; -webkit-border-radius: 100em;
border-radius: 100em border-radius: 100em;
background-size: cover;
background-repeat: no-repeat;
background-position: center center;
} }
.headerButton { .headerButton {

View file

@ -2,7 +2,7 @@
<div class="padded-left padded-right padded-bottom-page"> <div class="padded-left padded-right padded-bottom-page">
<div class="readOnlyContent" style="margin: 0 auto; padding: 0 1em;"> <div class="readOnlyContent" style="margin: 0 auto; padding: 0 1em;">
<div style="position:relative;display:inline-block;max-width:200px;"> <div style="position:relative;display:inline-block;max-width:200px;">
<img id="image" width="200px" /> <div id="image" style="width:200px;height:200px;background-repeat:no-repeat;background-position:center;border-radius:100%;background-size:cover;"></div>
<input id="uploadImage" type="file" accept="image/*" style="position:absolute;right:0;width:100%;height:100%;opacity:0;" /> <input id="uploadImage" type="file" accept="image/*" style="position:absolute;right:0;width:100%;height:100%;opacity:0;" />
</div> </div>
<div style="vertical-align:top;margin:1em 2em;display:inline-block;"> <div style="vertical-align:top;margin:1em 2em;display:inline-block;">

View file

@ -80,7 +80,7 @@ define(["dom", "layoutManager", "inputManager", "connectionManager", "events", "
function updateHeaderUserButton(src) { function updateHeaderUserButton(src) {
if (src) { if (src) {
headerUserButton.classList.add("headerUserButtonRound"); headerUserButton.classList.add("headerUserButtonRound");
headerUserButton.innerHTML = '<img src="' + src + '" />'; headerUserButton.innerHTML = '<div class="headerButton headerButtonRight paper-icon-button-light headerUserButtonRound" style="background-image:url(\'' + src + "');\"></div>";
} else { } else {
headerUserButton.classList.remove("headerUserButtonRound"); headerUserButton.classList.remove("headerUserButtonRound");
headerUserButton.innerHTML = '<i class="md-icon">&#xE7FD;</i>'; headerUserButton.innerHTML = '<i class="md-icon">&#xE7FD;</i>';

View file

@ -199,10 +199,10 @@
"EditSubtitles": "Untertitel bearbeiten", "EditSubtitles": "Untertitel bearbeiten",
"EnableBackdrops": "Aktiviere Hintergründe", "EnableBackdrops": "Aktiviere Hintergründe",
"EnableBackdropsHelp": "Wenn aktiviert, werden während des Browsens durch die Bibliothek auf einigen Seiten passende Hintergründe angezeigt.", "EnableBackdropsHelp": "Wenn aktiviert, werden während des Browsens durch die Bibliothek auf einigen Seiten passende Hintergründe angezeigt.",
"EnableCinemaMode": "Aktiviere den Kino-Modus", "EnableCinemaMode": "Kino-Modus",
"EnableColorCodedBackgrounds": "Aktiviere farbige Hintergründe", "EnableColorCodedBackgrounds": "Aktiviere farbige Hintergründe",
"EnableDisplayMirroring": "Aktiviere Display-Weiterleitung", "EnableDisplayMirroring": "Display-Spiegelung",
"EnableExternalVideoPlayers": "Aktiviere externe Videoplayer", "EnableExternalVideoPlayers": "Externe Videoplayer",
"EnableExternalVideoPlayersHelp": "Ein Menü für externe Videoplayer wird beim Start der Videowiedergabe angezeigt.", "EnableExternalVideoPlayersHelp": "Ein Menü für externe Videoplayer wird beim Start der Videowiedergabe angezeigt.",
"EnableHardwareEncoding": "Aktiviere Hardware-Encoding", "EnableHardwareEncoding": "Aktiviere Hardware-Encoding",
"EnableNextVideoInfoOverlay": "Aktiviere \"Next-Video-Info\" während der Wiedergabe", "EnableNextVideoInfoOverlay": "Aktiviere \"Next-Video-Info\" während der Wiedergabe",

View file

@ -1091,7 +1091,7 @@
"OptionDownloadBoxImage": "Box", "OptionDownloadBoxImage": "Box",
"OptionDownloadDiscImage": "Disc", "OptionDownloadDiscImage": "Disc",
"OptionDownloadImagesInAdvance": "Download images in advance", "OptionDownloadImagesInAdvance": "Download images in advance",
"OptionDownloadImagesInAdvanceHelp": "By default, most images are only downloaded when requested by an Jellyfin app. Enable this option to download all images in advance, as new media is imported. This may cause significantly longer library scans.", "OptionDownloadImagesInAdvanceHelp": "By default, most images are only downloaded when requested by a Jellyfin app. Enable this option to download all images in advance, as new media is imported. This may cause significantly longer library scans.",
"OptionDownloadLogoImage": "Logo", "OptionDownloadLogoImage": "Logo",
"OptionDownloadMenuImage": "Menu", "OptionDownloadMenuImage": "Menu",
"OptionDownloadPrimaryImage": "Primary", "OptionDownloadPrimaryImage": "Primary",

View file

@ -174,7 +174,7 @@
"EnableNextVideoInfoOverlay": "Muestra la información del siguiente video durante la reproducción", "EnableNextVideoInfoOverlay": "Muestra la información del siguiente video durante la reproducción",
"EnablePhotos": "Mostrar fotos", "EnablePhotos": "Mostrar fotos",
"EnablePhotosHelp": "Las imágenes se detectarán y se mostrarán junto con otros archivos multimedia.", "EnablePhotosHelp": "Las imágenes se detectarán y se mostrarán junto con otros archivos multimedia.",
"EnableStreamLooping": "Bucle automático de los streams en directo", "EnableStreamLooping": "Bucle automático de las emisiones en directo",
"EnableStreamLoopingHelp": "Habilite esto si las emisiones en directo sólo contienen unos pocos segundos de datos y necesitan ser solicitados continuamente.", "EnableStreamLoopingHelp": "Habilite esto si las emisiones en directo sólo contienen unos pocos segundos de datos y necesitan ser solicitados continuamente.",
"EnableThemeVideos": "Vídeos temáticos", "EnableThemeVideos": "Vídeos temáticos",
"Ended": "Finalizado", "Ended": "Finalizado",
@ -226,7 +226,7 @@
"HeaderActivity": "Actividad", "HeaderActivity": "Actividad",
"HeaderAddScheduledTaskTrigger": "Agregar Activador", "HeaderAddScheduledTaskTrigger": "Agregar Activador",
"HeaderAddToCollection": "Agregar a la colección", "HeaderAddToCollection": "Agregar a la colección",
"HeaderAddToPlaylist": "Añadir a la lista", "HeaderAddToPlaylist": "Añadir a la lista de reproducción",
"HeaderAddUpdateImage": "Añadir/Actualizar imagen", "HeaderAddUpdateImage": "Añadir/Actualizar imagen",
"HeaderAddUser": "Agregar usuario", "HeaderAddUser": "Agregar usuario",
"HeaderAdditionalParts": "Partes adicionales", "HeaderAdditionalParts": "Partes adicionales",
@ -323,7 +323,7 @@
"HeaderMediaFolders": "Carpetas de medios", "HeaderMediaFolders": "Carpetas de medios",
"HeaderMediaInfo": "Información multimedia", "HeaderMediaInfo": "Información multimedia",
"HeaderMetadataSettings": "Ajustes de metadatos", "HeaderMetadataSettings": "Ajustes de metadatos",
"HeaderMoreLikeThis": "Más como éste", "HeaderMoreLikeThis": "Más como este",
"HeaderMovies": "Películas", "HeaderMovies": "Películas",
"HeaderMusicVideos": "Vídeos musicales", "HeaderMusicVideos": "Vídeos musicales",
"HeaderMyDevice": "Mi dispositivo", "HeaderMyDevice": "Mi dispositivo",
@ -332,7 +332,7 @@
"HeaderNewApiKey": "Nueva clave API", "HeaderNewApiKey": "Nueva clave API",
"HeaderNewDevices": "Nuevos dispositivos", "HeaderNewDevices": "Nuevos dispositivos",
"HeaderNextEpisodePlayingInValue": "Siguiente episodio empezará en {0}", "HeaderNextEpisodePlayingInValue": "Siguiente episodio empezará en {0}",
"HeaderNextUp": "Siguiendo", "HeaderNextUp": "Siguiente",
"HeaderNextVideoPlayingInValue": "Siguiente vídeo empezará en {0}", "HeaderNextVideoPlayingInValue": "Siguiente vídeo empezará en {0}",
"HeaderOnNow": "Transmitiendo ahora", "HeaderOnNow": "Transmitiendo ahora",
"HeaderOtherItems": "Otros elementos", "HeaderOtherItems": "Otros elementos",
@ -645,7 +645,7 @@
"LabelPersonRole": "Rol:", "LabelPersonRole": "Rol:",
"LabelPlaceOfBirth": "Lugar de nacimiento:", "LabelPlaceOfBirth": "Lugar de nacimiento:",
"LabelPlayDefaultAudioTrack": "Reproducir pista de audio predeterminado, independientemente del idioma", "LabelPlayDefaultAudioTrack": "Reproducir pista de audio predeterminado, independientemente del idioma",
"LabelPlaylist": "Lista:", "LabelPlaylist": "Lista de reproducción:",
"LabelPostProcessor": "Aplicación de post-procesamiento:", "LabelPostProcessor": "Aplicación de post-procesamiento:",
"LabelPostProcessorArguments": "Argumentos de línea de comandos posprocesador:", "LabelPostProcessorArguments": "Argumentos de línea de comandos posprocesador:",
"LabelPostProcessorArgumentsHelp": "Utilice {path} como ruta del archivo de grabación.", "LabelPostProcessorArgumentsHelp": "Utilice {path} como ruta del archivo de grabación.",
@ -1053,7 +1053,7 @@
"ReleaseDate": "Fecha de lanzamiento", "ReleaseDate": "Fecha de lanzamiento",
"RememberMe": "Recuérdame", "RememberMe": "Recuérdame",
"RemoveFromCollection": "Quitar de la colección", "RemoveFromCollection": "Quitar de la colección",
"RemoveFromPlaylist": "Quitar de la lista", "RemoveFromPlaylist": "Quitar de la lista de reproducción",
"Repeat": "Repetir", "Repeat": "Repetir",
"RepeatAll": "Repetir todo", "RepeatAll": "Repetir todo",
"RepeatEpisodes": "Repetir episodios", "RepeatEpisodes": "Repetir episodios",
@ -1419,7 +1419,7 @@
"TV": "Televisión", "TV": "Televisión",
"TabInfo": "Info", "TabInfo": "Info",
"TabLogs": "Registros", "TabLogs": "Registros",
"TabPlugins": "Plugins", "TabPlugins": "Complementos",
"TabSeries": "Series", "TabSeries": "Series",
"TabTrailers": "Tráilers", "TabTrailers": "Tráilers",
"TagsValue": "Etiquetas: {0}", "TagsValue": "Etiquetas: {0}",

View file

@ -307,7 +307,7 @@
"HeaderContainerProfile": "Profil de conteneur", "HeaderContainerProfile": "Profil de conteneur",
"HeaderContainerProfileHelp": "Les profils de conteneur indiquent les limites d'un appareil lors de la lecture de formats spécifiques. Si la limite s'applique au média, ce dernier sera transcodé, même si le format est configuré pour la lecture directe.", "HeaderContainerProfileHelp": "Les profils de conteneur indiquent les limites d'un appareil lors de la lecture de formats spécifiques. Si la limite s'applique au média, ce dernier sera transcodé, même si le format est configuré pour la lecture directe.",
"HeaderContinueListening": "Reprendre l'écoute", "HeaderContinueListening": "Reprendre l'écoute",
"HeaderContinueWatching": "Reprendre", "HeaderContinueWatching": "Continuer à regarder",
"HeaderCustomDlnaProfiles": "Profils personnalisés", "HeaderCustomDlnaProfiles": "Profils personnalisés",
"HeaderDateIssued": "Date de publication", "HeaderDateIssued": "Date de publication",
"HeaderDefaultRecordingSettings": "Paramètres d'enregistrement par défaut", "HeaderDefaultRecordingSettings": "Paramètres d'enregistrement par défaut",

View file

@ -503,5 +503,6 @@
"Shows": "番組", "Shows": "番組",
"Songs": "曲", "Songs": "曲",
"Sync": "同期", "Sync": "同期",
"ValueSpecialEpisodeName": "スペシャル - {0}" "ValueSpecialEpisodeName": "スペシャル - {0}",
"ButtonAddImage": "イメージの追加"
} }

File diff suppressed because it is too large Load diff

View file

@ -404,7 +404,7 @@
"LabelAll": "Alle", "LabelAll": "Alle",
"LabelAllowHWTranscoding": "Tillat maskinvareomkoding", "LabelAllowHWTranscoding": "Tillat maskinvareomkoding",
"LabelAllowServerAutoRestart": "Tillat at serveren restartes automatisk for å gjennomføre oppdateringer", "LabelAllowServerAutoRestart": "Tillat at serveren restartes automatisk for å gjennomføre oppdateringer",
"LabelAllowServerAutoRestartHelp": "Serveren vil kun restartes i inaktive perioder, når ingen brukere er aktive.", "LabelAllowServerAutoRestartHelp": "Serveren vil kun restartes i inaktive perioder når ingen brukere er aktive.",
"LabelAppName": "Applikasjonsnavn", "LabelAppName": "Applikasjonsnavn",
"LabelAppNameExample": "Eksempel: Sickbeard, NzbDrone", "LabelAppNameExample": "Eksempel: Sickbeard, NzbDrone",
"LabelArtists": "Artister:", "LabelArtists": "Artister:",
@ -431,7 +431,7 @@
"LabelCurrentPassword": "Nåværende passord:", "LabelCurrentPassword": "Nåværende passord:",
"LabelCustomCertificatePath": "Tilpasset ssl-sertifikatbane:", "LabelCustomCertificatePath": "Tilpasset ssl-sertifikatbane:",
"LabelCustomCss": "Tilpass CSS:", "LabelCustomCss": "Tilpass CSS:",
"LabelCustomCssHelp": "Bruk din egen CSS på web-grensesnittet.", "LabelCustomCssHelp": "Bruk ditt eget stilark på web-grensesnittet.",
"LabelCustomDeviceDisplayName": "Visningsnavn:", "LabelCustomDeviceDisplayName": "Visningsnavn:",
"LabelCustomDeviceDisplayNameHelp": "Oppgi et egendefinert visningsnavn eller la det være tomt for å bruke navnet som enheten rapporterer.", "LabelCustomDeviceDisplayNameHelp": "Oppgi et egendefinert visningsnavn eller la det være tomt for å bruke navnet som enheten rapporterer.",
"LabelCustomRating": "Egen anmeldelse:", "LabelCustomRating": "Egen anmeldelse:",
@ -483,7 +483,7 @@
"LabelFinish": "Fullfør", "LabelFinish": "Fullfør",
"LabelForgotPasswordUsernameHelp": "Skriv inn brukernavnet ditt, dersom du husker det.", "LabelForgotPasswordUsernameHelp": "Skriv inn brukernavnet ditt, dersom du husker det.",
"LabelFriendlyName": "Vennlig navn:", "LabelFriendlyName": "Vennlig navn:",
"LabelServerNameHelp": "Dette navnet vil bli brukt for å identifisere denne serveren. Hvis feltet er tomt, vil maskinens navn bli brukt.", "LabelServerNameHelp": "Dette navnet vil bli brukt for å identifisere denne serveren; standardverdien er serverens maskinnavn.",
"LabelGroupMoviesIntoCollections": "Gruppér filmer i samlinger", "LabelGroupMoviesIntoCollections": "Gruppér filmer i samlinger",
"LabelGroupMoviesIntoCollectionsHelp": "Ved visning av filmlister vil filmer som tilhører en samling bli vist som ett gruppeelement.", "LabelGroupMoviesIntoCollectionsHelp": "Ved visning av filmlister vil filmer som tilhører en samling bli vist som ett gruppeelement.",
"LabelH264Crf": "H264-koding CRF:", "LabelH264Crf": "H264-koding CRF:",
@ -1101,7 +1101,7 @@
"Default": "Standard", "Default": "Standard",
"DatePlayed": "Sist spillt", "DatePlayed": "Sist spillt",
"DateAdded": "Dato lagt til", "DateAdded": "Dato lagt til",
"CriticRating": "Anmelder-vurdering", "CriticRating": "Kritikervurdering",
"CommunityRating": "Samfunnsvurdering", "CommunityRating": "Samfunnsvurdering",
"Channels": "Kanaler", "Channels": "Kanaler",
"ButtonTrailer": "Trailer", "ButtonTrailer": "Trailer",
@ -1443,5 +1443,11 @@
"ValueOneEpisode": "1 episode", "ValueOneEpisode": "1 episode",
"ValueSeconds": "{0} sekunder", "ValueSeconds": "{0} sekunder",
"Vertical": "Vertikal", "Vertical": "Vertikal",
"Whitelist": "Hviteliste" "Whitelist": "Hviteliste",
"AuthProviderHelp": "Velg en innloggingstilbyder som skal brukes for å autentisere denne brukerens passord.",
"DropShadow": "Underskygge",
"Depressed": "Nedtrykt",
"Features": "Med",
"LabelParentNumber": "Foreldrenummer:",
"OptionResElement": "res element"
} }

View file

@ -286,5 +286,7 @@
"AllComplexFormats": "Bütün karmaşık formatlar (ASS, SSA, VOBSUB, PGS, SUB/IDX, vb.)", "AllComplexFormats": "Bütün karmaşık formatlar (ASS, SSA, VOBSUB, PGS, SUB/IDX, vb.)",
"AllEpisodes": "Bütün bölümler", "AllEpisodes": "Bütün bölümler",
"AllLanguages": "Bütün diller", "AllLanguages": "Bütün diller",
"AllowMediaConversion": "Medya dönüşümüne izin ver" "AllowMediaConversion": "Medya dönüşümüne izin ver",
"AddItemToCollectionHelp": "Ögeleri koleksiyona eklemek için arama yapın ve üzerine sağ tıklayın veya sekme menüsünden koleksiyona ekleyin.",
"AllowHWTranscodingHelp": "Ayarlayıcının anında akışları dönüştürmesine izin verin. Bu, sunucunun gerektirdiği kodlamanın azaltılmasına yardımcı olabilir."
} }

View file

@ -206,7 +206,7 @@
"Ended": "结束", "Ended": "结束",
"EndsAtValue": "结束于 {0}", "EndsAtValue": "结束于 {0}",
"Episodes": "剧集", "Episodes": "剧集",
"ErrorAddingListingsToSchedulesDirect": "将阵容添加到您的计划直接帐户时出错。计划直接只允许每帐户数量有限的阵容。您可能需要登录到时间表直接网站和删除其他清单, 从您的帐户 proceeeding 之前。", "ErrorAddingListingsToSchedulesDirect": "我们将阵容添加到您的Schedules Direct帐户时出错。 Schedules Direct只允许有限的账号排序。 您可能需要在继续前直接登入Schedules Direct 网站并删除其他列表。",
"ErrorAddingMediaPathToVirtualFolder": "添加媒体路径时发生错误。请确认路径是有效的,并且你的 Jellyfin 服务器进程有对该位置的访问权。", "ErrorAddingMediaPathToVirtualFolder": "添加媒体路径时发生错误。请确认路径是有效的,并且你的 Jellyfin 服务器进程有对该位置的访问权。",
"ErrorAddingTunerDevice": "添加协调器设备时发生错误。请确认它是可访问的然后再试一次。", "ErrorAddingTunerDevice": "添加协调器设备时发生错误。请确认它是可访问的然后再试一次。",
"ErrorAddingXmlTvFile": "访问 XmlTV 文件时发生错误。请确认该文件是否存在然后再试一次。", "ErrorAddingXmlTvFile": "访问 XmlTV 文件时发生错误。请确认该文件是否存在然后再试一次。",
@ -493,7 +493,7 @@
"LabelBirthDate": "出生日期:", "LabelBirthDate": "出生日期:",
"LabelBirthYear": "出生年份:", "LabelBirthYear": "出生年份:",
"LabelBlastMessageInterval": "活动信号的时间间隔(秒)", "LabelBlastMessageInterval": "活动信号的时间间隔(秒)",
"LabelBlastMessageIntervalHelp": "确定由服务器活动信号的间隔秒数。", "LabelBlastMessageIntervalHelp": "确定爆炸活动消息之间的持续时间(以秒为单位)。",
"LabelBlockContentWithTags": "通过标签锁定内容:", "LabelBlockContentWithTags": "通过标签锁定内容:",
"LabelBurnSubtitles": "烧录字幕:", "LabelBurnSubtitles": "烧录字幕:",
"LabelCache": "缓存:", "LabelCache": "缓存:",
@ -554,9 +554,9 @@
"LabelEnableDlnaDebugLogging": "启用 DLNA 调试日志", "LabelEnableDlnaDebugLogging": "启用 DLNA 调试日志",
"LabelEnableDlnaDebugLoggingHelp": "创建一个很大的日志文件,仅应在排除故障时使用。", "LabelEnableDlnaDebugLoggingHelp": "创建一个很大的日志文件,仅应在排除故障时使用。",
"LabelEnableDlnaPlayTo": "启用 DLNA 播放", "LabelEnableDlnaPlayTo": "启用 DLNA 播放",
"LabelEnableDlnaPlayToHelp": "Jellyfin 可以侦测你网络里的设备并远程控制它们。", "LabelEnableDlnaPlayToHelp": "侦测你网络里的设备并远程控制它们。",
"LabelEnableDlnaServer": "启用 DLNA 服务器", "LabelEnableDlnaServer": "启用 DLNA 服务器",
"LabelEnableDlnaServerHelp": "允许你网络上的 UPnP 设备浏览并播放 Jellyfin 内容。", "LabelEnableDlnaServerHelp": "允许你网络上的 UPnP 设备浏览并播放内容。",
"LabelEnableHardwareDecodingFor": "启用硬件解码:", "LabelEnableHardwareDecodingFor": "启用硬件解码:",
"LabelEnableRealtimeMonitor": "启用实时监控", "LabelEnableRealtimeMonitor": "启用实时监控",
"LabelEnableRealtimeMonitorHelp": "文件更改将立即在支持的文件系统上处理。", "LabelEnableRealtimeMonitorHelp": "文件更改将立即在支持的文件系统上处理。",
@ -567,7 +567,7 @@
"LabelEvent": "事件:", "LabelEvent": "事件:",
"LabelEveryXMinutes": "每:", "LabelEveryXMinutes": "每:",
"LabelExtractChaptersDuringLibraryScan": "媒体库扫描过程中解压章节图像", "LabelExtractChaptersDuringLibraryScan": "媒体库扫描过程中解压章节图像",
"LabelExtractChaptersDuringLibraryScanHelp": "如果启用,当媒体库导入视频并扫描时,将提取章节图像。如果禁用,章节图像将在之后的计划任务提取,而媒体库会更快完成扫描。", "LabelExtractChaptersDuringLibraryScanHelp": "当媒体库导入视频并扫描时,将提取章节图像。否则,章节图像将在之后的计划任务提取,而媒体库会更快完成扫描。",
"LabelFailed": "失败", "LabelFailed": "失败",
"LabelFileOrUrl": "文件或网址:", "LabelFileOrUrl": "文件或网址:",
"LabelFinish": "完成", "LabelFinish": "完成",
@ -581,7 +581,7 @@
"LabelH264Crf": "H264 CRF 编码质量等级:", "LabelH264Crf": "H264 CRF 编码质量等级:",
"LabelH264EncodingPreset": "H264 编码预设:", "LabelH264EncodingPreset": "H264 编码预设:",
"LabelHardwareAccelerationType": "硬件加速:", "LabelHardwareAccelerationType": "硬件加速:",
"LabelHardwareAccelerationTypeHelp": "只能在支持的系统上使用。", "LabelHardwareAccelerationTypeHelp": "此特性只能在支持的系统上使用。",
"LabelHomeNetworkQuality": "家庭网络质量:", "LabelHomeNetworkQuality": "家庭网络质量:",
"LabelHomeScreenSectionValue": "主屏幕模块{0}:", "LabelHomeScreenSectionValue": "主屏幕模块{0}:",
"LabelHttpsPort": "本地 HTTPS 端口号:", "LabelHttpsPort": "本地 HTTPS 端口号:",
@ -599,15 +599,15 @@
"LabelInternetQuality": "网络质量:", "LabelInternetQuality": "网络质量:",
"LabelKidsCategories": "儿童分类:", "LabelKidsCategories": "儿童分类:",
"LabelKodiMetadataDateFormat": "发行日期格式:", "LabelKodiMetadataDateFormat": "发行日期格式:",
"LabelKodiMetadataDateFormatHelp": "Nfo的所有日期将使用这种格式被读取和写入。", "LabelKodiMetadataDateFormatHelp": "Nfo的所有日期将使用这种格式。",
"LabelKodiMetadataEnableExtraThumbs": "复制同人画到extrathumbs文件夹", "LabelKodiMetadataEnableExtraThumbs": "复制同人画到extrathumbs文件夹",
"LabelKodiMetadataEnableExtraThumbsHelp": "为了最大化兼容Kodi皮肤下载的图片同时保存在 extrafanart 和 extrathumbs 文件夹。", "LabelKodiMetadataEnableExtraThumbsHelp": "为了最大化兼容Kodi皮肤下载的图片同时保存在 extrafanart 和 extrathumbs 文件夹。",
"LabelKodiMetadataEnablePathSubstitution": "启用路径替换", "LabelKodiMetadataEnablePathSubstitution": "启用路径替换",
"LabelKodiMetadataEnablePathSubstitutionHelp": "允许图像的路径替换使用服务器的路径替换设置。", "LabelKodiMetadataEnablePathSubstitutionHelp": "允许图像的路径替换使用服务器的路径替换设置。",
"LabelKodiMetadataSaveImagePaths": "保存图像路径在NFO文件", "LabelKodiMetadataSaveImagePaths": "保存图像路径在NFO文件",
"LabelKodiMetadataSaveImagePathsHelp": "如果你的图像文件名不符合Kodi的规范推荐使用。", "LabelKodiMetadataSaveImagePathsHelp": "如果你的图像文件名不符合Kodi的规范推荐使用。",
"LabelKodiMetadataUser": "为以下用户保存观看历史数据", "LabelKodiMetadataUser": "为以下用户保存观看历史数据到NFO文件中",
"LabelKodiMetadataUserHelp": "启用此项以保存观看历史数据至 Nfo 文件中以供其他应用程序利用。", "LabelKodiMetadataUserHelp": "保存观看历史数据至 NFO 文件中以供其他应用程序利用。",
"LabelLanNetworks": "LAN网络", "LabelLanNetworks": "LAN网络",
"LabelLanguage": "语言:", "LabelLanguage": "语言:",
"LabelLineup": "排队:", "LabelLineup": "排队:",
@ -615,7 +615,7 @@
"LabelLocalHttpServerPortNumberHelp": "Jellyfin HTTP 服务器监听的 TCP 端口。", "LabelLocalHttpServerPortNumberHelp": "Jellyfin HTTP 服务器监听的 TCP 端口。",
"LabelLockItemToPreventChanges": "锁定此项目防止改动", "LabelLockItemToPreventChanges": "锁定此项目防止改动",
"LabelLoginDisclaimer": "登录声明:", "LabelLoginDisclaimer": "登录声明:",
"LabelLoginDisclaimerHelp": "将在登录页面底部显示。", "LabelLoginDisclaimerHelp": "将在登录页面底部显示的信息。",
"LabelLogs": "日志:", "LabelLogs": "日志:",
"LabelManufacturer": "制造商", "LabelManufacturer": "制造商",
"LabelManufacturerUrl": "厂商网址", "LabelManufacturerUrl": "厂商网址",
@ -624,9 +624,9 @@
"LabelMaxChromecastBitrate": "最大 Chromecast 比特率:", "LabelMaxChromecastBitrate": "最大 Chromecast 比特率:",
"LabelMaxParentalRating": "最大允许的家长评级:", "LabelMaxParentalRating": "最大允许的家长评级:",
"LabelMaxResumePercentage": "恢复播放最大百分比:", "LabelMaxResumePercentage": "恢复播放最大百分比:",
"LabelMaxResumePercentageHelp": "如果在此时间之后停止播放,媒体会标记为“已播放”", "LabelMaxResumePercentageHelp": "如果在此时间之后停止播放,媒体会标记为“已播放”",
"LabelMaxScreenshotsPerItem": "每个项目最大截图数目:", "LabelMaxScreenshotsPerItem": "每个项目最大截图数目:",
"LabelMaxStreamingBitrate": "最大串流质量", "LabelMaxStreamingBitrate": "最大串流质量:",
"LabelMaxStreamingBitrateHelp": "请指定一个流媒体串流时的最大比特率。", "LabelMaxStreamingBitrateHelp": "请指定一个流媒体串流时的最大比特率。",
"LabelMessageText": "消息文本:", "LabelMessageText": "消息文本:",
"LabelMessageTitle": "消息标题:", "LabelMessageTitle": "消息标题:",
@ -634,17 +634,17 @@
"LabelMetadataDownloadLanguage": "首选下载语言:", "LabelMetadataDownloadLanguage": "首选下载语言:",
"LabelMetadataDownloadersHelp": "启用媒体资料下载器的优先级排序,低优先级的下载器只会用来填补缺少的信息。", "LabelMetadataDownloadersHelp": "启用媒体资料下载器的优先级排序,低优先级的下载器只会用来填补缺少的信息。",
"LabelMetadataPath": "媒体资料路径:", "LabelMetadataPath": "媒体资料路径:",
"LabelMetadataPathHelp": "为下载的图像和元数据指定自定义路径", "LabelMetadataPathHelp": "为下载的图像和元数据指定自定义路径",
"LabelMetadataReaders": "媒体资料读取器:", "LabelMetadataReaders": "媒体资料读取器:",
"LabelMetadataReadersHelp": "为你首选的本地媒体资料源按优先级排序。找到的第一个文件将被读取。", "LabelMetadataReadersHelp": "为你首选的本地媒体资料源按优先级排序。找到的第一个文件将被读取。",
"LabelMetadataSavers": "媒体资料储存方式:", "LabelMetadataSavers": "媒体资料储存方式:",
"LabelMetadataSaversHelp": "选择储存媒体资料的文件格式。", "LabelMetadataSaversHelp": "选择储存媒体资料的文件格式。",
"LabelMethod": "方法:", "LabelMethod": "方法:",
"LabelMinBackdropDownloadWidth": "下载背景图的最小宽度:", "LabelMinBackdropDownloadWidth": "下载背景图的最小宽度:",
"LabelMinResumeDuration": "恢复播放最小时间(秒)", "LabelMinResumeDuration": "恢复播放最小时间",
"LabelMinResumeDurationHelp": "媒体播放时间过短,不可恢复播放", "LabelMinResumeDurationHelp": "以秒为单位保存播放视频位置并允许您继续播放。",
"LabelMinResumePercentage": "恢复播放最小百分比:", "LabelMinResumePercentage": "恢复播放最小百分比:",
"LabelMinResumePercentageHelp": "如果在此时间之前停止播放,媒体会标记为“未播放”", "LabelMinResumePercentageHelp": "如果在此时间之前停止播放,媒体会标记为“未播放”",
"LabelMinScreenshotDownloadWidth": "下载截图的最小宽度:", "LabelMinScreenshotDownloadWidth": "下载截图的最小宽度:",
"LabelModelDescription": "型号描述", "LabelModelDescription": "型号描述",
"LabelModelName": "型号名称", "LabelModelName": "型号名称",
@ -653,7 +653,7 @@
"LabelMonitorUsers": "监控活动:", "LabelMonitorUsers": "监控活动:",
"LabelMovieCategories": "电影分类:", "LabelMovieCategories": "电影分类:",
"LabelMoviePrefix": "电影前缀:", "LabelMoviePrefix": "电影前缀:",
"LabelMoviePrefixHelp": "如果将前缀应用于影片标题, 请在此处输入它, 以便 Jellyfin 可以正确处理它。", "LabelMoviePrefixHelp": "如果将前缀应用于影片标题, 请在此处输入它, 以便服务器可以正确处理它。",
"LabelMovieRecordingPath": "电影录制路径 (可选的)", "LabelMovieRecordingPath": "电影录制路径 (可选的)",
"LabelMusicStreamingTranscodingBitrate": "音乐转码的比特率:", "LabelMusicStreamingTranscodingBitrate": "音乐转码的比特率:",
"LabelMusicStreamingTranscodingBitrateHelp": "请指定一个音乐媒体串流时的最大比特率", "LabelMusicStreamingTranscodingBitrateHelp": "请指定一个音乐媒体串流时的最大比特率",
@ -1109,7 +1109,7 @@
"RecordSeries": "录制电视剧", "RecordSeries": "录制电视剧",
"RecordingCancelled": "录制已取消。", "RecordingCancelled": "录制已取消。",
"RecordingPathChangeMessage": "更改录制文件夹不会将现有录制从旧位置迁移到新的。您需要手动移动它们 (如果需要)。", "RecordingPathChangeMessage": "更改录制文件夹不会将现有录制从旧位置迁移到新的。您需要手动移动它们 (如果需要)。",
"RecordingScheduled": "录制预设", "RecordingScheduled": "录制预设",
"Refresh": "刷新", "Refresh": "刷新",
"RefreshMetadata": "刷新元数据", "RefreshMetadata": "刷新元数据",
"RefreshQueued": "列队已刷新。", "RefreshQueued": "列队已刷新。",
@ -1297,7 +1297,7 @@
"XmlTvSportsCategoriesHelp": "这些类别的节目将显示为体育节目。用 \"|\" 分隔多个。", "XmlTvSportsCategoriesHelp": "这些类别的节目将显示为体育节目。用 \"|\" 分隔多个。",
"Yes": "是", "Yes": "是",
"Yesterday": "昨天", "Yesterday": "昨天",
"Absolute": "绝对路径", "Absolute": "绝对",
"AnyLanguage": "任何语言", "AnyLanguage": "任何语言",
"Art": "图像", "Art": "图像",
"AspectRatio": "长宽比", "AspectRatio": "长宽比",
@ -1337,7 +1337,7 @@
"GroupBySeries": "按系列分组", "GroupBySeries": "按系列分组",
"HeaderApp": "应用程序", "HeaderApp": "应用程序",
"DirectStreamHelp1": "该媒体文件的分辨率和编码H.264、AC3 等)与您的设备兼容,但容器格式(.mkv、.avi、.wmv 等)不受支持。因此,视频在串流至您的设备之前将会被即时封装为另一种格式。", "DirectStreamHelp1": "该媒体文件的分辨率和编码H.264、AC3 等)与您的设备兼容,但容器格式(.mkv、.avi、.wmv 等)不受支持。因此,视频在串流至您的设备之前将会被即时封装为另一种格式。",
"HeaderAppearsOn": "出现于", "HeaderAppearsOn": "同时出现于",
"HeaderCancelSeries": "取消系列", "HeaderCancelSeries": "取消系列",
"HeaderFavoriteEpisodes": "最爱的剧集", "HeaderFavoriteEpisodes": "最爱的剧集",
"HeaderFavoriteArtists": "最爱的艺术家", "HeaderFavoriteArtists": "最爱的艺术家",
@ -1348,11 +1348,11 @@
"HeaderNextVideoPlayingInValue": "下一部影片在 {0} 后播放", "HeaderNextVideoPlayingInValue": "下一部影片在 {0} 后播放",
"HeaderPlayOn": "播放在", "HeaderPlayOn": "播放在",
"HeaderRestartingServer": "服务器重启中", "HeaderRestartingServer": "服务器重启中",
"HeaderSeriesStatus": "剧集状态", "HeaderSeriesStatus": "系列状态",
"HeaderStopRecording": "停止录制", "HeaderStopRecording": "停止录制",
"Horizontal": "横向", "Horizontal": "横向",
"LabelAuthProvider": "认证提供者:", "LabelAuthProvider": "认证提供者:",
"LabelKeepUpTo": "跟上", "LabelKeepUpTo": "保持",
"LabelPasswordResetProvider": "密码重置提供者:", "LabelPasswordResetProvider": "密码重置提供者:",
"LabelPersonRoleHelp": "示例:冰淇淋卡车司机", "LabelPersonRoleHelp": "示例:冰淇淋卡车司机",
"LabelSelectFolderGroups": "自动将下列文件夹中的内容分组到视图中,如电影、音乐、剧集:", "LabelSelectFolderGroups": "自动将下列文件夹中的内容分组到视图中,如电影、音乐、剧集:",
@ -1450,5 +1450,10 @@
"FetchingData": "提取其他数据", "FetchingData": "提取其他数据",
"CopyStreamURLSuccess": "已成功复制URL地址。", "CopyStreamURLSuccess": "已成功复制URL地址。",
"CopyStreamURL": "复制串流URL地址", "CopyStreamURL": "复制串流URL地址",
"ButtonAddImage": "添加图片" "ButtonAddImage": "添加图片",
"LabelPlayer": "播放器:",
"LabelBaseUrl": "基础 URL:",
"LabelBaseUrlHelp": "您可以在此处添加自定义子目录,以便从更唯一的 URL 访问服务器。",
"MoreMediaInfo": "媒体信息",
"MusicLibraryHelp": "重播 {0}音乐命名指南{1}。"
} }

1174
yarn.lock

File diff suppressed because it is too large Load diff