Browse Source

add custom title option to schedule items (#116)

pull/117/head
Jason Dove 5 years ago committed by GitHub
parent
commit
745b03af73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      ErsatzTV.Application/ProgramSchedules/Commands/AddProgramScheduleItem.cs
  2. 1
      ErsatzTV.Application/ProgramSchedules/Commands/IProgramScheduleItemRequest.cs
  3. 12
      ErsatzTV.Application/ProgramSchedules/Commands/ProgramScheduleItemCommandBase.cs
  4. 3
      ErsatzTV.Application/ProgramSchedules/Commands/ReplaceProgramScheduleItems.cs
  5. 12
      ErsatzTV.Application/ProgramSchedules/Mapper.cs
  6. 6
      ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemDurationViewModel.cs
  7. 6
      ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemFloodViewModel.cs
  8. 6
      ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemMultipleViewModel.cs
  9. 6
      ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemOneViewModel.cs
  10. 3
      ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemViewModel.cs
  11. 2
      ErsatzTV.Core/Domain/PlayoutItem.cs
  12. 1
      ErsatzTV.Core/Domain/ProgramScheduleItem.cs
  13. 104
      ErsatzTV.Core/Iptv/ChannelGuide.cs
  14. 18
      ErsatzTV.Core/Scheduling/PlayoutBuilder.cs
  15. 1829
      ErsatzTV.Infrastructure/Migrations/20210329204815_Add_ProgramScheduleItem_CustomTitle.Designer.cs
  16. 44
      ErsatzTV.Infrastructure/Migrations/20210329204815_Add_ProgramScheduleItem_CustomTitle.cs
  17. 9
      ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs
  18. 7
      ErsatzTV/Pages/ScheduleItemsEditor.razor
  19. 2
      ErsatzTV/Pages/TelevisionEpisodeList.razor
  20. 2
      ErsatzTV/Pages/TelevisionSeasonList.razor
  21. 2
      ErsatzTV/ViewModels/ProgramScheduleItemEditViewModel.cs

3
ErsatzTV.Application/ProgramSchedules/Commands/AddProgramScheduleItem.cs

@ -16,5 +16,6 @@ namespace ErsatzTV.Application.ProgramSchedules.Commands
int? MediaItemId, int? MediaItemId,
int? MultipleCount, int? MultipleCount,
TimeSpan? PlayoutDuration, TimeSpan? PlayoutDuration,
bool? OfflineTail) : IRequest<Either<BaseError, ProgramScheduleItemViewModel>>, IProgramScheduleItemRequest; bool? OfflineTail,
string CustomTitle) : IRequest<Either<BaseError, ProgramScheduleItemViewModel>>, IProgramScheduleItemRequest;
} }

1
ErsatzTV.Application/ProgramSchedules/Commands/IProgramScheduleItemRequest.cs

@ -13,5 +13,6 @@ namespace ErsatzTV.Application.ProgramSchedules.Commands
int? MultipleCount { get; } int? MultipleCount { get; }
TimeSpan? PlayoutDuration { get; } TimeSpan? PlayoutDuration { get; }
bool? OfflineTail { get; } bool? OfflineTail { get; }
string CustomTitle { get; }
} }
} }

12
ErsatzTV.Application/ProgramSchedules/Commands/ProgramScheduleItemCommandBase.cs

