Skip to content

Commit

Permalink
chore: update to async prompt calls
Browse files Browse the repository at this point in the history
  • Loading branch information
AdmiringWorm committed Sep 1, 2022
1 parent be96bb2 commit 53458bc
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 48 deletions.
89 changes: 61 additions & 28 deletions src/VideoConverter/Commands/AddFileCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,12 @@ public override async Task<int> ExecuteAsync(CommandContext context, AddFileOpti

if (episodeData is null)
{
var path = console.Prompt(
new TextPrompt<string>(
$"File '[fuchsia]{file.EscapeMarkup()}[/]'...\n" +
"We were unable to extract necessary information. Please input the location of the file to save,\n" +
$"[grey][[Optional]][/] Relative to the path ([fuchsia]{relativePath.EscapeMarkup()}[/]):"
)
.AllowEmpty()
);
var path = await TextPromptOptionalAsync<string>(
console,
$"File '[fuchsia]{file.EscapeMarkup()}[/]'...\n" +
"We were unable to extract necessary information. Please input the location of the file to save,\n" +
$"[grey][[Optional]][/] Relative to the path ([fuchsia]{relativePath.EscapeMarkup()}[/]):",
tokenSource.Token);

if (string.IsNullOrWhiteSpace(path))
{
Expand Down Expand Up @@ -219,15 +217,16 @@ public override async Task<int> ExecuteAsync(CommandContext context, AddFileOpti

var streams = new List<IStream>();

if (!AddStreams(
if (!await AddStreamsAsync(
streams,
mediaInfo.VideoStreams
.Where(v =>
!string.Equals(
v.Codec, "mjpeg",
StringComparison.OrdinalIgnoreCase)
)
.ToArray()
.ToArray(),
tokenSource.Token
)
)
{
Expand All @@ -238,13 +237,14 @@ public override async Task<int> ExecuteAsync(CommandContext context, AddFileOpti
break;
}

AddStreams(streams, mediaInfo.AudioStreams);
await AddStreamsAsync(streams, mediaInfo.AudioStreams, tokenSource.Token);

if (tokenSource.Token.IsCancellationRequested)
{
break;
}

AddStreams(streams, mediaInfo.SubtitleStreams);
await AddStreamsAsync(streams, mediaInfo.SubtitleStreams, tokenSource.Token);

if (tokenSource.IsCancellationRequested)
{
Expand Down Expand Up @@ -550,8 +550,34 @@ private static string RemoveInvalidChars(string text)
return Regex.Replace(sb.ToString(), @"\s{2,}", " ", RegexOptions.Compiled).Trim();
}

private bool AddStreams<T>(List<IStream> addedStreams, IEnumerable<T> streams)
where T : IStream
private static Task<TType> TextPromptAsync<TType>(
IAnsiConsole console,
string title,
TType defaultValue,
CancellationToken cancellationToken = default)
{
var textPrompt = new TextPrompt<TType>(title)
.DefaultValue(defaultValue);

return textPrompt.ShowAsync(console, cancellationToken);
}

private static Task<TType> TextPromptOptionalAsync<TType>(
IAnsiConsole console,
string title,
CancellationToken cancellationToken = default)
{
var textPrompt = new TextPrompt<TType>(title)
.AllowEmpty();

return textPrompt.ShowAsync(console, cancellationToken);
}

private async Task<bool> AddStreamsAsync<T>(
List<IStream> addedStreams,
IEnumerable<T> streams,
CancellationToken cancellationToken = default)
where T : IStream
{
var streamCount = streams.Count();
if (streamCount == 0)
Expand All @@ -568,19 +594,19 @@ private bool AddStreams<T>(List<IStream> addedStreams, IEnumerable<T> streams)
{
var prompt = new VideoStreamPrompt()
.AddStreams(videoStreams);
addedStreams.AddRange(prompt.Show(console));
addedStreams.AddRange(await prompt.ShowAsync(console, cancellationToken));
}
else if (streams is IEnumerable<IAudioStream> audioStreams)
{
var prompt = new AudioStreamPrompt()
.AddStreams(audioStreams);
addedStreams.AddRange(prompt.Show(console));
addedStreams.AddRange(await prompt.ShowAsync(console, cancellationToken));
}
else if (streams is IEnumerable<ISubtitleStream> subtitleStreams)
{
var prompt = new SubtitleStreamPrompt()
.AddStreams(subtitleStreams);
addedStreams.AddRange(prompt.Show(console));
addedStreams.AddRange(await prompt.ShowAsync(console, cancellationToken));
}

return true;
Expand All @@ -593,7 +619,8 @@ private async Task<bool> AskAcceptableAsync(
{
DisplayEpisodeData(episodeData);

var prompt = console.Prompt(new YesNoPrompt("Do this information look correct?"));
var consolePrompt = new YesNoPrompt("Do this information look correct?");
var prompt = await consolePrompt.ShowAsync(console, cancellationToken).ConfigureAwait(false);

if (cancellationToken.IsCancellationRequested)
{
Expand All @@ -617,15 +644,21 @@ private async Task<bool> AskAcceptableAsync(
var settings = new AddCriteriaOption
{
FilePath = episodeData.FileName,
SeriesName = console.Prompt(
new TextPrompt<string>(
"Name of Series")
.DefaultValue(episodeData.Series.EscapeMarkup())),
SeasonNumber = console.Prompt(
new TextPrompt<int>(
"Season Number")
.DefaultValue(episodeData.SeasonNumber ?? 1)),
EpisodeNumber = console.Prompt(new TextPrompt<int>("Episode Number").DefaultValue(episodeData.EpisodeNumber))
SeriesName = await TextPromptAsync(
console,
"Name of Series",
episodeData.Series.EscapeMarkup(),
tokenSource.Token),
SeasonNumber = await TextPromptAsync(
console,
"Season Number",
episodeData.SeasonNumber ?? 1,
tokenSource.Token),
EpisodeNumber = await TextPromptAsync(
console,
"Episode Number",
episodeData.EpisodeNumber,
tokenSource.Token)
};

if (cancellationToken.IsCancellationRequested)
Expand All @@ -652,7 +685,7 @@ private void CancelProcessing(object? sender, ConsoleCancelEventArgs e)
tokenSource.Cancel();
}

private void DisplayEpisodeData(Core.Models.EpisodeData episodeData)
private void DisplayEpisodeData(EpisodeData episodeData)
{
var grid = new Grid()
.AddColumn(new GridColumn().RightAligned())
Expand Down
14 changes: 12 additions & 2 deletions src/VideoConverter/Prompts/Streams/AudioStreamPrompt.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;

using Spectre.Console;

Expand All @@ -10,14 +12,22 @@ namespace VideoConverter.Prompts.Streams
{
internal sealed class AudioStreamPrompt : StreamPrompt<IAudioStream>
{
protected override IEnumerable<int> ShowBase(IAnsiConsole console, IEnumerable<IAudioStream> streams)
protected override async IAsyncEnumerable<int> ShowBaseAsync(
IAnsiConsole console,
IEnumerable<IAudioStream> streams,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
var prompt = new MultiSelectionPrompt<(int, string, string, int, string)>()
.Title("Which audio streams do you wish to use ([fuchsia]Select no streams to use all streams)[/]?")
.NotRequired()
.AddChoices(streams.Select(MapStream));

return console.Prompt(prompt).Select(p => p.Item1);
var values = await prompt.ShowAsync(console, cancellationToken).ConfigureAwait(false);

foreach (var item in values)
{
yield return item.Item1;
}
}

private (int, string, string, int, string) MapStream(IAudioStream stream)
Expand Down
31 changes: 23 additions & 8 deletions src/VideoConverter/Prompts/Streams/StreamPrompt.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

using Spectre.Console;

Expand All @@ -21,18 +23,31 @@ public StreamPrompt<T> AddStreams(IEnumerable<T> streams)

public IEnumerable<T> Show(IAnsiConsole console)
{
var indexes = ShowBase(console, streams);
throw new NotSupportedException("Synchron calling is not supported!");
}

if (indexes.Any())
{
return streams.Where(s => indexes.Contains(s.Index));
}
else
public async Task<IEnumerable<T>> ShowAsync(IAnsiConsole console, CancellationToken cancellationToken)
{
var streamDictionary = streams.ToDictionary(
k => k.Index,
v => v);

var result = new List<T>();

await foreach (var index in ShowBaseAsync(console, streams, cancellationToken))
{
return streams;
if (streamDictionary.ContainsKey(index))
{
result.Add(streamDictionary[index]);
}
}

return result;
}

protected abstract IEnumerable<int> ShowBase(IAnsiConsole console, IEnumerable<T> streams);
protected abstract IAsyncEnumerable<int> ShowBaseAsync(
IAnsiConsole console,
IEnumerable<T> streams,
CancellationToken cancellationToken);
}
}
14 changes: 12 additions & 2 deletions src/VideoConverter/Prompts/Streams/SubtitleStreamPrompt.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;

using Spectre.Console;

Expand All @@ -10,14 +12,22 @@ namespace VideoConverter.Prompts.Streams
{
internal sealed class SubtitleStreamPrompt : StreamPrompt<ISubtitleStream>
{
protected override IEnumerable<int> ShowBase(IAnsiConsole console, IEnumerable<ISubtitleStream> streams)
protected override async IAsyncEnumerable<int> ShowBaseAsync(
IAnsiConsole console,
IEnumerable<ISubtitleStream> streams,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
var prompt = new MultiSelectionPrompt<(int, string, string, string)>()
.Title("Which subtitle streams do you wish to use ([fuchsia]Select no streams to use all streams)[/]?")
.NotRequired()
.AddChoices(streams.Select(MapStream));

return console.Prompt(prompt).Select(p => p.Item1);
var values = await prompt.ShowAsync(console, cancellationToken).ConfigureAwait(false);

foreach (var item in values)
{
yield return item.Item1;
}
}

private (int, string, string, string) MapStream(ISubtitleStream stream)
Expand Down
14 changes: 12 additions & 2 deletions src/VideoConverter/Prompts/Streams/VideoStreamPrompt.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;

using Spectre.Console;

Expand All @@ -10,7 +12,10 @@ namespace VideoConverter.Prompts.Streams
{
internal sealed class VideoStreamPrompt : StreamPrompt<IVideoStream>
{
protected override IEnumerable<int> ShowBase(IAnsiConsole console, IEnumerable<IVideoStream> streams)
protected override async IAsyncEnumerable<int> ShowBaseAsync(
IAnsiConsole console,
IEnumerable<IVideoStream> streams,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
var prompt = new MultiSelectionPrompt<(int, string, string, TimeSpan)>()
.Title("Which video streams do you wish to use ([fuchsia] Select no streams to use all streams)[/]?")
Expand All @@ -23,7 +28,12 @@ protected override IEnumerable<int> ShowBase(IAnsiConsole console, IEnumerable<I
s.Duration
)));

return console.Prompt(prompt).Select(p => p.Item1);
var values = await prompt.ShowAsync(console, cancellationToken).ConfigureAwait(false);

foreach (var item in values)
{
yield return item.Item1;
}
}
}
}
25 changes: 19 additions & 6 deletions src/VideoConverter/Prompts/YesNoPrompt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
namespace VideoConverter.Prompts
{
using System;
using System.Threading;
using System.Threading.Tasks;

using Spectre.Console;

using VideoConverter.Core.Assertions;

internal sealed class YesNoPrompt : IPrompt<PromptResponse>
{
private readonly string _prompt;
Expand All @@ -19,6 +23,11 @@ public YesNoPrompt(string prompt)
public PromptResponse DefaultResponse { get; set; }

public PromptResponse Show(IAnsiConsole console)
{
throw new NotSupportedException("Sync calls are not supported!");
}

public async Task<PromptResponse> ShowAsync(IAnsiConsole console, CancellationToken cancellationToken)
{
if (console is null)
{
Expand All @@ -31,15 +40,14 @@ public PromptResponse Show(IAnsiConsole console)

while (true)
{
var key = console.Input.ReadKey(true);
var key = await console.Input.ReadKeyAsync(intercept: true, cancellationToken).ConfigureAwait(false);

if (key.Key == ConsoleKey.Enter)
if (!key.HasValue)
{
console.WriteLine(DefaultResponse.ToString(), promptStyle);
return DefaultResponse;
continue;
}

switch (key.Key)
switch (key.Value.Key)
{
case ConsoleKey.Y:
console.WriteLine("Yes", promptStyle);
Expand All @@ -54,12 +62,17 @@ public PromptResponse Show(IAnsiConsole console)
return PromptResponse.Skip;

case ConsoleKey.C:
if (key.Modifiers == ConsoleModifiers.Control)
if (key.Value.Modifiers == ConsoleModifiers.Control)
{
console.WriteLine("Skip", promptStyle);
return PromptResponse.Skip;
}

break;

case ConsoleKey.Enter:
console.WriteLine(DefaultResponse.ToString(), promptStyle);
return DefaultResponse;
}
}
}
Expand Down

0 comments on commit 53458bc

Please sign in to comment.