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

Merge remote-tracking branch 'upstream/master' into scrollbar-placeholder

This commit is contained in:
ferferga 2020-05-17 00:18:14 +02:00
commit 8cbec3fe22
36 changed files with 843 additions and 662 deletions

3
.gitignore vendored
View file

@ -9,3 +9,6 @@ node_modules
# ide
.idea
.vscode
#log
yarn-error.log

View file

@ -102,6 +102,10 @@
"src/scripts/filesystem.js",
"src/scripts/imagehelper.js",
"src/scripts/inputManager.js",
"src/components/deletehelper.js",
"src/components/actionsheet/actionsheet.js",
"src/components/playmenu.js",
"src/components/indicators/indicators.js",
"src/scripts/keyboardnavigation.js",
"src/scripts/settings/appSettings.js",
"src/scripts/settings/userSettings.js",

View file

@ -1,21 +1,23 @@
define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-button', 'css!./actionsheet', 'material-icons', 'scrollStyles', 'listViewStyle'], function (dialogHelper, layoutManager, globalize, browser, dom) {
'use strict';
import dialogHelper from 'dialogHelper';
import layoutManager from 'layoutManager';
import globalize from 'globalize';
import dom from 'dom';
import 'emby-button';
import 'css!./actionsheet';
import 'material-icons';
import 'scrollStyles';
import 'listViewStyle';
function getOffsets(elems) {
var doc = document;
var results = [];
let results = [];
if (!doc) {
if (!document) {
return results;
}
var box;
var elem;
for (var i = 0, length = elems.length; i < length; i++) {
elem = elems[i];
let box;
for (let elem of elems) {
// Support: BlackBerry 5, iOS 3 (original iPhone)
// If we don't have gBCR, just use 0,0 rather than error
if (elem.getBoundingClientRect) {
@ -24,12 +26,12 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
box = { top: 0, left: 0 };
}
results[i] = {
results.push({
top: box.top,
left: box.left,
width: box.width,
height: box.height
};
});
}
return results;
@ -37,11 +39,11 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
function getPosition(options, dlg) {
var windowSize = dom.getWindowSize();
var windowHeight = windowSize.innerHeight;
var windowWidth = windowSize.innerWidth;
const windowSize = dom.getWindowSize();
const windowHeight = windowSize.innerHeight;
const windowWidth = windowSize.innerWidth;
var pos = getOffsets([options.positionTo])[0];
let pos = getOffsets([options.positionTo])[0];
if (options.positionY !== 'top') {
pos.top += (pos.height || 0) / 2;
@ -49,16 +51,16 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
pos.left += (pos.width || 0) / 2;
var height = dlg.offsetHeight || 300;
var width = dlg.offsetWidth || 160;
const height = dlg.offsetHeight || 300;
const width = dlg.offsetWidth || 160;
// Account for popup size
pos.top -= height / 2;
pos.left -= width / 2;
// Avoid showing too close to the bottom
var overflowX = pos.left + width - windowWidth;
var overflowY = pos.top + height - windowHeight;
const overflowX = pos.left + width - windowWidth;
const overflowY = pos.top + height - windowHeight;
if (overflowX > 0) {
pos.left -= (overflowX + 20);
@ -79,30 +81,28 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
function centerFocus(elem, horiz, on) {
require(['scrollHelper'], function (scrollHelper) {
var fn = on ? 'on' : 'off';
const fn = on ? 'on' : 'off';
scrollHelper.centerFocus[fn](elem, horiz);
});
}
function show(options) {
export function show(options) {
// items
// positionTo
// showCancel
// title
var dialogOptions = {
let dialogOptions = {
removeOnClose: true,
enableHistory: options.enableHistory,
scrollY: false
};
var backButton = false;
var isFullscreen;
let isFullscreen;
if (layoutManager.tv) {
dialogOptions.size = 'fullscreen';
isFullscreen = true;
backButton = true;
dialogOptions.autoFocus = true;
} else {
@ -114,7 +114,7 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
dialogOptions.autoFocus = false;
}
var dlg = dialogHelper.createDialog(dialogOptions);
let dlg = dialogHelper.createDialog(dialogOptions);
if (isFullscreen) {
dlg.classList.add('actionsheet-fullscreen');
@ -128,28 +128,23 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
dlg.classList.add(options.dialogClass);
}
var html = '';
let html = '';
var scrollClassName = layoutManager.tv ? 'scrollY smoothScrollY hiddenScrollY' : 'scrollY';
var style = '';
const scrollClassName = layoutManager.tv ? 'scrollY smoothScrollY hiddenScrollY' : 'scrollY';
let style = '';
// Admittedly a hack but right now the scrollbar is being factored into the width which is causing truncation
if (options.items.length > 20) {
var minWidth = dom.getWindowSize().innerWidth >= 300 ? 240 : 200;
const minWidth = dom.getWindowSize().innerWidth >= 300 ? 240 : 200;
style += 'min-width:' + minWidth + 'px;';
}
var i;
var length;
var option;
var renderIcon = false;
var icons = [];
var itemIcon;
for (i = 0, length = options.items.length; i < length; i++) {
let renderIcon = false;
let icons = [];
let itemIcon;
for (let item of options.items) {
option = options.items[i];
itemIcon = option.icon || (option.selected ? 'check' : null);
itemIcon = item.icon || (item.selected ? 'check' : null);
if (itemIcon) {
renderIcon = true;
@ -162,7 +157,7 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
}
// If any items have an icon, give them all an icon just to make sure they're all lined up evenly
var center = options.title && (!renderIcon /*|| itemsWithIcons.length != options.items.length*/);
const center = options.title && (!renderIcon /*|| itemsWithIcons.length != options.items.length*/);
if (center || layoutManager.tv) {
html += '<div class="actionSheetContent actionSheetContent-centered">';
@ -172,23 +167,19 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
if (options.title) {
html += '<h1 class="actionSheetTitle">';
html += options.title;
html += '</h1>';
html += '<h1 class="actionSheetTitle">' + options.title + '</h1>';
}
if (options.text) {
html += '<p class="actionSheetText">';
html += options.text;
html += '</p>';
html += '<p class="actionSheetText">' + options.text + '</p>';
}
var scrollerClassName = 'actionSheetScroller';
let scrollerClassName = 'actionSheetScroller';
if (layoutManager.tv) {
scrollerClassName += ' actionSheetScroller-tv focuscontainer-x focuscontainer-y';
}
html += '<div class="' + scrollerClassName + ' ' + scrollClassName + '" style="' + style + '">';
var menuItemClass = 'listItem listItem-button actionSheetMenuItem';
let menuItemClass = 'listItem listItem-button actionSheetMenuItem';
if (options.border || options.shaded) {
menuItemClass += ' listItem-border';
@ -206,26 +197,23 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
menuItemClass += ' actionsheet-xlargeFont';
}
for (i = 0, length = options.items.length; i < length; i++) {
for (let [i, item] of options.items.entries()) {
option = options.items[i];
if (option.divider) {
if (item.divider) {
html += '<div class="actionsheetDivider"></div>';
continue;
}
var autoFocus = option.selected && layoutManager.tv ? ' autoFocus' : '';
const autoFocus = item.selected && layoutManager.tv ? ' autoFocus' : '';
// Check for null in case int 0 was passed in
var optionId = option.id == null || option.id === '' ? option.value : option.id;
const optionId = item.id == null || item.id === '' ? item.value : item.id;
html += '<button' + autoFocus + ' is="emby-button" type="button" class="' + menuItemClass + '" data-id="' + optionId + '">';
itemIcon = icons[i];
if (itemIcon) {
html += '<span class="actionsheetMenuItemIcon listItemIcon listItemIcon-transparent material-icons ' + itemIcon + '"></span>';
} else if (renderIcon && !center) {
html += '<span class="actionsheetMenuItemIcon listItemIcon listItemIcon-transparent material-icons check" style="visibility:hidden;"></span>';
@ -234,21 +222,17 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
html += '<div class="listItemBody actionsheetListItemBody">';
html += '<div class="listItemBodyText actionSheetItemText">';
html += (option.name || option.textContent || option.innerText);
html += (item.name || item.textContent || item.innerText);
html += '</div>';
if (option.secondaryText) {
html += '<div class="listItemBodyText secondary">';
html += option.secondaryText;
html += '</div>';
if (item.secondaryText) {
html += '<div class="listItemBodyText secondary">' + item.secondaryText + '</div>';
}
html += '</div>';
if (option.asideText) {
html += '<div class="listItemAside actionSheetItemAsideText">';
html += option.asideText;
html += '</div>';
if (item.asideText) {
html += '<div class="listItemAside actionSheetItemAsideText">' + item.asideText + '</div>';
}
html += '</button>';
@ -267,18 +251,18 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
centerFocus(dlg.querySelector('.actionSheetScroller'), false, true);
}
var btnCloseActionSheet = dlg.querySelector('.btnCloseActionSheet');
let btnCloseActionSheet = dlg.querySelector('.btnCloseActionSheet');
if (btnCloseActionSheet) {
dlg.querySelector('.btnCloseActionSheet').addEventListener('click', function () {
btnCloseActionSheet.addEventListener('click', function () {
dialogHelper.close(dlg);
});
}
// Seeing an issue in some non-chrome browsers where this is requiring a double click
//var eventName = browser.firefox ? 'mousedown' : 'click';
var selectedId;
let selectedId;
var timeout;
let timeout;
if (options.timeout) {
timeout = setTimeout(function () {
dialogHelper.close(dlg);
@ -287,11 +271,11 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
return new Promise(function (resolve, reject) {
var isResolved;
let isResolved;
dlg.addEventListener('click', function (e) {
var actionSheetMenuItem = dom.parentWithClass(e.target, 'actionSheetMenuItem');
const actionSheetMenuItem = dom.parentWithClass(e.target, 'actionSheetMenuItem');
if (actionSheetMenuItem) {
selectedId = actionSheetMenuItem.getAttribute('data-id');
@ -343,7 +327,7 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
dialogHelper.open(dlg);
var pos = options.positionTo && dialogOptions.size !== 'fullscreen' ? getPosition(options, dlg) : null;
const pos = options.positionTo && dialogOptions.size !== 'fullscreen' ? getPosition(options, dlg) : null;
if (pos) {
dlg.style.position = 'fixed';
@ -354,7 +338,6 @@ define(['dialogHelper', 'layoutManager', 'globalize', 'browser', 'dom', 'emby-bu
});
}
return {
export default {
show: show
};
});

View file

@ -359,7 +359,6 @@ define(['appSettings', 'browser', 'events', 'htmlMediaHelper', 'webSettings', 'g
return -1 !== supportedFeatures.indexOf(command.toLowerCase());
},
preferVisualCards: browser.android || browser.chrome,
moreIcon: browser.android ? 'more_vert' : 'more_horiz',
getSyncProfile: getSyncProfile,
getDefaultLayout: function () {
if (window.NativeShell) {

View file

@ -869,7 +869,7 @@ import 'programStyles';
if (isOuterFooter && options.cardLayout && layoutManager.mobile) {
if (options.cardFooterAside !== 'none') {
html += '<button is="paper-icon-button-light" class="itemAction btnCardOptions cardText-secondary" data-action="menu"><span class="material-icons more_horiz"></span></button>';
html += '<button is="paper-icon-button-light" class="itemAction btnCardOptions cardText-secondary" data-action="menu"><span class="material-icons more_vert"></span></button>';
}
}
@ -1426,7 +1426,7 @@ import 'programStyles';
}
if (options.overlayMoreButton) {
overlayButtons += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="menu"><span class="material-icons cardOverlayButtonIcon more_horiz"></span></button>';
overlayButtons += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="menu"><span class="material-icons cardOverlayButtonIcon more_vert"></span></button>';
}
}
@ -1580,7 +1580,7 @@ import 'programStyles';
html += '<button is="emby-ratingbutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-likes="' + likes + '" data-isfavorite="' + (userData.IsFavorite) + '"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover favorite"></span></button>';
}
html += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="menu"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover more_horiz"></span></button>';
html += '<button is="paper-icon-button-light" class="' + btnCssClass + '" data-action="menu"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover more_vert"></span></button>';
html += '</div>';
html += '</div>';

View file

@ -1,5 +1,7 @@
define(['connectionManager', 'confirm', 'appRouter', 'globalize'], function (connectionManager, confirm, appRouter, globalize) {
'use strict';
import connectionManager from 'connectionManager';
import confirm from 'confirm';
import appRouter from 'appRouter';
import globalize from 'globalize';
function alertText(options) {
@ -11,38 +13,34 @@ define(['connectionManager', 'confirm', 'appRouter', 'globalize'], function (con
});
}
function deleteItem(options) {
export function deleteItem(options) {
var item = options.item;
var itemId = item.Id;
var parentId = item.SeasonId || item.SeriesId || item.ParentId;
var serverId = item.ServerId;
const item = options.item;
const parentId = item.SeasonId || item.SeriesId || item.ParentId;
var msg = globalize.translate('ConfirmDeleteItem');
var title = globalize.translate('HeaderDeleteItem');
var apiClient = connectionManager.getApiClient(item.ServerId);
let apiClient = connectionManager.getApiClient(item.ServerId);
return confirm({
title: title,
text: msg,
title: globalize.translate('HeaderDeleteItem'),
text: globalize.translate('ConfirmDeleteItem'),
confirmText: globalize.translate('Delete'),
primary: 'delete'
}).then(function () {
return apiClient.deleteItem(itemId).then(function () {
return apiClient.deleteItem(item.Id).then(function () {
if (options.navigate) {
if (parentId) {
appRouter.showItem(parentId, serverId);
appRouter.showItem(parentId, item.ServerId);
} else {
appRouter.goHome();
}
}
}, function (err) {
var result = function () {
let result = function () {
return Promise.reject(err);
};
@ -51,7 +49,6 @@ define(['connectionManager', 'confirm', 'appRouter', 'globalize'], function (con
});
}
return {
export default {
deleteItem: deleteItem
};
});

View file

@ -10,7 +10,7 @@
<div class="guide-headerTimeslots">
<div class="guide-channelTimeslotHeader">
<button is="paper-icon-button-light" type="button" class="btnGuideViewSettings" title="${ButtonMore}">
<span class="material-icons btnGuideViewSettingsIcon more_horiz" aria-hidden="true"></span>
<span class="material-icons btnGuideViewSettingsIcon more_vert" aria-hidden="true"></span>
</button>
</div>
<div class="timeslotHeaders scrollX guideScroller"></div>

View file

@ -136,7 +136,10 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
requireHlsPlayer(function () {
var hls = new Hls({
manifestLoadingTimeOut: 20000
manifestLoadingTimeOut: 20000,
xhrSetup: function(xhr, url) {
xhr.withCredentials = true;
}
//appendErrorMaxRetry: 6,
//debug: true
});
@ -155,6 +158,9 @@ define(['events', 'browser', 'require', 'apphost', 'appSettings', 'htmlMediaHelp
elem.autoplay = true;
// Safari will not send cookies without this
elem.crossOrigin = 'use-credentials';
return htmlMediaHelper.applySrc(elem, val, options).then(function () {
self._currentSrc = val;

View file

@ -338,7 +338,10 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
requireHlsPlayer(function () {
var hls = new Hls({
manifestLoadingTimeOut: 20000
manifestLoadingTimeOut: 20000,
xhrSetup: function(xhr, xhr_url) {
xhr.withCredentials = true;
}
//appendErrorMaxRetry: 6,
//debug: true
});
@ -559,6 +562,9 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
elem.autoplay = true;
// Safari will not send cookies without this
elem.crossOrigin = 'use-credentials';
return htmlMediaHelper.applySrc(elem, val, options).then(function () {
self._currentSrc = val;

View file

@ -1,12 +1,13 @@
define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'material-icons'], function (datetime, itemHelper) {
'use strict';
import datetime from 'datetime';
import itemHelper from 'itemHelper';
import 'emby-progressbar';
import 'css!./indicators.css';
import 'material-icons';
function enableProgressIndicator(item) {
if (item.MediaType === 'Video') {
if (item.Type !== 'TvChannel') {
export function enableProgressIndicator(item) {
if (item.MediaType === 'Video' && item.Type !== 'TvChannel') {
return true;
}
}
if (item.Type === 'AudioBook' || item.Type === 'AudioPodcast') {
return true;
@ -15,26 +16,22 @@ define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'm
return false;
}
function getProgressHtml(pct, options) {
var containerClass = 'itemProgressBar';
if (options) {
if (options.containerClass) {
export function getProgressHtml(pct, options) {
let containerClass = 'itemProgressBar';
if (options && options.containerClass) {
containerClass += ' ' + options.containerClass;
}
}
return '<div class="' + containerClass + '"><div class="itemProgressBarForeground" style="width:' + pct + '%;"></div></div>';
}
function getAutoTimeProgressHtml(pct, options, isRecording, start, end) {
var containerClass = 'itemProgressBar';
if (options) {
if (options.containerClass) {
let containerClass = 'itemProgressBar';
if (options && options.containerClass) {
containerClass += ' ' + options.containerClass;
}
}
var foregroundClass = 'itemProgressBarForeground';
let foregroundClass = 'itemProgressBarForeground';
if (isRecording) {
foregroundClass += ' itemProgressBarForeground-recording';
}
@ -42,10 +39,11 @@ define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'm
return '<div is="emby-progressbar" data-automode="time" data-starttime="' + start + '" data-endtime="' + end + '" class="' + containerClass + '"><div class="' + foregroundClass + '" style="width:' + pct + '%;"></div></div>';
}
function getProgressBarHtml(item, options) {
var pct;
export function getProgressBarHtml(item, options) {
let pct;
if (enableProgressIndicator(item) && item.Type !== 'Recording') {
var userData = options ? (options.userData || item.UserData) : item.UserData;
const userData = options && options.userData ? options.userData : item.UserData;
if (userData) {
pct = userData.PlayedPercentage;
if (pct && pct < 100) {
@ -55,8 +53,8 @@ define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'm
}
if ((item.Type === 'Program' || item.Type === 'Timer' || item.Type === 'Recording') && item.StartDate && item.EndDate) {
var startDate = 0;
var endDate = 1;
let startDate = 0;
let endDate = 1;
try {
startDate = datetime.parseISO8601Date(item.StartDate).getTime();
@ -65,12 +63,12 @@ define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'm
console.error(err);
}
var now = new Date().getTime();
var total = endDate - startDate;
const now = new Date().getTime();
const total = endDate - startDate;
pct = 100 * ((now - startDate) / total);
if (pct > 0 && pct < 100) {
var isRecording = item.Type === 'Timer' || item.Type === 'Recording' || item.TimerId;
const isRecording = item.Type === 'Timer' || item.Type === 'Recording' || item.TimerId;
return getAutoTimeProgressHtml(pct, options, isRecording, startDate, endDate);
}
}
@ -78,13 +76,13 @@ define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'm
return '';
}
function enablePlayedIndicator(item) {
export function enablePlayedIndicator(item) {
return itemHelper.canMarkPlayed(item);
}
function getPlayedIndicator(item) {
export function getPlayedIndicatorHtml(item) {
if (enablePlayedIndicator(item)) {
var userData = item.UserData || {};
let userData = item.UserData || {};
if (userData.UnplayedItemCount) {
return '<div class="countIndicator indicator">' + userData.UnplayedItemCount + '</div>';
}
@ -97,25 +95,18 @@ define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'm
return '';
}
function getCountIndicatorHtml(count) {
return '<div class="countIndicator indicator">' + count + '</div>';
}
function getChildCountIndicatorHtml(item, options) {
var minCount = 0;
if (options) {
minCount = options.minCount || minCount;
}
export function getChildCountIndicatorHtml(item, options) {
const minCount = options && options.minCount ? options.minCount : 0;
if (item.ChildCount && item.ChildCount > minCount) {
return getCountIndicatorHtml(item.ChildCount);
return '<div class="countIndicator indicator">' + item.ChildCount + '</div>';
}
return '';
}
function getTimerIndicator(item) {
var status;
export function getTimerIndicator(item) {
let status;
if (item.Type === 'SeriesTimer') {
return '<span class="material-icons timerIndicator indicatorIcon fiber_smart_record"></span>';
@ -138,7 +129,7 @@ define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'm
return '<span class="material-icons timerIndicator indicatorIcon fiber_manual_record"></span>';
}
function getSyncIndicator(item) {
export function getSyncIndicator(item) {
if (item.SyncPercent === 100) {
return '<div class="syncIndicator indicator fullSyncIndicator"><span class="material-icons indicatorIcon file_download"></span></div>';
} else if (item.SyncPercent != null) {
@ -148,28 +139,23 @@ define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'm
return '';
}
function getTypeIndicator(item) {
if (item.Type === 'Video') {
return '<div class="indicator videoIndicator"><span class="material-icons indicatorIcon videocam"></span></div>';
}
if (item.Type === 'Folder') {
return '<div class="indicator videoIndicator"><span class="material-icons indicatorIcon folder"></span></div>';
}
if (item.Type === 'PhotoAlbum') {
return '<div class="indicator videoIndicator"><span class="material-icons indicatorIcon photo_album"></span></div>';
}
if (item.Type === 'Photo') {
return '<div class="indicator videoIndicator"><span class="material-icons indicatorIcon photo"></span></div>';
export function getTypeIndicator(item) {
const iconT = {
'Video' : 'videocam',
'Folder' : 'folder',
'PhotoAlbum' : 'photo_album',
'Photo' : 'photo'
};
const icon = iconT[item.Type];
return icon ? '<div class="indicator videoIndicator"><span class="material-icons indicatorIcon '+ icon +'"></span></div>' : '';
}
return '';
}
function getMissingIndicator(item) {
export function getMissingIndicator(item) {
if (item.Type === 'Episode' && item.LocationType === 'Virtual') {
if (item.PremiereDate) {
try {
var premiereDate = datetime.parseISO8601Date(item.PremiereDate).getTime();
const premiereDate = datetime.parseISO8601Date(item.PremiereDate).getTime();
if (premiereDate > new Date().getTime()) {
return '<div class="unairedIndicator">Unaired</div>';
}
@ -183,10 +169,10 @@ define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'm
return '';
}
return {
export default {
getProgressHtml: getProgressHtml,
getProgressBarHtml: getProgressBarHtml,
getPlayedIndicatorHtml: getPlayedIndicator,
getPlayedIndicatorHtml: getPlayedIndicatorHtml,
getChildCountIndicatorHtml: getChildCountIndicatorHtml,
enableProgressIndicator: enableProgressIndicator,
getTimerIndicator: getTimerIndicator,
@ -195,4 +181,3 @@ define(['datetime', 'itemHelper', 'emby-progressbar', 'css!./indicators.css', 'm
getTypeIndicator: getTypeIndicator,
getMissingIndicator: getMissingIndicator
};
});

View file

@ -426,7 +426,7 @@ define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutMan
html += '<div class="' + cssClass + '">';
const moreIcon = 'more_horiz';
const moreIcon = 'more_vert';
html += getTextLinesHtml(textlines, isLargeStyle);

View file

@ -490,26 +490,26 @@ define(['datetime', 'globalize', 'appRouter', 'itemHelper', 'indicators', 'mater
if (i.IsInterlaced) {
return '1440i';
}
return '1440P';
return '1440p';
}
if (width >= 1800 || height >= 1000) {
if (i.IsInterlaced) {
return '1080i';
}
return '1080P';
return '1080p';
}
if (width >= 1200 || height >= 700) {
if (i.IsInterlaced) {
return '720i';
}
return '720P';
return '720p';
}
if (width >= 700 || height >= 400) {
if (i.IsInterlaced) {
return '480i';
}
return '480P';
return '480p';
}
}

View file

@ -9,7 +9,7 @@
<span>${Save}</span>
</button>
<button is="paper-icon-button-light" class="btnMore autoSize" tabindex="-1">
<span class="material-icons more_horiz"></span>
<span class="material-icons more_vert"></span>
</button>
</div>
</div>

View file

@ -129,7 +129,7 @@ define(['browser', 'appStorage', 'apphost', 'loading', 'connectionManager', 'glo
html += '<button is="paper-icon-button-light" class="btnCloseSelectionPanel autoSize"><span class="material-icons close"></span></button>';
html += '<h1 class="itemSelectionCount"></h1>';
const moreIcon = 'more_horiz';
const moreIcon = 'more_vert';
html += '<button is="paper-icon-button-light" class="btnSelectionPanelOptions autoSize" style="margin-left:auto;"><span class="material-icons ' + moreIcon + '"></span></button>';
selectionCommandsPanel.innerHTML = html;

View file

@ -1,23 +1,20 @@
define(['actionsheet', 'datetime', 'playbackManager', 'globalize', 'appSettings'], function (actionsheet, datetime, playbackManager, globalize, appSettings) {
'use strict';
import actionsheet from 'actionsheet';
import datetime from 'datetime';
import playbackManager from 'playbackManager';
import globalize from 'globalize';
function show(options) {
export function show(options) {
var item = options.item;
var itemType = item.Type;
var isFolder = item.IsFolder;
var itemId = item.Id;
var channelId = item.ChannelId;
var serverId = item.ServerId;
var resumePositionTicks = item.UserData ? item.UserData.PlaybackPositionTicks : null;
var playableItemId = itemType === 'Program' ? channelId : itemId;
var playableItemId = item.Type === 'Program' ? item.ChannelId : item.Id;
if (!resumePositionTicks || isFolder) {
if (!resumePositionTicks || item.IsFolder) {
playbackManager.play({
ids: [playableItemId],
serverId: serverId
serverId: item.ServerId
});
return;
}
@ -45,14 +42,14 @@ define(['actionsheet', 'datetime', 'playbackManager', 'globalize', 'appSettings'
case 'play':
playbackManager.play({
ids: [playableItemId],
serverId: serverId
serverId: item.ServerId
});
break;
case 'resume':
playbackManager.play({
ids: [playableItemId],
startPositionTicks: resumePositionTicks,
serverId: serverId
serverId: item.ServerId
});
break;
case 'queue':
@ -69,7 +66,6 @@ define(['actionsheet', 'datetime', 'playbackManager', 'globalize', 'appSettings'
});
}
return {
export default {
show: show
};
});

View file

@ -89,7 +89,7 @@ define(['loading', 'dom', 'libraryMenu', 'globalize', 'scripts/imagehelper', 'da
if (canEdit || canDelete(device.Id)) {
deviceHtml += '<div style="text-align:right; float:right;padding-top:5px;">';
deviceHtml += '<button type="button" is="paper-icon-button-light" data-id="' + device.Id + '" title="' + globalize.translate('Menu') + '" class="btnDeviceMenu"><span class="material-icons more_horiz"></span></button>';
deviceHtml += '<button type="button" is="paper-icon-button-light" data-id="' + device.Id + '" title="' + globalize.translate('Menu') + '" class="btnDeviceMenu"><span class="material-icons more_vert"></span></button>';
deviceHtml += '</div>';
}

View file

@ -298,7 +298,7 @@ define(['jQuery', 'apphost', 'scripts/taskbutton', 'loading', 'libraryMenu', 'gl
if (virtualFolder.showMenu !== false) {
html += '<div style="text-align:right; float:right;padding-top:5px;">';
html += '<button type="button" is="paper-icon-button-light" class="btnCardMenu autoSize"><span class="material-icons more_horiz"></span></button>';
html += '<button type="button" is="paper-icon-button-light" class="btnCardMenu autoSize"><span class="material-icons more_vert"></span></button>';
html += '</div>';
}

View file

@ -47,7 +47,7 @@ define(['loading', 'libraryMenu', 'dom', 'globalize', 'cardStyle', 'emby-button'
html += '</div>';
html += '<div class="cardFooter">';
html += '<div style="text-align:right; float:right;padding-top:5px;">';
html += '<button type="button" is="paper-icon-button-light" class="btnCardMenu autoSize"><span class="material-icons more_horiz"></span></button>';
html += '<button type="button" is="paper-icon-button-light" class="btnCardMenu autoSize"><span class="material-icons more_vert"></span></button>';
html += '</div>';
html += "<div class='cardText'>";
html += configPage.DisplayName || plugin.Name;

View file

@ -30,7 +30,7 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layo
html += '</div>';
html += '</div>';
html += '<div class="cardFooter visualCardBox-cardFooter">';
html += '<button is="paper-icon-button-light" class="itemAction btnCardOptions autoSize" data-action="menu"><span class="material-icons more_horiz"></span></button>';
html += '<button is="paper-icon-button-light" class="itemAction btnCardOptions autoSize" data-action="menu"><span class="material-icons more_vert"></span></button>';
html += '<div class="cardText">' + (device.FriendlyName || getTunerName(device.Type)) + '</div>';
html += '<div class="cardText cardText-secondary">';
html += device.Url || '&nbsp;';
@ -112,7 +112,7 @@ define(['jQuery', 'globalize', 'scripts/taskbutton', 'dom', 'libraryMenu', 'layo
html += '</div>';
html += '</a>';
html += '</div>';
html += '<button type="button" is="paper-icon-button-light" class="btnOptions" data-id="' + provider.Id + '"><span class="material-icons listItemAside more_horiz"></span></button>';
html += '<button type="button" is="paper-icon-button-light" class="btnOptions" data-id="' + provider.Id + '"><span class="material-icons listItemAside more_vert"></span></button>';
html += '</div>';
}

View file

@ -1112,6 +1112,14 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
playbackManager.playPause(currentPlayer);
showOsd();
break;
case 'ArrowUp':
case 'Up':
playbackManager.volumeUp(currentPlayer);
break;
case 'ArrowDown':
case 'Down':
playbackManager.volumeDown(currentPlayer);
break;
case 'l':
case 'ArrowRight':
case 'Right':
@ -1134,6 +1142,18 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
playbackManager.toggleMute(currentPlayer);
showOsd();
break;
case 'p':
case 'P':
if (e.shiftKey) {
playbackManager.previousTrack(currentPlayer);
}
break;
case 'n':
case 'N':
if (e.shiftKey) {
playbackManager.nextTrack(currentPlayer);
}
break;
case 'NavigationLeft':
case 'GamepadDPadLeft':
case 'GamepadLeftThumbstickLeft':
@ -1151,6 +1171,26 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med
playbackManager.fastForward(currentPlayer);
showOsd();
}
break;
case 'Home':
playbackManager.seekPercent(0, currentPlayer);
break;
case 'End':
playbackManager.seekPercent(100, currentPlayer);
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
var percent = parseInt(key, 10) * 10;
playbackManager.seekPercent(percent, currentPlayer);
break;
}
}

View file

@ -115,7 +115,7 @@ define(['loading', 'dom', 'globalize', 'date-fns', 'dfnshelper', 'paper-icon-but
html += '<div class="flex-grow" style="overflow:hidden;text-overflow:ellipsis;">';
html += user.Name;
html += '</div>';
html += '<button type="button" is="paper-icon-button-light" class="btnUserMenu flex-shrink-zero"><span class="material-icons more_horiz"></span></button>';
html += '<button type="button" is="paper-icon-button-light" class="btnUserMenu flex-shrink-zero"><span class="material-icons more_vert"></span></button>';
html += '</div>';
html += '<div class="cardText cardText-secondary">';
var lastSeen = getLastSeenText(user.LastActivityDate);
@ -189,7 +189,7 @@ define(['loading', 'dom', 'globalize', 'date-fns', 'dfnshelper', 'paper-icon-but
html += '</div>';
html += '<div class="cardFooter visualCardBox-cardFooter">';
html += '<div class="cardText" style="text-align:right; float:right;padding:0;">';
html += '<button type="button" is="paper-icon-button-light" class="btnUserMenu"><span class="material-icons more_horiz"></span></button>';
html += '<button type="button" is="paper-icon-button-light" class="btnUserMenu"><span class="material-icons more_vert"></span></button>';
html += '</div>';
html += '<div class="cardText" style="padding-top:10px;padding-bottom:10px;">';
html += user.UserName;

View file

@ -101,7 +101,7 @@
<button is="emby-button" type="button" class="button-flat btnMoreCommands hide detailButton">
<div class="detailButton-content">
<span class="material-icons detailButton-icon more_horiz"></span>
<span class="material-icons detailButton-icon more_vert"></span>
<div class="detailButton-text">${ButtonMore}</div>
</div>
</button>

View file

@ -42,10 +42,10 @@
<span class="material-icons filter_list"></span>
</button>
<button is="emby-button" class="btnViewSettings button-flat listTextButton-autohide">
<span class="material-icons more_horiz"></span>
<span class="material-icons more_vert"></span>
</button>
<button is="paper-icon-button-light" class="btnViewSettings listIconButton-autohide">
<span class="material-icons more_horiz"></span>
<span class="material-icons more_vert"></span>
</button>
</div>
<div is="emby-itemscontainer" class="vertical-wrap itemsContainer centered" style="padding: 0 0 10vh 0;">

View file

@ -962,7 +962,7 @@
"AllowMediaConversion": "السماح بتحويل الوسائظ",
"AllLanguages": "كل اللغات",
"AllEpisodes": "كل الحلقات",
"AllComplexFormats": "جميع التنسيقات المعقدة (ASS ، SSA ، VOBSUB ، PGS ، SUB / IDX ، إلخ.)",
"AllComplexFormats": "جميع التنسيقات المعقدة (ASS ، SSA ، VOBSUB ، PGS ، SUB / IDX ، ...)",
"AllChannels": "كل القنوات",
"Albums": "ألبومات",
"Aired": "عرضت",

View file

@ -61,7 +61,7 @@
"Alerts": "Alertas",
"All": "Todo",
"AllChannels": "Todos los canales",
"AllComplexFormats": "Todos los formatos complejos (ASS, SSA, VOBSUB, PGS, SUB, IDX)",
"AllComplexFormats": "Todos los formatos complejos (ASS, SSA, VOBSUB, PGS, SUB, IDX, ...)",
"AllEpisodes": "Todos los capítulos",
"AllLanguages": "Todos los idiomas",
"AllLibraries": "Todas las bibliotecas",
@ -500,5 +500,45 @@
"HeaderDeleteItem": "Eliminar ítem",
"HeaderDeleteDevice": "Eliminar dispositivo",
"HeaderDefaultRecordingSettings": "Ajustes de grabación por defecto",
"UnsupportedPlayback": "Jellyfin no puede descifrar contenido protegido por DRM pero a pesar de esto lo intentará con todo el contenido, incluyendo títulos protegidos. Algunos archivos pueden aparecer completamente en negro por estar cifrados o por otras características no soportadas, como títulos interactivos."
"UnsupportedPlayback": "Jellyfin no puede descifrar contenido protegido por DRM pero a pesar de esto lo intentará con todo el contenido, incluyendo títulos protegidos. Algunos archivos pueden aparecer completamente en negro por estar cifrados o por otras características no soportadas, como títulos interactivos.",
"HeaderMediaFolders": "Carpetas de medios",
"HeaderMedia": "Medios",
"HeaderLoginFailure": "Error al iniciar sesión",
"HeaderLiveTvTunerSetup": "Configuración del sintonizador de TV en vivo",
"HeaderLiveTv": "TV en vivo",
"HeaderLibrarySettings": "Configuraciones de biblioteca",
"HeaderLibraryOrder": "Orden de biblioteca",
"HeaderLibraryFolders": "Carpetas de biblioteca",
"HeaderLibraryAccess": "Acceso a la biblioteca",
"HeaderLibraries": "Bibliotecas",
"HeaderLatestRecordings": "Grabaciones recientes",
"HeaderLatestMusic": "Música reciente",
"HeaderLatestMovies": "Películas recientes",
"HeaderLatestMedia": "Medios recientes",
"HeaderKeepSeries": "Mantener serie",
"HeaderKeepRecording": "Mantener grabación",
"HeaderItems": "Artículos",
"HeaderInstantMix": "Mezcla instantánea",
"HeaderInstall": "Instalar",
"HeaderImageSettings": "Configuraciones de imagen",
"HeaderImageOptions": "Opciones de imagen",
"HeaderIdentifyItemHelp": "Ingrese uno o más criterios de búsqueda. Eliminar criterios para aumentar los resultados de búsqueda.",
"HeaderIdentificationHeader": "Encabezado de identificación",
"HeaderIdentificationCriteriaHelp": "Ingrese al menos un criterio de identificación.",
"HeaderIdentification": "Identificación",
"HeaderHttpHeaders": "Encabezados HTTP",
"HeaderHome": "Inicio",
"HeaderGuideProviders": "Proveedores de datos de guías de TV",
"HeaderGenres": "Géneros",
"HeaderFrequentlyPlayed": "Reproducido con frecuencia",
"HeaderForgotPassword": "Olvidé la contraseña",
"HeaderForKids": "Para niños",
"HeaderFilters": "Filtros",
"HeaderFetcherSettings": "Configuración del recuperador",
"HeaderFetchImages": "Obtener imágenes:",
"HeaderFeatures": "Caracteristicas",
"HeaderFeatureAccess": "Acceso a características",
"HeaderFavoritePlaylists": "Listas de reproducción favoritas",
"ButtonTogglePlaylist": "Lista de reproducción",
"ButtonToggleContextMenu": "Más"
}

View file

@ -193,5 +193,10 @@
"AllowFfmpegThrottling": "Restreindre la vitesse de transcodage",
"AlbumArtist": "Artiste de l'Album",
"Album": "Album",
"AuthProviderHelp": "Sélectionner un fournisseur d'authentification pour authentifier le mot de passe de cet utilisateur."
"AuthProviderHelp": "Sélectionner un fournisseur d'authentification pour authentifier le mot de passe de cet utilisateur.",
"HeaderFavoriteSongs": "Chansons favorites",
"HeaderFavoriteShows": "Séries favorites",
"HeaderFavoriteEpisodes": "Épisodes favoris",
"HeaderFavoriteArtists": "Artistes favoris",
"HeaderFavoriteAlbums": "Albums favoris"
}

View file

@ -40,7 +40,7 @@
"BirthDateValue": "Nato il: {0}",
"BirthLocation": "Luogo di nascita",
"BirthPlaceValue": "nato a: {0}",
"BookLibraryHelp": "Libri e audiolibri sono supportati. Rivedere {0}la guida ai nomi dei libri di Jellyfin{1}.",
"BookLibraryHelp": "Libri e audiolibri sono supportati. Rivedi la guida {0} ai nomi dei libri {1} di Jellyfin.",
"Books": "Libri",
"BoxRear": "Box (retro)",
"Browse": "Esplora",

View file

@ -239,7 +239,7 @@
"Kids": "Bērni",
"Items": "Vienumi",
"ItemCount": "{0} vienumi",
"InstallingPackage": "Instalē {0}",
"InstallingPackage": "Instalē {0} (versija {1})",
"Images": "Attēli",
"Identify": "Identificēt",
"Horizontal": "Horizontāls",
@ -455,7 +455,7 @@
"DrmChannelsNotImported": "Kanāli ar DRM netiks importēti.",
"DownloadsValue": "{0} lejupielādes",
"Download": "Lejupielādēt",
"DisplayModeHelp": "Izvēlies ekrāna veidu, uz kura tu izmanto Jellyfin.",
"DisplayModeHelp": "Izvēlies izkārtojuma veidu, kuru tu gribi priekš šī interfeisa.",
"DoNotRecord": "Neierakstīt",
"DisplayInOtherHomeScreenSections": "Rādīt mājas ekrāna sadaļās kā jaunākā multvide un turpini skatīties",
"DisplayInMyMedia": "Rādīt mājas ekrānā",
@ -605,8 +605,8 @@
"Art": "Māksla",
"AroundTime": "Ap {0}",
"Anytime": "Jebkad",
"AnyLanguage": "Jebkura valoda",
"AlwaysPlaySubtitles": "Vienmēr rādīt subtitrus",
"AnyLanguage": "Jebkura Valoda",
"AlwaysPlaySubtitles": "Vienmēr Rādīt",
"AllowedRemoteAddressesHelp": "Ar komatiem atdalīts IP adrešu vai IP/tīkla masku saraksts, kas norāda uz tīkliem, kas var pieslēgties attālināti. Ja atstāts tukšs, visas attālinātās adreses tiks atļautas.",
"AllowRemoteAccessHelp": "Ja atķeksēts, visi attālinātie savienojumi tiks bloķēti.",
"AllowRemoteAccess": "Atļaut attālinātus savienojumus šim Jellyfin Serverim.",
@ -615,7 +615,7 @@
"AllLibraries": "Visas bibliotēkas",
"AllLanguages": "Visas valodas",
"AllEpisodes": "Visas epizodes",
"AllComplexFormats": "Visi sarezģītie formāti (ASS, SSA, VOBSUB, PGS, SUB/IDX, utt.)",
"AllComplexFormats": "Visi Sarežģītie formāti (ASS, SSA, VOBSUB, PGS, SUB, IDX, …)",
"AllChannels": "Visi kanāli",
"All": "Viss",
"Alerts": "Paziņojumi",
@ -951,8 +951,8 @@
"HeaderCustomDlnaProfiles": "Pielāgoti Profili",
"HeaderConfirmProfileDeletion": "Apstiprināt Profila Dzēšanu",
"HeaderChapterImages": "Nodaļu Attēli",
"HeaderCastCrew": "Lomas/Apkalpe",
"HeaderCastAndCrew": "Lomas/Apkalpe",
"HeaderCastCrew": "Lomas & Apkalpe",
"HeaderCastAndCrew": "Lomas un Apkalpe",
"HeaderAppearsOn": "Redzams",
"FFmpegSavePathNotFound": "Mēs nespējām atrast FFmpeg norādītajā ceļā. FFprobe arī ir vajadzīgs, un tam ir jāatrodas tajā pašā mapē. Šīs komponentes parasti tiek apvienotas vienā un tajā pašā lejupielādē. Lūdzu pārbaudiet ceļu un mēģiniet vēlreiz.",
"HeaderAdditionalParts": "Papildus Ceļi",
@ -1081,5 +1081,58 @@
"OptionAllowBrowsingLiveTv": "Atļaut Tiešraides TV piekļuvi",
"MediaInfoForced": "Piespiests",
"LabelPublicHttpPortHelp": "Publiskai porta numurs, kas tiks kartēts uz vietējo HTTP portu.",
"LabelOptionalNetworkPath": "(Neobligāts) Koplietota tīkla mape:"
"LabelOptionalNetworkPath": "(Neobligāts) Koplietota tīkla mape:",
"LabelLibraryPageSizeHelp": "Uzstāda vienumu daudzumu, ko rādīt bibliotēkas lapā. Uzstādi uz 0 lai atspējotu lapošanu.",
"LabelLibraryPageSize": "Bibliotēkas lapu lielums:",
"LabelKodiMetadataUserHelp": "Saglabāt skatīšanās datus uz NFO datnēm, lai tos varētu izmantot citas lietotnes.",
"LabelKodiMetadataDateFormatHelp": "Visi datumi iekš NFO datnēm tiks parsēti ar šo formātu.",
"LabelInNetworkSignInWithEasyPasswordHelp": "Izmanto vieglo pin kodu lai piekļūtu klientiem savā vietējā tīklā. Tava parastā parole būs vajadzīga ārpus mājām. Ja pin kods ir atstāts tukšs, tev nevajadzēs paroli savā vietējā mājas tīklā.",
"LabelInNetworkSignInWithEasyPassword": "Iespējot iekštīkla piekļuvi ar manu vieglo pin kodu",
"LabelImportOnlyFavoriteChannels": "Ierobežot uz kanāliem, kas atzīmēti kā favorīti",
"LabelGroupMoviesIntoCollectionsHelp": "Kad tiks rādīti filmu saraksti, filmas kas pieder pie kolekcijas tiks attēlotas kā viens grupēts vienums.",
"LabelServerNameHelp": "Šis vārds tiks izmantots lai identificētu tavu serveri un noklusējumā ir servera datora vārds.",
"LabelExtractChaptersDuringLibraryScan": "Izvilkt sadaļu attēlus bibliotēkas skenēšanas laikā",
"LabelBaseUrlHelp": "Šeit tu vari pievienot pielāgotas apakš-mapes lai piekļūtu serverim no unikālāka URL.",
"LabelBaseUrl": "Pamata URL:",
"LabelEnableSingleImageInDidlLimitHelp": "Dažas ierīces pareizi neatskaņos ja vairāki attēli ir iegulti iekš Didl.",
"LabelEnableSingleImageInDidlLimit": "Ierobežot uz vienu iegulto attēlu",
"LabelEnableDlnaClientDiscoveryIntervalHelp": "Nosaka laiku sekundēs starp Jellyfin veiktajiem SSDP meklējumiem.",
"LabelEmbedAlbumArtDidlHelp": "Dažas ierīces labprātāk izmanto šo metodi lai saņemtu albumu vākus. Citas var neatskaņot ar šo opciju ieslēgtu.",
"LabelDroppedFrames": "Nomestie kadri:",
"LabelDownMixAudioScaleHelp": "Pastiprināt audio lejupmiksēšanas laikā. Vērtība viens paturēs oriģinālo skaļumu.",
"LabelDownMixAudioScale": "Audio pastiprinājums lejupmiksējot:",
"LabelDisplayMissingEpisodesWithinSeasons": "Rādīt trūkstošās epizodes sezonās",
"LabelDateAddedBehaviorHelp": "Ja atrodas metadatu vērtība, tā vienmēr tiks izmantota pirms jebkuras no šīm opcijām.",
"LabelDashboardTheme": "Servera vadības paneļa tēma:",
"LabelCustomDeviceDisplayNameHelp": "Ievadi pielāgotu displeja vārdu vai atstāj tukšu lai izmantotu ierīces noteikto.",
"LabelCachePathHelp": "Nosaki pielāgotu atrašanās vietu priekš keša datnēm kā attēliem. Atstāj tukšu lai izmantotu servera noklusējumu.",
"LabelAllowedRemoteAddressesMode": "Attālās IP adreses filtra režīms:",
"LabelAllowedRemoteAddresses": "Attālās IP adreses filtrs:",
"LabelAlbumArtPN": "Albumu vāku PN:",
"LabelAirsBeforeSeason": "Tiešraidē pirms sezonas:",
"LabelAirsBeforeEpisode": "Tiešraidē pirms epizodes:",
"LabelAirsAfterSeason": "Tiešraidē pēc sezonas:",
"HeaderSubtitleProfilesHelp": "Subtitru profili apraksta ierīces atbalstītos subtitru formātus.",
"HeaderPendingInvitations": "Gaidošie Uzaicinājumi",
"HeaderKeepSeries": "Paturēt Sēriju",
"HeaderFavoritePlaylists": "Atskaņošanas Sarakstu Favorīti",
"ApiKeysCaption": "Saraksts ar pašlaik iespējotajām API atslēgām",
"EncoderPresetHelp": "Izvēlies ātrāku vērtību lai uzlabotu veiktspēju, vai lēnāku vērtību lai uzlabotu kvalitāti.",
"FetchingData": "Iegūst papildu datus",
"ErrorDeletingItem": "Notika kļūda dzēšot vienumu no Jellyfin Servera. Lūdzu pārliecinies vai Jellyfin Server ir rakstoša piekļuve pie satura mapes un mēģini vēlreiz.",
"ErrorAddingTunerDevice": "Kļūda pievienojot tūnera ierīci. Lūdzu pārliecinies ka tā ir pieejama un mēģini vēlreiz.",
"ErrorAddingMediaPathToVirtualFolder": "Notika kļūda pievienojot satura ceļu. Lūdzu pārliecinies ka ceļš ir derīgs un ka Jellyfin Servera procesam ir piekļuve tai vietai.",
"Episode": "Epizode",
"DeviceAccessHelp": "Tas attiecas tikai uz ierīcēm, kas var tikt unikāli identificētas un neaizliegs piekļuvi no pārlūka. Filtrējot lietotāju ierīču piekļuvi neatļaus tiem izmantot jaunas ierīces, līdz tās nav tikušas šeit atļautas.",
"DeinterlaceMethodHelp": "Izvēlies rindpārlēces sakļaušanas (deinterlacing) metodi kad tiek trans-kodēts rindpārlēces izvērsts (interlaced) saturs.",
"CustomDlnaProfilesHelp": "Izveido pielāgotu profilu priekš jaunas ierīces, vai pārraksti sistēmas profilu.",
"ColorTransfer": "Krāsu pārsūtīšana",
"ClientSettings": "Klientu Iestatījumi",
"ButtonTogglePlaylist": "Atskaņošanas Saraksts",
"ButtonToggleContextMenu": "Vairāk",
"BurnSubtitlesHelp": "Nosaka, vai serverim ir jāiededzina subtitri video trans-kodēšanas laikā. To nedarot tiks stipri palielināta veiktspēja. Izvēlies Auto lai iededzinātu uz attēliem bāzētus formātus (VOBSUB, PGS, SUB, IDX, …) un noteiktus ASS vai SSA subtitrus.",
"Artist": "Izpildītājs",
"AllowOnTheFlySubtitleExtractionHelp": "Iegultie subtitri var tikt izvilkto no video un nogādāti klientiem kā parasts teksts, lai nevajadzētu veikt lieku video trans kodēšanu. Uz dažām sistēmām tas var aizņemt ilgu laiku un likt video atskaņošanai uzkārties izvilkšanas procesa laikā. Atspējo šo lai iegultos subtitrus iededzinātu video trans kodēšanas veidā, kad tos noklusēti neatbalsta klienta ierīce.",
"AlbumArtist": "Albuma Izpildītājs",
"Album": "Albums"
}

View file

@ -1021,7 +1021,7 @@
"OptionMissingEpisode": "Episódios em Falta",
"OptionMonday": "Segunda-feira",
"OptionNameSort": "Nome",
"OptionNew": "Novo...",
"OptionNew": "Novo",
"OptionNone": "Nenhum",
"OptionOnAppStartup": "Ao iniciar a aplicação",
"OptionOnInterval": "Em um intervalo",
@ -1506,5 +1506,6 @@
"ButtonToggleContextMenu": "Mais",
"Filter": "Filtro",
"New": "Novo",
"HeaderFavoritePlaylists": "Playlists Favoritas"
"HeaderFavoritePlaylists": "Playlists Favoritas",
"ApiKeysCaption": "Lista de chaves API ativadas no momento"
}

View file

@ -249,7 +249,7 @@
"ButtonStop": "Stop",
"ButtonSubmit": "Trimite",
"Collections": "Colecții",
"AllowRemoteAccess": "Permite conexiuni externe către serverul Jellyfin.",
"AllowRemoteAccess": "Permite conexiuni externe către acest server Jellyfin.",
"AllowRemoteAccessHelp": "Dacă este nebifat, toate conexiunile externe vor fi blocate.",
"AlwaysPlaySubtitles": "Întotdeauna arată",
"AnyLanguage": "Orice Limbă",
@ -288,7 +288,7 @@
"Director": "Regizor",
"AllowOnTheFlySubtitleExtractionHelp": "Subtitrările încorporate pot fi extrase din video și transmise către client în mod text pentru a preveni transcodarea videoului. Pe unele sisteme acest lucru poate dura mult timp și poate cauza oprirea redării video în timpul procesului de extragere. Dezactivează opțiunea pentru a avea subtitrările încorporate incluse în videoul transcodat atunci când nu sunt nativ suportate de către dispozitivul client.",
"BirthLocation": "Locul nașterii",
"BurnSubtitlesHelp": "Determină dacă serverul ar trebui să includă subtitrări când face transcodarea video. Evitând acest lucru va îmbunătăți performanța serverului. Selectează Auto pentru includerea formaturilor bazate pe imagini (VOBSUB, PGS, SUB, IDX) și anumitor subtitrări ASS sau SSA.",
"BurnSubtitlesHelp": "Determină dacă serverul ar trebui să includă subtitrări când face transcodarea video. Evitând acest lucru va îmbunătăți performanța serverului. Selectează Auto pentru includerea formaturilor bazate pe imagini (VOBSUB, PGS, SUB, IDX, ...) și anumitor subtitrări ASS sau SSA.",
"ButtonPreviousTrack": "Calea anterioară",
"ButtonRevoke": "Revocă",
"ButtonSettings": "Setări",
@ -304,7 +304,7 @@
"Delete": "Șterge",
"DeleteImage": "Șterge Imaginea",
"DeleteUserConfirmation": "Sigur doriți să ștergeți acest utilizator?",
"Depressed": "Depresat",
"Depressed": "Deprimat",
"Descending": "Descendent",
"DetectingDevices": "Detectez dispozitive",
"DirectPlaying": "Redare directă",
@ -511,7 +511,7 @@
"GuestStar": "Vedeta invitata",
"GuideProviderSelectListings": "Selectați Listări",
"EncoderPresetHelp": "Alegeți o valoare mai rapidă pentru a îmbunătăți performanța sau o valoare mai lentă pentru a îmbunătăți calitatea.",
"HardwareAccelerationWarning": "Activarea accelerării hardware poate provoca instabilitate în anumite medii. Asigurați-vă că sistemul de operare și driverele video sunt complet actualizate. Dacă întâmpinați dificultăți pentru a reda video după activarea acestei opțiuni, va trebui să schimbați setarea la Nimic.",
"HardwareAccelerationWarning": "Activarea accelerării hardware poate provoca instabilitate în anumite medii. Asigurați-vă că sistemul de operare și driverele video sunt complet actualizate. Dacă întâmpinați dificultăți pentru a reda video după activarea acestei opțiuni, va trebui să schimbați setarea la inapoi la Nimic.",
"HeaderAccessSchedule": "Program de Acces",
"HeaderAccessScheduleHelp": "Creați un program de acces pentru a limita accesul la anumite ore.",
"HeaderActiveDevices": "Dispozitive active",
@ -1334,7 +1334,7 @@
"OptionOnInterval": "La un interval",
"OptionOnAppStartup": "La pornirea aplicației",
"OptionNone": "Nici unul",
"OptionNew": "Nou...",
"OptionNew": "Nou",
"OptionMissingEpisode": "Episoade lipsă",
"OptionMax": "Max",
"OptionLoginAttemptsBeforeLockoutHelp": "O valoare zero înseamnă că va moșteni valoarea implicită de trei încercări pentru utilizatorii normali și cinci pentru administratori. Setarea acestei opțiuni la -1 va dezactiva funcția.",
@ -1359,9 +1359,9 @@
"OptionEnableExternalContentInSuggestions": "Activați conținut extern în sugestii",
"OptionEmbedSubtitles": "Inclus în container",
"OptionDownloadLogoImage": "Siglă",
"OptionDownloadImagesInAdvanceHelp": "În mod implicit, majoritatea imaginilor sunt descărcate numai la cererea unei aplicații din Jellyfin. Activați această opțiune pentru a descărca în prealabil toate imaginile, în timp ce fișierele media noi sunt importate. Acest lucru poate provoca scanări ale bibliotecii semnificativ mai lungi.",
"OptionDownloadImagesInAdvanceHelp": "În mod implicit, majoritatea imaginilor sunt descărcate numai la cererea unei aplicații din Jellyfin. Activați această opțiune pentru a descărca în prealabil toate imaginile, pe măsură ce fișierele media sunt importate. Acest lucru poate provoca scanări ale bibliotecii semnificativ mai lungi.",
"OptionDownloadImagesInAdvance": "Descărcați imaginile în avans",
"OptionDownloadDiscImage": "Placă",
"OptionDownloadDiscImage": "Disc",
"OptionDisplayFolderViewHelp": "Afișați dosarele alături de celelalte biblioteci media. Acest lucru poate fi util dacă doriți să aveți o vizualizare direct în dosar.",
"OptionDisplayFolderView": "Afișați o vizualizare de dosar pentru a afișa dosarele media simple",
"OptionDateAddedImportTime": "Utilizați data scanării în bibliotecă",
@ -1465,8 +1465,8 @@
"NoCreatedLibraries": "Se pare că nu ați creat încă biblioteci. {0} Doriți să creați una acum? {1}",
"AskAdminToCreateLibrary": "Cereți unui administrator să creeze o bibliotecă.",
"PlaybackErrorNoCompatibleStream": "Clientul nu este compatibil cu formatul media, iar serverul nu trimite un format media compatibil.",
"AllowFfmpegThrottlingHelp": "Când un transcod sau un remux se află destul de departe înainte de poziția actuală de redare, întrerupeți procesul, astfel încât să consume mai puține resurse. Acest lucru este cel mai util când priviți fără a derula des. Dezactivați acestă opțiune dacă întâmpinați probleme de redare.",
"AllowFfmpegThrottling": "Accelerare Transcod-uri",
"AllowFfmpegThrottlingHelp": "Când un transcod sau un remux se află destul de departe înainte de poziția actuală de redare, întrerupeți procesul, astfel încât să consume mai puține resurse. Acest lucru este util atunci când priviți fără a derula des. Dezactivați acestă opțiune dacă întâmpinați probleme de redare.",
"AllowFfmpegThrottling": "Limitare Transcod-uri",
"Track": "Cale",
"Season": "Sezon",
"ReleaseGroup": "Gruparea lansării",
@ -1493,7 +1493,7 @@
"ListPaging": "{0}-{1} din {2}",
"WriteAccessRequired": "Jellyfin Server necesită acces de scriere la acest folder. Vă rugăm să vă asigurați accesul la scriere și încercați din nou.",
"PathNotFound": "Calea nu a fost găsită. Vă rugăm să vă asigurați de validitatea căii și încercați din nou.",
"YadifBob": "YADIF Bob",
"YadifBob": "Gigi Bob",
"Yadif": "YADIF",
"LabelDeinterlaceMethod": "Metoda de intercalare:",
"DeinterlaceMethodHelp": "Selectați metoda de intercalat pe care să o utilizați la transcodarea conținutului intercalat.",
@ -1505,5 +1505,6 @@
"ButtonToggleContextMenu": "Mai mult",
"Filter": "Filtru",
"New": "Nou",
"HeaderFavoritePlaylists": "Listă Favorită"
"HeaderFavoritePlaylists": "Listă Favorită",
"ApiKeysCaption": "Lista cheilor API active"
}

View file

@ -93,17 +93,17 @@
"ValueSeriesCount": "{0} серій",
"ValueSongCount": "{0} пісень",
"AddToPlaylist": "Додати до списку відтворення",
"AccessRestrictedTryAgainLater": "На даний момент доступ заборонений. Будь ласка спробуйте пізніше.",
"AccessRestrictedTryAgainLater": "На цей момент доступ заборонений. Повторіть спробу пізніше.",
"Actor": "Виконавець",
"AllLanguages": "Всі мови",
"AllLibraries": "Всі бібліотеки",
"AllLanguages": "Усі мови",
"AllLibraries": "Усі бібліотеки",
"AddToCollection": "Додати до колекції",
"AddToPlayQueue": "Додати до черги відтворення",
"All": "Всі",
"AllChannels": "Всі канали",
"AllEpisodes": "Всі епізоди",
"AllowRemoteAccess": "Дозволити віддалене підключення до цього сервера Jellyfin.",
"AlwaysPlaySubtitles": "Завжди відтворювати субтитри",
"AlwaysPlaySubtitles": "Завжди вмикати субтитри",
"AnyLanguage": "Будь-яка мова",
"Anytime": "Завжди",
"Add": "Додати",
@ -136,5 +136,28 @@
"Alerts": "Термінові сповіщення",
"AlbumArtist": "Виконавець альбому",
"Album": "Альбом",
"AdditionalNotificationServices": "Пошук у каталозі плагінів для встановлення додаткових сервісів сповіщень."
"AdditionalNotificationServices": "Пошук у каталозі плагінів для встановлення додаткових сервісів сповіщень.",
"ShowYear": "Відобразити рік",
"ShowTitle": "Відобразити назву",
"Raised": "Піднятий",
"OptionResElement": "кожний елемент",
"DropShadow": "Тінь",
"Blacklist": "Чорний список",
"BirthLocation": "Місце народження",
"Banner": "Обкладинка",
"AutoBasedOnLanguageSetting": "Автоматично (на основі поточної мови)",
"Auto": "Автоматично",
"AuthProviderHelp": "Оберіть сервіс аутентифікації, який буде використаний з поточним паролем користувача.",
"Audio": "Аудіо",
"AttributeNew": "Новий",
"AspectRatio": "Відношення сторін",
"AskAdminToCreateLibrary": "Попросіть адміністратора створити бібліотеку.",
"Ascending": "У порядку зростання",
"AsManyAsPossible": "Настільки багато наскільки можливо",
"Artist": "Виконавець",
"Art": "Мистецтво",
"AllowOnTheFlySubtitleExtractionHelp": "Вбудовані субтитри можуть бути експортовані з відео і надіслані, по черзі, клієнтам у вигляді тексту. Це допоможе уникнути перекодування відео. На деяких системах, перекодування може зайняти тривалий час і зупинити відтворення відео, для того щоб забезпечити експортування. Вимкнення цієї функції дозволить вбудованим субтитрам бути інтегрованим у відео, під час перекодування, якщо вбудовані субтитри не підтримуються на стороні клієнта.",
"AllowOnTheFlySubtitleExtraction": "Дозволити експортування субтитрів «на льоту»",
"AllowHWTranscodingHelp": "Дозволити клієнту перекодування на «на льоту». Це дозволить відмикати перекодування, якщо вона вимагається сервером.",
"AllComplexFormats": "Усі складні формати (ASS, SSA, VOBSUB, PGS, SUB, IDX, …)"
}

View file

@ -167,7 +167,7 @@
"ButtonAddScheduledTaskTrigger": "Thêm kích hoạt",
"ButtonAddMediaLibrary": "Thêm thư viện Media",
"ButtonAddImage": "Thêm hình ảnh",
"BurnSubtitlesHelp": "Xác định xem máy chủ có nên ghi phụ đề khi chuyển đổi video hay không. Tránh thực hiện việc này sẽ cải thiện hiệu suất máy chủ đáng kể. Chọn Tự động để ghi các phụ đề có định dạng dựa trên hình ảnh (VOBSUB, PGS, SUB, IDX) và một vài phụ đề ASS/SSA nhất định.",
"BurnSubtitlesHelp": "Xác định xem máy chủ có nên ghi phụ đề khi chuyển đổi video hay không. Tránh thực hiện việc này sẽ cải thiện hiệu suất máy chủ đáng kể. Chọn Tự động để ghi các phụ đề có định dạng dựa trên hình ảnh (VOBSUB, PGS, SUB, IDX, ...) và một vài phụ đề ASS/SSA nhất định.",
"Browse": "Duyệt",
"BoxRear": "Hộp (mặt sau)",
"Books": "Sách",
@ -196,7 +196,7 @@
"AllowedRemoteAddressesHelp": "Danh sách địa chỉ IP được phân tách bằng dấu phẩy hoặc các mục IP/netmask cho các mạng sẽ được phép kết nối từ xa. Nếu để trống, tất cả các địa chỉ sẽ được cho phép.",
"AllowRemoteAccessHelp": "Nếu không được chọn, tất cả các kết nối từ xa sẽ bị chặn.",
"AllowRemoteAccess": "Cho phép kết nối từ xa đến Máy chủ Jellyfin.",
"AllowOnTheFlySubtitleExtractionHelp": "Phụ đề nhúng có thể được trích xuất từ video và dùng như văn bản thuần túy để giúp ngăn chặn chuyển mã video. Trên một số hệ thống, việc này có thể mất nhiều thời gian và khiến quá trình phát video bị đình trệ trong quá trình trích xuất. Vô hiệu hóa điều này để có phụ đề nhúng được ghi trong chuyển mã video khi chúng không được thiết bị khách hỗ trợ.",
"AllowOnTheFlySubtitleExtractionHelp": "Phụ đề nhúng có thể được trích xuất từ video và dùng như văn bản thuần túy để giúp ngăn chặn chuyển mã video. Trên một số hệ thống, việc này có thể mất nhiều thời gian và khiến quá trình phát video bị đình trệ trong quá trình trích xuất. Vô hiệu hóa điều này để có phụ đề nhúng được ghi trong video khi chuyển mã trong trường hợp chúng không được hỗ trợ trên thiết bị phát.",
"AllowOnTheFlySubtitleExtraction": "Cho phép trích xuất phụ đề trực tiếp",
"AllowMediaConversionHelp": "Cấp hoặc từ chối truy cập vào tính năng chuyển đổi media.",
"AllowMediaConversion": "Cho phép chuyển đổi media",
@ -204,7 +204,7 @@
"AllLibraries": "Tất cả các thư viện",
"AllLanguages": "Tất cả các ngôn ngữ",
"AllEpisodes": "Tất cả các tập phim",
"AllComplexFormats": "Tất cả các định dạng phức tạp (ASS, SSA, VOBSUB, PGS, SUB, IDX)",
"AllComplexFormats": "Tất cả các định dạng phức tạp (ASS, SSA, VOBSUB, PGS, SUB, IDX, ...)",
"AllChannels": "Tất cả các kênh",
"Alerts": "Cảnh Báo",
"Albums": "Albums",
@ -672,5 +672,39 @@
"HeaderTuners": "Bộ Điều Khiển Thu Phát Sóng",
"HeaderTunerDevices": "Thiết Bị Bắt Sóng",
"HeaderTranscodingProfileHelp": "Thêm hồ sơ chuyển mã để chỉ ra những định dạng nên dùng khi cần chuyển mã.",
"HeaderTranscodingProfile": "Hồ Sơ Chuyển Mã"
"HeaderTranscodingProfile": "Hồ Sơ Chuyển Mã",
"LabelEnableAutomaticPortMap": "Kích hoạt tính năng tự động kết nối các port",
"LabelEmbedAlbumArtDidlHelp": "Một vài thiết bị ưu tiên phương pháp này để tải bìa album. Một số thiết bị khác có thể không phát được nếu tuỳ chọn này được kích hoạt.",
"LabelEmbedAlbumArtDidl": "Bìa album trong Didl",
"LabelEasyPinCode": "Mã PIN đơn giản:",
"LabelDynamicExternalId": "{0} Id:",
"LabelDropShadow": "Đổ bóng:",
"LabelDroppedFrames": "Những khung hình bị loại bỏ:",
"LabelDropImageHere": "Kéo thả hình ảnh vào đây, hoặc click để lựa chọn hình ảnh.",
"LabelDownloadLanguages": "Ngôn ngữ tải xuống:",
"LabelDownMixAudioScaleHelp": "Tăng cường âm lượng khi trộn âm thanh. Giá trị bằng 1 sẽ giữ nguyên âm lượng gốc.",
"LabelDownMixAudioScale": "Tăng cường âm lượng khi trộn âm thanh:",
"LabelDisplaySpecialsWithinSeasons": "Hiển thị những tập đặc biệt trong phần mà nó được phát sóng",
"LabelDisplayOrder": "Thứ tự hiển thị:",
"LabelDisplayName": "Tên hiển thị:",
"LabelDisplayMode": "Chế độ hiển thị:",
"LabelDisplayMissingEpisodesWithinSeasons": "Hiển thị những tập bị thiếu",
"LabelDisplayLanguageHelp": "Dự án chuyển ngữ Jellyfin là một dự án diễn ra ra liên tục.",
"LabelDisplayLanguage": "Ngôn ngữ hiển thị:",
"LabelDiscNumber": "Đĩa số:",
"LabelDidlMode": "Chế độ DIDL:",
"LabelDeviceDescription": "Mô tả thiết bị",
"LabelDeinterlaceMethod": "Phương pháp khử xen kẽ:",
"LabelDefaultUserHelp": "Xác định thư viện được hiển thị trên những thiết bị đã kết nối. Tuỳ chọn này có thể được ghi đè trên hồ sơ của từng thiết bị.",
"LabelDefaultUser": "Người dùng mặc định:",
"LabelDefaultScreen": "Màn hình mặc định:",
"LabelDeathDate": "Ngày mất:",
"LabelDateTimeLocale": "Ngày giờ địa phương:",
"LabelDateAddedBehaviorHelp": "Nếu có giá trị dữ liệu bổ trợ, nó sẽ luôn được sử dụng trước một trong các tùy chọn này.",
"LabelDateAddedBehavior": "Ngày thêm hành vi cho nội dung mới:",
"LabelDateAdded": "Ngày thêm vào:",
"LabelDashboardTheme": "Chủ đề bảng điều khiển máy chủ:",
"LabelCustomRating": "Đánh giá tuỳ chọn:",
"HeaderFavoritePlaylists": "Danh Sách Phát Yêu Thích",
"ApiKeysCaption": "Danh sách các mã API đang hoạt động"
}

View file

@ -212,7 +212,7 @@
"OptionMissingEpisode": "缺少了的單元",
"OptionMonday": "星期一",
"OptionNameSort": "名字",
"OptionNew": "新增...",
"OptionNew": "新增",
"OptionOnAppStartup": "在伺服器啟動",
"OptionOnInterval": "每時段",
"OptionParentalRating": "家長評級",
@ -1678,5 +1678,10 @@
"DeinterlaceMethodHelp": "選擇對隔行掃描內容進行轉碼時所用的反交錯方法。",
"BoxSet": "套裝",
"UnsupportedPlayback": "Jellyfin 無法解密受 DRM 保護的內容,但仍然會嘗試播放所有內容。某些檔案由於被加密或包含如互動標題等不受支援的內容,在播放時可能會沒有畫面。",
"MessageUnauthorizedUser": "您目前無權存取伺服器,請與您的伺服器管理員聯繫以獲取更多訊息。"
"MessageUnauthorizedUser": "您目前無權存取伺服器,請與您的伺服器管理員聯繫以獲取更多訊息。",
"Filter": "篩選器",
"New": "新增",
"ApiKeysCaption": "目前已啟用的API金鑰列表",
"ButtonTogglePlaylist": "播放清單",
"ButtonToggleContextMenu": "更多"
}