@ -100,7 +100,8 @@ namespace ErsatzTV.Application.ProgramSchedules.Commands
StartTime = item.StartTime, StartTime = item.StartTime,
CollectionType = item.CollectionType, CollectionType = item.CollectionType,
CollectionId = item.CollectionId, CollectionId = item.CollectionId,
MediaItemId = item.MediaItemId MediaItemId = item.MediaItemId,
CustomTitle = item.CustomTitle
}, },
PlayoutMode.One => new ProgramScheduleItemOne PlayoutMode.One => new ProgramScheduleItemOne
{ {
@ -109,7 +110,8 @@ namespace ErsatzTV.Application.ProgramSchedules.Commands
StartTime = item.StartTime, StartTime = item.StartTime,
CollectionType = item.CollectionType, CollectionType = item.CollectionType,
CollectionId = item.CollectionId, CollectionId = item.CollectionId,
MediaItemId = item.MediaItemId MediaItemId = item.MediaItemId,
CustomTitle = item.CustomTitle
}, },
PlayoutMode.Multiple => new ProgramScheduleItemMultiple PlayoutMode.Multiple => new ProgramScheduleItemMultiple
{ {
@ -119,7 +121,8 @@ namespace ErsatzTV.Application.ProgramSchedules.Commands
CollectionType = item.CollectionType, CollectionType = item.CollectionType,
CollectionId = item.CollectionId, CollectionId = item.CollectionId,
MediaItemId = item.MediaItemId, MediaItemId = item.MediaItemId,
Count = item.MultipleCount.GetValueOrDefault() Count = item.MultipleCount.GetValueOrDefault(),
CustomTitle = item.CustomTitle
}, },
PlayoutMode.Duration => new ProgramScheduleItemDuration PlayoutMode.Duration => new ProgramScheduleItemDuration
{ {
@ -130,7 +133,8 @@ namespace ErsatzTV.Application.ProgramSchedules.Commands
CollectionId = item.CollectionId, CollectionId = item.CollectionId,
MediaItemId = item.MediaItemId, MediaItemId = item.MediaItemId,
PlayoutDuration = item.PlayoutDuration.GetValueOrDefault(), PlayoutDuration = item.PlayoutDuration.GetValueOrDefault(),
OfflineTail = item.OfflineTail.GetValueOrDefault() OfflineTail = item.OfflineTail.GetValueOrDefault(),
CustomTitle = item.CustomTitle
}, },
_ => throw new NotSupportedException($"Unsupported playout mode {item.PlayoutMode}") _ => throw new NotSupportedException($"Unsupported playout mode {item.PlayoutMode}")
}; };

3
ErsatzTV.Application/ProgramSchedules/Commands/ReplaceProgramScheduleItems.cs

@ -17,7 +17,8 @@ namespace ErsatzTV.Application.ProgramSchedules.Commands
int? MediaItemId, int? MediaItemId,
int? MultipleCount, int? MultipleCount,
TimeSpan? PlayoutDuration, TimeSpan? PlayoutDuration,
bool? OfflineTail) : IProgramScheduleItemRequest; bool? OfflineTail,
string CustomTitle) : IProgramScheduleItemRequest;
public record ReplaceProgramScheduleItems public record ReplaceProgramScheduleItems
(int ProgramScheduleId, List<ReplaceProgramScheduleItem> Items) : IRequest< (int ProgramScheduleId, List<ReplaceProgramScheduleItem> Items) : IRequest<

12
ErsatzTV.Application/ProgramSchedules/Mapper.cs

@ -28,7 +28,8 @@ namespace ErsatzTV.Application.ProgramSchedules
_ => null _ => null
}, },
duration.PlayoutDuration, duration.PlayoutDuration,
duration.OfflineTail), duration.OfflineTail,
duration.CustomTitle),
ProgramScheduleItemFlood flood => ProgramScheduleItemFlood flood =>
new ProgramScheduleItemFloodViewModel( new ProgramScheduleItemFloodViewModel(
flood.Id, flood.Id,
@ -44,7 +45,8 @@ namespace ErsatzTV.Application.ProgramSchedules
Show show => MediaItems.Mapper.ProjectToViewModel(show), Show show => MediaItems.Mapper.ProjectToViewModel(show),
Season season => MediaItems.Mapper.ProjectToViewModel(season), Season season => MediaItems.Mapper.ProjectToViewModel(season),
_ => null _ => null
}), },
flood.CustomTitle),
ProgramScheduleItemMultiple multiple => ProgramScheduleItemMultiple multiple =>
new ProgramScheduleItemMultipleViewModel( new ProgramScheduleItemMultipleViewModel(
multiple.Id, multiple.Id,
@ -61,7 +63,8 @@ namespace ErsatzTV.Application.ProgramSchedules
Season season => MediaItems.Mapper.ProjectToViewModel(season), Season season => MediaItems.Mapper.ProjectToViewModel(season),
_ => null _ => null
}, },
multiple.Count), multiple.Count,
multiple.CustomTitle),
ProgramScheduleItemOne one => ProgramScheduleItemOne one =>
new ProgramScheduleItemOneViewModel( new ProgramScheduleItemOneViewModel(
one.Id, one.Id,
@ -77,7 +80,8 @@ namespace ErsatzTV.Application.ProgramSchedules
Show show => MediaItems.Mapper.ProjectToViewModel(show), Show show => MediaItems.Mapper.ProjectToViewModel(show),
Season season => MediaItems.Mapper.ProjectToViewModel(season), Season season => MediaItems.Mapper.ProjectToViewModel(season),
_ => null _ => null
}), },
one.CustomTitle),
_ => throw new NotSupportedException( _ => throw new NotSupportedException(
$"Unsupported program schedule item type {programScheduleItem.GetType().Name}") $"Unsupported program schedule item type {programScheduleItem.GetType().Name}")
}; };

