Browse Source

fix template editors (#1700)

pull/1701/head
Jason Dove 2 years ago committed by GitHub
parent
commit
5d89f5d0a4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CHANGELOG.md
  2. 7
      ErsatzTV.Application/Scheduling/Commands/ReplaceDecoTemplateItemsHandler.cs
  3. 4
      ErsatzTV.Application/Scheduling/Mapper.cs
  4. 7
      ErsatzTV.Application/Scheduling/Queries/GetDecoTemplateItemsHandler.cs
  5. 7
      ErsatzTV.Application/Scheduling/Queries/GetTemplateItemsHandler.cs
  6. 10
      ErsatzTV/Pages/DecoTemplateEditor.razor
  7. 46
      ErsatzTV/Pages/PlayoutTemplatesEditor.razor
  8. 6
      ErsatzTV/Pages/TemplateEditor.razor
  9. 2
      ErsatzTV/Pages/TraktLists.razor

1
CHANGELOG.md

@ -79,6 +79,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix Plex library scans with MySql/MariaDB - Fix Plex library scans with MySql/MariaDB
- Fix block playout playback when no deco is configured - Fix block playout playback when no deco is configured
- Fix `HLS Segmenter V2` to delete old segments (use less disk space while channel is active) - Fix `HLS Segmenter V2` to delete old segments (use less disk space while channel is active)
- Fix template and deco template editors to prevent items that go beyond midnight
### Changed ### Changed
- Use ffmpeg 7 in all docker images - Use ffmpeg 7 in all docker images

7
ErsatzTV.Application/Scheduling/Commands/ReplaceDecoTemplateItemsHandler.cs

@ -27,7 +27,12 @@ public class ReplaceDecoTemplateItemsHandler(IDbContextFactory<TvContext> dbCont
decoTemplate.DateUpdated = DateTime.UtcNow; decoTemplate.DateUpdated = DateTime.UtcNow;
dbContext.RemoveRange(decoTemplate.Items); dbContext.RemoveRange(decoTemplate.Items);
decoTemplate.Items = request.Items.Map(i => BuildItem(decoTemplate, i)).ToList();
// drop items that are invalid
decoTemplate.Items = request.Items
.Map(i => BuildItem(decoTemplate, i))
.Filter(i => i.StartTime < i.EndTime || i.EndTime == TimeSpan.Zero)
.ToList();
await dbContext.SaveChangesAsync(); await dbContext.SaveChangesAsync();

4
ErsatzTV.Application/Scheduling/Mapper.cs

@ -80,6 +80,10 @@ internal static class Mapper
{ {
DateTime startTime = DateTime.Today.Add(decoTemplateItem.StartTime); DateTime startTime = DateTime.Today.Add(decoTemplateItem.StartTime);
DateTime endTime = DateTime.Today.Add(decoTemplateItem.EndTime); DateTime endTime = DateTime.Today.Add(decoTemplateItem.EndTime);
if (startTime > endTime)
{
endTime = endTime.AddDays(1);
}
return new DecoTemplateItemViewModel(decoTemplateItem.DecoId, decoTemplateItem.Deco.Name, startTime, endTime); return new DecoTemplateItemViewModel(decoTemplateItem.DecoId, decoTemplateItem.Deco.Name, startTime, endTime);
} }

7
ErsatzTV.Application/Scheduling/Queries/GetDecoTemplateItemsHandler.cs

@ -10,11 +10,16 @@ public class GetDecoTemplateItemsHandler(IDbContextFactory<TvContext> dbContextF
{ {
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
// drop items that are invalid
return await dbContext.DecoTemplateItems return await dbContext.DecoTemplateItems
.AsNoTracking() .AsNoTracking()
.Filter(i => i.DecoTemplateId == request.DecoTemplateId) .Filter(i => i.DecoTemplateId == request.DecoTemplateId)
.Include(i => i.Deco) .Include(i => i.Deco)
.ToListAsync(cancellationToken) .ToListAsync(cancellationToken)
.Map(items => items.Map(Mapper.ProjectToViewModel).ToList()); .Map(
items => items
.Map(Mapper.ProjectToViewModel)
.Filter(i => i.StartTime < i.EndTime || i.EndTime.TimeOfDay == TimeSpan.Zero)
.ToList());
} }
} }

7
ErsatzTV.Application/Scheduling/Queries/GetTemplateItemsHandler.cs

@ -10,11 +10,16 @@ public class GetTemplateItemsHandler(IDbContextFactory<TvContext> dbContextFacto
{ {
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
// drop items that are invalid
return await dbContext.TemplateItems return await dbContext.TemplateItems
.AsNoTracking() .AsNoTracking()
.Filter(i => i.TemplateId == request.TemplateId) .Filter(i => i.TemplateId == request.TemplateId)
.Include(i => i.Block) .Include(i => i.Block)
.ToListAsync(cancellationToken) .ToListAsync(cancellationToken)
.Map(items => items.Map(Mapper.ProjectToViewModel).ToList()); .Map(
items => items
.Map(Mapper.ProjectToViewModel)
.Filter(i => i.StartTime < i.EndTime || i.EndTime.TimeOfDay == TimeSpan.Zero)
.ToList());
} }
} }

