From fedd9195018fb13287101d8ca74dda2196f48c83 Mon Sep 17 00:00:00 2001 From: HighImKevin Date: Sat, 6 Dec 2025 21:06:23 -0500 Subject: [PATCH] Add the ability to select a Render Mode for Home Screen sections: Normal, Spotlight, Random --- scripts/configuration.js | 19 +++++--- scripts/homeScreen.js | 97 +++++++++++++--------------------------- 2 files changed, 46 insertions(+), 70 deletions(-) diff --git a/scripts/configuration.js b/scripts/configuration.js index 761bfae..b9025c7 100644 --- a/scripts/configuration.js +++ b/scripts/configuration.js @@ -1180,6 +1180,7 @@ const cardFormat = section.cardFormat || 'Poster'; const order = section.order || 100; const spotlightEnabled = section.spotlight === true; + const renderMode = section.renderMode || (spotlightEnabled ? 'Spotlight' : 'Normal'); const discoveryEnabled = section.discoveryEnabled === true; const searchTerm = section.searchTerm || ''; const includeItemTypes = Array.isArray(section.includeItemTypes) ? section.includeItemTypes : (section.includeItemTypes ? section.includeItemTypes.split(',').map(s => s.trim()).filter(Boolean) : (type === 'Parent' ? [] : ['Movie'])); @@ -1269,15 +1270,19 @@ if (useImprovedLayout) { // Custom sections: Row 1 (checkboxes + type), Row 2 (source), Row 3+ (remaining fields in 3 columns) sectionContent = ` - +
Enabled
${buildJellyfinCheckbox(`${prefix}_section_enabled_${sectionIndex}`, enabled, '', { 'data-section-index': sectionIndex, 'data-prefix': prefix, 'class': `${prefix}_section_enabled` })}
-
Spotlight
- ${buildJellyfinCheckbox(spotlightCheckboxId, spotlightEnabled, 'Enable Spotlight', { 'data-section-index': sectionIndex, 'data-prefix': prefix, 'class': `${prefix}_section_spotlight` })} +
Render Mode
+
Discovery
@@ -4760,9 +4765,12 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`; const sortOrderDirection = sectionItem.querySelector(`#${prefix}_section_${sanitizedIndex}_sortOrderDirection`)?.value || 'Ascending'; const cardFormat = sectionItem.querySelector(`#${prefix}_section_${sanitizedIndex}_cardFormat`)?.value || 'Poster'; const order = parseInt(sectionItem.querySelector(`#${prefix}_section_${sanitizedIndex}_order`)?.value || '100', 10); - const spotlightCheckbox = sectionItem.querySelector(`#${prefix}_section_${sanitizedIndex}_spotlight`) || sectionItem.querySelector(`.${prefix}_section_spotlight[data-section-index="${sectionIndex}"]`); + + const renderModeSelect = sectionItem.querySelector(`.${prefix}_section_renderMode[data-section-index="${sectionIndex}"]`); + const renderMode = renderModeSelect ? renderModeSelect.value : 'Normal'; + const spotlight = renderMode === 'Spotlight'; // Legacy compatibility + const discoveryCheckbox = sectionItem.querySelector(`#${prefix}_section_${sanitizedIndex}_discovery`) || sectionItem.querySelector(`.${prefix}_section_discovery[data-section-index="${sectionIndex}"]`); - const spotlight = spotlightCheckbox?.checked === true; const discoveryEnabled = discoveryCheckbox?.checked === true; const searchTerm = sectionItem.querySelector(`#${prefix}_section_${sanitizedIndex}_searchTerm`)?.value?.trim() || ''; @@ -4809,6 +4817,7 @@ window.KefinTweaksConfig = ${JSON.stringify(config, null, 2)};`; sortOrderDirection: sortOrderDirection, cardFormat: cardFormat, order: order, + renderMode: renderMode, spotlight: spotlight, discoveryEnabled: discoveryEnabled, searchTerm: searchTerm, diff --git a/scripts/homeScreen.js b/scripts/homeScreen.js index 2a044c0..c2bfb95 100644 --- a/scripts/homeScreen.js +++ b/scripts/homeScreen.js @@ -1326,68 +1326,20 @@ */ async function renderCustomSection(section, container) { try { - // Support new structure (type + source) and legacy structure (sourceId) - const type = section.type; - const source = section.source || section.sourceId || section.id; + // Support legacy structure (sourceId/id without source) + // Create a copy to avoid mutating the original config object + const sectionConfig = { ...section }; - if (!source) { - ERR(`No source provided for section ${section.name}`); - return false; +/* if (!sectionConfig.source && (sectionConfig.sourceId || sectionConfig.id)) { + sectionConfig.source = sectionConfig.sourceId || sectionConfig.id; + } */ + + // Ensure ID exists for renderSection + if (!sectionConfig.id) { + sectionConfig.id = sectionConfig.source; } - const sortOrder = section.sortOrder ?? defaultSortOrder; - const sortOrderDirection = section.sortOrderDirection ?? 'Ascending'; - const cardFormat = section.cardFormat ?? defaultCardFormat; - const order = section.order ?? 100; - const useSpotlight = section.spotlight === true; - - let viewMoreUrl = null; - switch (type) { - case 'Genre': - viewMoreUrl = `#/list.html?genreId=${source}&serverId=${ApiClient.serverId()}`; - break; - case 'Studio': - viewMoreUrl = `#/list.html?studioId=${source}&serverId=${ApiClient.serverId()}`; - break; - case 'Playlist': - case 'BoxSet': - viewMoreUrl = `#/details?id=${source}&serverId=${ApiClient.serverId()}`; - break; - case 'Parent': - viewMoreUrl = `#/list.html?parentId=${source}&serverId=${ApiClient.serverId()}`; - break; - default: - viewMoreUrl = null; - break; - } - - // If new structure with type, use renderSection helper - if (useSpotlight && window.cardBuilder.renderSpotlightSection) { - const items = await loadItemsForSectionConfig(section); - - const spotlightContainer = window.cardBuilder.renderSpotlightSection( - items, - section.name ?? 'Spotlight', - { - autoPlay: spotlightAutoPlay, - interval: spotlightInterval, - showDots: spotlightShowDots, - showNavButtons: spotlightShowNavButtons, - showClearArt: spotlightShowClearArt, - viewMoreUrl: viewMoreUrl - } - ); - - spotlightContainer.setAttribute('data-custom-section-id', section.id || source); - spotlightContainer.setAttribute('data-custom-section-name', section.name); - spotlightContainer.setAttribute('data-custom-section-type', type); - spotlightContainer.style.order = order; - - container.appendChild(spotlightContainer); - return true; - } - - return await renderSection(section, container, 'custom'); + return await renderSection(sectionConfig, container, 'custom'); } catch (err) { ERR(`Error rendering section ${section.name}:`, err); return false; @@ -5660,21 +5612,33 @@ let cardContainer = null; - if (sectionConfig.spotlight === true) { + // Render Mode Logic + const renderMode = sectionConfig.renderMode || (sectionConfig.spotlight ? 'Spotlight' : 'Normal'); + let useSpotlight = renderMode === 'Spotlight'; + + if (renderMode === 'Random') { + useSpotlight = Math.random() < 0.5; + } + + if (useSpotlight) { if (!window.cardBuilder || !window.cardBuilder.renderSpotlightSection) { WARN("cardBuilder.renderSpotlightSection not available"); return false; } + // Use global spotlight config if available + const homeScreenConfig = window.KefinTweaksConfig?.homeScreen || {}; + const spotlightConfig = homeScreenConfig.spotlight || {}; + cardContainer = window.cardBuilder.renderSpotlightSection( limited, sectionConfig.name, { - autoPlay: true, - interval: 5000, - showDots: true, - showNavButtons: true, - showClearArt: true, + autoPlay: spotlightConfig.autoPlay ?? true, + interval: spotlightConfig.interval ?? 5000, + showDots: spotlightConfig.showDots ?? true, + showNavButtons: spotlightConfig.showNavButtons ?? true, + showClearArt: spotlightConfig.showClearArt ?? true, viewMoreUrl: viewMoreUrl } ); @@ -5697,6 +5661,9 @@ cardContainer.setAttribute('data-custom-section-id', sectionId); cardContainer.setAttribute('data-custom-section-name', sectionConfig.name); + if (sectionConfig.type) { + cardContainer.setAttribute('data-custom-section-type', sectionConfig.type); + } cardContainer.style.order = order; container.appendChild(cardContainer);