Browse Source

replace channel active mode with is enabled and show in epg (#2256)

* add channel enabled setting

* remove channel active mode
pull/2257/head
Jason Dove 1 year ago committed by GitHub
parent
commit
b40ac9ef52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      CHANGELOG.md
  2. 5
      ErsatzTV.Application/Channels/ChannelViewModel.cs
  3. 5
      ErsatzTV.Application/Channels/Commands/CreateChannel.cs
  4. 5
      ErsatzTV.Application/Channels/Commands/CreateChannelHandler.cs
  5. 6
      ErsatzTV.Application/Channels/Commands/RefreshChannelDataHandler.cs
  6. 2
      ErsatzTV.Application/Channels/Commands/RefreshChannelListHandler.cs
  7. 5
      ErsatzTV.Application/Channels/Commands/UpdateChannel.cs
  8. 3
      ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs
  9. 5
      ErsatzTV.Application/Channels/Mapper.cs
  10. 7
      ErsatzTV.Application/Channels/Queries/GetChannelGuideHandler.cs
  11. 5
      ErsatzTV.Application/Channels/Queries/GetChannelLineupHandler.cs
  12. 2
      ErsatzTV.Application/Channels/Queries/GetChannelPlaylistHandler.cs
  13. 3
      ErsatzTV.Core/Domain/Channel.cs
  14. 8
      ErsatzTV.Core/Domain/ChannelActiveMode.cs
  15. 6179
      ErsatzTV.Infrastructure.MySql/Migrations/20250804203757_Add_ChannelIsEnabled.Designer.cs
  16. 43
      ErsatzTV.Infrastructure.MySql/Migrations/20250804203757_Add_ChannelIsEnabled.cs
  17. 6176
      ErsatzTV.Infrastructure.MySql/Migrations/20250804211606_Remove_ChannelActiveMode.Designer.cs
  18. 29
      ErsatzTV.Infrastructure.MySql/Migrations/20250804211606_Remove_ChannelActiveMode.cs
  19. 13
      ErsatzTV.Infrastructure.MySql/Migrations/TvContextModelSnapshot.cs
  20. 6016
      ErsatzTV.Infrastructure.Sqlite/Migrations/20250804203715_Add_ChannelIsEnabled.Designer.cs
  21. 43
      ErsatzTV.Infrastructure.Sqlite/Migrations/20250804203715_Add_ChannelIsEnabled.cs
  22. 6013
      ErsatzTV.Infrastructure.Sqlite/Migrations/20250804211635_Remove_ChannelActiveMode.Designer.cs
  23. 29
      ErsatzTV.Infrastructure.Sqlite/Migrations/20250804211635_Remove_ChannelActiveMode.cs
  24. 13
      ErsatzTV.Infrastructure.Sqlite/Migrations/TvContextModelSnapshot.cs
  25. 6
      ErsatzTV.Infrastructure/Data/Configurations/ChannelConfiguration.cs
  26. 4
      ErsatzTV.Infrastructure/Data/DbInitializer.cs
  27. 8
      ErsatzTV/Controllers/IptvController.cs
  28. 19
      ErsatzTV/Pages/ChannelEditor.razor
  29. 2
      ErsatzTV/Pages/Channels.razor
  30. 13
      ErsatzTV/ViewModels/ChannelEditViewModel.cs

4
CHANGELOG.md

@ -74,6 +74,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- This controls the progression of the channel's playout, and has nothing to do with transcoding - This controls the progression of the channel's playout, and has nothing to do with transcoding
- `Always` is now called `Continuous` (playout progresses with wall clock) - `Always` is now called `Continuous` (playout progresses with wall clock)
- `On Demand` is unchanged (playout only progresses while a client is watching the channel) - `On Demand` is unchanged (playout only progresses while a client is watching the channel)
- Replace channel `Active Mode` setting with new `Is Enabled` and `Show In EPG` settings
- `Active` channels will be converted to `Is Enabled` = true and `Show In EPG` = true
- `Hidden` channels will be converted to `Is Enabled` = true and `Show In EPG` = false
- `Inactive` channels will be converted to `Is Enabled` = false and `Show In EPG` = false
## [25.3.1] - 2025-07-24 ## [25.3.1] - 2025-07-24
### Fixed ### Fixed

5
ErsatzTV.Application/Channels/ChannelViewModel.cs

@ -26,9 +26,10 @@ public record ChannelViewModel(
ChannelMusicVideoCreditsMode MusicVideoCreditsMode, ChannelMusicVideoCreditsMode MusicVideoCreditsMode,
string MusicVideoCreditsTemplate, string MusicVideoCreditsTemplate,
ChannelSongVideoMode SongVideoMode, ChannelSongVideoMode SongVideoMode,
ChannelActiveMode ActiveMode,
ChannelTranscodeMode TranscodeMode, ChannelTranscodeMode TranscodeMode,
ChannelIdleBehavior IdleBehavior) ChannelIdleBehavior IdleBehavior,
bool IsEnabled,
bool ShowInEpg)
{ {
public string WebEncodedName => WebUtility.UrlEncode(Name); public string WebEncodedName => WebUtility.UrlEncode(Name);
} }