6
ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemDurationViewModel.cs

@ -16,7 +16,8 @@ namespace ErsatzTV.Application.ProgramSchedules
MediaCollectionViewModel collection, MediaCollectionViewModel collection,
NamedMediaItemViewModel mediaItem, NamedMediaItemViewModel mediaItem,
TimeSpan playoutDuration, TimeSpan playoutDuration,
bool offlineTail) : base( bool offlineTail,
string customTitle) : base(
id, id,
index, index,
startType, startType,
@ -24,7 +25,8 @@ namespace ErsatzTV.Application.ProgramSchedules
PlayoutMode.Duration, PlayoutMode.Duration,
collectionType, collectionType,
collection, collection,
mediaItem) mediaItem,
customTitle)
{ {
PlayoutDuration = playoutDuration; PlayoutDuration = playoutDuration;
OfflineTail = offlineTail; OfflineTail = offlineTail;

6
ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemFloodViewModel.cs

@ -14,7 +14,8 @@ namespace ErsatzTV.Application.ProgramSchedules
TimeSpan? startTime, TimeSpan? startTime,
ProgramScheduleItemCollectionType collectionType, ProgramScheduleItemCollectionType collectionType,
MediaCollectionViewModel collection, MediaCollectionViewModel collection,
NamedMediaItemViewModel mediaItem) : base( NamedMediaItemViewModel mediaItem,
string customTitle) : base(
id, id,
index, index,
startType, startType,
@ -22,7 +23,8 @@ namespace ErsatzTV.Application.ProgramSchedules
PlayoutMode.Flood, PlayoutMode.Flood,
collectionType, collectionType,
collection, collection,
mediaItem) mediaItem,
customTitle)
{ {
} }
} }

6
ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemMultipleViewModel.cs

@ -15,7 +15,8 @@ namespace ErsatzTV.Application.ProgramSchedules
ProgramScheduleItemCollectionType collectionType, ProgramScheduleItemCollectionType collectionType,
MediaCollectionViewModel collection, MediaCollectionViewModel collection,
NamedMediaItemViewModel mediaItem, NamedMediaItemViewModel mediaItem,
int count) : base( int count,
string customTitle) : base(
id, id,
index, index,
startType, startType,
@ -23,7 +24,8 @@ namespace ErsatzTV.Application.ProgramSchedules
PlayoutMode.Multiple, PlayoutMode.Multiple,
collectionType, collectionType,
collection, collection,
mediaItem) => mediaItem,
customTitle) =>
Count = count; Count = count;
public int Count { get; } public int Count { get; }

6
ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemOneViewModel.cs

@ -14,7 +14,8 @@ namespace ErsatzTV.Application.ProgramSchedules
TimeSpan? startTime, TimeSpan? startTime,
ProgramScheduleItemCollectionType collectionType, ProgramScheduleItemCollectionType collectionType,
MediaCollectionViewModel collection, MediaCollectionViewModel collection,
NamedMediaItemViewModel mediaItem) : base( NamedMediaItemViewModel mediaItem,
string customTitle) : base(
id, id,
index, index,
startType, startType,
@ -22,7 +23,8 @@ namespace ErsatzTV.Application.ProgramSchedules
PlayoutMode.One, PlayoutMode.One,
collectionType, collectionType,
collection, collection,
mediaItem) mediaItem,
customTitle)
{ {
} }
} }

3
ErsatzTV.Application/ProgramSchedules/ProgramScheduleItemViewModel.cs

