mirror of
https://github.com/ranaldsgift/KefinTweaks.git
synced 2026-11-05 15:52:47 +01:00
Improve Home Screen configuration and add functionality to hide the mobile Category Home rail on scroll
This commit is contained in:
1 parent
f8bce09895
commit
281514aae3
6 files changed
+413
-211
No files matched your search
@@ -74,13 +74,18 @@
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
[data-modal-id="kefin-homescreen-config-main"] div#section-content {
|
||||
[data-modal-id="kefin-homescreen-config-main"] div#section-content,
|
||||
[data-modal-id="kefin-homescreen-config-main"] div#global-settings-content,
|
||||
[data-modal-id="kefin-homescreen-config-main"] #home-screen-benchmark-root {
|
||||
max-height: calc(90vh - 19em);
|
||||
overflow: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
[data-modal-id="kefin-homescreen-config-main"] #section-content > div > div:last-child {
|
||||
margin-bottom: 6em;
|
||||
|
||||
[data-modal-id="kefin-homescreen-config-main"] div#global-settings-content > *:last-child,
|
||||
[data-modal-id="kefin-homescreen-config-main"] #home-screen-benchmark-root > *:last-child,
|
||||
[data-modal-id="kefin-homescreen-config-main"] #section-content > div > *:last-child {
|
||||
margin-bottom: 4em !important;
|
||||
}
|
||||
|
||||
div#order-sections-container .editable-group-name {
|
||||
@@ -364,3 +369,18 @@ span.listItemBodyText.secondary.seasonal-tag {
|
||||
.section-row-actions .btnSectionConfigure {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dialogContainer[data-modal-id="kefin-homescreen-config-main"] .formDialogHeader + div > div {
|
||||
padding: 1.25em 1.5em;
|
||||
height: calc(100% - 2.5em);
|
||||
}
|
||||
.dialogContainer[data-modal-id="kefin-homescreen-config-main"] .formDialogHeader + div {
|
||||
padding: 0 !important;
|
||||
overflow-y: hidden !important;
|
||||
}
|
||||
.dialogContainer[data-modal-id="kefin-homescreen-config-main"] .formDialogHeader + div > div > div #section-content > div {
|
||||
padding-bottom: 4em;
|
||||
}
|
||||
.config-tab-nav button[data-tab="order"] {
|
||||
display: none;
|
||||
}
|
||||
@@ -68,8 +68,8 @@
|
||||
off: 'Studios without any image may be rendered in Popular Studios sections. You can enable the Optional CSS Module "Studio Thumbnails" to overlay a background with the Studio Name on items without an image.'
|
||||
},
|
||||
'home-loadPeopleEpisodeData': {
|
||||
on: 'Loads all Person appearances from all episodes in your library. This data takes much longer to cache than just the Movies/Series level data.',
|
||||
off: 'Person appearance data is limited to only Movies and Series.'
|
||||
on: 'Not Recommended for larger libraries. Loads all Person appearances from all episodes in your library. This data takes much longer to cache than just the Movies/Series level data.',
|
||||
off: 'This is recommended. Person appearance data is limited to only Movies and Series.'
|
||||
},
|
||||
'home-showCreateSectionButtonOnHome': {
|
||||
on: 'Adds a button to the bottom left corner of the home screen so that you can quickly create a new section directly from the Home Screen. Only admins will see this button. The button is hidden on mobile.',
|
||||
@@ -680,7 +680,7 @@
|
||||
return BROWSE_BY_STUDIO_CATALOG.every((entry) => resolvedNames.has(entry.name));
|
||||
}
|
||||
|
||||
async function fetchAllStudiosForBrowseSection() {
|
||||
function fetchAllStudiosForBrowseSection() {
|
||||
if (browseStudiosFetchPromise) {
|
||||
return browseStudiosFetchPromise;
|
||||
}
|
||||
@@ -960,7 +960,8 @@
|
||||
if (browseSection && isBrowseByStudioCatalogFullyResolved(existingItems)) {
|
||||
LOG('Browse by Studio catalog fully resolved; skipping /Studios fetch');
|
||||
} else {
|
||||
const studios = await fetchAllStudiosForBrowseSection();
|
||||
const studiosPromise = fetchAllStudiosForBrowseSection();
|
||||
const studios = await studiosPromise;
|
||||
|
||||
if (!browseSection) {
|
||||
const items = buildBrowseByStudioItems(studios, []);
|
||||
@@ -999,16 +1000,184 @@
|
||||
queryOptions: ['Fields', 'Filters', 'IncludeItemTypes', 'MediaTypes', 'IsActive', 'IsScheduled', 'IsAiring', 'HasAired', 'IsInProgress'],
|
||||
};
|
||||
|
||||
function buildCanonicalHomeSectionMap() {
|
||||
function buildCanonicalSectionMapForGroups(groupKey) {
|
||||
const defaults = window.KefinHomeConfig2;
|
||||
const map = new Map();
|
||||
if (!defaults?.HOME_SECTION_GROUPS) return map;
|
||||
flattenSectionGroups(defaults.HOME_SECTION_GROUPS).forEach(section => {
|
||||
flattenSectionGroups(defaults?.[groupKey] || []).forEach((section) => {
|
||||
if (section?.id) map.set(section.id, section);
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
function buildCanonicalHomeSectionMap() {
|
||||
return buildCanonicalSectionMapForGroups('HOME_SECTION_GROUPS');
|
||||
}
|
||||
|
||||
function getAllKefinDefaultSectionIds() {
|
||||
const ids = new Set();
|
||||
['HOME_SECTION_GROUPS', 'SEASONAL_SECTION_GROUPS', 'DISCOVERY_SECTION_GROUPS'].forEach((key) => {
|
||||
buildCanonicalSectionMapForGroups(key).forEach((_, id) => ids.add(id));
|
||||
});
|
||||
return ids;
|
||||
}
|
||||
|
||||
const KEFIN_DEFAULT_GROUP_KEYS = ['HOME_SECTION_GROUPS', 'SEASONAL_SECTION_GROUPS', 'DISCOVERY_SECTION_GROUPS'];
|
||||
const LIBRARY_RESOLVED_ID_PREFIXES = ['recently-added-', 'popular-genres-'];
|
||||
const FIXED_TEMPLATE_SECTION_IDS = new Set([BROWSE_BY_STUDIO_SECTION_ID]);
|
||||
|
||||
function isLibraryResolvedSectionId(sectionId) {
|
||||
if (!sectionId) return false;
|
||||
return LIBRARY_RESOLVED_ID_PREFIXES.some((prefix) => sectionId.startsWith(prefix));
|
||||
}
|
||||
|
||||
function shouldKeepDefaultSurfaceSection(section, defaultSectionIds) {
|
||||
if (!section?.id) return false;
|
||||
if (section.deleted === true) return true;
|
||||
if (defaultSectionIds.has(section.id)) return true;
|
||||
if (FIXED_TEMPLATE_SECTION_IDS.has(section.id)) return true;
|
||||
if (isLibraryResolvedSectionId(section.id)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function addMissingKefinDefaultSections(config) {
|
||||
const defaults = window.KefinHomeConfig2;
|
||||
if (!defaults) return false;
|
||||
let hasChanges = false;
|
||||
|
||||
KEFIN_DEFAULT_GROUP_KEYS.forEach((groupKey) => {
|
||||
const defaultGroups = defaults[groupKey] || [];
|
||||
if (!Array.isArray(config[groupKey])) config[groupKey] = [];
|
||||
|
||||
defaultGroups.forEach((defaultGroup) => {
|
||||
let savedGroup = null;
|
||||
if (defaultGroup.id) {
|
||||
savedGroup = config[groupKey].find((g) => g.id === defaultGroup.id) || null;
|
||||
}
|
||||
if (!savedGroup && defaultGroup.name) {
|
||||
savedGroup = config[groupKey].find((g) => g.name === defaultGroup.name) || null;
|
||||
}
|
||||
|
||||
if (!savedGroup) {
|
||||
config[groupKey].push(JSON.parse(JSON.stringify(defaultGroup)));
|
||||
hasChanges = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Array.isArray(savedGroup.sections)) savedGroup.sections = [];
|
||||
const existingIds = new Set(savedGroup.sections.map((s) => s?.id).filter(Boolean));
|
||||
(defaultGroup.sections || []).forEach((defaultSection) => {
|
||||
if (!defaultSection?.id || existingIds.has(defaultSection.id)) return;
|
||||
const tombstone = savedGroup.sections.find((s) => s?.id === defaultSection.id && s.deleted === true);
|
||||
if (tombstone) return;
|
||||
savedGroup.sections.push(JSON.parse(JSON.stringify(defaultSection)));
|
||||
existingIds.add(defaultSection.id);
|
||||
hasChanges = true;
|
||||
LOG(`Added missing default section: ${defaultSection.id}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
function countOrphanKefinDefaultSections(config) {
|
||||
const defaultSectionIds = getAllKefinDefaultSectionIds();
|
||||
let count = 0;
|
||||
KEFIN_DEFAULT_GROUP_KEYS.forEach((groupKey) => {
|
||||
(config[groupKey] || []).forEach((group) => {
|
||||
(group.sections || []).forEach((section) => {
|
||||
if (!shouldKeepDefaultSurfaceSection(section, defaultSectionIds)) count += 1;
|
||||
});
|
||||
});
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
function pruneOrphanKefinDefaultSections(config) {
|
||||
const defaultSectionIds = getAllKefinDefaultSectionIds();
|
||||
let hasChanges = false;
|
||||
|
||||
KEFIN_DEFAULT_GROUP_KEYS.forEach((groupKey) => {
|
||||
(config[groupKey] || []).forEach((group) => {
|
||||
if (!Array.isArray(group.sections)) return;
|
||||
const before = group.sections.length;
|
||||
group.sections = group.sections.filter((section) => {
|
||||
const keep = shouldKeepDefaultSurfaceSection(section, defaultSectionIds);
|
||||
if (!keep) LOG(`Pruning orphan default-surface section: ${section?.id}`);
|
||||
return keep;
|
||||
});
|
||||
if (group.sections.length !== before) hasChanges = true;
|
||||
});
|
||||
});
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
async function backupConfigBeforeDefaultPrune(configToBackup) {
|
||||
try {
|
||||
if (!window.ApiClient || !window.ApiClient._serverAddress || !window.ApiClient.accessToken) {
|
||||
WARN('ApiClient not available, cannot create pre-prune backup');
|
||||
return false;
|
||||
}
|
||||
if (!window.KefinTweaksUtils?.resolvePluginId || !window.KefinTweaksUtils?.getPluginConfiguration) {
|
||||
WARN('Cannot create pre-prune backup: plugin helpers unavailable');
|
||||
return false;
|
||||
}
|
||||
if (!window.apiHelper?.getAuthHeader) {
|
||||
WARN('Cannot create pre-prune backup: apiHelper unavailable');
|
||||
return false;
|
||||
}
|
||||
|
||||
const injectorAliases = ['JavaScript Injector', 'JS Injector'];
|
||||
const pluginId = await window.KefinTweaksUtils.resolvePluginId(injectorAliases);
|
||||
if (!pluginId) {
|
||||
WARN('Cannot create pre-prune backup: Injector plugin not found');
|
||||
return false;
|
||||
}
|
||||
|
||||
const injectorConfig = await window.KefinTweaksUtils.getPluginConfiguration(injectorAliases);
|
||||
if (!injectorConfig.CustomJavaScripts) injectorConfig.CustomJavaScripts = [];
|
||||
|
||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
|
||||
const backupName = `KefinTweaks-Config-Backup-${timestamp}`;
|
||||
const backupScriptContent = `// KefinTweaks Configuration Backup
|
||||
// Automatically created before default-section prune sync
|
||||
// Created: ${new Date().toISOString()}
|
||||
// Do not edit manually
|
||||
|
||||
window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`;
|
||||
|
||||
injectorConfig.CustomJavaScripts.push({
|
||||
Name: backupName,
|
||||
Script: backupScriptContent,
|
||||
Enabled: false,
|
||||
RequiresAuthentication: false
|
||||
});
|
||||
|
||||
const server = window.ApiClient._serverAddress;
|
||||
const configUrl = `${server}/Plugins/${pluginId}/Configuration`;
|
||||
const saveResponse = await fetch(configUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': window.apiHelper.getAuthHeader(),
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(injectorConfig)
|
||||
});
|
||||
|
||||
if (!saveResponse.ok) {
|
||||
WARN(`Failed to save pre-prune backup: ${saveResponse.statusText}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(`Created pre-prune backup: ${backupName}`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
ERR('Error creating pre-prune config backup:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getRecentlyAddedCanonicalQuery() {
|
||||
return {
|
||||
path: '/Items/Latest',
|
||||
@@ -1059,37 +1228,54 @@
|
||||
}
|
||||
|
||||
function syncKefinTweaksDefaultSections(config) {
|
||||
const canonicalMap = buildCanonicalHomeSectionMap();
|
||||
const recentlyAddedTemplate = getRecentlyAddedCanonicalQuery();
|
||||
let hasChanges = false;
|
||||
|
||||
const groups = config.HOME_SECTION_GROUPS || [];
|
||||
for (const group of groups) {
|
||||
for (const section of group.sections || []) {
|
||||
if (!section?.id) continue;
|
||||
KEFIN_DEFAULT_GROUP_KEYS.forEach((groupKey) => {
|
||||
const canonicalMap = buildCanonicalSectionMapForGroups(groupKey);
|
||||
const groups = config[groupKey] || [];
|
||||
for (const group of groups) {
|
||||
for (const section of group.sections || []) {
|
||||
if (!section?.id) continue;
|
||||
|
||||
let canonical = canonicalMap.get(section.id);
|
||||
if (!canonical && section.id.startsWith('recently-added-')) {
|
||||
canonical = { queries: [recentlyAddedTemplate] };
|
||||
}
|
||||
if (!canonical?.queries?.length) continue;
|
||||
|
||||
if (!Array.isArray(section.queries)) section.queries = [];
|
||||
|
||||
for (let i = 0; i < canonical.queries.length; i++) {
|
||||
if (!section.queries[i]) {
|
||||
section.queries[i] = { queryOptions: {} };
|
||||
let canonical = canonicalMap.get(section.id);
|
||||
if (!canonical && section.id.startsWith('recently-added-')) {
|
||||
canonical = { queries: [recentlyAddedTemplate] };
|
||||
}
|
||||
if (syncQueryFromCanonical(section.queries[i], canonical.queries[i])) {
|
||||
hasChanges = true;
|
||||
if (!canonical?.queries?.length) continue;
|
||||
|
||||
if (!Array.isArray(section.queries)) section.queries = [];
|
||||
|
||||
for (let i = 0; i < canonical.queries.length; i++) {
|
||||
if (!section.queries[i]) {
|
||||
section.queries[i] = { queryOptions: {} };
|
||||
}
|
||||
if (syncQueryFromCanonical(section.queries[i], canonical.queries[i])) {
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always overwrite seasonalThemes from KefinHomeConfig2 (not user-editable yet).
|
||||
* Preserves enableSeasonalAnimations / enableSeasonalBackground / seasonToggles / enabled.
|
||||
*/
|
||||
function syncSeasonalThemesFromDefaults(config) {
|
||||
const defaults = window.KefinHomeConfig2?.SEASONAL_THEME_SETTINGS;
|
||||
if (!defaults?.seasonalThemes) return false;
|
||||
const next = JSON.parse(JSON.stringify(defaults.seasonalThemes));
|
||||
const prev = config.SEASONAL_THEME_SETTINGS?.seasonalThemes;
|
||||
const changed = JSON.stringify(prev) !== JSON.stringify(next);
|
||||
if (!config.SEASONAL_THEME_SETTINGS) config.SEASONAL_THEME_SETTINGS = {};
|
||||
config.SEASONAL_THEME_SETTINGS.seasonalThemes = next;
|
||||
return changed;
|
||||
}
|
||||
|
||||
async function ensureKefinTweaksDefaultSections() {
|
||||
try {
|
||||
if (!window.ApiClient || !window.ApiClient._loggedIn) {
|
||||
@@ -1106,11 +1292,31 @@
|
||||
|
||||
const config = loadConfig();
|
||||
const { hasChanges: libraryChanges } = await verifyLibrarySectionsConfig(config);
|
||||
const queryChanges = syncKefinTweaksDefaultSections(config);
|
||||
const addedDefaults = addMissingKefinDefaultSections(config);
|
||||
|
||||
if (libraryChanges || queryChanges) {
|
||||
const orphanCount = countOrphanKefinDefaultSections(config);
|
||||
let prunedOrphans = false;
|
||||
if (orphanCount > 0) {
|
||||
const snapshot = JSON.parse(JSON.stringify(window.KefinTweaksConfig || {}));
|
||||
if (!snapshot.homeScreenConfig) {
|
||||
snapshot.homeScreenConfig = JSON.parse(JSON.stringify(config));
|
||||
}
|
||||
await backupConfigBeforeDefaultPrune(snapshot);
|
||||
prunedOrphans = pruneOrphanKefinDefaultSections(config);
|
||||
}
|
||||
|
||||
const queryChanges = syncKefinTweaksDefaultSections(config);
|
||||
const seasonalThemeChanges = syncSeasonalThemesFromDefaults(config);
|
||||
|
||||
if (libraryChanges || addedDefaults || prunedOrphans || queryChanges || seasonalThemeChanges) {
|
||||
await saveConfig(config);
|
||||
LOG('KefinTweaks default home sections synced on startup');
|
||||
LOG('KefinTweaks default home sections synced on startup', {
|
||||
libraryChanges,
|
||||
addedDefaults,
|
||||
prunedOrphans,
|
||||
queryChanges,
|
||||
seasonalThemeChanges
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
ERR('Error ensuring KefinTweaks default sections:', error);
|
||||
@@ -1133,6 +1339,15 @@
|
||||
}
|
||||
|
||||
try {
|
||||
let admin = false;
|
||||
try {
|
||||
admin = !!(await window.apiHelper?.isAdmin?.());
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
if (!admin) return;
|
||||
|
||||
// Legacy homeScreen → homeScreenConfig (no-ops once homeScreenConfig exists)
|
||||
if (window.migrateHomeScreenConfig) {
|
||||
await window.migrateHomeScreenConfig();
|
||||
}
|
||||
@@ -1179,7 +1394,13 @@
|
||||
'custom'
|
||||
),
|
||||
DISCOVERY_SETTINGS: { ...defaults.DISCOVERY_SETTINGS, ...(existingConfig.DISCOVERY_SETTINGS || {}) },
|
||||
SEASONAL_THEME_SETTINGS: { ...defaults.SEASONAL_THEME_SETTINGS, ...(existingConfig.SEASONAL_THEME_SETTINGS || {}) },
|
||||
SEASONAL_THEME_SETTINGS: {
|
||||
...defaults.SEASONAL_THEME_SETTINGS,
|
||||
...(existingConfig.SEASONAL_THEME_SETTINGS || {}),
|
||||
seasonalThemes: JSON.parse(JSON.stringify(
|
||||
defaults.SEASONAL_THEME_SETTINGS?.seasonalThemes || {}
|
||||
))
|
||||
},
|
||||
CACHE: { ...defaults.CACHE, ...(existingConfig.CACHE || {}) },
|
||||
SPOTLIGHT_SETTINGS: { ...defaults.SPOTLIGHT_SETTINGS, ...(existingConfig.SPOTLIGHT_SETTINGS || {}) },
|
||||
HOME_SETTINGS: { ...defaults.HOME_SETTINGS, ...(existingConfig.HOME_SETTINGS || {}) },
|
||||
|
||||
@@ -569,7 +569,7 @@
|
||||
|
||||
:is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) .hsse-custom-item-tile,
|
||||
:is([data-modal-id="kefin-homescreen-section-editor"], [data-modal-id="kefin-homescreen-section-create-flow"]) .hsse-custom-item-add-tile {
|
||||
width: 6.5rem;
|
||||
width: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@@ -578,7 +578,7 @@
|
||||
|
||||
: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: 6.5rem;
|
||||
width: auto;
|
||||
height: 9.75rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
|
||||
@@ -378,11 +378,11 @@
|
||||
*/
|
||||
async function resolveQueryPayload(result) {
|
||||
if (!result) return null;
|
||||
if (typeof result.ensureData === 'function' || result.dataPromise != null) {
|
||||
if (result.data != null) return result.data;
|
||||
return await (typeof result.ensureData === 'function'
|
||||
? result.ensureData()
|
||||
: result.dataPromise);
|
||||
if (typeof result.ensureData === 'function') {
|
||||
return await result.ensureData();
|
||||
}
|
||||
if (result.dataPromise != null) {
|
||||
return await result.dataPromise;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+41
-77
@@ -6,10 +6,6 @@
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.snowverlay {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.homePage [data-section-id] h2.sectionTitle,
|
||||
.homePage [data-section-id] .sectionTitleTextButton > .material-icons {
|
||||
margin-bottom: 0 !important;
|
||||
@@ -243,24 +239,6 @@ div#discovery-loading-indicator:not(.show)::after {
|
||||
font-size: 1.5rem !important;
|
||||
line-height: 1.8rem !important;
|
||||
}
|
||||
|
||||
/* .homeSectionsContainer [data-section-id*="thematic-"] .card[data-type="Folder"] .cardText {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-card-format="Square"] [data-type="Person"] .cardScalable,
|
||||
[data-card-format="Square"] [data-type="Actor"] .cardScalable,
|
||||
[data-card-format="Square"] [data-type="Writer"] .cardScalable,
|
||||
[data-card-format="Square"] [data-type="Director"] .cardScalable {
|
||||
border-radius: 50% !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
[data-card-format="Square"] [data-type="Actor"] .cardText {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
} */
|
||||
|
||||
.section0:not([data-page]),
|
||||
.section1:not([data-page]),
|
||||
.section2:not([data-page]),
|
||||
@@ -270,33 +248,7 @@ div#discovery-loading-indicator:not(.show)::after {
|
||||
.section6:not([data-page]),
|
||||
.section7:not([data-page]),
|
||||
.section8:not([data-page]),
|
||||
.section9:not([data-page]),
|
||||
.homeSectionsContainer:has([data-page], [data-section-id])
|
||||
> :is(
|
||||
.section0:not([data-page]),
|
||||
.section1:not([data-page]),
|
||||
.section2:not([data-page]),
|
||||
.section3:not([data-page]),
|
||||
.section4:not([data-page]),
|
||||
.section5:not([data-page]),
|
||||
.section6:not([data-page]),
|
||||
.section7:not([data-page]),
|
||||
.section8:not([data-page]),
|
||||
.section9:not([data-page])
|
||||
),
|
||||
.homeSectionsContainer[data-sections-rendered="true"]
|
||||
> :is(
|
||||
.section0:not([data-page]),
|
||||
.section1:not([data-page]),
|
||||
.section2:not([data-page]),
|
||||
.section3:not([data-page]),
|
||||
.section4:not([data-page]),
|
||||
.section5:not([data-page]),
|
||||
.section6:not([data-page]),
|
||||
.section7:not([data-page]),
|
||||
.section8:not([data-page]),
|
||||
.section9:not([data-page])
|
||||
) {
|
||||
.section9:not([data-page]) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -318,30 +270,27 @@ div#discovery-loading-indicator:not(.show)::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body:not(:has(#slides-container)) .homeSectionsContainer .section9 + .custom-scroller-container {
|
||||
margin-top: 1em;
|
||||
body[data-seasonal-background="true"]:has(.homePage:not(.hide))
|
||||
#reactRoot:has(.homePage:not(.hide) #homeTab.is-active)
|
||||
> .backdropContainer
|
||||
.backdropImage {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
/* .pageTabContent:has(.kefinHomeSectionsContainer[data-kefin-home-screen]) .homeSectionsContainer:not([data-kefin-home-screen]) {
|
||||
display: none !important;
|
||||
body[data-seasonal-background="true"]:has(.homePage:not(.hide))
|
||||
#reactRoot:has(.homePage:not(.hide) #homeTab.is-active)
|
||||
> .backgroundContainer::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0%;
|
||||
background: linear-gradient(rgba(0, 0, 0, 0.65), rgba(0, 0, 0, 0.85)), var(--seasonal-background-image);
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
body[data-seasonal-background="true"]:has(.homePage:not(.hide)) #reactRoot:has(.libraryPage:not(.hide) .pageTabContent.is-active[data-index="0"])>.backgroundContainer::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0%;
|
||||
background: linear-gradient(rgba(0, 0, 0, 0.65), rgba(0, 0, 0, 0.85)), var(--seasonal-background-image);
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
body[data-seasonal-animations="true"]:has(.homePage:not(.hide)) .snowverlay {
|
||||
display: block;
|
||||
} */
|
||||
|
||||
.homePage[data-discovery-ready] div#discovery-loading-indicator:not(.show) {
|
||||
min-height: 50px;
|
||||
}
|
||||
@@ -402,10 +351,18 @@ body[data-seasonal-animations="true"]:has(.homePage:not(.hide)) .snowverlay {
|
||||
.kefin-home-chrome:focus-within {
|
||||
opacity: 1;
|
||||
}
|
||||
.kefin-home-chrome[hidden],
|
||||
#kefin-home-category-rail[hidden] {
|
||||
.kefin-home-chrome.hide,
|
||||
#kefin-home-category-rail.hide,
|
||||
#kefin-home-category-rail.hide .kefin-home-category-rail {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Hide home chrome off-home via root page key (no :has; JMP-safe) */
|
||||
html:not([data-active-page="home"]) #kefin-home-category-rail,
|
||||
html:not([data-active-page="home"]) #kefin-home-create-section-btn {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.kefin-home-chrome button,
|
||||
#kefin-home-category-rail button {
|
||||
pointer-events: auto;
|
||||
@@ -477,6 +434,14 @@ body[data-seasonal-animations="true"]:has(.homePage:not(.hide)) .snowverlay {
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
backdrop-filter: blur(10px);
|
||||
border: none !important;
|
||||
transition:
|
||||
transform 0.25s ease,
|
||||
opacity 0.25s ease;
|
||||
}
|
||||
#kefin-home-category-rail.is-scroll-hidden .kefin-home-category-rail {
|
||||
transform: translateY(100%);
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
}
|
||||
.kefin-home-create-section,
|
||||
#kefin-home-create-section-btn {
|
||||
@@ -491,11 +456,6 @@ body[data-seasonal-animations="true"]:has(.homePage:not(.hide)) .snowverlay {
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
body:not(:has(.homePage:not(.hide) #homeTab.is-active)) div#kefin-home-category-rail,
|
||||
body:not(:has(.homePage:not(.hide) #homeTab.is-active)) div#kefin-home-create-section-btn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 900px) {
|
||||
#kefin-home-category-rail .kefin-home-category-rail,
|
||||
#kefin-home-category-rail .kefin-home-category-rail::before {
|
||||
@@ -531,8 +491,12 @@ body:not(:has(#slides-container)):has(.MuiBox-root) .homeSectionsContainer:has([
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
body:has(.kefin-home-category-btn.is-active[data-category-id="discovery"]) .sections.homeSectionsContainer::before {
|
||||
.sections.homeSectionsContainer[data-category="discovery"]::before {
|
||||
content: "Discover Something To Watch";
|
||||
padding-left: max(env(safe-area-inset-left), 3.3%);
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
html:not([data-active-page="home"]) .snowverlay {
|
||||
display: none;
|
||||
}
|
||||
+91
-94
@@ -91,11 +91,6 @@
|
||||
}
|
||||
state.getDisplayPrefernces = fetchDisplayPreferences;
|
||||
|
||||
const performanceTimer = {
|
||||
loadTimeStart: null,
|
||||
loadTimeEnd: null,
|
||||
};
|
||||
|
||||
// Cache used to support re-rendering our sections after Jellyfin overwrites the container
|
||||
const sectionCache = {
|
||||
renderedSections: [], // Array of section configs + results
|
||||
@@ -105,14 +100,6 @@
|
||||
pendingJellyfinSectionObservers: []
|
||||
};
|
||||
|
||||
// Basic performance metrics for measuring initial and recovery renders
|
||||
const performanceMetrics = {
|
||||
initialRenderStart: null,
|
||||
initialRenderEnd: null,
|
||||
jellyfinDetected: null,
|
||||
recoveryRenderEnd: null
|
||||
};
|
||||
|
||||
// Create loading indicator element (always last child of the sections container)
|
||||
function createDiscoveryLoadingIndicator(container) {
|
||||
// Prefer the provided container, but fall back to the standard sections container
|
||||
@@ -420,7 +407,10 @@
|
||||
document.body.dataset.seasonalAnimations = 'true';
|
||||
|
||||
// Add the animation script to the head
|
||||
const animation = seasonalThemes[activeSeasonalThemeGroup.id]?.animation;
|
||||
const theme = seasonalThemes[activeSeasonalThemeGroup.id] || {};
|
||||
const animation = theme.animation;
|
||||
document.body.dataset.seasonalShape = theme.shape || 'snowflake';
|
||||
document.body.dataset.seasonalAnimationStyle = theme.animationStyle || 'fall';
|
||||
if (animation) {
|
||||
const animationScript = document.querySelector(`script[src*="${animation}.js"]`);
|
||||
if (!animationScript) {
|
||||
@@ -439,26 +429,16 @@
|
||||
*/
|
||||
async function enhanceHomeScreen() {
|
||||
LOG('Initializing Home Screen v3...');
|
||||
performanceTimer.loadTimeStart = performance.now();
|
||||
performanceMetrics.initialRenderStart = performance.now();
|
||||
|
||||
mountCreateSectionButton();
|
||||
// Defer mountCategoryRail until pinned availability is known (avoids first-load tab jump)
|
||||
syncHomeScreenChromeVisibility();
|
||||
|
||||
// Reset cache/metrics for a new initialization cycle
|
||||
// Reset cache for a new initialization cycle
|
||||
sectionCache.renderedSections = [];
|
||||
sectionCache.fragmentCache = null;
|
||||
sectionCache.isInitialRender = true;
|
||||
sectionCache.jellyfinHasRendered = false;
|
||||
performanceMetrics.initialRenderEnd = null;
|
||||
performanceMetrics.jellyfinDetected = null;
|
||||
performanceMetrics.recoveryRenderEnd = null;
|
||||
|
||||
// Run migration if needed (check for legacy homeScreen config)
|
||||
if (window.migrateHomeScreenConfig) {
|
||||
await window.migrateHomeScreenConfig();
|
||||
}
|
||||
|
||||
const container = document.querySelector(HOME_SECTIONS_SELECTOR);
|
||||
if (!container) {
|
||||
@@ -501,18 +481,10 @@
|
||||
return;
|
||||
}
|
||||
|
||||
let performanceStartTime = performance.now();
|
||||
|
||||
// Fetch display preferences
|
||||
//state.userDisplayPreferences = await fetchDisplayPreferences();
|
||||
|
||||
let performanceEndTime = performance.now();
|
||||
let performanceDuration = performanceEndTime - performanceStartTime;
|
||||
LOG(`Home Screen v3 Fetch display preferences initialization time: ${performanceDuration.toFixed(2)}ms`);
|
||||
|
||||
// Load user preferences and apply filtering/ordering
|
||||
performanceStartTime = performance.now();
|
||||
|
||||
const userHomeConfig = window.KefinUserHomeScreenConfig;
|
||||
let filteredHomeSections;
|
||||
let homeScreen;
|
||||
@@ -546,10 +518,6 @@
|
||||
mountCategoryRail();
|
||||
syncHomeScreenChromeVisibility();
|
||||
|
||||
performanceEndTime = performance.now();
|
||||
performanceDuration = performanceEndTime - performanceStartTime;
|
||||
LOG(`Home Screen v3 Load user home screen sections initialization time: ${performanceDuration.toFixed(2)}ms`);
|
||||
|
||||
const nextupSectionConfig = filteredHomeSections.find(s => s.id === 'nextUp');
|
||||
const continueWatchingSectionConfig = filteredHomeSections.find(s => s.id === 'continueWatching');
|
||||
const continueWatchingAndNextUpSectionConfig = filteredHomeSections.find(s => s.id === 'continueWatchingAndNextUp');
|
||||
@@ -589,11 +557,6 @@
|
||||
observeSectionUntilChildrenThenClone(sectionEl, kefinHome);
|
||||
}
|
||||
});
|
||||
|
||||
performanceMetrics.recoveryRenderEnd = performance.now();
|
||||
if (performanceMetrics.jellyfinDetected) {
|
||||
LOG(`Home Screen v3 Jellyfin section mirroring duration: ${(performanceMetrics.recoveryRenderEnd - performanceMetrics.jellyfinDetected).toFixed(2)}ms`);
|
||||
}
|
||||
}; */
|
||||
|
||||
//let containerForRender = container;
|
||||
@@ -607,18 +570,9 @@
|
||||
//containerForRender.dataset.kefinHomeScreen = 'true';
|
||||
|
||||
// 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);
|
||||
performanceEndTime = performance.now();
|
||||
performanceDuration = performanceEndTime - performanceStartTime;
|
||||
LOG(`Home Screen v3 Render home sections (initial) initialization time: ${performanceDuration.toFixed(2)}ms`);
|
||||
|
||||
performanceMetrics.initialRenderEnd = performanceEndTime;
|
||||
|
||||
performanceTimer.loadTimeEnd = performance.now();
|
||||
LOG(`Home Screen v3 load time initialization: ${(performanceTimer.loadTimeEnd - performanceTimer.loadTimeStart).toFixed(2)}ms`);
|
||||
|
||||
LOG('Initializing Discovery Sections...');
|
||||
setupDiscoveryInteraction(container);
|
||||
|
||||
@@ -653,13 +607,7 @@
|
||||
* Now reads from all 4 groups: HOME, SEASONAL, DISCOVERY, CUSTOM
|
||||
*/
|
||||
async function mergeHomeSectionConfigs(defaultSections) {
|
||||
|
||||
const performanceStartTime = performance.now();
|
||||
const kefinSections = await window.KefinHomeScreen.getSections();
|
||||
const performanceEndTime = performance.now();
|
||||
const performanceDuration = performanceEndTime - performanceStartTime;
|
||||
LOG(`Home Screen v3 Get kefin home screen config initialization time: ${performanceDuration.toFixed(2)}ms`);
|
||||
|
||||
return kefinSections.enabledHomeSections;
|
||||
|
||||
// Return all enabled sections from HOME_SECTION_GROUPS
|
||||
@@ -1195,14 +1143,7 @@
|
||||
|
||||
const sectionPromises = [];
|
||||
|
||||
let performanceStartTime = performance.now();
|
||||
let performanceEndTime;
|
||||
let performanceDuration;
|
||||
|
||||
const performanceTimes = [];
|
||||
|
||||
for (const sectionConfig of sortedSections) {
|
||||
const loopStartTime = performance.now();
|
||||
if (sectionConfig.enabled === false) {
|
||||
LOG(`Skipping disabled section: ${sectionConfig.id}`);
|
||||
continue;
|
||||
@@ -1223,30 +1164,13 @@
|
||||
}
|
||||
|
||||
sectionPromises.push(loadSectionForRendering(sectionConfig));
|
||||
|
||||
const loopEndTime = performance.now();
|
||||
const loopDuration = loopEndTime - loopStartTime;
|
||||
performanceTimes.push(loopDuration);
|
||||
LOG(`Section ${sectionConfig.id} initialization time: ${loopDuration.toFixed(2)}ms`);
|
||||
}
|
||||
|
||||
performanceEndTime = performance.now();
|
||||
performanceDuration = performanceEndTime - performanceStartTime;
|
||||
LOG(`Render home sections configs loaded initialization time: ${performanceDuration.toFixed(2)}ms`);
|
||||
|
||||
LOG(`Total performance time: ${performanceTimes.reduce((a, b) => a + b, 0).toFixed(2)}ms`);
|
||||
|
||||
performanceStartTime = performance.now();
|
||||
|
||||
// Resolve all section promises
|
||||
let sectionResults = await Promise.all(sectionPromises);
|
||||
sectionResults = sectionResults.filter(result => result !== null);
|
||||
sectionsToRender.push(...sectionResults);
|
||||
|
||||
performanceEndTime = performance.now();
|
||||
performanceDuration = performanceEndTime - performanceStartTime;
|
||||
LOG(`Home Screen v3 Resolve all section promises initialization time: ${performanceDuration.toFixed(2)}ms`);
|
||||
|
||||
// Cache the rendered sections for potential re-render after Jellyfin overwrites the container
|
||||
sectionCache.renderedSections = [...sectionsToRender];
|
||||
}
|
||||
@@ -1263,7 +1187,6 @@
|
||||
}
|
||||
|
||||
if (!state.isRenderingHome && !kefinSections) {
|
||||
const renderStartTime = performance.now();
|
||||
state.isRenderingHome = true;
|
||||
|
||||
await window.cardBuilder.renderProgressiveSections(targetContainer, sectionsToRender, {
|
||||
@@ -1274,10 +1197,6 @@
|
||||
|
||||
state.isRenderingHome = false;
|
||||
|
||||
const renderEndTime = performance.now();
|
||||
const renderDuration = renderEndTime - renderStartTime;
|
||||
LOG(`Home Screen v3 Render progressive sections initialization time: ${renderDuration.toFixed(2)}ms`);
|
||||
|
||||
// If MediaBar plugin is in use, call LayoutSync.update() to update the layout
|
||||
if (typeof LayoutSync !== 'undefined' && LayoutSync && typeof LayoutSync.update === 'function') {
|
||||
LayoutSync.update();
|
||||
@@ -1374,7 +1293,7 @@
|
||||
const isDynamic = !!(sectionConfig.discoveryType || sectionConfig.source === 'Dynamic');
|
||||
if (isDynamic) {
|
||||
// Sync stub + lazy resolve; do not await ensureData here
|
||||
return window.sectionHelper.buildDiscoverySectionPromise(sectionConfig, {
|
||||
return await window.sectionHelper.buildDiscoverySectionPromise(sectionConfig, {
|
||||
order: sectionConfig.order,
|
||||
pairSpotlight: true
|
||||
});
|
||||
@@ -1869,6 +1788,70 @@
|
||||
let homeChromeCategoryMounted = false;
|
||||
let homeChromeHasPinnedContent = false;
|
||||
let homeChromeVisibilityObserver = null;
|
||||
let homeChromeRailScrollBound = false;
|
||||
let homeChromeRailLastY = 0;
|
||||
const HOME_CHROME_RAIL_SCROLL_DELTA = 8;
|
||||
const HOME_CHROME_RAIL_MOBILE_MQ = '(max-width: 899px)';
|
||||
|
||||
function isHomeCategoryRailMobile() {
|
||||
return typeof window.matchMedia === 'function'
|
||||
? window.matchMedia(HOME_CHROME_RAIL_MOBILE_MQ).matches
|
||||
: window.innerWidth < 900;
|
||||
}
|
||||
|
||||
function setHomeCategoryRailScrollHidden(hidden) {
|
||||
const rail = document.getElementById(HOME_CHROME_CATEGORY_RAIL_ID);
|
||||
if (!rail) return;
|
||||
rail.classList.toggle('is-scroll-hidden', !!hidden);
|
||||
}
|
||||
|
||||
function clearHomeCategoryRailScrollHidden() {
|
||||
setHomeCategoryRailScrollHidden(false);
|
||||
}
|
||||
|
||||
function handleHomeCategoryRailScroll() {
|
||||
const rail = document.getElementById(HOME_CHROME_CATEGORY_RAIL_ID);
|
||||
if (!rail || rail.classList.contains('hide') || !isHomeCategoryRailMobile()) {
|
||||
clearHomeCategoryRailScrollHidden();
|
||||
return;
|
||||
}
|
||||
const y = window.pageYOffset || document.documentElement.scrollTop || 0;
|
||||
if (y <= HOME_CHROME_RAIL_SCROLL_DELTA) {
|
||||
clearHomeCategoryRailScrollHidden();
|
||||
homeChromeRailLastY = y;
|
||||
return;
|
||||
}
|
||||
const delta = y - homeChromeRailLastY;
|
||||
if (Math.abs(delta) < HOME_CHROME_RAIL_SCROLL_DELTA) return;
|
||||
if (delta > 0) {
|
||||
setHomeCategoryRailScrollHidden(true);
|
||||
} else {
|
||||
setHomeCategoryRailScrollHidden(false);
|
||||
}
|
||||
homeChromeRailLastY = y;
|
||||
}
|
||||
|
||||
function syncHomeCategoryRailScrollListener() {
|
||||
const rail = document.getElementById(HOME_CHROME_CATEGORY_RAIL_ID);
|
||||
const showFilters = getHomeSettings().showCategoryFilters !== false;
|
||||
const shouldListen = !!(rail && !rail.classList.contains('hide') && isHomePageVisible() && showFilters && isHomeCategoryRailMobile());
|
||||
if (shouldListen) {
|
||||
if (!homeChromeRailScrollBound) {
|
||||
homeChromeRailLastY = window.pageYOffset || document.documentElement.scrollTop || 0;
|
||||
window.addEventListener('scroll', handleHomeCategoryRailScroll, { passive: true });
|
||||
window.addEventListener('resize', syncHomeCategoryRailScrollListener, { passive: true });
|
||||
homeChromeRailScrollBound = true;
|
||||
}
|
||||
if (!isHomeCategoryRailMobile()) clearHomeCategoryRailScrollHidden();
|
||||
return;
|
||||
}
|
||||
if (homeChromeRailScrollBound) {
|
||||
window.removeEventListener('scroll', handleHomeCategoryRailScroll);
|
||||
window.removeEventListener('resize', syncHomeCategoryRailScrollListener);
|
||||
homeChromeRailScrollBound = false;
|
||||
}
|
||||
clearHomeCategoryRailScrollHidden();
|
||||
}
|
||||
|
||||
function getHomeSettings() {
|
||||
return window.KefinTweaksConfig?.homeScreenConfig?.HOME_SETTINGS
|
||||
@@ -1915,26 +1898,32 @@
|
||||
}
|
||||
|
||||
function isHomePageVisible() {
|
||||
return !!document.querySelector('.homePage:not(.hide)');
|
||||
const active = document.documentElement.getAttribute('data-active-page');
|
||||
if (active !== null) {
|
||||
return active === 'home';
|
||||
}
|
||||
return !!document.querySelector('.homePage:not(.hide) #homeTab.is-active');
|
||||
}
|
||||
|
||||
function syncHomeScreenChromeVisibility() {
|
||||
const onHome = isHomePageVisible();
|
||||
const createBtn = document.getElementById(HOME_CHROME_CREATE_ID);
|
||||
if (createBtn) {
|
||||
createBtn.hidden = !onHome;
|
||||
createBtn.classList.toggle('hide', !onHome);
|
||||
createBtn.setAttribute('aria-hidden', onHome ? 'false' : 'true');
|
||||
}
|
||||
const showFilters = getHomeSettings().showCategoryFilters !== false;
|
||||
const rail = document.getElementById(HOME_CHROME_CATEGORY_RAIL_ID);
|
||||
if (rail) {
|
||||
const visible = onHome && showFilters;
|
||||
rail.hidden = !visible;
|
||||
rail.classList.toggle('hide', !visible);
|
||||
rail.setAttribute('aria-hidden', visible ? 'false' : 'true');
|
||||
if (!visible) clearHomeCategoryRailScrollHidden();
|
||||
}
|
||||
if (onHome) {
|
||||
applyActiveHomeCategory(homeChromeActiveCategory || 'none');
|
||||
}
|
||||
syncHomeCategoryRailScrollListener();
|
||||
}
|
||||
|
||||
function ensureHomeChromeVisibilityObserver() {
|
||||
@@ -1980,7 +1969,8 @@
|
||||
const wrap = document.createElement('div');
|
||||
wrap.id = HOME_CHROME_CREATE_ID;
|
||||
wrap.className = 'kefin-home-chrome kefin-home-create-section';
|
||||
wrap.hidden = !isHomePageVisible();
|
||||
wrap.classList.toggle('hide', !isHomePageVisible());
|
||||
wrap.setAttribute('aria-hidden', isHomePageVisible() ? 'false' : 'true');
|
||||
wrap.innerHTML = `
|
||||
<button type="button" class="paper-icon-button-light emby-button kefin-home-create-section-btn" title="Create Section" aria-label="Create Section">
|
||||
<span class="material-icons" aria-hidden="true">add_circle</span>
|
||||
@@ -2085,6 +2075,7 @@
|
||||
ensureCategoryFilterStyles();
|
||||
homeChromeActiveCategory = 'none';
|
||||
applyActiveHomeCategory('none');
|
||||
syncHomeCategoryRailScrollListener();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2104,10 +2095,10 @@
|
||||
const outer = document.createElement('div');
|
||||
outer.id = HOME_CHROME_CATEGORY_RAIL_ID;
|
||||
outer.className = 'sectionTabs';
|
||||
outer.hidden = !isHomePageVisible();
|
||||
outer.classList.toggle('hide', !isHomePageVisible());
|
||||
outer.setAttribute('role', 'toolbar');
|
||||
outer.setAttribute('aria-label', 'Home categories');
|
||||
//outer.setAttribute('aria-hidden', outer.hidden ? 'true' : 'false');
|
||||
outer.setAttribute('aria-hidden', isHomePageVisible() ? 'false' : 'true');
|
||||
|
||||
const inner = document.createElement('div');
|
||||
inner.className = getCategoryRailNativeClasses();
|
||||
@@ -2140,6 +2131,7 @@
|
||||
document.body.appendChild(outer);
|
||||
homeChromeCategoryMounted = true;
|
||||
applyActiveHomeCategory(desiredCategory);
|
||||
syncHomeCategoryRailScrollListener();
|
||||
}
|
||||
|
||||
function getMountedRailCategoryIds() {
|
||||
@@ -2198,6 +2190,10 @@
|
||||
//initHomeScreenChrome();
|
||||
|
||||
if (window.KefinTweaksUtils && typeof window.KefinTweaksUtils.onViewPage === 'function') {
|
||||
window.KefinTweaksUtils.onViewPage(() => {
|
||||
syncHomeScreenChromeVisibility();
|
||||
}, { pages: [] });
|
||||
|
||||
window.KefinTweaksUtils.onViewPage((view, element, hash) => {
|
||||
// Get selected tab from hash
|
||||
const hashParams = hash.includes('?') ? hash.split('?')[1] : '';
|
||||
@@ -2205,8 +2201,9 @@
|
||||
const currentTab = urlParams.get('tab');
|
||||
const currentTabIndex = currentTab ? parseInt(currentTab, 10) : 0;
|
||||
|
||||
// If the tab isn't 0, don't render the home screen
|
||||
// If the tab isn't 0, don't render the home screen (still sync chrome)
|
||||
if (currentTabIndex !== 0) {
|
||||
syncHomeScreenChromeVisibility();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user