5
ErsatzTV.Application/Channels/Commands/CreateChannel.cs

@ -24,6 +24,7 @@ public record CreateChannel(
ChannelMusicVideoCreditsMode MusicVideoCreditsMode, ChannelMusicVideoCreditsMode MusicVideoCreditsMode,
string MusicVideoCreditsTemplate, string MusicVideoCreditsTemplate,
ChannelSongVideoMode SongVideoMode, ChannelSongVideoMode SongVideoMode,
ChannelActiveMode ActiveMode,
ChannelTranscodeMode TranscodeMode, ChannelTranscodeMode TranscodeMode,
ChannelIdleBehavior IdleBehavior) : IRequest<Either<BaseError, CreateChannelResult>>; ChannelIdleBehavior IdleBehavior,
bool IsEnabled,
bool ShowInEpg) : IRequest<Either<BaseError, CreateChannelResult>>;

5
ErsatzTV.Application/Channels/Commands/CreateChannelHandler.cs

@ -88,9 +88,10 @@ public class CreateChannelHandler(
MusicVideoCreditsMode = request.MusicVideoCreditsMode, MusicVideoCreditsMode = request.MusicVideoCreditsMode,
MusicVideoCreditsTemplate = request.MusicVideoCreditsTemplate, MusicVideoCreditsTemplate = request.MusicVideoCreditsTemplate,
SongVideoMode = request.SongVideoMode, SongVideoMode = request.SongVideoMode,
ActiveMode = request.ActiveMode,
TranscodeMode = request.TranscodeMode, TranscodeMode = request.TranscodeMode,
IdleBehavior = request.IdleBehavior IdleBehavior = request.IdleBehavior,
IsEnabled = request.IsEnabled,
ShowInEpg = request.ShowInEpg
}; };
foreach (int id in watermarkId) foreach (int id in watermarkId)

6
ErsatzTV.Application/Channels/Commands/RefreshChannelDataHandler.cs

