mirror of
https://github.com/ranaldsgift/KefinTweaks.git
synced 2026-11-05 15:52:47 +01:00
Fix problem caused by using legacy sortOrder/sortOrderDirection for discovery sections
This commit is contained in:
1 parent
a93a82decc
commit
0394aced14
5 files changed
+253
-74
No files matched your search
@@ -167,7 +167,7 @@
|
||||
'itemsLayout', 'useGaplessCards', 'sectionCssClass', 'hideName'
|
||||
];
|
||||
const RESTORE_ADVANCED_KEYS = [
|
||||
'ttl', 'sortBy', 'sortOrder', 'sortOrderDirection',
|
||||
'ttl', 'sortBy', 'sortOrder',
|
||||
'minimumItems', 'itemLimit', 'flattenSeries', 'limitBeforeSort', 'hideWatched'
|
||||
];
|
||||
const TTL_UNIT_OPTIONS = [
|
||||
@@ -1444,6 +1444,63 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`;
|
||||
return true; // flag always newly stamped → needs save
|
||||
}
|
||||
|
||||
// TEMPORARY: one-time overwrite of saved Kefin discovery sort fields from the new
|
||||
// sortBy + sortOrder defaults. Remove in a future release once existing installs
|
||||
// have picked up the patch (see discoverySortOrdersPatched).
|
||||
// TODO(remove): patchDiscoverySortOrdersOnce + call site + discoverySortPatch log field
|
||||
function patchDiscoverySortOrdersOnce(config) {
|
||||
if (!window.KefinTweaksConfig) window.KefinTweaksConfig = {};
|
||||
if (window.KefinTweaksConfig.discoverySortOrdersPatched === true) return false;
|
||||
if (!Array.isArray(window.KefinHomeConfig2?.DISCOVERY_SECTION_GROUPS)) return false;
|
||||
|
||||
const canonicalMap = buildCanonicalSectionMapForGroups('DISCOVERY_SECTION_GROUPS');
|
||||
const isDirection = (value) => value === 'Ascending' || value === 'Descending';
|
||||
const topRatedQueryResetIds = new Set(['spotlightGenre', 'spotlightGenreSeries', 'spotlightNetwork']);
|
||||
|
||||
const applySortPair = (target, canonical, fieldKey, directionKey) => {
|
||||
if (!target || !canonical) return;
|
||||
if (canonical[fieldKey]) target[fieldKey] = canonical[fieldKey];
|
||||
else delete target[fieldKey];
|
||||
|
||||
if (isDirection(canonical[directionKey])) target[directionKey] = canonical[directionKey];
|
||||
else delete target[directionKey];
|
||||
};
|
||||
|
||||
for (const group of config.DISCOVERY_SECTION_GROUPS || []) {
|
||||
for (const section of group.sections || []) {
|
||||
if (!section?.id) continue;
|
||||
const canonical = canonicalMap.get(section.id);
|
||||
if (!canonical) continue;
|
||||
|
||||
applySortPair(section, canonical, 'sortBy', 'sortOrder');
|
||||
delete section.sortOrderDirection;
|
||||
|
||||
const savedQueries = section.queries || [];
|
||||
const canonicalQueries = canonical.queries || [];
|
||||
const count = Math.min(savedQueries.length, canonicalQueries.length);
|
||||
const replaceQueryOptions = topRatedQueryResetIds.has(section.id);
|
||||
for (let i = 0; i < count; i++) {
|
||||
const savedQuery = savedQueries[i];
|
||||
const canonicalQuery = canonicalQueries[i];
|
||||
if (!savedQuery || !canonicalQuery) continue;
|
||||
if (replaceQueryOptions) {
|
||||
savedQuery.queryOptions = JSON.parse(JSON.stringify(canonicalQuery.queryOptions || {}));
|
||||
continue;
|
||||
}
|
||||
const canonicalOpts = canonicalQuery.queryOptions || {};
|
||||
if (!savedQuery.queryOptions) {
|
||||
if (!canonicalOpts.SortBy && !isDirection(canonicalOpts.SortOrder)) continue;
|
||||
savedQuery.queryOptions = {};
|
||||
}
|
||||
applySortPair(savedQuery.queryOptions, canonicalOpts, 'SortBy', 'SortOrder');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.KefinTweaksConfig.discoverySortOrdersPatched = true;
|
||||
return true; // flag always newly stamped → needs save
|
||||
}
|
||||
|
||||
async function ensureKefinTweaksDefaultSections() {
|
||||
try {
|
||||
if (!window.ApiClient || !window.ApiClient._loggedIn) {
|
||||
@@ -1477,8 +1534,10 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`;
|
||||
const seasonalThemeChanges = syncSeasonalThemesFromDefaults(config);
|
||||
// TEMPORARY / TODO(remove): one-time liveTv-on-now Limit patch
|
||||
const liveTvLimitPatch = patchLiveTvOnNowLimitOnce(config);
|
||||
// TEMPORARY / TODO(remove): one-time discovery sortBy/sortOrder overwrite
|
||||
const discoverySortPatch = patchDiscoverySortOrdersOnce(config);
|
||||
|
||||
if (libraryChanges || addedDefaults || prunedOrphans || defaultSyncChanges || seasonalThemeChanges || liveTvLimitPatch) {
|
||||
if (libraryChanges || addedDefaults || prunedOrphans || defaultSyncChanges || seasonalThemeChanges || liveTvLimitPatch || discoverySortPatch) {
|
||||
await saveConfig(config);
|
||||
LOG('KefinTweaks default home sections synced on startup', {
|
||||
libraryChanges,
|
||||
@@ -1486,7 +1545,8 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`;
|
||||
prunedOrphans,
|
||||
defaultSyncChanges,
|
||||
seasonalThemeChanges,
|
||||
liveTvLimitPatch
|
||||
liveTvLimitPatch,
|
||||
discoverySortPatch
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -1919,6 +1979,11 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`;
|
||||
...(savedQuery.queryOptions || {}),
|
||||
...currentQuery.queryOptions
|
||||
};
|
||||
['SortBy', 'SortOrder'].forEach((key) => {
|
||||
if (!Object.prototype.hasOwnProperty.call(currentQuery.queryOptions, key)) {
|
||||
delete merged.queryOptions[key];
|
||||
}
|
||||
});
|
||||
} else if (savedQuery.queryOptions) {
|
||||
merged.queryOptions = JSON.parse(JSON.stringify(savedQuery.queryOptions));
|
||||
}
|
||||
@@ -1992,6 +2057,12 @@ window.KefinTweaksConfig = ${JSON.stringify(configToBackup, null, 2)};`;
|
||||
merged[key] = currentSection[key];
|
||||
}
|
||||
});
|
||||
|
||||
['sortBy', 'sortOrder'].forEach((key) => {
|
||||
if (!Object.prototype.hasOwnProperty.call(currentSection, key)) {
|
||||
delete merged[key];
|
||||
}
|
||||
});
|
||||
|
||||
// Ensure id is preserved from currentSection
|
||||
if (currentSection.id) {
|
||||
|
||||
@@ -628,8 +628,25 @@
|
||||
found.section.isPlayed = legacySectionConfig.isPlayed;
|
||||
}
|
||||
if (legacySectionConfig.minimumItems !== undefined) found.section.minimumItems = legacySectionConfig.minimumItems;
|
||||
if (legacySectionConfig.sortOrder !== undefined) found.section.sortOrder = legacySectionConfig.sortOrder;
|
||||
if (legacySectionConfig.sortOrderDirection !== undefined) found.section.sortOrderDirection = legacySectionConfig.sortOrderDirection;
|
||||
if (legacySectionConfig.sortOrder !== undefined) {
|
||||
const legacySort = String(legacySectionConfig.sortOrder).trim();
|
||||
if (legacySort === 'Ascending' || legacySort === 'Descending') {
|
||||
found.section.sortOrder = legacySort;
|
||||
} else if (legacySort) {
|
||||
found.section.sortBy = legacySort;
|
||||
const existingOrder = found.section.sortOrder == null ? '' : String(found.section.sortOrder).trim();
|
||||
if (existingOrder !== 'Ascending' && existingOrder !== 'Descending') {
|
||||
delete found.section.sortOrder;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (legacySectionConfig.sortOrderDirection !== undefined) {
|
||||
const legacyDirection = String(legacySectionConfig.sortOrderDirection).trim();
|
||||
if (legacyDirection === 'Ascending' || legacyDirection === 'Descending') {
|
||||
found.section.sortOrder = legacyDirection;
|
||||
}
|
||||
}
|
||||
delete found.section.sortOrderDirection;
|
||||
|
||||
const isRecentlyWatchedPerson = RECENTLY_WATCHED_PERSON_IDS.has(sectionKey);
|
||||
if (legacySectionConfig.name !== undefined) {
|
||||
|
||||
@@ -452,11 +452,26 @@
|
||||
.replace(/([A-Z])([A-Z][a-z])/g, '$1 $2');
|
||||
}
|
||||
|
||||
const SORT_BY_NONE = 'None';
|
||||
|
||||
function toSortBySelectOptions(sortOrders) {
|
||||
return (sortOrders || []).map(value => ({
|
||||
value,
|
||||
label: humanizeSortOrderLabel(value)
|
||||
}));
|
||||
return [
|
||||
{ value: SORT_BY_NONE, label: 'None' },
|
||||
...(sortOrders || []).map(value => ({
|
||||
value,
|
||||
label: humanizeSortOrderLabel(value)
|
||||
}))
|
||||
];
|
||||
}
|
||||
|
||||
function sortBySelectValue(stored) {
|
||||
const value = stored == null ? '' : String(stored).trim();
|
||||
return value || SORT_BY_NONE;
|
||||
}
|
||||
|
||||
function isSortByNone(value) {
|
||||
const by = value == null ? '' : String(value).trim();
|
||||
return !by || by === SORT_BY_NONE;
|
||||
}
|
||||
|
||||
function getSectionSortOrderDirectionOptions(directions) {
|
||||
@@ -484,15 +499,63 @@
|
||||
return allowed.includes(profile);
|
||||
}
|
||||
|
||||
const SECTION_SORT_DIRECTIONS = new Set(['Ascending', 'Descending']);
|
||||
|
||||
function isSectionSortDirection(value) {
|
||||
return SECTION_SORT_DIRECTIONS.has(String(value || '').trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy sortOrder stored the field (Random, CommunityRating, …) and
|
||||
* sortOrderDirection stored Ascending/Descending. Current model is
|
||||
* sortBy = field, sortOrder = direction only.
|
||||
*/
|
||||
function normalizeSectionSortFields(section) {
|
||||
if (!section || typeof section !== 'object') return section;
|
||||
const order = section.sortOrder == null ? '' : String(section.sortOrder).trim();
|
||||
const legacyDirection = section.sortOrderDirection == null ? '' : String(section.sortOrderDirection).trim();
|
||||
|
||||
if (order && !isSectionSortDirection(order)) {
|
||||
if (!section.sortBy) section.sortBy = order;
|
||||
delete section.sortOrder;
|
||||
}
|
||||
if (isSectionSortDirection(legacyDirection)) {
|
||||
section.sortOrder = legacyDirection;
|
||||
}
|
||||
delete section.sortOrderDirection;
|
||||
return section;
|
||||
}
|
||||
|
||||
function applySectionLevelSort(section, sortBy, sortOrder) {
|
||||
const by = sortBy == null ? '' : String(sortBy).trim();
|
||||
const order = sortOrder == null ? '' : String(sortOrder).trim();
|
||||
delete section.sortOrderDirection;
|
||||
|
||||
if (!by || by === 'Default') delete section.sortBy;
|
||||
else section.sortBy = by;
|
||||
if (isSortByNone(by)) {
|
||||
delete section.sortBy;
|
||||
delete section.sortOrder;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!order || order === 'Default') delete section.sortOrder;
|
||||
else section.sortOrder = order;
|
||||
section.sortBy = by;
|
||||
if (isSectionSortDirection(order)) section.sortOrder = order;
|
||||
else delete section.sortOrder;
|
||||
}
|
||||
|
||||
function applyCollectedQuerySort(queryOptions, sortBy, sortOrder) {
|
||||
if (!queryOptions) return;
|
||||
const by = sortBy == null ? '' : String(sortBy).trim();
|
||||
const order = sortOrder == null ? '' : String(sortOrder).trim();
|
||||
|
||||
if (isSortByNone(by)) {
|
||||
delete queryOptions.SortBy;
|
||||
delete queryOptions.SortOrder;
|
||||
return;
|
||||
}
|
||||
|
||||
queryOptions.SortBy = by;
|
||||
if (isSectionSortDirection(order)) queryOptions.SortOrder = order;
|
||||
else delete queryOptions.SortOrder;
|
||||
}
|
||||
|
||||
function resolvePremiereAgeFields(section) {
|
||||
@@ -513,19 +576,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
const sortByEl = dialog.querySelector('#hsae-advanced-sortBy');
|
||||
if (isProfileFieldActive(root, sortByEl)) {
|
||||
const sortVal = sortByEl?.value;
|
||||
delete section.sortBy;
|
||||
if (sortVal && sortVal !== 'Default') section.sortOrder = sortVal;
|
||||
else delete section.sortOrder;
|
||||
}
|
||||
normalizeSectionSortFields(section);
|
||||
|
||||
const sortByEl = dialog.querySelector('#hsae-advanced-sortBy');
|
||||
const sortDirEl = dialog.querySelector('#hsae-advanced-sortOrder');
|
||||
if (isProfileFieldActive(root, sortDirEl)) {
|
||||
const dirVal = sortDirEl?.value;
|
||||
if (dirVal && dirVal !== 'Default') section.sortOrderDirection = dirVal;
|
||||
else delete section.sortOrderDirection;
|
||||
if (isProfileFieldActive(root, sortByEl)) {
|
||||
applySectionLevelSort(section, sortByEl?.value, sortDirEl?.value);
|
||||
} else {
|
||||
delete section.sortOrderDirection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -545,10 +603,12 @@
|
||||
|
||||
const sortByEl = dialog.querySelector('#hsae-advanced-sortBy');
|
||||
const sortOrderEl = dialog.querySelector('#hsae-advanced-sortOrder');
|
||||
normalizeSectionSortFields(section);
|
||||
if (isProfileFieldActive(root, sortByEl) && !isDiscoverySection(section)) {
|
||||
if (section.useRandomQuery) {
|
||||
delete section.sortBy;
|
||||
delete section.sortOrder;
|
||||
delete section.sortOrderDirection;
|
||||
} else {
|
||||
applySectionLevelSort(section, sortByEl?.value, sortOrderEl?.value);
|
||||
}
|
||||
@@ -991,9 +1051,13 @@
|
||||
const renderMode = section.renderMode || (section.spotlight ? 'Spotlight' : 'Normal');
|
||||
const ttlMatch = matchTtlPreset(section.ttl);
|
||||
const groupSelection = resolveGroupSelection(section, context);
|
||||
const isDiscovery = isDiscoverySection(section);
|
||||
const sectionSortBy = section.sortBy || (isDiscovery ? section.sortOrder : '') || '';
|
||||
const sectionSortOrder = isDiscovery ? (section.sortOrderDirection || '') : (section.sortOrder || '');
|
||||
const normalizedSort = normalizeSectionSortFields({
|
||||
sortBy: section.sortBy,
|
||||
sortOrder: section.sortOrder,
|
||||
sortOrderDirection: section.sortOrderDirection
|
||||
});
|
||||
const sectionSortBy = normalizedSort.sortBy || '';
|
||||
const sectionSortOrder = isSectionSortDirection(normalizedSort.sortOrder) ? normalizedSort.sortOrder : '';
|
||||
|
||||
return {
|
||||
section,
|
||||
@@ -1540,7 +1604,7 @@
|
||||
|
||||
<div class="hsae-field-grid hsae-query-row-sort">
|
||||
<div class="hsae-query-sort-by" data-hsae-profiles="full normal dateCutoffs">
|
||||
${buildSelect(`query-${index}-SortBy`, toSortBySelectOptions(SORT_ORDERS), queryOptions.SortBy || '', 'Sort By')}
|
||||
${buildSelect(`query-${index}-SortBy`, toSortBySelectOptions(SORT_ORDERS), sortBySelectValue(queryOptions.SortBy), 'Sort By')}
|
||||
</div>
|
||||
<div class="hsae-query-sort-order" data-hsae-profiles="full normal dateCutoffs">
|
||||
${buildSelect(`query-${index}-SortOrder`, SORT_ORDER_DIRECTIONS, queryOptions.SortOrder || '', 'Sort Order')}
|
||||
@@ -2310,7 +2374,7 @@
|
||||
|
||||
<div class="hsae-advanced-section-sort hsae-field-grid hsae-field-grid-2 hsae-advanced-sort-row" data-hsae-profiles="full postProcessing normal dateCutoffs">
|
||||
<div class="hsae-field-with-hint">
|
||||
${buildSelect('hsae-advanced-sortBy', toSortBySelectOptions(SORT_ORDERS), state.sortBy || '', 'Sort By')}
|
||||
${buildSelect('hsae-advanced-sortBy', toSortBySelectOptions(SORT_ORDERS), sortBySelectValue(state.sortBy), 'Sort By')}
|
||||
<div class="listItemBodyText secondary hsae-field-hint">Items will be sorted in this order after they are returned from Jellyfin.</div>
|
||||
</div>
|
||||
<div class="hsae-field-with-hint">
|
||||
@@ -2442,12 +2506,11 @@
|
||||
}
|
||||
}
|
||||
if (isProfileFieldActive(root, sortByEl)) {
|
||||
const sortBy = sortByEl?.value;
|
||||
const sortOrder = editor.querySelector(`#query-${queryIndex}-SortOrder`)?.value;
|
||||
if (sortBy) query.queryOptions.SortBy = sortBy;
|
||||
else delete query.queryOptions.SortBy;
|
||||
if (sortOrder) query.queryOptions.SortOrder = sortOrder;
|
||||
else delete query.queryOptions.SortOrder;
|
||||
applyCollectedQuerySort(
|
||||
query.queryOptions,
|
||||
sortByEl?.value,
|
||||
editor.querySelector(`#query-${queryIndex}-SortOrder`)?.value
|
||||
);
|
||||
}
|
||||
if (hideWatched) query.queryOptions.IsUnplayed = true;
|
||||
else if (query.queryOptions) delete query.queryOptions.IsUnplayed;
|
||||
@@ -2467,10 +2530,11 @@
|
||||
if (staticItems.length) {
|
||||
query.queryOptions.Ids = staticItems.map(item => item.id);
|
||||
}
|
||||
['SortBy', 'SortOrder'].forEach(key => {
|
||||
const value = editor.querySelector(`#query-${queryIndex}-${key}`)?.value;
|
||||
if (value) query.queryOptions[key] = value;
|
||||
});
|
||||
applyCollectedQuerySort(
|
||||
query.queryOptions,
|
||||
editor.querySelector(`#query-${queryIndex}-SortBy`)?.value,
|
||||
editor.querySelector(`#query-${queryIndex}-SortOrder`)?.value
|
||||
);
|
||||
return query;
|
||||
}
|
||||
|
||||
@@ -2479,10 +2543,11 @@
|
||||
|| CACHE_SOURCE_OPTIONS[0]?.value;
|
||||
if (dataSource) query.dataSource = dataSource;
|
||||
query.queryOptions = {};
|
||||
['SortBy', 'SortOrder'].forEach(key => {
|
||||
const value = editor.querySelector(`#query-${queryIndex}-${key}`)?.value;
|
||||
if (value) query.queryOptions[key] = value;
|
||||
});
|
||||
applyCollectedQuerySort(
|
||||
query.queryOptions,
|
||||
editor.querySelector(`#query-${queryIndex}-SortBy`)?.value,
|
||||
editor.querySelector(`#query-${queryIndex}-SortOrder`)?.value
|
||||
);
|
||||
const limit = editor.querySelector(`#query-${queryIndex}-Limit`)?.value;
|
||||
if (limit !== '' && limit != null) {
|
||||
const limitN = parseInt(limit, 10);
|
||||
@@ -2550,7 +2615,12 @@
|
||||
delete query.queryOptions.PlaylistIds;
|
||||
delete query.queryOptions._parentItemType;
|
||||
|
||||
['SortBy', 'SortOrder', 'Filters', 'SearchTerm'].forEach(key => {
|
||||
applyCollectedQuerySort(
|
||||
query.queryOptions,
|
||||
editor.querySelector(`#query-${queryIndex}-SortBy`)?.value,
|
||||
editor.querySelector(`#query-${queryIndex}-SortOrder`)?.value
|
||||
);
|
||||
['Filters', 'SearchTerm'].forEach(key => {
|
||||
const value = editor.querySelector(`#query-${queryIndex}-${key}`)?.value;
|
||||
if (value) query.queryOptions[key] = value;
|
||||
});
|
||||
@@ -3651,7 +3721,7 @@
|
||||
'name', 'caption', 'description', 'enabled', 'order', 'cardFormat', 'renderMode', 'ttl',
|
||||
'queries', 'items', 'externalListUrls', 'spotlightConfig', 'hideName', 'userConfigurable',
|
||||
'useRandomQuery', 'useMultiQueryPicker', 'multiQueryPickerLabel', 'useQueryNamesForSection',
|
||||
'sortBy', 'sortOrder', 'sortOrderDirection', 'itemLimit', 'minimumItems', 'flattenSeries',
|
||||
'sortBy', 'sortOrder', 'itemLimit', 'minimumItems', 'flattenSeries',
|
||||
'limitBeforeSort', 'sectionCssClass', 'borderStyle', 'borderColor', 'cardTitleColor',
|
||||
'itemsLayout', 'useGaplessCards', 'cardTitleVisibility', 'useParentCard', 'cardTitlePosition',
|
||||
'cardTitleCapitalization', 'cardTitleFontFamily', 'cardTitleFontSize', 'startDate', 'endDate',
|
||||
@@ -3959,6 +4029,8 @@
|
||||
function diffSectionAgainstDefault(current, canonical) {
|
||||
const diffs = [];
|
||||
if (!current || !canonical) return diffs;
|
||||
current = normalizeSectionSortFields({ ...current });
|
||||
canonical = normalizeSectionSortFields({ ...canonical });
|
||||
for (const key of HSAE_SECTION_DIFF_KEYS) {
|
||||
const hasCurrent = Object.prototype.hasOwnProperty.call(current, key);
|
||||
const hasCanonical = Object.prototype.hasOwnProperty.call(canonical, key);
|
||||
|
||||
@@ -1814,7 +1814,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -1881,7 +1881,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -1912,7 +1912,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -1943,7 +1943,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -1989,7 +1989,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2028,7 +2028,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2067,7 +2067,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2110,7 +2110,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
{
|
||||
@@ -2144,7 +2144,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2178,7 +2178,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2212,7 +2212,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2251,7 +2251,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2294,7 +2294,7 @@
|
||||
Recursive: true,
|
||||
IncludeItemTypes: ["Series"],
|
||||
MinCommunityRating: 7.5,
|
||||
Limit: 20,
|
||||
Limit: 100,
|
||||
Fields: DISCOVERY_CONTENT_FIELDS,
|
||||
},
|
||||
},
|
||||
@@ -2328,7 +2328,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
{
|
||||
@@ -2363,7 +2363,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2435,7 +2435,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
{
|
||||
@@ -2468,7 +2468,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2502,7 +2502,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2536,7 +2536,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2563,7 +2563,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2599,7 +2599,7 @@
|
||||
enabled: false,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Thumb",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2631,7 +2631,7 @@
|
||||
enabled: false,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Thumb",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2663,7 +2663,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2708,7 +2708,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Poster",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2747,7 +2747,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Thumb",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2787,7 +2787,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Thumb",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
@@ -2834,7 +2834,7 @@
|
||||
enabled: true,
|
||||
userConfigurable: true,
|
||||
itemLimit: 20,
|
||||
sortOrder: "Random",
|
||||
sortBy: "Random",
|
||||
cardFormat: "Thumb",
|
||||
ttl: CACHE_CONFIG.DISCOVERY_TTL,
|
||||
queries: [
|
||||
|
||||
@@ -8,6 +8,24 @@
|
||||
const ERR = (...args) => console.error('[KefinTweaks SectionHelper]', ...args);
|
||||
|
||||
const ApiHelper = window.apiHelper || window.ApiHelper;
|
||||
|
||||
function isSortDirectionValue(value) {
|
||||
const v = value == null ? '' : String(value).trim();
|
||||
return v === 'Ascending' || v === 'Descending';
|
||||
}
|
||||
|
||||
/** Legacy sortOrder was the field; sortOrder is now Ascending/Descending only. */
|
||||
function normalizeInstanceSort(instanceConfig) {
|
||||
const sortBy = instanceConfig?.sortBy == null ? '' : String(instanceConfig.sortBy).trim();
|
||||
const order = instanceConfig?.sortOrder == null ? '' : String(instanceConfig.sortOrder).trim();
|
||||
const legacyDirection = instanceConfig?.sortOrderDirection == null
|
||||
? ''
|
||||
: String(instanceConfig.sortOrderDirection).trim();
|
||||
const out = { sortBy, sortOrder: isSortDirectionValue(order) ? order : '' };
|
||||
if (order && !isSortDirectionValue(order) && !out.sortBy) out.sortBy = order;
|
||||
if (isSortDirectionValue(legacyDirection)) out.sortOrder = legacyDirection;
|
||||
return out;
|
||||
}
|
||||
const Config = () => window.KefinHomeConfig2 || window.KefinHomeScreen?.getConfig?.() || {};
|
||||
|
||||
const discoveryState = {
|
||||
@@ -1213,8 +1231,9 @@
|
||||
};
|
||||
|
||||
if (!hasTemplateQueries) {
|
||||
if (instanceConfig.sortOrder) queryOptions.SortBy = instanceConfig.sortOrder;
|
||||
if (instanceConfig.sortOrderDirection) queryOptions.SortOrder = instanceConfig.sortOrderDirection;
|
||||
const sort = normalizeInstanceSort(instanceConfig);
|
||||
if (sort.sortBy) queryOptions.SortBy = sort.sortBy;
|
||||
if (sort.sortOrder) queryOptions.SortOrder = sort.sortOrder;
|
||||
} else if (!queryOptions.IncludeItemTypes?.length) {
|
||||
queryOptions.IncludeItemTypes = contentTypes;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user