Browse Source

schedule item editor updates (#1407)

pull/1408/head
Jason Dove 2 years ago committed by GitHub
parent
commit
e5962699a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      CHANGELOG.md
  2. 10
      ErsatzTV.Application/ProgramSchedules/Commands/ProgramScheduleItemCommandBase.cs
  3. 2
      ErsatzTV.Application/ProgramSchedules/Commands/ReplaceProgramScheduleItemsHandler.cs
  4. 20
      ErsatzTV/Pages/ScheduleItemsEditor.razor
  5. 50
      ErsatzTV/ViewModels/ProgramScheduleItemEditViewModel.cs

4
CHANGELOG.md

@ -28,6 +28,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -28,6 +28,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
- Optimize transcoding session to only work ahead (at max speed) for 2 minutes before throttling to realtime
- This should *greatly* reduce cpu/gpu use when joining a channel, particularly with long content
- Allow manually editing (typing) schedule item fixed start time
- Use different control for editing schedule item duration, and allow 24-hour duration
- This is needed if you want a default/fallback alternate schedule to fill the entire day with one schedule item
- The schedule item should have a fixed start time of midnight (00:00) and a duration of 24 hours
## [0.8.1-beta] - 2023-08-07
### Added

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

@ -83,6 +83,11 @@ public abstract class ProgramScheduleItemCommandBase @@ -83,6 +83,11 @@ public abstract class ProgramScheduleItemCommandBase
return BaseError.New("[PlayoutDuration] is required for playout mode 'duration'");
}
if (item.PlayoutDuration <= TimeSpan.Zero || item.PlayoutDuration > TimeSpan.FromHours(24))
{
return BaseError.New("[PlayoutDuration] must be between 1 minute and 24 hours");
}
if (item.DiscardToFillAttempts is null)
{
return BaseError.New("[DiscardToFillAttempts] is required for playout mode 'duration'");
@ -251,7 +256,7 @@ public abstract class ProgramScheduleItemCommandBase @@ -251,7 +256,7 @@ public abstract class ProgramScheduleItemCommandBase
SmartCollectionId = item.SmartCollectionId,
MediaItemId = item.MediaItemId,
PlaybackOrder = item.PlaybackOrder,
PlayoutDuration = FixDuration(item.PlayoutDuration.GetValueOrDefault()),
PlayoutDuration = item.PlayoutDuration.GetValueOrDefault(),
TailMode = item.TailMode,
DiscardToFillAttempts = FixDiscardToFillAttempts(
item.PlaybackOrder,
@ -272,9 +277,6 @@ public abstract class ProgramScheduleItemCommandBase @@ -272,9 +277,6 @@ public abstract class ProgramScheduleItemCommandBase
_ => throw new NotSupportedException($"Unsupported playout mode {item.PlayoutMode}")
};
private static TimeSpan FixDuration(TimeSpan duration) =>
duration >= TimeSpan.FromDays(1) ? duration.Subtract(TimeSpan.FromDays(1)) : duration;
private static TimeSpan? FixStartTime(TimeSpan? startTime) =>
startTime.HasValue && startTime.Value >= TimeSpan.FromDays(1)
? startTime.Value.Subtract(TimeSpan.FromDays(1))

2
ErsatzTV.Application/ProgramSchedules/Commands/ReplaceProgramScheduleItemsHandler.cs

@ -29,7 +29,7 @@ public class ReplaceProgramScheduleItemsHandler : ProgramScheduleItemCommandBase @@ -29,7 +29,7 @@ public class ReplaceProgramScheduleItemsHandler : ProgramScheduleItemCommandBase
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, ProgramSchedule> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, ps => PersistItems(dbContext, request, ps));
return await validation.Apply(ps => PersistItems(dbContext, request, ps));
}
private async Task<IEnumerable<ProgramScheduleItemViewModel>> PersistItems(

20
ErsatzTV/Pages/ScheduleItemsEditor.razor

@ -100,7 +100,7 @@ @@ -100,7 +100,7 @@
<MudSelectItem Value="StartType.Fixed">Fixed</MudSelectItem>
}
</MudSelect>
<MudTimePicker Class="mt-3" Label="Start Time" @bind-Time="@_selectedItem.StartTime" For="@(() => _selectedItem.StartTime)" Disabled="@(_selectedItem.StartType == StartType.Dynamic)"/>
<MudTimePicker Class="mt-3" Label="Start Time" @bind-Time="@_selectedItem.StartTime" For="@(() => _selectedItem.StartTime)" Disabled="@(_selectedItem.StartType == StartType.Dynamic)" Editable="true"/>
<MudSelect Class="mt-3" Label="Collection Type" @bind-Value="_selectedItem.CollectionType" For="@(() => _selectedItem.CollectionType)">
<MudSelectItem Value="ProgramScheduleItemCollectionType.Collection">Collection</MudSelectItem>
<MudSelectItem Value="ProgramScheduleItemCollectionType.TelevisionShow">Television Show</MudSelectItem>
@ -221,7 +221,23 @@ @@ -221,7 +221,23 @@
<MudSelectItem Value="PlayoutMode.Duration">Duration</MudSelectItem>
</MudSelect>
<MudTextField Class="mt-3" Label="Multiple Count" @bind-Value="@_selectedItem.MultipleCount" For="@(() => _selectedItem.MultipleCount)" Disabled="@(_selectedItem.PlayoutMode != PlayoutMode.Multiple)"/>
<MudTimePicker Class="mt-3" Label="Playout Duration" @bind-Time="@_selectedItem.PlayoutDuration" For="@(() => _selectedItem.PlayoutDuration)" Disabled="@(_selectedItem.PlayoutMode != PlayoutMode.Duration)"/>
<MudGrid Class="mt-3" Style="align-items: center" Justify="Justify.Center">
<MudItem xs="6">
<MudTextField T="int"
Label="Playout Duration"
@bind-Value="_selectedItem.PlayoutDurationHours"
Adornment="Adornment.End"
AdornmentText="hours"
Disabled="@(_selectedItem.PlayoutMode != PlayoutMode.Duration)" />
</MudItem>
<MudItem xs="6">
<MudTextField T="int"
@bind-Value="_selectedItem.PlayoutDurationMinutes"
Adornment="Adornment.End"
AdornmentText="minutes"
Disabled="@(_selectedItem.PlayoutMode != PlayoutMode.Duration)"/>
</MudItem>
</MudGrid>
<MudSelect Class="mt-3" Label="Tail Mode" @bind-Value="@_selectedItem.TailMode" For="@(() => _selectedItem.TailMode)" Disabled="@(_selectedItem.PlayoutMode != PlayoutMode.Duration)">
<MudSelectItem Value="@TailMode.None">(none)</MudSelectItem>
<MudSelectItem Value="@TailMode.Offline">Offline</MudSelectItem>

50
ErsatzTV/ViewModels/ProgramScheduleItemEditViewModel.cs

@ -16,6 +16,8 @@ public class ProgramScheduleItemEditViewModel : INotifyPropertyChanged @@ -16,6 +16,8 @@ public class ProgramScheduleItemEditViewModel : INotifyPropertyChanged
private int? _multipleCount;
private TimeSpan? _playoutDuration;
private TimeSpan? _startTime;
private int _playoutDurationHours;
private int _playoutDurationMinutes;
public int Id { get; set; }
public int Index { get; set; }
@ -93,7 +95,31 @@ public class ProgramScheduleItemEditViewModel : INotifyPropertyChanged @@ -93,7 +95,31 @@ public class ProgramScheduleItemEditViewModel : INotifyPropertyChanged
public TimeSpan? PlayoutDuration
{
get => PlayoutMode == PlayoutMode.Duration ? _playoutDuration : null;
set => _playoutDuration = value;
set
{
_playoutDuration = value;
CheckPlayoutDuration();
}
}
public int PlayoutDurationHours
{
get => _playoutDurationHours;
set
{
_playoutDuration = TimeSpan.FromHours(value) + TimeSpan.FromMinutes(_playoutDuration?.Minutes ?? 0);
CheckPlayoutDuration();
}
}
public int PlayoutDurationMinutes
{
get => _playoutDurationMinutes;
set
{
_playoutDuration = TimeSpan.FromHours(_playoutDuration?.Hours ?? 0) + TimeSpan.FromMinutes(value);
CheckPlayoutDuration();
}
}
public TailMode TailMode { get; set; }
@ -115,4 +141,26 @@ public class ProgramScheduleItemEditViewModel : INotifyPropertyChanged @@ -115,4 +141,26 @@ public class ProgramScheduleItemEditViewModel : INotifyPropertyChanged
[CallerMemberName]
string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private void CheckPlayoutDuration()
{
_playoutDuration ??= TimeSpan.Zero;
if (_playoutDuration > TimeSpan.FromHours(24))
{
_playoutDuration = TimeSpan.FromHours(24);
}
if (_playoutDuration < TimeSpan.FromMinutes(1))
{
_playoutDuration = TimeSpan.FromMinutes(1);
}
_playoutDurationHours = (int)_playoutDuration.Value.TotalHours;
_playoutDurationMinutes = _playoutDuration.Value.Minutes;
OnPropertyChanged(nameof(PlayoutDuration));
OnPropertyChanged(nameof(PlayoutDurationHours));
OnPropertyChanged(nameof(PlayoutDurationMinutes));
}
}

Loading…
Cancel
Save