diff --git a/src/assets/css/librarybrowser.scss b/src/assets/css/librarybrowser.scss index d9c2b9118a..d5020a1006 100644 --- a/src/assets/css/librarybrowser.scss +++ b/src/assets/css/librarybrowser.scss @@ -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 { diff --git a/src/controllers/dashboard/library.js b/src/controllers/dashboard/library.js index faea38bb34..24e7a477d1 100644 --- a/src/controllers/dashboard/library.js +++ b/src/controllers/dashboard/library.js @@ -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) { diff --git a/src/controllers/dashboard/plugins/available/index.html b/src/controllers/dashboard/plugins/available/index.html index 6c9b89c26d..68567db744 100644 --- a/src/controllers/dashboard/plugins/available/index.html +++ b/src/controllers/dashboard/plugins/available/index.html @@ -1,6 +1,9 @@
+
+ +
${MessageNoAvailablePlugins}
diff --git a/src/controllers/dashboard/plugins/available/index.js b/src/controllers/dashboard/plugins/available/index.js index b10518bc74..095bbb8659 100644 --- a/src/controllers/dashboard/plugins/available/index.js +++ b/src/controllers/dashboard/plugins/available/index.js @@ -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; diff --git a/src/controllers/dashboard/plugins/installed/index.html b/src/controllers/dashboard/plugins/installed/index.html index d2b11592e9..4aedb8a9de 100644 --- a/src/controllers/dashboard/plugins/installed/index.html +++ b/src/controllers/dashboard/plugins/installed/index.html @@ -1,6 +1,9 @@
+
+ +
diff --git a/src/controllers/dashboard/plugins/installed/index.js b/src/controllers/dashboard/plugins/installed/index.js index b8ddbbbf85..13d0132c94 100644 --- a/src/controllers/dashboard/plugins/installed/index.js +++ b/src/controllers/dashboard/plugins/installed/index.js @@ -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 += '
'; } + // 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); diff --git a/src/controllers/session/selectServer/index.js b/src/controllers/session/selectServer/index.js index 75a0b0789d..3db27beb1f 100644 --- a/src/controllers/session/selectServer/index.js +++ b/src/controllers/session/selectServer/index.js @@ -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 = ''; - } else { - cardImageContainer = '
'; - } - // TODO move card creation code to Card component - + const cardImageContainer = ''; let cssClass = 'card overflowSquareCard loginSquareCard scalableCard overflowSquareCard-scalable'; if (layoutManager.tv) { diff --git a/src/controllers/user/menu/index.html b/src/controllers/user/menu/index.html index 2741f89282..1c83bd9d68 100644 --- a/src/controllers/user/menu/index.html +++ b/src/controllers/user/menu/index.html @@ -14,7 +14,7 @@
- +
${QuickConnect}
@@ -98,7 +98,7 @@

${HeaderUser}

- +
${SelectServer}
diff --git a/src/components/castSenderApi.js b/src/plugins/chromecastPlayer/castSenderApi.js similarity index 100% rename from src/components/castSenderApi.js rename to src/plugins/chromecastPlayer/castSenderApi.js diff --git a/src/plugins/chromecastPlayer/plugin.js b/src/plugins/chromecastPlayer/plugin.js index ca362c2c80..9044cd3e30 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -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'; diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js index 6065d9a8d5..3afc730c33 100644 --- a/src/scripts/libraryMenu.js +++ b/src/scripts/libraryMenu.js @@ -325,7 +325,7 @@ import '../assets/css/flexstyles.scss'; html += ''; if (appHost.supports('multiserver')) { - html += `
${globalize.translate('SelectServer')}`; + html += `${globalize.translate('SelectServer')}`; } html += `${globalize.translate('Settings')}`; diff --git a/src/strings/cs.json b/src/strings/cs.json index 0eb7979241..1b0a122ca6 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -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í." } diff --git a/src/strings/en-us.json b/src/strings/en-us.json index af4478dff3..4fa437b462 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -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.", diff --git a/src/strings/fr.json b/src/strings/fr.json index 41fdac284c..7503627e46 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -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." } diff --git a/src/strings/uk.json b/src/strings/uk.json index 25ced73697..572609eb10 100644 --- a/src/strings/uk.json +++ b/src/strings/uk.json @@ -582,7 +582,7 @@ "Image": "Зображення", "Identify": "Ідентифікувати", "Horizontal": "Горизонтально", - "Home": "Домівка", + "Home": "Головна", "HideWatchedContentFromLatestMedia": "Приховати переглянуте з останніх медіа", "Hide": "Приховати", "Help": "Допомога", diff --git a/webpack.common.js b/webpack.common.js index d1b7a22946..e820878021 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -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]}`; }