fix(overlays): add daysAgoNextSeason and fix AWAITING DOWNLOAD preset template

This commit is contained in:
Tom Wheeler
2025-12-16 02:57:19 +13:00
parent da31ec4e45
commit 9d2f6aec8f
4 changed files with 71 additions and 10 deletions

View File

@@ -256,6 +256,11 @@ class OverlayLibraryService {
let errorCount = 0;
for (const item of allItems) {
// CRITICAL: Skip episodes and seasons - overlays only apply to movies and shows
if (item.type === 'episode' || item.type === 'season') {
continue;
}
// Check for cancellation
if (checkCancelled && checkCancelled()) {
logger.info(
@@ -417,6 +422,14 @@ class OverlayLibraryService {
const itemMetadata = await plexApi.getMetadata(ratingKey);
if (itemMetadata) {
// CRITICAL: Skip episodes and seasons - overlays only apply to movies and shows
if (
itemMetadata.type === 'episode' ||
itemMetadata.type === 'season'
) {
continue;
}
// Convert to PlexLibraryItem format (cast to satisfy type requirements)
const item = {
ratingKey: itemMetadata.ratingKey,
@@ -430,6 +443,8 @@ class OverlayLibraryService {
index: itemMetadata.index,
addedAt: itemMetadata.addedAt || 0,
updatedAt: itemMetadata.updatedAt || 0,
editionTitle: (itemMetadata as { editionTitle?: string })
.editionTitle,
} as PlexLibraryItem;
await this.applyOverlaysToItem(
@@ -584,6 +599,7 @@ class OverlayLibraryService {
let daysAgo: number | undefined;
let daysUntilNextEpisode: number | undefined;
let daysUntilNextSeason: number | undefined;
let daysAgoNextSeason: number | undefined;
if (releaseDateInfo.releaseDate) {
const daysSince = calculateDaysSince(releaseDateInfo.releaseDate);
@@ -609,6 +625,8 @@ class OverlayLibraryService {
);
if (daysSince < 0) {
daysUntilNextSeason = -daysSince;
} else {
daysAgoNextSeason = daysSince;
}
}
@@ -620,6 +638,7 @@ class OverlayLibraryService {
daysUntilNextEpisode,
nextSeasonAirDate: releaseDateInfo.nextSeasonAirDate,
daysUntilNextSeason,
daysAgoNextSeason,
seasonNumber: releaseDateInfo.seasonNumber,
};
}
@@ -656,11 +675,11 @@ class OverlayLibraryService {
const context: OverlayRenderContext = {
...baseContext,
...releaseDateContext,
...monitoringContext,
...contextOverrides,
isPlaceholder: actualIsPlaceholder,
downloaded,
...contextOverrides,
...releaseDateContext,
...monitoringContext,
};
// Filter templates by conditions to get only templates that will actually be applied

View File

@@ -244,6 +244,7 @@ export interface OverlayRenderContext {
daysUntilNextEpisode?: number; // Calculated days until ANY next episode
nextSeasonAirDate?: string; // Raw date for SEASON PREMIERES only (episode 1)
daysUntilNextSeason?: number; // Calculated days until next SEASON PREMIERE only
daysAgoNextSeason?: number; // Days since next season premiered (only if nextSeasonAirDate is in the past)
// Episode information
seasonNumber?: number;

View File

@@ -328,10 +328,15 @@ export const PRESET_TEMPLATES: {
applicationCondition: {
sections: [
{
// MOVIES: Released (daysAgo >= 0), not downloaded, monitored, in Radarr
rules: [
// Released items only (daysAgo >= 0 means already released)
// Note: daysUntilRelease and daysAgo are mutually exclusive
{ field: 'daysAgo', operator: 'gte', value: 0 },
{ field: 'mediaType', operator: 'neq', value: 'show' },
{
ruleOperator: 'and',
field: 'daysAgo',
operator: 'gte',
value: 0,
},
{
ruleOperator: 'and',
field: 'downloaded',
@@ -344,15 +349,39 @@ export const PRESET_TEMPLATES: {
operator: 'eq',
value: true,
},
{
ruleOperator: 'and',
field: 'inRadarr',
operator: 'eq',
value: true,
},
],
},
{
// AND (in Radarr OR in Sonarr)
sectionOperator: 'and',
// OR TV SHOWS: Monitored season has aired (daysAgoNextSeason >= 0), not downloaded, monitored, in Sonarr
sectionOperator: 'or',
rules: [
{ field: 'inRadarr', operator: 'eq', value: true },
{ field: 'mediaType', operator: 'eq', value: 'show' },
{
ruleOperator: 'or',
ruleOperator: 'and',
field: 'daysAgoNextSeason',
operator: 'gte',
value: 0,
},
{
ruleOperator: 'and',
field: 'downloaded',
operator: 'eq',
value: false,
},
{
ruleOperator: 'and',
field: 'isMonitored',
operator: 'eq',
value: true,
},
{
ruleOperator: 'and',
field: 'inSonarr',
operator: 'eq',
value: true,

View File

@@ -209,6 +209,7 @@ export interface OverlayRenderContext {
daysUntilNextEpisode?: number; // Calculated days until ANY next episode
nextSeasonAirDate?: string; // Raw date for SEASON PREMIERES only (episode 1)
daysUntilNextSeason?: number; // Calculated days until next SEASON PREMIERE only
daysAgoNextSeason?: number; // Days since next season premiered (only if nextSeasonAirDate is in the past)
// Episode information
seasonNumber?: number;
@@ -322,6 +323,11 @@ export const AVAILABLE_VARIABLES = {
label: 'Days Until Next Season (TV)',
example: '45',
},
{
field: 'daysAgoNextSeason',
label: 'Days Since Next Season Premiered (TV)',
example: '7',
},
{ field: 'seasonNumber', label: 'Season Number', example: '5' },
{ field: 'episodeNumber', label: 'Episode Number', example: '16' },
{
@@ -432,6 +438,11 @@ export const CONDITION_FIELD_CATEGORIES = {
label: 'Days Until Next Season (TV)',
example: '45',
},
{
field: 'daysAgoNextSeason',
label: 'Days Since Next Season Premiered (TV)',
example: '7',
},
{ field: 'seasonNumber', label: 'Season Number', example: '5' },
{ field: 'episodeNumber', label: 'Episode Number', example: '16' },
{ field: 'episodeLabel', label: 'Episode Label', example: 'SERIES FINALE' },
@@ -560,6 +571,7 @@ export const SAMPLE_PREVIEW_CONTEXTS: {
daysUntilNextEpisode: 7, // Days until next episode
nextSeasonAirDate: '2025-02-05', // Next SEASON premiere (episode 1 only)
daysUntilNextSeason: 45, // Days until next season
daysAgoNextSeason: undefined, // Not set when season hasn't aired yet
daysAgo: 0,
isMonitored: true,
inSonarr: true,