Enhance channel settings to include icon image support for IPTV
ci / build-backend (push) Successful in 1m18s
ci / build-frontend (push) Successful in 39s
ci / tests (push) Successful in 1m22s
ci / sonar (push) Successful in 3m41s

Updated the Channel and related DTOs to incorporate an optional IconImageId property, allowing for the specification of a channel icon for external IPTV players. Modified the UpdateChannelSettings command and its handler to accommodate this new property. Adjusted frontend components to manage the icon image, including selection and display functionality. Updated localization files to support new UI elements related to the IPTV icon. This enhancement improves the user experience by providing a visual representation of channels in IPTV applications.
This commit is contained in:
Leonid Pershin
2026-08-02 17:07:24 +03:00
parent bed6d4fcfc
commit 7a164dbd90
27 changed files with 1758 additions and 28 deletions
@@ -21,7 +21,7 @@ public class ChannelDetailsTests
var channel = Channel.Create("Первый", "one", T0);
var fillerId = Guid.NewGuid();
var logoId = Guid.NewGuid();
channel.UpdateSettings("Первый", isEnabled: true, fillerId);
channel.UpdateSettings("Первый", isEnabled: true, fillerId, null);
channel.UpdateTimeSettings(3, 120, new TimeOnly(5, 0));
channel.UpdateViewerSettings(logoId, LogoCorner.BottomLeft, 0.4, showClock: true, 0.25);
@@ -48,7 +48,7 @@ public class ChannelHandlersTests
await using var db = fixture.New();
var result = await new UpdateChannelSettingsCommandHandler(db).Handle(
new UpdateChannelSettingsCommand(channel.Id, "c2", true, null),
new UpdateChannelSettingsCommand(channel.Id, "c2", true, null, null),
CancellationToken.None
);
Assert.True(result.IsSuccess);
@@ -168,7 +168,7 @@ public class DeleteGuardsTests
var fixture = new TestDb();
var asset = MediaAsset.Register("filler.mkv", ".mkv", MediaSource.Upload);
var channel = Channel.Create("c", "c", T0);
channel.UpdateSettings(channel.Name, isEnabled: true, asset.Id);
channel.UpdateSettings(channel.Name, isEnabled: true, asset.Id, null);
await using (var seed = fixture.New())
{
@@ -92,7 +92,7 @@ public class TelegramBotTests
var userId = Guid.NewGuid();
var code = TelegramLinkCode.Issue("abc123", userId, Now);
var channel = Channel.Create("Мультреалити", "mult", Now);
channel.UpdateSettings(channel.Name, isEnabled: true, null);
channel.UpdateSettings(channel.Name, isEnabled: true, null, null);
await using (var seed = fixture.New())
{
@@ -145,7 +145,7 @@ public class TelegramBotTests
{
var fixture = new TestDb();
var channel = Channel.Create("Мультреалити", "mult", Now);
channel.UpdateSettings(channel.Name, isEnabled: true, null);
channel.UpdateSettings(channel.Name, isEnabled: true, null, null);
var subscriber = TelegramSubscriber.Create(100, Guid.NewGuid(), "viewer", Now);
await using (var seed = fixture.New())
@@ -194,7 +194,7 @@ public class TelegramBotTests
// один блок: зритель спрашивает «что дальше», а не «в каком порядке лежат файлы».
var fixture = new TestDb();
var channel = Channel.Create("Мультреалити", "mult", Now);
channel.UpdateSettings(channel.Name, isEnabled: true, null);
channel.UpdateSettings(channel.Name, isEnabled: true, null, null);
var first = Show.Create("Симпсоны", ShowKind.Series);
var second = Show.Create("Футурама", ShowKind.Series);
var subscriber = TelegramSubscriber.Create(100, Guid.NewGuid(), "viewer", Now);
@@ -250,7 +250,7 @@ public class TelegramBotTests
// Два меню в чате — это две панели с разными галочками, и одна из них врёт. Старое снимаем.
var fixture = new TestDb();
var channel = Channel.Create("Мультреалити", "mult", Now);
channel.UpdateSettings(channel.Name, isEnabled: true, null);
channel.UpdateSettings(channel.Name, isEnabled: true, null, null);
var subscriber = TelegramSubscriber.Create(100, Guid.NewGuid(), "viewer", Now);
await using (var seed = fixture.New())
@@ -125,7 +125,7 @@ public class IptvGuideTests
var fixture = new TestDb();
var visible = Enabled("Первый", "one");
var hidden = Channel.Create("Выключенный", "off", T0);
hidden.UpdateSettings("Выключенный", isEnabled: false, null);
hidden.UpdateSettings("Выключенный", isEnabled: false, null, null);
var show = Show.Create("Ворон", ShowKind.Single);
var asset = MediaAsset.Register("crow.mkv", ".mkv", MediaSource.Upload);
@@ -187,7 +187,7 @@ public class IptvGuideTests
private static Channel Enabled(string name, string slug)
{
var channel = Channel.Create(name, slug, T0);
channel.UpdateSettings(name, isEnabled: true, null);
channel.UpdateSettings(name, isEnabled: true, null, null);
return channel;
}
@@ -31,8 +31,8 @@ public class ListPublicChannelsTests
var disabled = Channel.Create("Выключенный", "off", T0);
foreach (var channel in new[] { numbered, first, unnumbered })
channel.UpdateSettings(channel.Name, isEnabled: true, null);
disabled.UpdateSettings("Выключенный", isEnabled: false, null);
channel.UpdateSettings(channel.Name, isEnabled: true, null, null);
disabled.UpdateSettings("Выключенный", isEnabled: false, null, null);
await using (var seed = fixture.New())
{
@@ -57,7 +57,7 @@ public class ListPublicChannelsTests
{
var fixture = new TestDb();
var channel = Channel.Create("Первый", "one", T0);
channel.UpdateSettings("Первый", isEnabled: true, null);
channel.UpdateSettings("Первый", isEnabled: true, null, null);
var logoId = Guid.NewGuid();
channel.UpdateViewerSettings(logoId, LogoCorner.TopRight, 0.5, showClock: true, 0.3);
@@ -61,7 +61,7 @@ public class ValidatorTests
{
var v = new UpdateChannelSettingsCommandValidator();
var good = new UpdateChannelSettingsCommand(Guid.NewGuid(), "Name", true, null);
var good = new UpdateChannelSettingsCommand(Guid.NewGuid(), "Name", true, null, null);
Assert.True(v.Validate(good).IsValid);
Assert.False(v.Validate(good with { Name = "" }).IsValid);