From a890894fb851b45764aea61542db3c366c5c46d5 Mon Sep 17 00:00:00 2001 From: HighImKevin Date: Wed, 28 Jan 2026 22:59:38 -0500 Subject: [PATCH] Update logic related to rendering home sections into the .sections container --- scripts/homeScreen.css | 18 ++++++++++------ scripts/homeScreen3.js | 49 +++++++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/scripts/homeScreen.css b/scripts/homeScreen.css index 73d0079..e3acf03 100644 --- a/scripts/homeScreen.css +++ b/scripts/homeScreen.css @@ -152,7 +152,7 @@ div#discovery-loading-indicator:not(.show)::after { display: block; visibility: visible; order: 99998 !important; - margin: 0 auto; + margin: 2em auto; } .sections.loading-discovery .load-more-discovery-btn { @@ -200,20 +200,20 @@ div#discovery-loading-indicator:not(.show)::after { } /* Hide next up section if next up if KefinTweaks next up section is present */ -.homeSectionsContainer:has([data-section-id="nextUp"]) > div:nth-child(-n+10):has(a[href*="nextup"]) { +/* .homeSectionsContainer:has([data-section-id="nextUp"]) > div:nth-child(-n+10):has(a[href*="nextup"]) { display: none; -} +} */ /* Hide continue watching section if continue watching if KefinTweaks continue watching section is present */ -.homeSectionsContainer:has([data-section-id="continueWatching"]) > div:nth-child(-n+10):has([data-positionticks][data-mediatype="Video"]) { +/* .homeSectionsContainer:has([data-section-id="continueWatching"]) > div:nth-child(-n+10):has([data-positionticks][data-mediatype="Video"]) { display: none; -} +} */ /* Hide recently added section if recently added if KefinTweaks recently added section is present */ -.homeSectionsContainer:has([data-section-id*="recently-added"]) > div:nth-child(-n+10):has(a[href*="movies&tab=1"]), +/* .homeSectionsContainer:has([data-section-id*="recently-added"]) > div:nth-child(-n+10):has(a[href*="movies&tab=1"]), .homeSectionsContainer:has([data-section-id*="recently-added"]) > div:nth-child(-n+10):has(a[href*="tv&tab=1"]), .homeSectionsContainer:has([data-section-id*="recently-added"]) > div:nth-child(-n+10):has(a[href*="music&tab=1"]) { display: none; -} +} */ /* Hide scroll buttons on mobile and tablet layouts */ @media (max-width: 768px) { @@ -275,4 +275,8 @@ div#discovery-loading-indicator:not(.show)::after { .homeSectionsContainer [data-section-id="popularTVNetworks"] .card .cardText { visibility: hidden; +} + +.homeSectionsContainer:not(.kefinHomeSectionsContainer) { + display: none !important; } \ No newline at end of file diff --git a/scripts/homeScreen3.js b/scripts/homeScreen3.js index 4f62777..4ac275c 100644 --- a/scripts/homeScreen3.js +++ b/scripts/homeScreen3.js @@ -316,13 +316,26 @@ if (window.migrateHomeScreenConfig) { await window.migrateHomeScreenConfig(); } - + const container = document.querySelector('.homePage:not(.hide) #homeTab .sections'); if (!container) { LOG('Home sections container not found'); return; } + // Create Kefin home sections container as a sibling of the Jellyfin sections container + let kefinHomeSectionsContainer = document.querySelector('.homePage:not(.hide) #homeTab .kefinHomeSectionsContainer'); + if (!kefinHomeSectionsContainer) { + kefinHomeSectionsContainer = document.createElement('div'); + kefinHomeSectionsContainer.className = 'sections homeSectionsContainer kefinHomeSectionsContainer'; + if (container.parentNode) { + container.parentNode.insertBefore(kefinHomeSectionsContainer, container.nextSibling); + } else { + LOG('Sections container has no parent node; appending Kefin container to body as fallback'); + document.body.appendChild(kefinHomeSectionsContainer); + } + } + // If we've already initialized and Jellyfin has completed its render, avoid re-running if (container.dataset.kefinHomeScreen && sectionCache.jellyfinHasRendered) { LOG('Home screen already initialized and Jellyfin has rendered'); @@ -390,28 +403,40 @@ // Set flag to indicate we've started initializing this container container.dataset.kefinHomeScreen = 'true'; - // Set up mutation observer BEFORE rendering, so we can react when Jellyfin overwrites the container + // Set up mutation observer BEFORE rendering, so we can react when Jellyfin renders home sections const handleJellyfinRender = async () => { - if (!container.dataset.sectionsPrerendered) { - LOG('Jellyfin rendering detected, sections not pre-rendered yet, skipping'); + const jellyHome = document.querySelector('.homePage:not(.hide) #homeTab .homeSectionsContainer'); + const kefinHome = document.querySelector('.homePage:not(.hide) #homeTab .kefinHomeSectionsContainer'); + + if (!jellyHome || !kefinHome) { + LOG('Jellyfin render detected but required containers not found; skipping Jellyfin section mirroring'); return; } - LOG('Jellyfin rendering detected, re-rendering from cache'); - await renderHomeSections(filteredHomeSections, container, true); // useCache = true - await setupDiscoveryInteraction(container); + // Remove any previously cloned Jellyfin sections from our container + kefinHome.querySelectorAll('[data-jellyfin-section-clone="true"]').forEach(el => el.remove()); + + // Copy Jellyfin .sectionN containers into the Kefin container + const jellySections = jellyHome.querySelectorAll('.section0, .section1, .section2, .section3, .section4, .section5, .section6, .section7, .section8'); + + jellySections.forEach(sectionEl => { + const clone = sectionEl.cloneNode(true); + clone.dataset.jellyfinSectionClone = 'true'; + kefinHome.appendChild(clone); + }); + performanceMetrics.recoveryRenderEnd = performance.now(); if (performanceMetrics.jellyfinDetected) { - LOG(`Home Screen v3 recovery render duration: ${(performanceMetrics.recoveryRenderEnd - performanceMetrics.jellyfinDetected).toFixed(2)}ms`); + LOG(`Home Screen v3 Jellyfin section mirroring duration: ${(performanceMetrics.recoveryRenderEnd - performanceMetrics.jellyfinDetected).toFixed(2)}ms`); } }; const observer = observeContainerMutations(container, handleJellyfinRender); - // Initial render directly into .sections (no waiting for Jellyfin) + // Initial render directly into Kefin container (no waiting for Jellyfin) performanceStartTime = performance.now(); LOG('Rendering Standard/Seasonal Sections (initial render)...'); - await renderHomeSections(filteredHomeSections, container, false); + await renderHomeSections(filteredHomeSections, kefinHomeSectionsContainer, false); performanceEndTime = performance.now(); performanceDuration = performanceEndTime - performanceStartTime; LOG(`Home Screen v3 Render home sections (initial) initialization time: ${performanceDuration.toFixed(2)}ms`); @@ -422,7 +447,7 @@ LOG(`Home Screen v3 load time initialization: ${(performanceTimer.loadTimeEnd - performanceTimer.loadTimeStart).toFixed(2)}ms`); LOG('Initializing Discovery Sections...'); - await setupDiscoveryInteraction(container); + await setupDiscoveryInteraction(kefinHomeSectionsContainer); // If Jellyfin hasn't rendered after 5 seconds, assume it won't and clean up the observer setTimeout(() => { @@ -1943,7 +1968,7 @@ const activeTab = document.querySelector('.headerTabs .emby-tab-button-active').getAttribute('data-index'); if (activeTab !== '0') return; - const activeContainer = document.querySelector('.libraryPage:not(.hide) .homeSectionsContainer'); + const activeContainer = document.querySelector('.libraryPage:not(.hide) .kefinHomeSectionsContainer'); if (!activeContainer) return;