From 07658f4fbc72fa9aadda08ec753fc9b9d9549851 Mon Sep 17 00:00:00 2001
From: CodeDevMLH <145071728+CodeDevMLH@users.noreply.github.com>
Date: Sun, 8 Mar 2026 19:32:15 +0100
Subject: [PATCH] Add Exclude Seasonal Content option to configuration and
update related logic
---
.../Configuration/PluginConfiguration.cs | 1 +
.../Configuration/configPage.html | 12 +++++-
.../Web/mediaBarEnhanced.js | 37 ++++++++++++++++++-
3 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Configuration/PluginConfiguration.cs b/Jellyfin.Plugin.MediaBarEnhanced/Configuration/PluginConfiguration.cs
index ac445a3..dc93253 100644
--- a/Jellyfin.Plugin.MediaBarEnhanced/Configuration/PluginConfiguration.cs
+++ b/Jellyfin.Plugin.MediaBarEnhanced/Configuration/PluginConfiguration.cs
@@ -40,6 +40,7 @@ namespace Jellyfin.Plugin.MediaBarEnhanced.Configuration
public bool EnableCustomMediaIds { get; set; } = true;
public string PreferredVideoQuality { get; set; } = "Auto";
public bool EnableSeasonalContent { get; set; } = false;
+ public bool ExcludeSeasonalContent { get; set; } = true;
public string SeasonalSections { get; set; } = "[]";
public bool IsEnabled { get; set; } = true;
public bool EnableClientSideSettings { get; set; } = false;
diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html b/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html
index 651ab9a..b1afc7a 100644
--- a/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html
+++ b/Jellyfin.Plugin.MediaBarEnhanced/Configuration/configPage.html
@@ -183,6 +183,14 @@
during their active date ranges. If no season matches the current date, the default
Custom Media IDs above or random selection are used as fallback.
+
IsEnabled, to avoid conflicts with other plugins
@@ -621,7 +629,7 @@
'PreferLocalTrailers', 'ApplyLimitsToCustomIds', 'SeasonalSections',
'PreferLocalBackdrops', 'RandomizeThemeVideos', 'RandomizeLocalTrailers',
'IncludeWatchedContent', 'ShowPaginationDots', 'MaxParentalRating',
- 'MaxDaysRecent'
+ 'MaxDaysRecent', 'ExcludeSeasonalContent'
];
keys.forEach(function (key) {
diff --git a/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js b/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js
index 689b016..d12f6d5 100644
--- a/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js
+++ b/Jellyfin.Plugin.MediaBarEnhanced/Web/mediaBarEnhanced.js
@@ -66,6 +66,7 @@ const CONFIG = {
sortOrder: "Ascending",
applyLimitsToCustomIds: false,
seasonalSections: "[]",
+ excludeSeasonalContent: true,
isEnabled: true,
};
@@ -1125,9 +1126,43 @@ const ApiUtils = {
pastDate.setDate(pastDate.getDate() - CONFIG.maxDaysRecent);
dateFilter = `&minDateLastSaved=${pastDate.toISOString()}`;
}
+
+ // Exclude seasonal content from random lists
+ let excludeFilter = '';
+ if (CONFIG.excludeSeasonalContent && CONFIG.seasonalSections) {
+ try {
+ const sections = JSON.parse(CONFIG.seasonalSections || "[]");
+ let allExcludedIds = [];
+
+ for (const section of sections) {
+ if (section.MediaIds) {
+ const idsInThisSection = section.MediaIds.split(/[\n,]/)
+ .map((line) => {
+ const urlMatch = line.match(/\[(.*?)\]/);
+ let id = line;
+ if (urlMatch) {
+ id = line.replace(/\[.*?\]/, '').trim();
+ const guidMatch = id.match(/([0-9a-f]{32})/i);
+ if (guidMatch) { id = guidMatch[1]; } else { id = id.split('|')[0].trim(); }
+ }
+ return id.trim();
+ })
+ .filter((id) => id);
+
+ allExcludedIds.push(...idsInThisSection);
+ }
+ }
+
+ if (allExcludedIds.length > 0) {
+ excludeFilter = `&ExcludeItemIds=${allExcludedIds.join(',')}`;
+ }
+ } catch(e) {
+ console.error("🎬 Media Bar:", "Error extracting seasonal IDs for exclusion:", e);
+ }
+ }
const fetchItems = async (currentDateFilter) => {
- const url = `${STATE.jellyfinData.serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&hasOverview=true&imageTypes=Logo,Backdrop&${sortParams}${playedFilter}${parentalFilter}${currentDateFilter}&enableUserData=true&Limit=${CONFIG.maxItems}&fields=Id,DateCreated`;
+ const url = `${STATE.jellyfinData.serverAddress}/Items?IncludeItemTypes=Movie,Series&Recursive=true&hasOverview=true&imageTypes=Logo,Backdrop&${sortParams}${playedFilter}${parentalFilter}${currentDateFilter}${excludeFilter}&enableUserData=true&Limit=${CONFIG.maxItems}&fields=Id,DateCreated`;
const resp = await fetch(url, { headers: this.getAuthHeaders() });
return resp;
};