diff --git a/CHANGELOG.md b/CHANGELOG.md index f2cc8b289..3c3a0646f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,9 +80,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - This bug caused some graphics elements to display too early after first joining a channel - Optimize database calls made for search index rebuilds and updates - This should improve performance of library scans +- Add toggle to hide/show disabled channels in channel list +- Add disabled text color and `(D)` and `(H)` labels for disabled and hidden channels in channel list ### Changed -- Classic playouts: `Refresh` classic playouts from playout list; do not `Reset` them +- Classic schedules: `Refresh` classic playouts from playout list; do not `Reset` them - This mode maintains progress; progress can be reset by editing the playout and clicking `Erase Items and History` - Use smaller batch size for search index updates (100, down from 1000) - This should help newly scanned items appear in the UI more quickly diff --git a/ErsatzTV.Application/Channels/Queries/GetAllChannels.cs b/ErsatzTV.Application/Channels/Queries/GetAllChannels.cs index 5cdd67d45..f49820ebc 100644 --- a/ErsatzTV.Application/Channels/Queries/GetAllChannels.cs +++ b/ErsatzTV.Application/Channels/Queries/GetAllChannels.cs @@ -1,3 +1,3 @@ namespace ErsatzTV.Application.Channels; -public record GetAllChannels : IRequest>; +public record GetAllChannels(bool ShowDisabled = true) : IRequest>; diff --git a/ErsatzTV.Application/Channels/Queries/GetAllChannelsHandler.cs b/ErsatzTV.Application/Channels/Queries/GetAllChannelsHandler.cs index a17bba49a..66d02d669 100644 --- a/ErsatzTV.Application/Channels/Queries/GetAllChannelsHandler.cs +++ b/ErsatzTV.Application/Channels/Queries/GetAllChannelsHandler.cs @@ -9,7 +9,8 @@ public class GetAllChannelsHandler(IChannelRepository channelRepository) { public async Task> Handle(GetAllChannels request, CancellationToken cancellationToken) => await channelRepository.GetAll(cancellationToken) - .Map(list => list.Map(c => ProjectToViewModel(c, GetPlayoutsCount(c))).ToList()); + .Map(list => list.Where(c => c.IsEnabled || request.ShowDisabled) + .Map(c => ProjectToViewModel(c, GetPlayoutsCount(c))).ToList()); private static int GetPlayoutsCount(Channel channel) { diff --git a/ErsatzTV.Core/Domain/ConfigElementKey.cs b/ErsatzTV.Core/Domain/ConfigElementKey.cs index 7f4661321..c1f89cdbf 100644 --- a/ErsatzTV.Core/Domain/ConfigElementKey.cs +++ b/ErsatzTV.Core/Domain/ConfigElementKey.cs @@ -33,6 +33,7 @@ public class ConfigElementKey public static ConfigElementKey HDHRUUID => new("hdhr.uuid"); public static ConfigElementKey PagesIsDarkMode => new("pages.is_dark_mode"); public static ConfigElementKey ChannelsPageSize => new("pages.channels.page_size"); + public static ConfigElementKey ChannelsShowDisabled => new("pages.channels.show_disabled"); public static ConfigElementKey CollectionsPageSize => new("pages.collections.page_size"); public static ConfigElementKey MultiCollectionsPageSize => new("pages.multi_collections.page_size"); public static ConfigElementKey SmartCollectionsPageSize => new("pages.smart_collections.page_size"); diff --git a/ErsatzTV/Pages/Channels.razor b/ErsatzTV/Pages/Channels.razor index 294b6100e..d9d8af814 100644 --- a/ErsatzTV/Pages/Channels.razor +++ b/ErsatzTV/Pages/Channels.razor @@ -27,7 +27,11 @@ + @ref="_table" + RowClassFunc="ChannelRowClassFunc"> + + + @@ -53,7 +57,24 @@ - @context.Number + + @if (!context.IsEnabled) + { + + @($"(D) {context.Number}") + + } + else if (!context.ShowInEpg) + { + + @($"(H) {context.Number}") + + } + else + { + @context.Number + } + @if (!string.IsNullOrWhiteSpace(context.Logo?.Path)) { @@ -110,14 +131,14 @@ } else { -
+
} - @if (context.PlayoutCount > 0) + @if (context.PlayoutCount > 0 && context.IsEnabled) { _ffmpegProfiles = []; private readonly System.Collections.Generic.HashSet _channelsThatCanPreview = []; private readonly Dictionary _ffmpegProfilesThatCanPreview = []; - + private bool _showDisabled; private int _rowsPerPage = 10; + private bool ShowDisabled + { + get => _showDisabled; + set + { + if (_showDisabled != value) + { + _showDisabled = value; + _table?.ReloadServerData(); + } + } + } + protected override void OnInitialized() => SegmenterService.OnWorkersChanged += WorkersChanged; private void WorkersChanged(object sender, EventArgs e) => @@ -181,6 +215,8 @@ token.ThrowIfCancellationRequested(); _rowsPerPage = await Mediator.Send(new GetConfigElementByKey(ConfigElementKey.ChannelsPageSize), token) .Map(maybeRows => maybeRows.Match(ce => int.TryParse(ce.Value, out int rows) ? rows : 10, () => 10)); + _showDisabled = await Mediator.Send(new GetConfigElementByKey(ConfigElementKey.ChannelsShowDisabled), token) + .Map(maybeShow => maybeShow.Match(ce => bool.TryParse(ce.Value, out bool show) && show, () => false)); } catch (OperationCanceledException) { @@ -292,9 +328,11 @@ private async Task> ServerReload(TableState state, CancellationToken cancellationToken) { await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.ChannelsPageSize, state.PageSize.ToString()), cancellationToken); + await Mediator.Send(new SaveConfigElementByKey(ConfigElementKey.ChannelsShowDisabled, _showDisabled.ToString()), cancellationToken); + cancellationToken.ThrowIfCancellationRequested(); - List channels = await Mediator.Send(new GetAllChannels(), cancellationToken); + List channels = await Mediator.Send(new GetAllChannels(_showDisabled), cancellationToken); // TODO: properly page this data IOrderedEnumerable sorted = channels.OrderBy(c => decimal.Parse(c.Number, CultureInfo.InvariantCulture)) .Skip(state.Page * state.PageSize) @@ -348,4 +386,9 @@ return await JsRuntime.InvokeAsync("mediaSourceSupports", codecString); } + private string ChannelRowClassFunc(ChannelViewModel channel, int index) + { + return channel.IsEnabled && channel.ShowInEpg ? string.Empty : "channel-disabled"; + } + } diff --git a/ErsatzTV/wwwroot/css/site.css b/ErsatzTV/wwwroot/css/site.css index b085a1a0f..a75f6d322 100644 --- a/ErsatzTV/wwwroot/css/site.css +++ b/ErsatzTV/wwwroot/css/site.css @@ -226,3 +226,7 @@ div.ersatztv-light { .playout-filler-unscheduled { background-color: #52040d; } + +.channel-disabled .mud-table-cell { + color: var(--mud-palette-text-disabled) !important; +}