From bc3ef1a3a9c11e2a5d9317d6fc0c86c11f3403ff Mon Sep 17 00:00:00 2001 From: SergeantPanda Date: Fri, 26 Dec 2025 14:58:02 -0600 Subject: [PATCH] Bug Fix: M3U and EPG manager page no longer crashes when a playlist references a deleted channel group (Fixes screen blank on navigation) --- CHANGELOG.md | 1 + .../src/components/forms/LiveGroupFilter.jsx | 44 ++++++++++--------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1dadb4c..0b0c8011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- M3U and EPG manager page no longer crashes when a playlist references a deleted channel group (Fixes screen blank on navigation) - Stream validation now returns original URL instead of redirected URL to prevent issues with temporary redirect URLs that expire before clients can connect - XtreamCodes EPG limit parameter now properly converted to integer to prevent type errors when accessing EPG listings (Fixes #781) - Stream validation now continues with GET request if HEAD request fails due to connection issues - Thanks [@kvnnap](https://github.com/kvnnap) (Fixes #782) diff --git a/frontend/src/components/forms/LiveGroupFilter.jsx b/frontend/src/components/forms/LiveGroupFilter.jsx index 3497957b..ef68bee8 100644 --- a/frontend/src/components/forms/LiveGroupFilter.jsx +++ b/frontend/src/components/forms/LiveGroupFilter.jsx @@ -96,28 +96,30 @@ const LiveGroupFilter = ({ } setGroupStates( - playlist.channel_groups.map((group) => { - // Parse custom_properties if present - let customProps = {}; - if (group.custom_properties) { - try { - customProps = - typeof group.custom_properties === 'string' - ? JSON.parse(group.custom_properties) - : group.custom_properties; - } catch { - customProps = {}; + playlist.channel_groups + .filter((group) => channelGroups[group.channel_group]) // Filter out groups that don't exist + .map((group) => { + // Parse custom_properties if present + let customProps = {}; + if (group.custom_properties) { + try { + customProps = + typeof group.custom_properties === 'string' + ? JSON.parse(group.custom_properties) + : group.custom_properties; + } catch { + customProps = {}; + } } - } - return { - ...group, - name: channelGroups[group.channel_group].name, - auto_channel_sync: group.auto_channel_sync || false, - auto_sync_channel_start: group.auto_sync_channel_start || 1.0, - custom_properties: customProps, - original_enabled: group.enabled, - }; - }) + return { + ...group, + name: channelGroups[group.channel_group].name, + auto_channel_sync: group.auto_channel_sync || false, + auto_sync_channel_start: group.auto_sync_channel_start || 1.0, + custom_properties: customProps, + original_enabled: group.enabled, + }; + }) ); }, [playlist, channelGroups]);