add channel active mode (#2083)
This commit is contained in:
+7
-1
@@ -29,10 +29,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||||||
- `channels` (audio only)
|
- `channels` (audio only)
|
||||||
- An example subtitle condition: `lang like 'en%' and external`
|
- An example subtitle condition: `lang like 'en%' and external`
|
||||||
- An example audio condition: `title like '%movie%' and channels > 2`
|
- An example audio condition: `title like '%movie%' and channels > 2`
|
||||||
|
- Add new channel setting `Active Mode`
|
||||||
|
- `Active` - default value, channel streams as normal and has normal visibility
|
||||||
|
- `Hidden` - channel streams as normal and is hidden from M3U/XMLTV/HDHR
|
||||||
|
- `Inactive` - channel cannot stream (will 404) and is hidden from M3U/XMLTV/HDHR
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Fix QSV acceleration in docker with older Intel devices
|
- Fix QSV acceleration in docker with older Intel devices
|
||||||
- Fix software tonemap when used with NVIDIA accel (`ETV_DISABLE_VULKAN` env var)
|
- Fix HDR transcoding with NVIDIA accel for:
|
||||||
|
- All NVIDIA docker users
|
||||||
|
- Windows NVIDIA users who have set the `ETV_DISABLE_VULKAN` env var
|
||||||
|
|
||||||
## [25.2.0] - 2025-06-24
|
## [25.2.0] - 2025-06-24
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ public record ChannelViewModel(
|
|||||||
ChannelSubtitleMode SubtitleMode,
|
ChannelSubtitleMode SubtitleMode,
|
||||||
ChannelMusicVideoCreditsMode MusicVideoCreditsMode,
|
ChannelMusicVideoCreditsMode MusicVideoCreditsMode,
|
||||||
string MusicVideoCreditsTemplate,
|
string MusicVideoCreditsTemplate,
|
||||||
ChannelSongVideoMode SongVideoMode)
|
ChannelSongVideoMode SongVideoMode,
|
||||||
|
ChannelActiveMode ActiveMode)
|
||||||
{
|
{
|
||||||
public string WebEncodedName => WebUtility.UrlEncode(Name);
|
public string WebEncodedName => WebUtility.UrlEncode(Name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,4 +22,5 @@ public record CreateChannel(
|
|||||||
ChannelSubtitleMode SubtitleMode,
|
ChannelSubtitleMode SubtitleMode,
|
||||||
ChannelMusicVideoCreditsMode MusicVideoCreditsMode,
|
ChannelMusicVideoCreditsMode MusicVideoCreditsMode,
|
||||||
string MusicVideoCreditsTemplate,
|
string MusicVideoCreditsTemplate,
|
||||||
ChannelSongVideoMode SongVideoMode) : IRequest<Either<BaseError, CreateChannelResult>>;
|
ChannelSongVideoMode SongVideoMode,
|
||||||
|
ChannelActiveMode ActiveMode) : IRequest<Either<BaseError, CreateChannelResult>>;
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ public class CreateChannelHandler(
|
|||||||
SubtitleMode = request.SubtitleMode,
|
SubtitleMode = request.SubtitleMode,
|
||||||
MusicVideoCreditsMode = request.MusicVideoCreditsMode,
|
MusicVideoCreditsMode = request.MusicVideoCreditsMode,
|
||||||
MusicVideoCreditsTemplate = request.MusicVideoCreditsTemplate,
|
MusicVideoCreditsTemplate = request.MusicVideoCreditsTemplate,
|
||||||
SongVideoMode = request.SongVideoMode
|
SongVideoMode = request.SongVideoMode,
|
||||||
|
ActiveMode = request.ActiveMode
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (int id in watermarkId)
|
foreach (int id in watermarkId)
|
||||||
|
|||||||
@@ -49,6 +49,18 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
|
|||||||
|
|
||||||
_localFileSystem.EnsureFolderExists(FileSystemLayout.ChannelGuideCacheFolder);
|
_localFileSystem.EnsureFolderExists(FileSystemLayout.ChannelGuideCacheFolder);
|
||||||
|
|
||||||
|
string targetFile = Path.Combine(FileSystemLayout.ChannelGuideCacheFolder, $"{request.ChannelNumber}.xml");
|
||||||
|
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||||
|
|
||||||
|
int inactiveCount = await dbContext.Channels
|
||||||
|
.Where(c => c.Number == request.ChannelNumber && c.ActiveMode != ChannelActiveMode.Active)
|
||||||
|
.CountAsync(cancellationToken);
|
||||||
|
if (inactiveCount > 0)
|
||||||
|
{
|
||||||
|
File.Delete(targetFile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
string movieTemplateFileName = GetMovieTemplateFileName();
|
string movieTemplateFileName = GetMovieTemplateFileName();
|
||||||
string episodeTemplateFileName = GetEpisodeTemplateFileName();
|
string episodeTemplateFileName = GetEpisodeTemplateFileName();
|
||||||
string musicVideoTemplateFileName = GetMusicVideoTemplateFileName();
|
string musicVideoTemplateFileName = GetMusicVideoTemplateFileName();
|
||||||
@@ -85,8 +97,6 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
|
|||||||
string otherVideoText = await File.ReadAllTextAsync(otherVideoTemplateFileName, cancellationToken);
|
string otherVideoText = await File.ReadAllTextAsync(otherVideoTemplateFileName, cancellationToken);
|
||||||
var otherVideoTemplate = Template.Parse(otherVideoText, otherVideoTemplateFileName);
|
var otherVideoTemplate = Template.Parse(otherVideoText, otherVideoTemplateFileName);
|
||||||
|
|
||||||
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
|
||||||
|
|
||||||
List<Playout> playouts = await dbContext.Playouts
|
List<Playout> playouts = await dbContext.Playouts
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.Filter(pi => pi.Channel.Number == request.ChannelNumber)
|
.Filter(pi => pi.Channel.Number == request.ChannelNumber)
|
||||||
@@ -244,7 +254,6 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
|
|||||||
string tempFile = Path.GetTempFileName();
|
string tempFile = Path.GetTempFileName();
|
||||||
await File.WriteAllBytesAsync(tempFile, ms.ToArray(), cancellationToken);
|
await File.WriteAllBytesAsync(tempFile, ms.ToArray(), cancellationToken);
|
||||||
|
|
||||||
string targetFile = Path.Combine(FileSystemLayout.ChannelGuideCacheFolder, $"{request.ChannelNumber}.xml");
|
|
||||||
File.Move(tempFile, targetFile, true);
|
File.Move(tempFile, targetFile, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
where C.Id in (select ChannelId from Playout) and C.ActiveMode = 0
|
||||||
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
|
||||||
|
|
||||||
|
|||||||
@@ -23,4 +23,5 @@ public record UpdateChannel(
|
|||||||
ChannelSubtitleMode SubtitleMode,
|
ChannelSubtitleMode SubtitleMode,
|
||||||
ChannelMusicVideoCreditsMode MusicVideoCreditsMode,
|
ChannelMusicVideoCreditsMode MusicVideoCreditsMode,
|
||||||
string MusicVideoCreditsTemplate,
|
string MusicVideoCreditsTemplate,
|
||||||
ChannelSongVideoMode SongVideoMode) : IRequest<Either<BaseError, ChannelViewModel>>;
|
ChannelSongVideoMode SongVideoMode,
|
||||||
|
ChannelActiveMode ActiveMode) : IRequest<Either<BaseError, ChannelViewModel>>;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ 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.Artwork ??= [];
|
c.Artwork ??= [];
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(update.Logo))
|
if (!string.IsNullOrWhiteSpace(update.Logo))
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ internal static class Mapper
|
|||||||
channel.SubtitleMode,
|
channel.SubtitleMode,
|
||||||
channel.MusicVideoCreditsMode,
|
channel.MusicVideoCreditsMode,
|
||||||
channel.MusicVideoCreditsTemplate,
|
channel.MusicVideoCreditsTemplate,
|
||||||
channel.SongVideoMode);
|
channel.SongVideoMode,
|
||||||
|
channel.ActiveMode);
|
||||||
|
|
||||||
internal static ChannelResponseModel ProjectToResponseModel(Channel channel) =>
|
internal static ChannelResponseModel ProjectToResponseModel(Channel channel) =>
|
||||||
new(
|
new(
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
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;
|
||||||
@@ -29,6 +31,12 @@ 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
|
||||||
|
.Where(c => c.ActiveMode != ChannelActiveMode.Active)
|
||||||
|
.Select(c => c.Number)
|
||||||
|
.AsEnumerable()
|
||||||
|
.Select(n => $"{n}.xml")
|
||||||
|
.ToImmutableHashSet();
|
||||||
|
|
||||||
string channelsFile = Path.Combine(FileSystemLayout.ChannelGuideCacheFolder, "channels.xml");
|
string channelsFile = Path.Combine(FileSystemLayout.ChannelGuideCacheFolder, "channels.xml");
|
||||||
if (!_localFileSystem.FileExists(channelsFile))
|
if (!_localFileSystem.FileExists(channelsFile))
|
||||||
@@ -60,6 +68,11 @@ public class GetChannelGuideHandler : IRequestHandler<GetChannelGuide, Either<Ba
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inactiveChannelNumbers.Contains(Path.GetFileName(fileName)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
string channelDataFragment = await File.ReadAllTextAsync(fileName, Encoding.UTF8, cancellationToken);
|
string channelDataFragment = await File.ReadAllTextAsync(fileName, Encoding.UTF8, cancellationToken);
|
||||||
|
|
||||||
channelDataFragment = channelDataFragment
|
channelDataFragment = channelDataFragment
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using ErsatzTV.Core.Hdhr;
|
using ErsatzTV.Core.Domain;
|
||||||
|
using ErsatzTV.Core.Hdhr;
|
||||||
using ErsatzTV.Core.Interfaces.Repositories;
|
using ErsatzTV.Core.Interfaces.Repositories;
|
||||||
|
|
||||||
namespace ErsatzTV.Application.Channels;
|
namespace ErsatzTV.Application.Channels;
|
||||||
@@ -11,5 +12,5 @@ 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.Map(c => new LineupItem(request.Scheme, request.Host, c)).ToList());
|
.Map(channels => channels.Where(c => c.ActiveMode is ChannelActiveMode.Active).Map(c => new LineupItem(request.Scheme, request.Host, c)).ToList());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ 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)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (mode.ToLowerInvariant())
|
switch (mode.ToLowerInvariant())
|
||||||
{
|
{
|
||||||
case "segmenter":
|
case "segmenter":
|
||||||
|
|||||||
@@ -33,5 +33,6 @@ public class Channel
|
|||||||
public string MusicVideoCreditsTemplate { get; set; }
|
public string MusicVideoCreditsTemplate { get; set; }
|
||||||
public ChannelSongVideoMode SongVideoMode { get; set; }
|
public ChannelSongVideoMode SongVideoMode { get; set; }
|
||||||
public ChannelProgressMode ProgressMode { get; set; }
|
public ChannelProgressMode ProgressMode { get; set; }
|
||||||
|
public ChannelActiveMode ActiveMode { get; set; }
|
||||||
public string WebEncodedName => WebUtility.UrlEncode(Name);
|
public string WebEncodedName => WebUtility.UrlEncode(Name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace ErsatzTV.Core.Domain;
|
||||||
|
|
||||||
|
public enum ChannelActiveMode
|
||||||
|
{
|
||||||
|
Active = 0,
|
||||||
|
Hidden = 1,
|
||||||
|
Inactive = 2
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ public static class AvailablePixelFormats
|
|||||||
|
|
||||||
private static Option<IPixelFormat> LogUnknownPixelFormat(string pixelFormat, ILogger? logger)
|
private static Option<IPixelFormat> LogUnknownPixelFormat(string pixelFormat, ILogger? logger)
|
||||||
{
|
{
|
||||||
logger?.LogWarning("Unexpected pixel format {PixelFormat} may have playback issues", pixelFormat);
|
logger?.LogDebug("Unexpected pixel format {PixelFormat} may have playback issues", pixelFormat);
|
||||||
return Option<IPixelFormat>.None;
|
return Option<IPixelFormat>.None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5893
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace ErsatzTV.Infrastructure.MySql.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Add_ChannelActiveMode : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "ActiveMode",
|
||||||
|
table: "Channel",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "ActiveMode",
|
||||||
|
table: "Channel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -241,6 +241,9 @@ 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");
|
||||||
|
|
||||||
|
|||||||
Generated
+5732
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace ErsatzTV.Infrastructure.Sqlite.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Add_ChannelActiveMode : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<int>(
|
||||||
|
name: "ActiveMode",
|
||||||
|
table: "Channel",
|
||||||
|
type: "INTEGER",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "ActiveMode",
|
||||||
|
table: "Channel");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -228,6 +228,9 @@ 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");
|
||||||
|
|
||||||
|
|||||||
@@ -83,10 +83,15 @@ public class IptvController : ControllerBase
|
|||||||
[FromQuery]
|
[FromQuery]
|
||||||
string mode = null)
|
string mode = null)
|
||||||
{
|
{
|
||||||
|
Option<ChannelViewModel> maybeChannel = await _mediator.Send(new GetChannelByNumber(channelNumber));
|
||||||
|
if (maybeChannel.IsNone || await maybeChannel.Map(c => c.ActiveMode).IfNoneAsync(ChannelActiveMode.Inactive) is ChannelActiveMode.Inactive)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
// if mode is "unspecified" - find the configured mode and set it or redirect
|
// if mode is "unspecified" - find the configured mode and set it or redirect
|
||||||
if (string.IsNullOrWhiteSpace(mode) || mode == "mixed")
|
if (string.IsNullOrWhiteSpace(mode) || mode == "mixed")
|
||||||
{
|
{
|
||||||
Option<ChannelViewModel> maybeChannel = await _mediator.Send(new GetChannelByNumber(channelNumber));
|
|
||||||
foreach (ChannelViewModel channel in maybeChannel)
|
foreach (ChannelViewModel channel in maybeChannel)
|
||||||
{
|
{
|
||||||
switch (channel.StreamingMode)
|
switch (channel.StreamingMode)
|
||||||
@@ -180,10 +185,15 @@ public class IptvController : ControllerBase
|
|||||||
[FromQuery]
|
[FromQuery]
|
||||||
string mode = "mixed")
|
string mode = "mixed")
|
||||||
{
|
{
|
||||||
|
Option<ChannelViewModel> maybeChannel = await _mediator.Send(new GetChannelByNumber(channelNumber));
|
||||||
|
if (maybeChannel.IsNone || await maybeChannel.Map(c => c.ActiveMode).IfNoneAsync(ChannelActiveMode.Inactive) is ChannelActiveMode.Inactive)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
// if mode is "unspecified" - find the configured mode and set it or redirect
|
// if mode is "unspecified" - find the configured mode and set it or redirect
|
||||||
if (string.IsNullOrWhiteSpace(mode) || mode == "mixed")
|
if (string.IsNullOrWhiteSpace(mode) || mode == "mixed")
|
||||||
{
|
{
|
||||||
Option<ChannelViewModel> maybeChannel = await _mediator.Send(new GetChannelByNumber(channelNumber));
|
|
||||||
foreach (ChannelViewModel channel in maybeChannel)
|
foreach (ChannelViewModel channel in maybeChannel)
|
||||||
{
|
{
|
||||||
switch (channel.StreamingMode)
|
switch (channel.StreamingMode)
|
||||||
|
|||||||
@@ -30,6 +30,11 @@
|
|||||||
<MudTextField Class="mt-3" Label="Name" @bind-Value="_model.Name" For="@(() => _model.Name)"/>
|
<MudTextField Class="mt-3" Label="Name" @bind-Value="_model.Name" For="@(() => _model.Name)"/>
|
||||||
<MudTextField Class="mt-3" Label="Group" @bind-Value="_model.Group" For="@(() => _model.Group)"/>
|
<MudTextField Class="mt-3" Label="Group" @bind-Value="_model.Group" For="@(() => _model.Group)"/>
|
||||||
<MudTextField Class="mt-3" Label="Categories" @bind-Value="_model.Categories" For="@(() => _model.Categories)" Placeholder="Comma-separated list of categories"/>
|
<MudTextField Class="mt-3" Label="Categories" @bind-Value="_model.Categories" For="@(() => _model.Categories)" Placeholder="Comma-separated list of categories"/>
|
||||||
|
<MudSelect Class="mt-3" Label="Active Mode" @bind-Value="_model.ActiveMode" For="@(() => _model.ActiveMode)">
|
||||||
|
<MudSelectItem Value="@(ChannelActiveMode.Active)">Active</MudSelectItem>
|
||||||
|
<MudSelectItem Value="@(ChannelActiveMode.Hidden)">Hidden</MudSelectItem>
|
||||||
|
<MudSelectItem Value="@(ChannelActiveMode.Inactive)">Inactive</MudSelectItem>
|
||||||
|
</MudSelect>
|
||||||
<MudSelect Class="mt-3" Label="Progress Mode" @bind-Value="_model.ProgressMode" For="@(() => _model.ProgressMode)">
|
<MudSelect Class="mt-3" Label="Progress Mode" @bind-Value="_model.ProgressMode" For="@(() => _model.ProgressMode)">
|
||||||
<MudSelectItem Value="@(ChannelProgressMode.Always)">Always</MudSelectItem>
|
<MudSelectItem Value="@(ChannelProgressMode.Always)">Always</MudSelectItem>
|
||||||
<MudSelectItem Value="@(ChannelProgressMode.OnDemand)">On Demand</MudSelectItem>
|
<MudSelectItem Value="@(ChannelProgressMode.OnDemand)">On Demand</MudSelectItem>
|
||||||
@@ -233,6 +238,7 @@
|
|||||||
_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;
|
||||||
},
|
},
|
||||||
() => NavigationManager.NavigateTo("404"));
|
() => NavigationManager.NavigateTo("404"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class ChannelEditViewModel
|
|||||||
set => _musicVideoCreditsTemplate = value;
|
set => _musicVideoCreditsTemplate = value;
|
||||||
}
|
}
|
||||||
public ChannelSongVideoMode SongVideoMode { get; set; }
|
public ChannelSongVideoMode SongVideoMode { get; set; }
|
||||||
|
public ChannelActiveMode ActiveMode { get; set; }
|
||||||
|
|
||||||
public UpdateChannel ToUpdate() =>
|
public UpdateChannel ToUpdate() =>
|
||||||
new(
|
new(
|
||||||
@@ -55,7 +56,8 @@ public class ChannelEditViewModel
|
|||||||
SubtitleMode,
|
SubtitleMode,
|
||||||
MusicVideoCreditsMode,
|
MusicVideoCreditsMode,
|
||||||
MusicVideoCreditsTemplate,
|
MusicVideoCreditsTemplate,
|
||||||
SongVideoMode);
|
SongVideoMode,
|
||||||
|
ActiveMode);
|
||||||
|
|
||||||
public CreateChannel ToCreate() =>
|
public CreateChannel ToCreate() =>
|
||||||
new(
|
new(
|
||||||
@@ -77,5 +79,6 @@ public class ChannelEditViewModel
|
|||||||
SubtitleMode,
|
SubtitleMode,
|
||||||
MusicVideoCreditsMode,
|
MusicVideoCreditsMode,
|
||||||
MusicVideoCreditsTemplate,
|
MusicVideoCreditsTemplate,
|
||||||
SongVideoMode);
|
SongVideoMode,
|
||||||
|
ActiveMode);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user