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

Merge branch 'jellyfin:master' into add/device-logos

This commit is contained in:
photonconvergence 2022-10-25 17:25:30 -07:00 committed by GitHub
commit 7ab1edd3c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 70 additions and 20 deletions

View file

@ -305,10 +305,16 @@
right: 0;
bottom: 0;
left: 0;
pointer-events: none;
[dir="rtl"] & {
transition: right ease-in-out 0.3s, padding ease-in-out 0.3s;
}
> .page {
// Fix pointer events being swallowed by the react root when a dashboard page is not rendered by react
pointer-events: all;
}
}
.centerMessage {

View file

@ -77,6 +77,7 @@ import cardBuilder from '../../components/cardbuilder/cardBuilder';
import('../../components/prompt/prompt').then(({default: prompt}) => {
prompt({
label: globalize.translate('LabelNewName'),
description: globalize.translate('MessageRenameMediaFolder'),
confirmText: globalize.translate('ButtonRename')
}).then(function (newName) {
if (newName && newName != virtualFolder.Name) {

View file

@ -1,6 +1,9 @@
<div id="pluginCatalogPage" data-role="page" class="page type-interior pluginConfigurationPage withTabs fullWidthContent">
<div>
<div class="content-primary">
<div class="inputContainer">
<input id="txtSearchPlugins" name="txtSearchPlugins" type="text" is="emby-input" label="${Search}" />
</div>
<div id="noPlugins" class="hide">${MessageNoAvailablePlugins}</div>
<div id="pluginTiles" style="text-align:left;"></div>
</div>

View file

@ -86,10 +86,37 @@ function populateList(options) {
options.noItemsElement.classList.remove('hide');
}
const searchBar = document.getElementById('txtSearchPlugins');
if (searchBar) {
searchBar.addEventListener('input', () => onSearchBarType(searchBar));
}
options.catalogElement.innerHTML = html;
loading.hide();
}
function onSearchBarType(searchBar) {
const filter = searchBar.value.toLowerCase();
for (const header of document.querySelectorAll('div .verticalSection')) {
// keep track of shown cards after each search
let shown = 0;
for (const card of header.querySelectorAll('div .card')) {
if (filter && filter != '' && !card.textContent.toLowerCase().includes(filter)) {
card.style.display = 'none';
} else {
card.style.display = 'unset';
shown++;
}
}
// hide title if no cards are shown
if (shown <= 0) {
header.style.display = 'none';
} else {
header.style.display = 'unset';
}
}
}
function getPluginHtml(plugin, options, installedPlugins) {
let html = '';
let href = plugin.externalUrl ? plugin.externalUrl : '#/addplugin.html?name=' + encodeURIComponent(plugin.name) + '&guid=' + plugin.guid;

View file

@ -1,6 +1,9 @@
<div id="pluginsPage" data-role="page" class="page type-interior pluginConfigurationPage withTabs fullWidthContent">
<div>
<div class="content-primary">
<div class="inputContainer">
<input id="txtSearchPlugins" name="txtSearchPlugins" type="text" is="emby-input" label="${Search}" />
</div>
<div class="installedPlugins"></div>
</div>
</div>

View file

@ -112,7 +112,6 @@ function populateList(page, plugins, pluginConfigurationPages) {
if (plugin1.Name > plugin2.Name) {
return 1;
}
return -1;
});
@ -136,6 +135,12 @@ function populateList(page, plugins, pluginConfigurationPages) {
html += '</div>';
}
// add search box listener
const searchBar = page.querySelector('#txtSearchPlugins');
if (searchBar) {
searchBar.addEventListener('input', () => onFilterType(page, searchBar));
}
installedPluginsElement.innerHTML = html;
loading.hide();
}
@ -239,6 +244,17 @@ function onInstalledPluginsClick(e) {
}
}
function onFilterType(page, searchBar) {
const filter = searchBar.value.toLowerCase();
for (const card of page.querySelectorAll('.card')) {
if (filter && filter != '' && !card.textContent.toLowerCase().includes(filter)) {
card.style.display = 'none';
} else {
card.style.display = 'unset';
}
}
}
pageIdOn('pageshow', 'pluginsPage', function () {
libraryMenu.setTabs('plugins', 0, getTabs);
reloadList(this);

View file

@ -28,24 +28,15 @@ import cardBuilder from '../../../components/cardbuilder/cardBuilder';
const items = servers.map(function (server) {
return {
name: server.Name,
showIcon: true,
icon: 'cast',
icon: 'storage',
cardType: '',
id: server.Id,
server: server
};
});
let html = items.map(function (item) {
let cardImageContainer;
if (item.showIcon) {
cardImageContainer = '<span class="cardImageIcon material-icons ' + item.icon + '" aria-hidden="true"></span>';
} else {
cardImageContainer = '<div class="cardImage" style="' + item.cardImageStyle + '"></div>';
}
// TODO move card creation code to Card component
const cardImageContainer = '<span class="cardImageIcon material-icons ' + item.icon + '" aria-hidden="true"></span>';
let cssClass = 'card overflowSquareCard loginSquareCard scalableCard overflowSquareCard-scalable';
if (layoutManager.tv) {

View file

@ -14,7 +14,7 @@
<a is="emby-linkbutton" data-ripple="false" href="#" style="display:block;padding:0;margin:0;" class="lnkQuickConnectPreferences listItem-border hide">
<div class="listItem">
<span class="material-icons listItemIcon listItemIcon-transparent tap_and_play" aria-hidden="true"></span>
<span class="material-icons listItemIcon listItemIcon-transparent phonelink_lock" aria-hidden="true"></span>
<div class="listItemBody">
<div class="listItemBodyText">${QuickConnect}</div>
</div>
@ -98,7 +98,7 @@
<h2 class="sectionTitle" style="padding-left:.25em;">${HeaderUser}</h2>
<a is="emby-linkbutton" data-ripple="false" href="#" style="display:block;padding:0;margin:0;" class="selectServer hide listItem-border">
<div class="listItem">
<span class="material-icons listItemIcon listItemIcon-transparent wifi" aria-hidden="true"></span>
<span class="material-icons listItemIcon listItemIcon-transparent storage" aria-hidden="true"></span>
<div class="listItemBody">
<div class="listItemBodyText">${SelectServer}</div>
</div>

View file

@ -2,7 +2,7 @@ import appSettings from '../../scripts/settings/appSettings';
import * as userSettings from '../../scripts/settings/userSettings';
import { playbackManager } from '../../components/playback/playbackmanager';
import globalize from '../../scripts/globalize';
import castSenderApiLoader from '../../components/castSenderApi';
import castSenderApiLoader from './castSenderApi';
import ServerConnections from '../../components/ServerConnections';
import alert from '../../components/alert';
import Events from '../../utils/events.ts';

View file

@ -325,7 +325,7 @@ import '../assets/css/flexstyles.scss';
html += '</h3>';
if (appHost.supports('multiserver')) {
html += `<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder btnSelectServer" data-itemid="selectserver" href="#"><span class="material-icons navMenuOptionIcon wifi" aria-hidden="true"></span><span class="navMenuOptionText">${globalize.translate('SelectServer')}</span></a>`;
html += `<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder btnSelectServer" data-itemid="selectserver" href="#"><span class="material-icons navMenuOptionIcon storage" aria-hidden="true"></span><span class="navMenuOptionText">${globalize.translate('SelectServer')}</span></a>`;
}
html += `<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder btnSettings" data-itemid="settings" href="#"><span class="material-icons navMenuOptionIcon settings" aria-hidden="true"></span><span class="navMenuOptionText">${globalize.translate('Settings')}</span></a>`;

View file

@ -1679,5 +1679,6 @@
"IgnoreDtsHelp": "Vypnutím se mohou vyřešit některé problémy, např. chybějící zvuk u kanálů s oddělenými zvukovými a video stopami.",
"IgnoreDts": "Ignorovat DTS (časové razítko dekódování)",
"OptionDateEpisodeAdded": "Datum přidání epizody",
"OptionDateShowAdded": "Datum přidání pořadu"
"OptionDateShowAdded": "Datum přidání pořadu",
"MessageRenameMediaFolder": "Přejmenování knihovny médií způsobí ztrátu všech metadat, postupujte proto s opatrností."
}

View file

@ -1085,6 +1085,7 @@
"MessagePluginInstalled": "The plugin has been successfully installed. The server will need to be restarted for changes to take effect.",
"MessagePluginInstallError": "An error occurred while installing the plugin.",
"MessageReenableUser": "See below to reenable",
"MessageRenameMediaFolder": "Renaming a media library will cause all metadata to be lost, proceed with caution.",
"MessageSent": "Message sent.",
"MessageSyncPlayCreateGroupDenied": "Permission required to create a group.",
"MessageSyncPlayDisabled": "SyncPlay disabled.",

View file

@ -1679,5 +1679,6 @@
"IgnoreDtsHelp": "La désactivation de cette option peut résoudre certains problèmes, par ex. audio manquant sur les canaux avec des flux audio et vidéo séparés.",
"OptionDateShowAdded": "Date d'ajout de la série",
"OptionDateEpisodeAdded": "Date d'ajout de l'épisode",
"IgnoreDts": "Ignorer DTS (horodatage de décodage)"
"IgnoreDts": "Ignorer DTS (horodatage de décodage)",
"MessageRenameMediaFolder": "Renommer une médiathèque entraînera la perte de toutes les métadonnées, procédez avec prudence."
}

View file

@ -582,7 +582,7 @@
"Image": "Зображення",
"Identify": "Ідентифікувати",
"Horizontal": "Горизонтально",
"Home": "Домівка",
"Home": "Головна",
"HideWatchedContentFromLatestMedia": "Приховати переглянуте з останніх медіа",
"Hide": "Приховати",
"Help": "Допомога",

View file

@ -109,7 +109,7 @@ const config = {
if (packageName.startsWith('@')) {
const parts = module.context
.substring(module.context.lastIndexOf(packageName))
.split('/');
.split(/[\\/]/);
return `node_modules.${parts[0]}.${parts[1]}`;
}