@ -13,7 +13,8 @@ namespace ErsatzTV.Application.ProgramSchedules
PlayoutMode PlayoutMode, PlayoutMode PlayoutMode,
ProgramScheduleItemCollectionType CollectionType, ProgramScheduleItemCollectionType CollectionType,
MediaCollectionViewModel Collection, MediaCollectionViewModel Collection,
NamedMediaItemViewModel MediaItem) NamedMediaItemViewModel MediaItem,
string CustomTitle)
{ {
public string Name => CollectionType switch public string Name => CollectionType switch
{ {

2
ErsatzTV.Core/Domain/PlayoutItem.cs

@ -9,6 +9,8 @@ namespace ErsatzTV.Core.Domain
public MediaItem MediaItem { get; set; } public MediaItem MediaItem { get; set; }
public DateTime Start { get; set; } public DateTime Start { get; set; }
public DateTime Finish { get; set; } public DateTime Finish { get; set; }
public string CustomTitle { get; set; }
public bool CustomGroup { get; set; }
public int PlayoutId { get; set; } public int PlayoutId { get; set; }
public Playout Playout { get; set; } public Playout Playout { get; set; }

1
ErsatzTV.Core/Domain/ProgramScheduleItem.cs

@ -9,6 +9,7 @@ namespace ErsatzTV.Core.Domain
public StartType StartType => StartTime.HasValue ? StartType.Fixed : StartType.Dynamic; public StartType StartType => StartTime.HasValue ? StartType.Fixed : StartType.Dynamic;
public TimeSpan? StartTime { get; set; } public TimeSpan? StartTime { get; set; }
public ProgramScheduleItemCollectionType CollectionType { get; set; } public ProgramScheduleItemCollectionType CollectionType { get; set; }
public string CustomTitle { get; set; }
public int ProgramScheduleId { get; set; } public int ProgramScheduleId { get; set; }
public ProgramSchedule ProgramSchedule { get; set; } public ProgramSchedule ProgramSchedule { get; set; }
public int? CollectionId { get; set; } public int? CollectionId { get; set; }

104
ErsatzTV.Core/Iptv/ChannelGuide.cs

@ -57,49 +57,36 @@ namespace ErsatzTV.Core.Iptv
foreach (Channel channel in _channels.OrderBy(c => c.Number)) foreach (Channel channel in _channels.OrderBy(c => c.Number))
{ {
foreach (PlayoutItem playoutItem in channel.Playouts.Collect(p => p.Items).OrderBy(i => i.Start)) var sorted = channel.Playouts.Collect(p => p.Items).OrderBy(x => x.Start).ToList();
var i = 0;
while (i < sorted.Count)
{ {
string start = playoutItem.StartOffset.ToString("yyyyMMddHHmmss zzz").Replace(":", string.Empty); PlayoutItem startItem = sorted[i];
string stop = playoutItem.FinishOffset.ToString("yyyyMMddHHmmss zzz").Replace(":", string.Empty); bool hasCustomTitle = !string.IsNullOrWhiteSpace(startItem.CustomTitle);
string title = playoutItem.MediaItem switch int finishIndex = i;
while (hasCustomTitle && finishIndex + 1 < sorted.Count && sorted[finishIndex + 1].CustomGroup)
{ {
Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Title ?? string.Empty) finishIndex++;
.IfNone("[unknown movie]"), }
Episode e => e.Season.Show.ShowMetadata.HeadOrNone().Map(em => em.Title ?? string.Empty)
.IfNone("[unknown show]"),
_ => "[unknown]"
};
string subtitle = playoutItem.MediaItem switch
{
Episode e => e.EpisodeMetadata.HeadOrNone().Match(
em => em.Title ?? string.Empty,
() => string.Empty),
_ => string.Empty
};
string description = playoutItem.MediaItem switch PlayoutItem finishItem = sorted[finishIndex];
{ i = finishIndex;
Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Plot ?? string.Empty).IfNone(string.Empty),
Episode e => e.EpisodeMetadata.HeadOrNone().Map(em => em.Plot ?? string.Empty)
.IfNone(string.Empty),
_ => string.Empty
};
string contentRating = playoutItem.MediaItem switch string start = startItem.StartOffset.ToString("yyyyMMddHHmmss zzz").Replace(":", string.Empty);
{ string stop = finishItem.FinishOffset.ToString("yyyyMMddHHmmss zzz").Replace(":", string.Empty);
// TODO: re-implement content rating
// Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.ContentRating).IfNone(string.Empty), string title = GetTitle(startItem);
_ => string.Empty string subtitle = GetSubtitle(startItem);
}; string description = GetDescription(startItem);
string contentRating = string.Empty;
xml.WriteStartElement("programme"); xml.WriteStartElement("programme");
xml.WriteAttributeString("start", start); xml.WriteAttributeString("start", start);
xml.WriteAttributeString("stop", stop); xml.WriteAttributeString("stop", stop);
xml.WriteAttributeString("channel", channel.Number); xml.WriteAttributeString("channel", channel.Number);
if (playoutItem.MediaItem is Movie movie) if (!hasCustomTitle && startItem.MediaItem is Movie movie)
{ {
xml.WriteStartElement("category"); xml.WriteStartElement("category");
xml.WriteAttributeString("lang", "en"); xml.WriteAttributeString("lang", "en");
@ -150,7 +137,7 @@ namespace ErsatzTV.Core.Iptv
xml.WriteStartElement("previously-shown"); xml.WriteStartElement("previously-shown");
xml.WriteEndElement(); // previously-shown xml.WriteEndElement(); // previously-shown
if (playoutItem.MediaItem is Episode episode) if (!hasCustomTitle && startItem.MediaItem is Episode episode)
{ {
Option<ShowMetadata> maybeMetadata = Option<ShowMetadata> maybeMetadata =
Optional(episode.Season?.Show?.ShowMetadata.HeadOrNone()).Flatten(); Optional(episode.Season?.Show?.ShowMetadata.HeadOrNone()).Flatten();
@ -209,6 +196,8 @@ namespace ErsatzTV.Core.Iptv
} }
xml.WriteEndElement(); // programme xml.WriteEndElement(); // programme
i++;
} }
} }
@ -218,5 +207,54 @@ namespace ErsatzTV.Core.Iptv
xml.Flush(); xml.Flush();
return Encoding.UTF8.GetString(ms.ToArray()); return Encoding.UTF8.GetString(ms.ToArray());
} }
private static string GetTitle(PlayoutItem playoutItem)
{
if (!string.IsNullOrWhiteSpace(playoutItem.CustomTitle))
{
return playoutItem.CustomTitle;
}
return playoutItem.MediaItem switch
{
Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Title ?? string.Empty)
.IfNone("[unknown movie]"),
Episode e => e.Season.Show.ShowMetadata.HeadOrNone().Map(em => em.Title ?? string.Empty)
.IfNone("[unknown show]"),
_ => "[unknown]"
};
}
private static string GetSubtitle(PlayoutItem playoutItem)
{
if (!string.IsNullOrWhiteSpace(playoutItem.CustomTitle))
{
return string.Empty;
}
return playoutItem.MediaItem switch
{
Episode e => e.EpisodeMetadata.HeadOrNone().Match(
em => em.Title ?? string.Empty,
() => string.Empty),
_ => string.Empty
};
}
private static string GetDescription(PlayoutItem playoutItem)
{
if (!string.IsNullOrWhiteSpace(playoutItem.CustomTitle))
{
return string.Empty;
}
return playoutItem.MediaItem switch
{
Movie m => m.MovieMetadata.HeadOrNone().Map(mm => mm.Plot ?? string.Empty).IfNone(string.Empty),
Episode e => e.EpisodeMetadata.HeadOrNone().Map(em => em.Plot ?? string.Empty)
.IfNone(string.Empty),
_ => string.Empty
};
}
} }
} }