@ -52,10 +52,10 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
string targetFile = Path.Combine(FileSystemLayout.ChannelGuideCacheFolder, $"{request.ChannelNumber}.xml"); string targetFile = Path.Combine(FileSystemLayout.ChannelGuideCacheFolder, $"{request.ChannelNumber}.xml");
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
int inactiveCount = await dbContext.Channels int hiddenCount = await dbContext.Channels
.Where(c => c.Number == request.ChannelNumber && c.ActiveMode != ChannelActiveMode.Active) .Where(c => c.Number == request.ChannelNumber && c.ShowInEpg == false)
.CountAsync(cancellationToken); .CountAsync(cancellationToken);
if (inactiveCount > 0) if (hiddenCount > 0)
{ {
File.Delete(targetFile); File.Delete(targetFile);
return; return;

2
ErsatzTV.Application/Channels/Commands/RefreshChannelListHandler.cs

@ -118,7 +118,7 @@ public class RefreshChannelListHandler : IRequestHandler<RefreshChannelList>
const string QUERY = @"select C.Number, C.Name, C.Categories, A.Path as ArtworkPath const string QUERY = @"select C.Number, C.Name, C.Categories, A.Path as ArtworkPath
from Channel C from Channel C
left outer join Artwork A on C.Id = A.ChannelId and A.ArtworkKind = 2 left outer join Artwork A on C.Id = A.ChannelId and A.ArtworkKind = 2
where C.Id in (select ChannelId from Playout) and C.ActiveMode = 0 where C.Id in (select ChannelId from Playout) and C.IsEnabled = 1 and C.ShowInEPG = 1
order by CAST(C.Number as double)"; order by CAST(C.Number as double)";
// TODO: this needs to be fixed for sqlite/mariadb // TODO: this needs to be fixed for sqlite/mariadb

5
ErsatzTV.Application/Channels/Commands/UpdateChannel.cs

@ -25,6 +25,7 @@ public record UpdateChannel(
ChannelMusicVideoCreditsMode MusicVideoCreditsMode, ChannelMusicVideoCreditsMode MusicVideoCreditsMode,
string MusicVideoCreditsTemplate, string MusicVideoCreditsTemplate,
ChannelSongVideoMode SongVideoMode, ChannelSongVideoMode SongVideoMode,
ChannelActiveMode ActiveMode,
ChannelTranscodeMode TranscodeMode, ChannelTranscodeMode TranscodeMode,
ChannelIdleBehavior IdleBehavior) : IRequest<Either<BaseError, ChannelViewModel>>; ChannelIdleBehavior IdleBehavior,
bool IsEnabled,
bool ShowInEpg) : IRequest<Either<BaseError, ChannelViewModel>>;

3
ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs

@ -43,9 +43,10 @@ public class UpdateChannelHandler(
c.MusicVideoCreditsMode = update.MusicVideoCreditsMode; c.MusicVideoCreditsMode = update.MusicVideoCreditsMode;
c.MusicVideoCreditsTemplate = update.MusicVideoCreditsTemplate; c.MusicVideoCreditsTemplate = update.MusicVideoCreditsTemplate;
c.SongVideoMode = update.SongVideoMode; c.SongVideoMode = update.SongVideoMode;
c.ActiveMode = update.ActiveMode;
c.TranscodeMode = update.TranscodeMode; c.TranscodeMode = update.TranscodeMode;
c.IdleBehavior = update.IdleBehavior; c.IdleBehavior = update.IdleBehavior;
c.IsEnabled = update.IsEnabled;
c.ShowInEpg = update.ShowInEpg;
c.Artwork ??= []; c.Artwork ??= [];
if (!string.IsNullOrWhiteSpace(update.Logo?.Path)) if (!string.IsNullOrWhiteSpace(update.Logo?.Path))

5
ErsatzTV.Application/Channels/Mapper.cs

@ -29,9 +29,10 @@ internal static class Mapper
channel.MusicVideoCreditsMode, channel.MusicVideoCreditsMode,
channel.MusicVideoCreditsTemplate, channel.MusicVideoCreditsTemplate,
channel.SongVideoMode, channel.SongVideoMode,
channel.ActiveMode,
channel.TranscodeMode, channel.TranscodeMode,
channel.IdleBehavior); channel.IdleBehavior,
channel.IsEnabled,
channel.ShowInEpg);
internal static ChannelResponseModel ProjectToResponseModel(Channel channel) => internal static ChannelResponseModel ProjectToResponseModel(Channel channel) =>
new( new(

7
ErsatzTV.Application/Channels/Queries/GetChannelGuideHandler.cs

@ -1,7 +1,6 @@
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Text; using System.Text;
using ErsatzTV.Core; using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Metadata;
using ErsatzTV.Core.Iptv; using ErsatzTV.Core.Iptv;
using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Data;
@ -31,8 +30,8 @@ public class GetChannelGuideHandler : IRequestHandler<GetChannelGuide, Either<Ba
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
var inactiveChannelNumbers = dbContext.Channels var hiddenChannelNumbers = dbContext.Channels
.Where(c => c.ActiveMode != ChannelActiveMode.Active) .Where(c => c.ShowInEpg == false)
.Select(c => c.Number) .Select(c => c.Number)
.AsEnumerable() .AsEnumerable()
.Select(n => $"{n}.xml") .Select(n => $"{n}.xml")
@ -68,7 +67,7 @@ public class GetChannelGuideHandler : IRequestHandler<GetChannelGuide, Either<Ba
continue; continue;
} }
if (inactiveChannelNumbers.Contains(Path.GetFileName(fileName))) if (hiddenChannelNumbers.Contains(Path.GetFileName(fileName)))
{ {
continue; continue;
} }

