diff --git a/configuration/homeScreen-configuration.js b/configuration/homeScreen-configuration.js index 5f49877..2b060a8 100644 --- a/configuration/homeScreen-configuration.js +++ b/configuration/homeScreen-configuration.js @@ -1008,20 +1008,7 @@ } const browseSection = studiosGroup.sections.find((s) => s?.id === BROWSE_BY_STUDIO_SECTION_ID); - const catalogNames = new Set(BROWSE_BY_STUDIO_CATALOG.map((entry) => entry.name)); - - // Prune items no longer in Kefin catalog (even when catalog is otherwise fully resolved) - if (browseSection && Array.isArray(browseSection.items)) { - const beforeLen = browseSection.items.length; - browseSection.items = browseSection.items.filter( - (item) => item?.Name && catalogNames.has(item.Name) - ); - if (browseSection.items.length !== beforeLen) { - hasChanges = true; - LOG(`Pruned ${beforeLen - browseSection.items.length} browse-by-studio studios not in catalog`); - } - } - + // Append-only: do not prune user-kept studios that leave the Kefin catalog const existingItems = Array.isArray(browseSection?.items) ? browseSection.items : []; if (browseSection && isBrowseByStudioCatalogFullyResolved(existingItems)) { diff --git a/configuration/homeScreenAdvancedEditor.css b/configuration/homeScreenAdvancedEditor.css index 2787297..a51aa75 100644 --- a/configuration/homeScreenAdvancedEditor.css +++ b/configuration/homeScreenAdvancedEditor.css @@ -563,8 +563,9 @@ display: flex; flex-wrap: wrap; gap: 1em; - justify-content: center; + justify-content: start; padding: 0.5em 0 1em; + align-items: center; } :is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) .hsse-custom-item-tile, @@ -576,6 +577,68 @@ gap: 0.35em; } +.hsse-custom-items-grid > * { + max-width: 120px; +} +.listItemBodyText.hsse-custom-item-tile-label { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 1; +} +.hsse-custom-item-edit-badge { + position: absolute; + bottom: 0.2em; + right: 0.2em; +} +.hsse-custom-item-actions > * { + height: 25px; + width: 25px; + display: flex; + justify-content: center; +} + +:is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) + .hsse-custom-item-tile.is-hidden + .hsse-custom-item-tile-image, +:is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) + .hsse-custom-item-tile.is-hidden + .hsse-custom-item-tile-label { + opacity: 0.4; + filter: grayscale(0.35); +} + +:is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) + .hsse-custom-item-actions { + display: flex; + align-items: center; + justify-content: center; + gap: 0.2em; +} + +:is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) + .hsse-custom-item-action, +:is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) + .hsse-custom-item-trash { + font-size: 0; + padding: 0.3em; + min-height: 0; + min-width: 0; + line-height: 1; +} + +:is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) + .hsse-custom-item-action:disabled { + opacity: 0.35; + cursor: default; +} + +:is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) + .hsse-custom-item-action-icon, +:is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) + .hsse-custom-item-trash-icon { + font-size: 1.1rem; +} + :is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) .hsse-custom-item-tile-image, :is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) .hsse-custom-item-add-tile { width: auto; @@ -1598,7 +1661,7 @@ display: grid !important; } -/* Item source — show only the panel matching the active source (profile rules still gate custom items on non-full profiles) */ +/* Item source — show only the panel matching the active source */ .hsae-root[data-item-source="jellyfin"] .hsae-custom-items-group, .hsae-root[data-item-source="jellyfin"] .hsae-external-list-group { display: none !important; @@ -1660,6 +1723,7 @@ } .hsse-image-preview img { - height: 200px; + height: 120px; + max-width: 120px; width: auto !important; } \ No newline at end of file diff --git a/configuration/homeScreenAdvancedEditor.js b/configuration/homeScreenAdvancedEditor.js index 7bbf4c9..fbc6b27 100644 --- a/configuration/homeScreenAdvancedEditor.js +++ b/configuration/homeScreenAdvancedEditor.js @@ -656,6 +656,23 @@ return window.KefinHomeScreenCustomItemsEditor; } + /** User-created / custom-group sections may delete items; default Kefin sections may only hide. */ + function shouldAllowCustomItemRemove(state) { + const id = state?.section?.id || ''; + if (state?.context?.isCustomSection === true) return true; + if (state?.section?.isCustom === true) return true; + if (id.startsWith('custom-')) return true; + return false; + } + + function getAdvancedCustomItemsOptions(state) { + const customEditor = getCustomItemsEditor(); + if (!customEditor?.getCustomItemsOptions) return {}; + return customEditor.getCustomItemsOptions({ + allowRemove: shouldAllowCustomItemRemove(state) + }); + } + function getCachePresets() { const cache = window.KefinHomeConfig2?.CACHE || window.KefinHomeConfig2?.CACHE_CONFIG || {}; return [ @@ -1110,7 +1127,7 @@ const customEditor = getCustomItemsEditor(); if (customEditor && state.itemSource === 'custom') { - customEditor.collectCustomItemsFromForm(root, state, customEditor.getCustomItemsOptions()); + customEditor.collectCustomItemsFromForm(root, state, getAdvancedCustomItemsOptions(state)); } if (state.itemSource === 'external') { @@ -1863,15 +1880,19 @@ function buildCustomItemsHTML(state) { const customEditor = getCustomItemsEditor(); + const allowRemove = shouldAllowCustomItemRemove(state); const html = customEditor - ? customEditor.renderCustomItemsHTML(state, customEditor.getCustomItemsOptions()) + ? customEditor.renderCustomItemsHTML(state, getAdvancedCustomItemsOptions(state)) : '
Name and poster required. Link and other images optional.