10
ErsatzTV/Pages/DecoTemplateEditor.razor

@ -251,7 +251,9 @@
// don't allow any overlap // don't allow any overlap
if (calendarItem is DecoTemplateItemEditViewModel item) if (calendarItem is DecoTemplateItemEditViewModel item)
{ {
if (item.End.HasValue && IntersectsOthers(item, item.Start, item.End.Value)) bool intersects = item.End.HasValue && IntersectsOthers(item, item.Start, item.End.Value);
bool crossesMidnight = item.End.HasValue && item.End.Value.TimeOfDay > TimeSpan.Zero && item.End.Value.TimeOfDay < item.Start.TimeOfDay;
if (intersects || crossesMidnight)
{ {
// roll back // roll back
item.Start = item.LastStart; item.Start = item.LastStart;
@ -295,7 +297,11 @@
private async Task SaveChanges() private async Task SaveChanges()
{ {
await Task.Delay(10); if (_decoTemplate.Items.Any(i => i.End is null))
{
Snackbar.Add("Template item cannot end after midnight", Severity.Error);
return;
}
var items = _decoTemplate.Items.Map(item => new ReplaceDecoTemplateItem(item.DecoId, item.Start.TimeOfDay, item.End!.Value.TimeOfDay)).ToList(); var items = _decoTemplate.Items.Map(item => new ReplaceDecoTemplateItem(item.DecoId, item.Start.TimeOfDay, item.End!.Value.TimeOfDay)).ToList();

46
ErsatzTV/Pages/PlayoutTemplatesEditor.razor

@ -376,12 +376,12 @@
{ {
_selectedItem = template; _selectedItem = template;
foreach (TemplateGroupViewModel group in Optional(_templateGroups.Find(group => group.Id == _selectedItem.Template.TemplateGroupId))) foreach (TemplateGroupViewModel group in Optional(_templateGroups.Find(group => group.Id == _selectedItem?.Template?.TemplateGroupId)))
{ {
await UpdateTemplateGroupItems(group); await UpdateTemplateGroupItems(group);
} }
foreach (DecoTemplateGroupViewModel group in Optional(_decoTemplateGroups.Find(group => group.Id == _selectedItem.DecoTemplate?.DecoTemplateGroupId))) foreach (DecoTemplateGroupViewModel group in Optional(_decoTemplateGroups.Find(group => group.Id == _selectedItem?.DecoTemplate?.DecoTemplateGroupId)))
{ {
await UpdateDecoTemplateGroupItems(group); await UpdateDecoTemplateGroupItems(group);
} }
@ -389,7 +389,7 @@
private void DayOfWeekChanged(DayOfWeek dayOfWeek, bool isChecked) private void DayOfWeekChanged(DayOfWeek dayOfWeek, bool isChecked)
{ {
if (isChecked && !_selectedItem.DaysOfWeek.Contains(dayOfWeek)) if (isChecked && _selectedItem != null && !_selectedItem.DaysOfWeek.Contains(dayOfWeek))
{ {
_selectedItem.DaysOfWeek.Add(dayOfWeek); _selectedItem.DaysOfWeek.Add(dayOfWeek);
_selectedItem.DaysOfWeek = _selectedItem.DaysOfWeek.OrderBy(x => ((int)x + 6) % 7).ToList(); _selectedItem.DaysOfWeek = _selectedItem.DaysOfWeek.OrderBy(x => ((int)x + 6) % 7).ToList();
@ -397,14 +397,14 @@
if (!isChecked) if (!isChecked)
{ {
_selectedItem.DaysOfWeek.Remove(dayOfWeek); _selectedItem?.DaysOfWeek.Remove(dayOfWeek);
} }
} }
private void SelectWeekdays() private void SelectWeekdays()
{ {
_selectedItem.DaysOfWeek.Clear(); _selectedItem?.DaysOfWeek.Clear();
_selectedItem.DaysOfWeek.AddRange( _selectedItem?.DaysOfWeek.AddRange(
new[] new[]
{ {
DayOfWeek.Monday, DayOfWeek.Monday,
@ -417,8 +417,8 @@
private void SelectWeekends() private void SelectWeekends()
{ {
_selectedItem.DaysOfWeek.Clear(); _selectedItem?.DaysOfWeek.Clear();
_selectedItem.DaysOfWeek.AddRange( _selectedItem?.DaysOfWeek.AddRange(
new[] new[]
{ {
DayOfWeek.Saturday, DayOfWeek.Saturday,
@ -428,37 +428,37 @@
private void SelectAllDaysOfWeek() private void SelectAllDaysOfWeek()
{ {
_selectedItem.DaysOfWeek.Clear(); _selectedItem?.DaysOfWeek.Clear();
_selectedItem.DaysOfWeek.AddRange(PlayoutTemplate.AllDaysOfWeek()); _selectedItem?.DaysOfWeek.AddRange(PlayoutTemplate.AllDaysOfWeek());
} }
private void SelectNoDaysOfWeek() => _selectedItem.DaysOfWeek.Clear(); private void SelectNoDaysOfWeek() => _selectedItem?.DaysOfWeek.Clear();
private void DayOfMonthChanged(int dayOfMonth, bool isChecked) private void DayOfMonthChanged(int dayOfMonth, bool isChecked)
{ {
if (isChecked && !_selectedItem.DaysOfMonth.Contains(dayOfMonth)) if (isChecked && !_selectedItem.DaysOfMonth.Contains(dayOfMonth))
{ {
_selectedItem.DaysOfMonth.Add(dayOfMonth); _selectedItem?.DaysOfMonth.Add(dayOfMonth);
_selectedItem.DaysOfMonth.Sort(); _selectedItem?.DaysOfMonth.Sort();
} }
if (!isChecked) if (!isChecked)
{ {
_selectedItem.DaysOfMonth.Remove(dayOfMonth); _selectedItem?.DaysOfMonth.Remove(dayOfMonth);
} }
} }
private void SelectAllDaysOfMonth() private void SelectAllDaysOfMonth()
{ {
_selectedItem.DaysOfMonth.Clear(); _selectedItem?.DaysOfMonth.Clear();
_selectedItem.DaysOfMonth.AddRange(PlayoutTemplate.AllDaysOfMonth()); _selectedItem?.DaysOfMonth.AddRange(PlayoutTemplate.AllDaysOfMonth());
} }
private void SelectNoDaysOfMonth() => _selectedItem.DaysOfMonth.Clear(); private void SelectNoDaysOfMonth() => _selectedItem?.DaysOfMonth.Clear();
private void MonthOfYearChanged(int monthOfYear, bool isChecked) private void MonthOfYearChanged(int monthOfYear, bool isChecked)
{ {
if (isChecked && !_selectedItem.MonthsOfYear.Contains(monthOfYear)) if (isChecked && _selectedItem != null && !_selectedItem.MonthsOfYear.Contains(monthOfYear))
{ {
_selectedItem.MonthsOfYear.Add(monthOfYear); _selectedItem.MonthsOfYear.Add(monthOfYear);
_selectedItem.MonthsOfYear.Sort(); _selectedItem.MonthsOfYear.Sort();
@ -466,17 +466,17 @@
if (!isChecked) if (!isChecked)
{ {
_selectedItem.MonthsOfYear.Remove(monthOfYear); _selectedItem?.MonthsOfYear.Remove(monthOfYear);
} }
} }
private void SelectAllMonthsOfYear() private void SelectAllMonthsOfYear()
{ {
_selectedItem.MonthsOfYear.Clear(); _selectedItem?.MonthsOfYear.Clear();
_selectedItem.MonthsOfYear.AddRange(PlayoutTemplate.AllMonthsOfYear()); _selectedItem?.MonthsOfYear.AddRange(PlayoutTemplate.AllMonthsOfYear());
} }
private void SelectNoMonthsOfYear() => _selectedItem.MonthsOfYear.Clear(); private void SelectNoMonthsOfYear() => _selectedItem?.MonthsOfYear.Clear();
private void AddTemplate() private void AddTemplate()
{ {
@ -554,7 +554,7 @@
private async Task DateRangeChanged(DateRange dateRange) private async Task DateRangeChanged(DateRange dateRange)
{ {
await Task.Delay(10); await Task.CompletedTask;
_previewItems.Clear(); _previewItems.Clear();

6
ErsatzTV/Pages/TemplateEditor.razor

@ -224,7 +224,9 @@
// don't allow any overlap // don't allow any overlap
if (calendarItem is TemplateItemEditViewModel item) if (calendarItem is TemplateItemEditViewModel item)
{ {
if (item.End.HasValue && IntersectsOthers(item, item.Start, item.End.Value)) bool intersects = item.End.HasValue && IntersectsOthers(item, item.Start, item.End.Value);
bool crossesMidnight = item.End.HasValue && item.End.Value.TimeOfDay > TimeSpan.Zero && item.End.Value.TimeOfDay < item.Start.TimeOfDay;
if (intersects || crossesMidnight)
{ {
// roll back // roll back
item.Start = item.LastStart; item.Start = item.LastStart;
@ -268,8 +270,6 @@
private async Task SaveChanges() private async Task SaveChanges()
{ {
await Task.Delay(10);
var items = _template.Items.Map(item => new ReplaceTemplateItem(item.BlockId, item.Start.TimeOfDay)).ToList(); var items = _template.Items.Map(item => new ReplaceTemplateItem(item.BlockId, item.Start.TimeOfDay)).ToList();
Seq<BaseError> errorMessages = await Mediator.Send(new ReplaceTemplateItems(Id, _template.Name, items), _cts.Token) Seq<BaseError> errorMessages = await Mediator.Send(new ReplaceTemplateItems(Id, _template.Name, items), _cts.Token)

2
ErsatzTV/Pages/TraktLists.razor

@ -138,7 +138,7 @@
PagedTraktListsViewModel data = await _mediator.Send(new GetPagedTraktLists(state.Page, state.PageSize), _cts.Token); PagedTraktListsViewModel data = await _mediator.Send(new GetPagedTraktLists(state.Page, state.PageSize), _cts.Token);
return new TableData<TraktListViewModel> { TotalItems = data.TotalCount, Items = data.Page }; return new TableData<TraktListViewModel> { TotalItems = data.TotalCount, Items = data.Page };
} }
catch (Exception ex) when (ex is TaskCanceledException or OperationCanceledException or AggregateException) catch (Exception)
{ {
return new TableData<TraktListViewModel> return new TableData<TraktListViewModel>
{ {

Loading…
Cancel
Save