5
ErsatzTV.Application/Channels/Queries/GetChannelLineupHandler.cs

@ -1,5 +1,4 @@
using ErsatzTV.Core.Domain; using ErsatzTV.Core.Hdhr;
using ErsatzTV.Core.Hdhr;
using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Repositories;
namespace ErsatzTV.Application.Channels; namespace ErsatzTV.Application.Channels;
@ -12,6 +11,6 @@ public class GetChannelLineupHandler : IRequestHandler<GetChannelLineup, List<Li
public Task<List<LineupItem>> Handle(GetChannelLineup request, CancellationToken cancellationToken) => public Task<List<LineupItem>> Handle(GetChannelLineup request, CancellationToken cancellationToken) =>
_channelRepository.GetAll() _channelRepository.GetAll()
.Map(channels => channels.Where(c => c.ActiveMode is ChannelActiveMode.Active) .Map(channels => channels.Where(c => c.IsEnabled)
.Map(c => new LineupItem(request.Scheme, request.Host, c)).ToList()); .Map(c => new LineupItem(request.Scheme, request.Host, c)).ToList());
} }

2
ErsatzTV.Application/Channels/Queries/GetChannelPlaylistHandler.cs

@ -27,7 +27,7 @@ public class GetChannelPlaylistHandler : IRequestHandler<GetChannelPlaylist, Cha
var result = new List<Channel>(); var result = new List<Channel>();
foreach (Channel channel in channels) foreach (Channel channel in channels)
{ {
if (channel.ActiveMode is not ChannelActiveMode.Active) if (channel.IsEnabled == false)
{ {
continue; continue;
} }

3
ErsatzTV.Core/Domain/Channel.cs

@ -33,8 +33,9 @@ public class Channel
public string MusicVideoCreditsTemplate { get; set; } public string MusicVideoCreditsTemplate { get; set; }
public ChannelSongVideoMode SongVideoMode { get; set; } public ChannelSongVideoMode SongVideoMode { get; set; }
public ChannelPlayoutMode PlayoutMode { get; set; } public ChannelPlayoutMode PlayoutMode { get; set; }
public ChannelActiveMode ActiveMode { get; set; }
public ChannelTranscodeMode TranscodeMode { get; set; } public ChannelTranscodeMode TranscodeMode { get; set; }
public ChannelIdleBehavior IdleBehavior { get; set; } public ChannelIdleBehavior IdleBehavior { get; set; }
public bool IsEnabled { get; set; }
public bool ShowInEpg { get; set; }
public string WebEncodedName => WebUtility.UrlEncode(Name); public string WebEncodedName => WebUtility.UrlEncode(Name);
} }

8
ErsatzTV.Core/Domain/ChannelActiveMode.cs

@ -1,8 +0,0 @@
namespace ErsatzTV.Core.Domain;
public enum ChannelActiveMode
{
Active = 0,
Hidden = 1,
Inactive = 2
}

6179
ErsatzTV.Infrastructure.MySql/Migrations/20250804203757_Add_ChannelIsEnabled.Designer.cs generated

File diff suppressed because it is too large Load Diff

43
ErsatzTV.Infrastructure.MySql/Migrations/20250804203757_Add_ChannelIsEnabled.cs

@ -0,0 +1,43 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ErsatzTV.Infrastructure.MySql.Migrations
{
/// <inheritdoc />
public partial class Add_ChannelIsEnabled : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsEnabled",
table: "Channel",
type: "tinyint(1)",
nullable: false,
defaultValue: true);
migrationBuilder.AddColumn<bool>(
name: "ShowInEpg",
table: "Channel",
type: "tinyint(1)",
nullable: false,
defaultValue: true);
migrationBuilder.Sql("UPDATE `Channel` SET `IsEnabled` = 0 WHERE `ActiveMode` = 2");
migrationBuilder.Sql("UPDATE `Channel` SET `ShowInEpg` = 0 WHERE `ActiveMode` = 1");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsEnabled",
table: "Channel");
migrationBuilder.DropColumn(
name: "ShowInEpg",
table: "Channel");
}
}
}

