From 3f46f28a709dccbd60ae5c34053c8e0a913371c9 Mon Sep 17 00:00:00 2001 From: SergeantPanda Date: Fri, 2 Jan 2026 15:22:25 -0600 Subject: [PATCH] Bug Fix: Auto Channel Sync Force EPG Source feature not properly forcing "No EPG" assignment - When selecting "Force EPG Source" > "No EPG (Disabled)", channels were still being auto-matched to EPG data instead of forcing dummy/no EPG. Now correctly sets `force_dummy_epg` flag to prevent unwanted EPG assignment. (Fixes #788) --- CHANGELOG.md | 1 + .../src/components/forms/LiveGroupFilter.jsx | 133 ++++++++++++------ 2 files changed, 90 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 381b5570..ef933e8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Auto Channel Sync Force EPG Source feature not properly forcing "No EPG" assignment - When selecting "Force EPG Source" > "No EPG (Disabled)", channels were still being auto-matched to EPG data instead of forcing dummy/no EPG. Now correctly sets `force_dummy_epg` flag to prevent unwanted EPG assignment. (Fixes #788) - VOD episode processing now properly handles season and episode numbers from APIs that return string values instead of integers, with comprehensive error logging to track data quality issues - Thanks [@patchy8736](https://github.com/patchy8736) (Fixes #770) - VOD episode-to-stream relations are now validated to ensure episodes have been saved to the database before creating relations, preventing integrity errors when bulk_create operations encounter conflicts - Thanks [@patchy8736](https://github.com/patchy8736) - VOD category filtering now correctly handles category names containing pipe "|" characters (e.g., "PL | BAJKI", "EN | MOVIES") by using `rsplit()` to split from the right instead of the left, ensuring the category type is correctly extracted as the last segment - Thanks [@Vitekant](https://github.com/Vitekant) diff --git a/frontend/src/components/forms/LiveGroupFilter.jsx b/frontend/src/components/forms/LiveGroupFilter.jsx index ef68bee8..b6e6494c 100644 --- a/frontend/src/components/forms/LiveGroupFilter.jsx +++ b/frontend/src/components/forms/LiveGroupFilter.jsx @@ -369,7 +369,8 @@ const LiveGroupFilter = ({ if ( group.custom_properties?.custom_epg_id !== undefined || - group.custom_properties?.force_dummy_epg + group.custom_properties?.force_dummy_epg || + group.custom_properties?.force_epg_selected ) { selectedValues.push('force_epg'); } @@ -432,23 +433,20 @@ const LiveGroupFilter = ({ // Handle force_epg if (selectedOptions.includes('force_epg')) { - // Migrate from old force_dummy_epg if present + // Set default to force_dummy_epg if no EPG settings exist yet if ( - newCustomProps.force_dummy_epg && - newCustomProps.custom_epg_id === undefined + newCustomProps.custom_epg_id === + undefined && + !newCustomProps.force_dummy_epg ) { - // Migrate: force_dummy_epg=true becomes custom_epg_id=null - newCustomProps.custom_epg_id = null; - delete newCustomProps.force_dummy_epg; - } else if ( - newCustomProps.custom_epg_id === undefined - ) { - // New configuration: initialize with null (no EPG/default dummy) - newCustomProps.custom_epg_id = null; + // Default to "No EPG (Disabled)" + newCustomProps.force_dummy_epg = true; } } else { - // Only remove custom_epg_id when deselected + // Remove all EPG settings when deselected delete newCustomProps.custom_epg_id; + delete newCustomProps.force_dummy_epg; + delete newCustomProps.force_epg_selected; } // Handle group_override @@ -1124,7 +1122,8 @@ const LiveGroupFilter = ({ {/* Show EPG selector when force_epg is selected */} {(group.custom_properties?.custom_epg_id !== undefined || - group.custom_properties?.force_dummy_epg) && ( + group.custom_properties?.force_dummy_epg || + group.custom_properties?.force_epg_selected) && ( { - // Handle migration from force_dummy_epg + // Show custom EPG if set if ( group.custom_properties?.custom_epg_id !== - undefined + undefined && + group.custom_properties?.custom_epg_id !== null ) { - // Convert to string, use '0' for null/no EPG - return group.custom_properties.custom_epg_id === - null - ? '0' - : group.custom_properties.custom_epg_id.toString(); - } else if ( - group.custom_properties?.force_dummy_epg - ) { - // Show "No EPG" for old force_dummy_epg configs + return group.custom_properties.custom_epg_id.toString(); + } + // Show "No EPG" if force_dummy_epg is set + if (group.custom_properties?.force_dummy_epg) { return '0'; } - return '0'; + // Otherwise show empty/placeholder + return null; })()} onChange={(value) => { - // Convert back: '0' means no EPG (null) - const newValue = - value === '0' ? null : parseInt(value); - setGroupStates( - groupStates.map((state) => { - if ( - state.channel_group === group.channel_group - ) { - return { - ...state, - custom_properties: { + if (value === '0') { + // "No EPG (Disabled)" selected - use force_dummy_epg + setGroupStates( + groupStates.map((state) => { + if ( + state.channel_group === + group.channel_group + ) { + const newProps = { ...state.custom_properties, - custom_epg_id: newValue, - }, - }; - } - return state; - }) - ); + }; + delete newProps.custom_epg_id; + delete newProps.force_epg_selected; + newProps.force_dummy_epg = true; + return { + ...state, + custom_properties: newProps, + }; + } + return state; + }) + ); + } else if (value) { + // Specific EPG source selected + const epgId = parseInt(value); + setGroupStates( + groupStates.map((state) => { + if ( + state.channel_group === + group.channel_group + ) { + const newProps = { + ...state.custom_properties, + }; + newProps.custom_epg_id = epgId; + delete newProps.force_dummy_epg; + delete newProps.force_epg_selected; + return { + ...state, + custom_properties: newProps, + }; + } + return state; + }) + ); + } else { + // Cleared - remove all EPG settings + setGroupStates( + groupStates.map((state) => { + if ( + state.channel_group === + group.channel_group + ) { + const newProps = { + ...state.custom_properties, + }; + delete newProps.custom_epg_id; + delete newProps.force_dummy_epg; + delete newProps.force_epg_selected; + return { + ...state, + custom_properties: newProps, + }; + } + return state; + }) + ); + } }} data={[ { value: '0', label: 'No EPG (Disabled)' },