18
ErsatzTV.Core/Scheduling/PlayoutBuilder.cs

@ -149,6 +149,8 @@ namespace ErsatzTV.Core.Scheduling
Option<int> multipleRemaining = Optional(startAnchor.MultipleRemaining); Option<int> multipleRemaining = Optional(startAnchor.MultipleRemaining);
Option<DateTimeOffset> durationFinish = startAnchor.DurationFinishOffset; Option<DateTimeOffset> durationFinish = startAnchor.DurationFinishOffset;
bool customGroup = multipleRemaining.IsSome || durationFinish.IsSome;
// loop until we're done filling the desired amount of time // loop until we're done filling the desired amount of time
while (currentTime < playoutFinish) while (currentTime < playoutFinish)
{ {
@ -185,9 +187,15 @@ namespace ErsatzTV.Core.Scheduling
{ {
MediaItemId = mediaItem.Id, MediaItemId = mediaItem.Id,
Start = itemStartTime.UtcDateTime, Start = itemStartTime.UtcDateTime,
Finish = itemStartTime.UtcDateTime + version.Duration Finish = itemStartTime.UtcDateTime + version.Duration,
CustomGroup = customGroup
}; };
if (!string.IsNullOrWhiteSpace(scheduleItem.CustomTitle))
{
playoutItem.CustomTitle = scheduleItem.CustomTitle;
}
currentTime = itemStartTime + version.Duration; currentTime = itemStartTime + version.Duration;
enumerator.MoveNext(); enumerator.MoveNext();
@ -201,11 +209,13 @@ namespace ErsatzTV.Core.Scheduling
"Advancing to next schedule item after playout mode {PlayoutMode}", "Advancing to next schedule item after playout mode {PlayoutMode}",
"One"); "One");
index++; index++;
customGroup = false;
break; break;
case ProgramScheduleItemMultiple multiple: case ProgramScheduleItemMultiple multiple:
if (multipleRemaining.IsNone) if (multipleRemaining.IsNone)
{ {
multipleRemaining = multiple.Count; multipleRemaining = multiple.Count;
customGroup = true;
} }
multipleRemaining = multipleRemaining.Map(i => i - 1); multipleRemaining = multipleRemaining.Map(i => i - 1);
@ -216,6 +226,7 @@ namespace ErsatzTV.Core.Scheduling
"Multiple"); "Multiple");
index++; index++;
multipleRemaining = None; multipleRemaining = None;
customGroup = false;
} }
break; break;
@ -223,6 +234,8 @@ namespace ErsatzTV.Core.Scheduling
enumerator.Current.Do( enumerator.Current.Do(
peekMediaItem => peekMediaItem =>
{ {
customGroup = true;
MediaVersion peekVersion = peekMediaItem switch MediaVersion peekVersion = peekMediaItem switch
{ {
Movie m => m.MediaVersions.Head(), Movie m => m.MediaVersions.Head(),
@ -249,6 +262,7 @@ namespace ErsatzTV.Core.Scheduling
"Advancing to next schedule item after playout mode {PlayoutMode}", "Advancing to next schedule item after playout mode {PlayoutMode}",
"Flood"); "Flood");
index++; index++;
customGroup = false;
} }
}); });
break; break;
@ -267,6 +281,7 @@ namespace ErsatzTV.Core.Scheduling
if (durationFinish.IsNone) if (durationFinish.IsNone)
{ {
durationFinish = itemStartTime + duration.PlayoutDuration; durationFinish = itemStartTime + duration.PlayoutDuration;
customGroup = true;
} }
bool willNotFinishInTime = bool willNotFinishInTime =
@ -279,6 +294,7 @@ namespace ErsatzTV.Core.Scheduling
"Advancing to next schedule item after playout mode {PlayoutMode}", "Advancing to next schedule item after playout mode {PlayoutMode}",
"Duration"); "Duration");
index++; index++;
customGroup = false;
if (duration.OfflineTail) if (duration.OfflineTail)
{ {

1829
ErsatzTV.Infrastructure/Migrations/20210329204815_Add_ProgramScheduleItem_CustomTitle.Designer.cs generated

File diff suppressed because it is too large Load Diff

44
ErsatzTV.Infrastructure/Migrations/20210329204815_Add_ProgramScheduleItem_CustomTitle.cs

@ -0,0 +1,44 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace ErsatzTV.Infrastructure.Migrations
{
public partial class Add_ProgramScheduleItem_CustomTitle : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
"CustomTitle",
"ProgramScheduleItem",
"TEXT",
nullable: true);
migrationBuilder.AddColumn<bool>(
"CustomGroup",
"PlayoutItem",
"INTEGER",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<string>(
"CustomTitle",
"PlayoutItem",
"TEXT",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
"CustomTitle",
"ProgramScheduleItem");
migrationBuilder.DropColumn(
"CustomGroup",
"PlayoutItem");
migrationBuilder.DropColumn(
"CustomTitle",
"PlayoutItem");
}
}
}

9
ErsatzTV.Infrastructure/Migrations/TvContextModelSnapshot.cs

@ -611,6 +611,12 @@ namespace ErsatzTV.Infrastructure.Migrations
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<bool>("CustomGroup")
.HasColumnType("INTEGER");
b.Property<string>("CustomTitle")
.HasColumnType("TEXT");
b.Property<DateTime>("Finish") b.Property<DateTime>("Finish")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
@ -752,6 +758,9 @@ namespace ErsatzTV.Infrastructure.Migrations
b.Property<int>("CollectionType") b.Property<int>("CollectionType")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<string>("CustomTitle")
.HasColumnType("TEXT");
b.Property<int>("Index") b.Property<int>("Index")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");

7
ErsatzTV/Pages/ScheduleItemsEditor.razor

@ -140,6 +140,7 @@
<MudElement HtmlTag="div" Class="mt-3"> <MudElement HtmlTag="div" Class="mt-3">
<MudSwitch Label="Offline Tail" @bind-Checked="@_selectedItem.OfflineTail" For="@(() => _selectedItem.OfflineTail)" Disabled="@(_selectedItem.PlayoutMode != PlayoutMode.Duration)"/> <MudSwitch Label="Offline Tail" @bind-Checked="@_selectedItem.OfflineTail" For="@(() => _selectedItem.OfflineTail)" Disabled="@(_selectedItem.PlayoutMode != PlayoutMode.Duration)"/>
</MudElement> </MudElement>
<MudTextField Class="mt-3" Label="Custom Title" @bind-Value="@_selectedItem.CustomTitle" For="@(() => _selectedItem.CustomTitle)"/>
</MudCardContent> </MudCardContent>
</MudCard> </MudCard>
</EditForm> </EditForm>
@ -210,7 +211,8 @@
PlayoutMode = item.PlayoutMode, PlayoutMode = item.PlayoutMode,
CollectionType = item.CollectionType, CollectionType = item.CollectionType,
Collection = item.Collection, Collection = item.Collection,
MediaItem = item.MediaItem MediaItem = item.MediaItem,
CustomTitle = item.CustomTitle
}; };
switch (item) switch (item)
@ -286,7 +288,8 @@
item.MediaItem?.MediaItemId, item.MediaItem?.MediaItemId,
item.MultipleCount, item.MultipleCount,
item.PlayoutDuration, item.PlayoutDuration,
item.PlayoutMode == PlayoutMode.Duration ? item.OfflineTail.IfNone(false) : null)).ToList(); item.PlayoutMode == PlayoutMode.Duration ? item.OfflineTail.IfNone(false) : null,
item.CustomTitle)).ToList();
Seq<BaseError> errorMessages = await Mediator.Send(new ReplaceProgramScheduleItems(Id, items)).Map(e => e.LeftToSeq()); Seq<BaseError> errorMessages = await Mediator.Send(new ReplaceProgramScheduleItems(Id, items)).Map(e => e.LeftToSeq());