6176
ErsatzTV.Infrastructure.MySql/Migrations/20250804211606_Remove_ChannelActiveMode.Designer.cs generated

File diff suppressed because it is too large Load Diff

29
ErsatzTV.Infrastructure.MySql/Migrations/20250804211606_Remove_ChannelActiveMode.cs

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ErsatzTV.Infrastructure.MySql.Migrations
{
/// <inheritdoc />
public partial class Remove_ChannelActiveMode : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ActiveMode",
table: "Channel");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "ActiveMode",
table: "Channel",
type: "int",
nullable: false,
defaultValue: 0);
}
}
}

13
ErsatzTV.Infrastructure.MySql/Migrations/TvContextModelSnapshot.cs

@ -254,9 +254,6 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id")); MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<int>("ActiveMode")
.HasColumnType("int");
b.Property<string>("Categories") b.Property<string>("Categories")
.HasColumnType("longtext"); .HasColumnType("longtext");
@ -275,6 +272,11 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
b.Property<int>("IdleBehavior") b.Property<int>("IdleBehavior")
.HasColumnType("int"); .HasColumnType("int");
b.Property<bool>("IsEnabled")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasDefaultValue(true);
b.Property<int>("MusicVideoCreditsMode") b.Property<int>("MusicVideoCreditsMode")
.HasColumnType("int"); .HasColumnType("int");
@ -299,6 +301,11 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations
b.Property<string>("PreferredSubtitleLanguageCode") b.Property<string>("PreferredSubtitleLanguageCode")
.HasColumnType("longtext"); .HasColumnType("longtext");
b.Property<bool>("ShowInEpg")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasDefaultValue(true);
b.Property<int>("SongVideoMode") b.Property<int>("SongVideoMode")
.HasColumnType("int"); .HasColumnType("int");

6016
ErsatzTV.Infrastructure.Sqlite/Migrations/20250804203715_Add_ChannelIsEnabled.Designer.cs generated

File diff suppressed because it is too large Load Diff

43
ErsatzTV.Infrastructure.Sqlite/Migrations/20250804203715_Add_ChannelIsEnabled.cs

@ -0,0 +1,43 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ErsatzTV.Infrastructure.Sqlite.Migrations
{
/// <inheritdoc />
public partial class Add_ChannelIsEnabled : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsEnabled",
table: "Channel",
type: "INTEGER",
nullable: false,
defaultValue: true);
migrationBuilder.AddColumn<bool>(
name: "ShowInEpg",
table: "Channel",
type: "INTEGER",
nullable: false,
defaultValue: true);
migrationBuilder.Sql("UPDATE `Channel` SET `IsEnabled` = 0 WHERE `ActiveMode` = 2");
migrationBuilder.Sql("UPDATE `Channel` SET `ShowInEpg` = 0 WHERE `ActiveMode` = 1");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsEnabled",
table: "Channel");
migrationBuilder.DropColumn(
name: "ShowInEpg",
table: "Channel");
}
}
}

6013
ErsatzTV.Infrastructure.Sqlite/Migrations/20250804211635_Remove_ChannelActiveMode.Designer.cs generated

File diff suppressed because it is too large Load Diff

29
ErsatzTV.Infrastructure.Sqlite/Migrations/20250804211635_Remove_ChannelActiveMode.cs

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ErsatzTV.Infrastructure.Sqlite.Migrations
{
/// <inheritdoc />
public partial class Remove_ChannelActiveMode : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "ActiveMode",
table: "Channel");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "ActiveMode",
table: "Channel",
type: "INTEGER",
nullable: false,
defaultValue: 0);
}
}
}

13
ErsatzTV.Infrastructure.Sqlite/Migrations/TvContextModelSnapshot.cs

@ -241,9 +241,6 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<int>("ActiveMode")
.HasColumnType("INTEGER");
b.Property<string>("Categories") b.Property<string>("Categories")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
@ -262,6 +259,11 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
b.Property<int>("IdleBehavior") b.Property<int>("IdleBehavior")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<bool>("IsEnabled")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasDefaultValue(true);
b.Property<int>("MusicVideoCreditsMode") b.Property<int>("MusicVideoCreditsMode")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
@ -286,6 +288,11 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations
b.Property<string>("PreferredSubtitleLanguageCode") b.Property<string>("PreferredSubtitleLanguageCode")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<bool>("ShowInEpg")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER")
.HasDefaultValue(true);
b.Property<int>("SongVideoMode") b.Property<int>("SongVideoMode")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");

