From 719a9752108781e1ee73a97f721813cce3de7e85 Mon Sep 17 00:00:00 2001 From: SergeantPanda Date: Fri, 9 Jan 2026 14:57:07 -0600 Subject: [PATCH] Enhancement: Visual stale indicators for streams and groups: Added `is_stale` field to Stream and both `is_stale` and `last_seen` fields to ChannelGroupM3UAccount models to track items in their retention grace period. Stale groups display with orange buttons and a warning tooltip, while stale streams show with a red background color matching the visual treatment of empty channels. --- CHANGELOG.md | 2 +- .../src/components/forms/LiveGroupFilter.jsx | 51 ++++++++++++------- .../components/tables/ChannelTableStreams.jsx | 4 ++ .../src/components/tables/StreamsTable.jsx | 8 +++ 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b797e0a6..4758b146 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Group retention policy for M3U accounts: Groups now follow the same stale retention logic as streams, using the account's `stale_stream_days` setting. Groups that temporarily disappear from an M3U source are retained for the configured retention period instead of being immediately deleted, preserving user settings and preventing data loss when providers temporarily remove/re-add groups. (Closes #809) -- Stale status indicators for streams and groups: Added `is_stale` field to both Stream and ChannelGroupM3UAccount models to track items in their grace period (seen in previous refresh but not current). +- Visual stale indicators for streams and groups: Added `is_stale` field to Stream and both `is_stale` and `last_seen` fields to ChannelGroupM3UAccount models to track items in their retention grace period. Stale groups display with orange buttons and a warning tooltip, while stale streams show with a red background color matching the visual treatment of empty channels. ### Changed diff --git a/frontend/src/components/forms/LiveGroupFilter.jsx b/frontend/src/components/forms/LiveGroupFilter.jsx index b6e6494c..68f4db8c 100644 --- a/frontend/src/components/forms/LiveGroupFilter.jsx +++ b/frontend/src/components/forms/LiveGroupFilter.jsx @@ -263,25 +263,42 @@ const LiveGroupFilter = ({ }} > {/* Group Enable/Disable Button */} - + + {/* Auto Sync Controls */} diff --git a/frontend/src/components/tables/ChannelTableStreams.jsx b/frontend/src/components/tables/ChannelTableStreams.jsx index 947320dc..4fb62009 100644 --- a/frontend/src/components/tables/ChannelTableStreams.jsx +++ b/frontend/src/components/tables/ChannelTableStreams.jsx @@ -105,6 +105,7 @@ const DraggableRow = ({ row, index }) => { }} > {row.getVisibleCells().map((cell) => { + const isStale = row.original.is_stale; return ( { ? cell.column.getSize() : undefined, minWidth: 0, + ...(isStale && { + backgroundColor: 'rgba(239, 68, 68, 0.15)', + }), }} > diff --git a/frontend/src/components/tables/StreamsTable.jsx b/frontend/src/components/tables/StreamsTable.jsx index dbc5634e..b8ce52a4 100644 --- a/frontend/src/components/tables/StreamsTable.jsx +++ b/frontend/src/components/tables/StreamsTable.jsx @@ -885,6 +885,14 @@ const StreamsTable = ({ onReady }) => { bodyCellRenderFns: { actions: renderBodyCell, }, + getRowStyles: (row) => { + if (row.original.is_stale) { + return { + backgroundColor: 'rgba(239, 68, 68, 0.15)', + }; + } + return {}; + }, }); /**