2
ErsatzTV/Pages/TelevisionEpisodeList.razor

@ -139,7 +139,7 @@
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule) if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule)
{ {
await Mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionSeason, null, SeasonId, null, null, null)); await Mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionSeason, null, SeasonId, null, null, null, null));
NavigationManager.NavigateTo($"/schedules/{schedule.Id}/items"); NavigationManager.NavigateTo($"/schedules/{schedule.Id}/items");
} }
} }

2
ErsatzTV/Pages/TelevisionSeasonList.razor

@ -143,7 +143,7 @@
DialogResult result = await dialog.Result; DialogResult result = await dialog.Result;
if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule) if (!result.Cancelled && result.Data is ProgramScheduleViewModel schedule)
{ {
await Mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionShow, null, ShowId, null, null, null)); await Mediator.Send(new AddProgramScheduleItem(schedule.Id, StartType.Dynamic, null, PlayoutMode.One, ProgramScheduleItemCollectionType.TelevisionShow, null, ShowId, null, null, null, null));
NavigationManager.NavigateTo($"/schedules/{schedule.Id}/items"); NavigationManager.NavigateTo($"/schedules/{schedule.Id}/items");
} }
} }

2
ErsatzTV/ViewModels/ProgramScheduleItemEditViewModel.cs

@ -75,6 +75,8 @@ namespace ErsatzTV.ViewModels
set => _offlineTail = value; set => _offlineTail = value;
} }
public string CustomTitle { get; set; }
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator] [NotifyPropertyChangedInvocator]

Loading…
Cancel
Save