6
ErsatzTV.Infrastructure/Data/Configurations/ChannelConfiguration.cs

@ -13,6 +13,12 @@ public class ChannelConfiguration : IEntityTypeConfiguration<Channel>
builder.HasIndex(c => c.Number) builder.HasIndex(c => c.Number)
.IsUnique(); .IsUnique();
builder.Property(c => c.IsEnabled)
.HasDefaultValue(true);
builder.Property(c => c.ShowInEpg)
.HasDefaultValue(true);
builder.HasMany(c => c.Playouts) // TODO: is this correct, or should we have one to one? builder.HasMany(c => c.Playouts) // TODO: is this correct, or should we have one to one?
.WithOne(p => p.Channel) .WithOne(p => p.Channel)
.HasForeignKey(p => p.ChannelId) .HasForeignKey(p => p.ChannelId)

4
ErsatzTV.Infrastructure/Data/DbInitializer.cs

@ -103,7 +103,9 @@ public static class DbInitializer
Number = "1", Number = "1",
Name = "ErsatzTV", Name = "ErsatzTV",
FFmpegProfile = defaultProfile, FFmpegProfile = defaultProfile,
StreamingMode = StreamingMode.TransportStreamHybrid StreamingMode = StreamingMode.TransportStreamHybrid,
IsEnabled = true,
ShowInEpg = true
}; };
await context.Channels.AddAsync(defaultChannel, cancellationToken); await context.Channels.AddAsync(defaultChannel, cancellationToken);
await context.SaveChangesAsync(cancellationToken); await context.SaveChangesAsync(cancellationToken);

8
ErsatzTV/Controllers/IptvController.cs

@ -84,9 +84,7 @@ public class IptvController : ControllerBase
string mode = null) string mode = null)
{ {
Option<ChannelViewModel> maybeChannel = await _mediator.Send(new GetChannelByNumber(channelNumber)); Option<ChannelViewModel> maybeChannel = await _mediator.Send(new GetChannelByNumber(channelNumber));
if (maybeChannel.IsNone || if (maybeChannel.IsNone || await maybeChannel.Map(c => c.IsEnabled).IfNoneAsync(false) == false)
await maybeChannel.Map(c => c.ActiveMode).IfNoneAsync(ChannelActiveMode.Inactive) is ChannelActiveMode
.Inactive)
{ {
return NotFound(); return NotFound();
} }
@ -189,9 +187,7 @@ public class IptvController : ControllerBase
string mode = "mixed") string mode = "mixed")
{ {
Option<ChannelViewModel> maybeChannel = await _mediator.Send(new GetChannelByNumber(channelNumber)); Option<ChannelViewModel> maybeChannel = await _mediator.Send(new GetChannelByNumber(channelNumber));
if (maybeChannel.IsNone || if (maybeChannel.IsNone || await maybeChannel.Map(c => c.IsEnabled).IfNoneAsync(false) == false)
await maybeChannel.Map(c => c.ActiveMode).IfNoneAsync(ChannelActiveMode.Inactive) is ChannelActiveMode
.Inactive)
{ {
return NotFound(); return NotFound();
} }

19
ErsatzTV/Pages/ChannelEditor.razor

@ -78,13 +78,15 @@
</MudStack> </MudStack>
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5"> <MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5">
<div class="d-flex"> <div class="d-flex">
<MudText>Active Mode</MudText> <MudText>Is Enabled</MudText>
</div> </div>
<MudSelect @bind-Value="_model.ActiveMode" For="@(() => _model.ActiveMode)"> <MudCheckBox @bind-Value="_model.IsEnabled" Dense="true"/>
<MudSelectItem Value="@(ChannelActiveMode.Active)">Active</MudSelectItem> </MudStack>
<MudSelectItem Value="@(ChannelActiveMode.Hidden)">Hidden</MudSelectItem> <MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5">
<MudSelectItem Value="@(ChannelActiveMode.Inactive)">Inactive</MudSelectItem> <div class="d-flex">
</MudSelect> <MudText>Show In EPG</MudText>
</div>
<MudCheckBox @bind-Value="_model.ShowInEpg" Dense="true"/>
</MudStack> </MudStack>
<MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5"> <MudStack Row="true" Breakpoint="Breakpoint.SmAndDown" Class="form-field-stack gap-md-8 mb-5">
<div class="d-flex"> <div class="d-flex">
@ -340,9 +342,10 @@
_model.MusicVideoCreditsMode = channelViewModel.MusicVideoCreditsMode; _model.MusicVideoCreditsMode = channelViewModel.MusicVideoCreditsMode;
_model.MusicVideoCreditsTemplate = channelViewModel.MusicVideoCreditsTemplate; _model.MusicVideoCreditsTemplate = channelViewModel.MusicVideoCreditsTemplate;
_model.SongVideoMode = channelViewModel.SongVideoMode; _model.SongVideoMode = channelViewModel.SongVideoMode;
_model.ActiveMode = channelViewModel.ActiveMode;
_model.TranscodeMode = channelViewModel.TranscodeMode; _model.TranscodeMode = channelViewModel.TranscodeMode;
_model.IdleBehavior = channelViewModel.IdleBehavior; _model.IdleBehavior = channelViewModel.IdleBehavior;
_model.IsEnabled = channelViewModel.IsEnabled;
_model.ShowInEpg = channelViewModel.ShowInEpg;
}, },
() => NavigationManager.NavigateTo("404")); () => NavigationManager.NavigateTo("404"));
} }
@ -359,6 +362,8 @@
_model.Group = "ErsatzTV"; _model.Group = "ErsatzTV";
_model.FFmpegProfileId = ffmpegSettings.DefaultFFmpegProfileId; _model.FFmpegProfileId = ffmpegSettings.DefaultFFmpegProfileId;
_model.StreamingMode = StreamingMode.TransportStreamHybrid; _model.StreamingMode = StreamingMode.TransportStreamHybrid;
_model.IsEnabled = true;
_model.ShowInEpg = true;
} }
} }

