mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge branch 'master' into eslint-no-sequences
This commit is contained in:
commit
a2fe92f192
80 changed files with 2166 additions and 1116 deletions
|
@ -237,7 +237,7 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
|
|||
value: 'books',
|
||||
message: getLink('BookLibraryHelp', 'https://docs.jellyfin.org/general/server/media/books.html')
|
||||
}, {
|
||||
name: globalize.translate('Photos'),
|
||||
name: globalize.translate('HomeVideosPhotos'),
|
||||
value: 'homevideos'
|
||||
}, {
|
||||
name: globalize.translate('MusicVideos'),
|
||||
|
|
|
@ -42,39 +42,64 @@ function saveList(page) {
|
|||
}
|
||||
|
||||
function populateList(options) {
|
||||
let html = '';
|
||||
const paperList = document.createElement('div');
|
||||
paperList.className = 'paperList';
|
||||
|
||||
html += '<div class="paperList">';
|
||||
for (let i = 0; i < options.repositories.length; i++) {
|
||||
html += getRepositoryHtml(options.repositories[i]);
|
||||
}
|
||||
options.repositories.forEach(repo => {
|
||||
paperList.appendChild(getRepositoryElement(repo));
|
||||
});
|
||||
|
||||
html += '</div>';
|
||||
if (!options.repositories.length) {
|
||||
options.noneElement.classList.remove('hide');
|
||||
} else {
|
||||
options.noneElement.classList.add('hide');
|
||||
}
|
||||
|
||||
options.listElement.innerHTML = html;
|
||||
options.listElement.innerHTML = '';
|
||||
options.listElement.appendChild(paperList);
|
||||
loading.hide();
|
||||
}
|
||||
|
||||
function getRepositoryHtml(repository) {
|
||||
let html = '';
|
||||
function getRepositoryElement(repository) {
|
||||
const listItem = document.createElement('div');
|
||||
listItem.className = 'listItem listItem-border';
|
||||
|
||||
html += '<div class="listItem listItem-border">';
|
||||
html += `<a is="emby-linkbutton" style="margin:0;padding:0" class="clearLink listItemIconContainer" href="${repository.Url}" rel="noopener noreferrer" target="_blank">`;
|
||||
html += '<span class="material-icons listItemIcon open_in_new" aria-hidden="true"></span>';
|
||||
html += '</a>';
|
||||
html += '<div class="listItemBody two-line">';
|
||||
html += `<h3 class="listItemBodyText">${repository.Name}</h3>`;
|
||||
html += `<div class="listItemBodyText secondary">${repository.Url}</div>`;
|
||||
html += '</div>';
|
||||
html += `<button type="button" is="paper-icon-button-light" id="${repository.Url}" class="btnDelete" title="${globalize.translate('Delete')}"><span class="material-icons delete" aria-hidden="true"></span></button>`;
|
||||
html += '</div>';
|
||||
const repoLink = document.createElement('a');
|
||||
repoLink.setAttribute('is', 'emby-linkbutton');
|
||||
repoLink.className = 'clearLink listItemIconContainer';
|
||||
repoLink.style.margin = '0';
|
||||
repoLink.style.padding = '0';
|
||||
repoLink.rel = 'noopener noreferrer';
|
||||
repoLink.target = '_blank';
|
||||
repoLink.href = repository.Url;
|
||||
repoLink.innerHTML = '<span class="material-icons listItemIcon open_in_new" aria-hidden="true"></span>';
|
||||
listItem.appendChild(repoLink);
|
||||
|
||||
return html;
|
||||
const body = document.createElement('div');
|
||||
body.className = 'listItemBody two-line';
|
||||
|
||||
const name = document.createElement('h3');
|
||||
name.className = 'listItemBodyText';
|
||||
name.innerText = repository.Name;
|
||||
body.appendChild(name);
|
||||
|
||||
const url = document.createElement('div');
|
||||
url.className = 'listItemBodyText secondary';
|
||||
url.innerText = repository.Url;
|
||||
body.appendChild(url);
|
||||
|
||||
listItem.appendChild(body);
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.setAttribute('is', 'paper-icon-button-light');
|
||||
button.className = 'btnDelete';
|
||||
button.id = repository.Url;
|
||||
button.title = globalize.translate('Delete');
|
||||
button.innerHTML = '<span class="material-icons delete" aria-hidden="true"></span>';
|
||||
listItem.appendChild(button);
|
||||
|
||||
return listItem;
|
||||
}
|
||||
|
||||
function getTabs() {
|
||||
|
|
|
@ -23,7 +23,13 @@ import '../../../elements/emby-button/emby-button';
|
|||
tasks = tasks.sort(function(a, b) {
|
||||
a = a.Category + ' ' + a.Name;
|
||||
b = b.Category + ' ' + b.Name;
|
||||
return a == b ? 0 : a < b ? -1 : 1;
|
||||
if (a > b) {
|
||||
return 1;
|
||||
} else if (a < b) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
let currentCategory;
|
||||
|
|
|
@ -791,7 +791,7 @@ function renderDetailImage(elem, item, imageLoader) {
|
|||
imageLoader.lazyChildren(elem);
|
||||
|
||||
// Avoid breaking the design by preventing focus of the poster using the keyboard.
|
||||
elem.querySelector('a').tabIndex = -1;
|
||||
elem.querySelector('a, button').tabIndex = -1;
|
||||
}
|
||||
|
||||
function renderImage(page, item) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<div class="pageTabContent" id="moviesTab" data-index="0">
|
||||
<div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom focuscontainer-x">
|
||||
<div class="paging"></div>
|
||||
<button is="paper-icon-button-light" class="btnShuffle autoSize hide" title="${Shuffle}"><span class="material-icons shuffle" aria-hidden="true"></span></button>
|
||||
<button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy" aria-hidden="true"></span></button>
|
||||
<button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha" aria-hidden="true"></span></button>
|
||||
<button is="paper-icon-button-light" class="btnFilter autoSize" title="${Filter}"><span class="material-icons filter_list" aria-hidden="true"></span></button>
|
||||
|
|
|
@ -6,6 +6,7 @@ import { AlphaPicker } from '../../components/alphaPicker/alphaPicker';
|
|||
import listView from '../../components/listview/listview';
|
||||
import cardBuilder from '../../components/cardbuilder/cardBuilder';
|
||||
import globalize from '../../scripts/globalize';
|
||||
import { playbackManager } from '../../components/playback/playbackmanager';
|
||||
import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
||||
|
||||
/* eslint-disable indent */
|
||||
|
@ -29,6 +30,15 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
|||
return ApiClient.getItems(ApiClient.getCurrentUserId(), query);
|
||||
}
|
||||
|
||||
function shuffle() {
|
||||
ApiClient.getItem(
|
||||
ApiClient.getCurrentUserId(),
|
||||
params.topParentId
|
||||
).then((item) => {
|
||||
playbackManager.shuffle(item);
|
||||
});
|
||||
}
|
||||
|
||||
const afterRefresh = (result) => {
|
||||
function onNextPageClick() {
|
||||
if (isLoading) {
|
||||
|
@ -77,6 +87,8 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
|||
elem.addEventListener('click', onPreviousPageClick);
|
||||
}
|
||||
|
||||
tabContent.querySelector('.btnShuffle').classList.toggle('hide', result.TotalRecordCount < 1);
|
||||
|
||||
isLoading = false;
|
||||
loading.hide();
|
||||
|
||||
|
@ -243,6 +255,8 @@ import '../../elements/emby-itemscontainer/emby-itemscontainer';
|
|||
onViewStyleChange();
|
||||
itemsContainer.refreshItems();
|
||||
});
|
||||
|
||||
tabContent.querySelector('.btnShuffle').addEventListener('click', shuffle);
|
||||
};
|
||||
|
||||
let itemsContainer = tabContent.querySelector('.itemsContainer');
|
||||
|
|
|
@ -66,7 +66,7 @@ import Dashboard from '../../utils/dashboard';
|
|||
SortOrder: 'Descending',
|
||||
IncludeItemTypes: 'Movie',
|
||||
Filters: 'IsResumable',
|
||||
Limit: screenWidth >= 1920 ? 5 : screenWidth >= 1600 ? 5 : 3,
|
||||
Limit: screenWidth >= 1600 ? 5 : 3,
|
||||
Recursive: true,
|
||||
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
|
||||
CollapseBoxSetItems: false,
|
||||
|
@ -157,10 +157,17 @@ import Dashboard from '../../utils/dashboard';
|
|||
|
||||
function loadSuggestions(page, userId) {
|
||||
const screenWidth = dom.getWindowSize().innerWidth;
|
||||
let itemLimit = 5;
|
||||
if (screenWidth >= 1600) {
|
||||
itemLimit = 8;
|
||||
} else if (screenWidth >= 1200) {
|
||||
itemLimit = 6;
|
||||
}
|
||||
|
||||
const url = ApiClient.getUrl('Movies/Recommendations', {
|
||||
userId: userId,
|
||||
categoryLimit: 6,
|
||||
ItemLimit: screenWidth >= 1920 ? 8 : screenWidth >= 1600 ? 8 : screenWidth >= 1200 ? 6 : 5,
|
||||
ItemLimit: itemLimit,
|
||||
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
|
||||
ImageTypeLimit: 1,
|
||||
EnableImageTypes: 'Primary,Backdrop,Banner,Thumb'
|
||||
|
|
|
@ -27,6 +27,8 @@ import LibraryMenu from '../../../scripts/libraryMenu';
|
|||
import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components/backdrop/backdrop';
|
||||
|
||||
/* eslint-disable indent */
|
||||
const TICKS_PER_MINUTE = 600000000;
|
||||
const TICKS_PER_SECOND = 10000000;
|
||||
|
||||
function getOpenedDialog() {
|
||||
return document.querySelector('.dialogContainer .dialog.opened');
|
||||
|
@ -210,7 +212,18 @@ import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components
|
|||
itemName = parentName || '';
|
||||
}
|
||||
|
||||
LibraryMenu.setTitle(itemName);
|
||||
// Display the item with its premiere date if it has one
|
||||
let title = itemName;
|
||||
if (item.PremiereDate) {
|
||||
try {
|
||||
const year = datetime.parseISO8601Date(item.PremiereDate).getFullYear();
|
||||
title += ` (${year})`;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
LibraryMenu.setTitle(title);
|
||||
|
||||
const documentTitle = parentName || (item ? item.Name : null);
|
||||
|
||||
|
@ -587,11 +600,16 @@ import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../../components
|
|||
|
||||
function showComingUpNextIfNeeded(player, currentItem, currentTimeTicks, runtimeTicks) {
|
||||
if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && currentItem.Type === 'Episode' && userSettings.enableNextVideoInfoOverlay()) {
|
||||
const showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30;
|
||||
const showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4;
|
||||
let showAtSecondsLeft = 30;
|
||||
if (runtimeTicks >= 50 * TICKS_PER_MINUTE) {
|
||||
showAtSecondsLeft = 40;
|
||||
} else if (runtimeTicks >= 40 * TICKS_PER_MINUTE) {
|
||||
showAtSecondsLeft = 35;
|
||||
}
|
||||
const showAtTicks = runtimeTicks - showAtSecondsLeft * TICKS_PER_SECOND;
|
||||
const timeRemainingTicks = runtimeTicks - currentTimeTicks;
|
||||
|
||||
if (currentTimeTicks >= showAtTicks && runtimeTicks >= 6e9 && timeRemainingTicks >= 2e8) {
|
||||
if (currentTimeTicks >= showAtTicks && runtimeTicks >= (10 * TICKS_PER_MINUTE) && timeRemainingTicks >= (20 * TICKS_PER_SECOND)) {
|
||||
showComingUpNext(player);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ import autoFocuser from '../../components/autoFocuser';
|
|||
SortOrder: 'Descending',
|
||||
IncludeItemTypes: 'Episode',
|
||||
Filters: 'IsResumable',
|
||||
Limit: screenWidth >= 1920 ? 5 : screenWidth >= 1600 ? 5 : 3,
|
||||
Limit: screenWidth >= 1600 ? 5 : 3,
|
||||
Recursive: true,
|
||||
Fields: 'PrimaryImageAspectRatio,MediaSourceCount,BasicSyncInfo',
|
||||
CollapseBoxSetItems: false,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<div>${QuickConnectDescription}</div>
|
||||
<br />
|
||||
<div class="inputContainer">
|
||||
<input is="emby-input" type="number" min="0" max="999999" required id="txtQuickConnectCode" label="${LabelQuickConnectCode}" autocomplete="off" />
|
||||
<input is="emby-input" type="text" inputmode="numeric" pattern="[0-9\s]*" minlength="6" required id="txtQuickConnectCode" label="${LabelQuickConnectCode}" autocomplete="off" />
|
||||
</div>
|
||||
<button id="btnQuickConnectAuthorize" is="emby-button" type="submit" class="raised button-submit block">
|
||||
<span>${Authorize}</span>
|
||||
|
|
|
@ -15,7 +15,9 @@ export default function (view) {
|
|||
return;
|
||||
}
|
||||
|
||||
authorize(codeElement.value);
|
||||
// Remove spaces from code
|
||||
const normalizedCode = codeElement.value.replace(/\s/g, '');
|
||||
authorize(normalizedCode);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue