diff --git a/CHANGELOG.md b/CHANGELOG.md index 696fa330..5190db86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Improved the HDHR, M3U, and EPG URL builder popovers in the Channels table: each popover now opens with a brief intro sentence describing its purpose. Toggle switches were refactored to use Mantine's native `label` and `description` props (replacing the previous manual `Group`/`Stack`/`Text` layout), giving each switch a properly styled description line beneath its label. Switch alignment was also corrected. Toggles now appear on the left with the label and description stacked to the right, consistent with standard Mantine form layout. - Redesigned the User settings modal with a tabbed layout: **Account** (username, email, name, password), **Permissions** (user level, stream limit, channel profiles, mature content filter - admin only), **EPG Defaults** (days forward/back), and **API & XC** (XC password, API key management). Fields are now logically grouped rather than split across two ad-hoc columns. - EPG channel scanning now automatically removes stale `EPGData` entries. tvg-ids that were present in a previous scan but are no longer found in the upstream source, provided they are not mapped to any channel. This prevents unbounded database bloat over time. Entries mapped to at least one channel are always preserved. - Rewrote the M3U line parser as an `iter_m3u_entries` generator that owns the full per-entry state machine. Intermediate directive lines between `#EXTINF` and the stream URL are now handled correctly rather than corrupting the pending entry or being silently misassigned. A `#EXTINF` with no following URL is discarded with a warning instead of carrying over a `url`-less entry into batch processing. Attribute keys are normalised to lowercase during parsing (provider attribute names remain case-insensitive end-to-end). The `#EXTINF` attribute regex is pre-compiled at module load, and attribute lookups use O(1) `dict.get()` instead of linear scans — approximately 10% faster parsing on large M3U files. diff --git a/frontend/src/components/tables/ChannelsTable.jsx b/frontend/src/components/tables/ChannelsTable.jsx index b931a551..c3a3e363 100644 --- a/frontend/src/components/tables/ChannelsTable.jsx +++ b/frontend/src/components/tables/ChannelsTable.jsx @@ -1251,7 +1251,7 @@ const ChannelsTable = ({ onReady }) => { - { width: 'max-content', }} > - - + Use this URL in HDHomeRun-compatible apps and IPTV + clients. + + - - - + readOnly + style={{ width: '100%' }} + rightSection={ + + + + } + /> + { onClick={stopPropagation} onMouseDown={stopPropagation} > + + Use this URL in your media player or IPTV app to load your + channel list. + { } /> - - Use cached logos - - setM3uParams((prev) => ({ - ...prev, - cachedlogos: event.target.checked, - })) - } - /> - - - Direct stream URLs - - setM3uParams((prev) => ({ - ...prev, - direct: event.target.checked, - })) - } - /> - {' '} + + setM3uParams((prev) => ({ + ...prev, + cachedlogos: event.target.checked, + })) + } + /> + + setM3uParams((prev) => ({ + ...prev, + direct: event.target.checked, + })) + } + /> setEpgParams((prev) => ({ @@ -1446,7 +1466,8 @@ const ChannelsTable = ({ onReady }) => { /> { />