2
ErsatzTV/Pages/Channels.razor

@ -151,7 +151,7 @@
private bool CanPreviewChannel(ChannelViewModel channel) private bool CanPreviewChannel(ChannelViewModel channel)
{ {
if (channel.ActiveMode is ChannelActiveMode.Inactive) if (!channel.IsEnabled)
{ {
return false; return false;
} }

13
ErsatzTV/ViewModels/ChannelEditViewModel.cs

@ -36,9 +36,10 @@ public class ChannelEditViewModel
} }
public ChannelSongVideoMode SongVideoMode { get; set; } public ChannelSongVideoMode SongVideoMode { get; set; }
public ChannelActiveMode ActiveMode { get; set; }
public ChannelTranscodeMode TranscodeMode { get; set; } public ChannelTranscodeMode TranscodeMode { get; set; }
public ChannelIdleBehavior IdleBehavior { get; set; } public ChannelIdleBehavior IdleBehavior { get; set; }
public bool IsEnabled { get; set; }
public bool ShowInEpg { get; set; }
public UpdateChannel ToUpdate() => public UpdateChannel ToUpdate() =>
new( new(
@ -64,9 +65,10 @@ public class ChannelEditViewModel
MusicVideoCreditsMode, MusicVideoCreditsMode,
MusicVideoCreditsTemplate, MusicVideoCreditsTemplate,
SongVideoMode, SongVideoMode,
ActiveMode,
TranscodeMode, TranscodeMode,
IdleBehavior); IdleBehavior,
IsEnabled,
ShowInEpg);
public CreateChannel ToCreate() => public CreateChannel ToCreate() =>
new( new(
@ -91,7 +93,8 @@ public class ChannelEditViewModel
MusicVideoCreditsMode, MusicVideoCreditsMode,
MusicVideoCreditsTemplate, MusicVideoCreditsTemplate,
SongVideoMode, SongVideoMode,
ActiveMode,
TranscodeMode, TranscodeMode,
IdleBehavior); IdleBehavior,
IsEnabled,
ShowInEpg);
} }

Loading…
Cancel
Save