Skip to content

Commit

Permalink
#27 WIP Timer/Stopwatch
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-hedley committed Sep 26, 2023
1 parent 752460a commit 60d1263
Show file tree
Hide file tree
Showing 9 changed files with 305 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/Utility.Test/StopwatchTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Bunit;
using Xunit;

using Utility.Components.Stopwatch;

namespace Utility.Test;

public class StopwatchTest : TestContext
{
public StopwatchTest() {}

// [Fact]
public void StopwatchShouldStart()
{
string input = "";
string expectedInput = "";


var cut = RenderComponent<Stopwatch>(parameters => parameters
.Add(p => p.Input, input)
);

cut.FindAll("button")[0].Click();
// string markup = "";
// cut.FindAll("input")[1].MarkupMatches(markup);

Stopwatch stopwatch = cut.Instance;
Assert.Equal(stopwatch.Input, input);
}

// [Fact]
public void StopwatchShouldStop()
{

}
}
34 changes: 34 additions & 0 deletions src/Utility.Test/TimerControlTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Bunit;
using Xunit;

using Utility.Components.TimerControl;

namespace Utility.Test;

public class TimerControlTest : TestContext
{
public TimerControlTest() {}

// [Fact]
public void TimerControlShouldStart()
{
string input = "5m 00s";
string expectedInput = "";
var cut = RenderComponent<TimerControl>(parameters => parameters
.Add(p => p.Input, input)
);

cut.FindAll("button")[0].Click();
// string markup = "";
// cut.FindAll("input")[1].MarkupMatches(markup);

TimerControl timerControl = cut.Instance;
Assert.Equal(timerControl.Input, input);
}

// [Fact]
public void TimerControlShouldStop()
{

}
}
109 changes: 109 additions & 0 deletions src/Utility/Components/Stopwatch/Stopwatch.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
@using System.Timers
@implements IDisposable

<div class="container">
<div class="row">
<div class="col">
<h2><i class="fas fa-stopwatch"></i> Stopwatch</h2>
</div>
</div>

<div class="row">
<div class="col">
<input id="input" name="input" class="form-control" @bind="Input" placeholder="00:00" />
</div>
</div>

<div class="row">
<div class="col">
<button id="btnStartStop" name="btnStartStop" class="btn btn-success" @onclick="StartStop"><i class="fas fa-play"></i><i class="fas fa-stop"></i></button>
<button id="btnReset" name="btnReset" class="btn btn-info float-right" @onclick="Reset"><i class="fas fa-sync"></i></button>
</div>
</div>

@* <div class="row"> *@
@* <div class="col"> *@
@* <p>Inspired from <a href="" target="_blank"></a></p> *@
@* </div> *@
@* </div> *@

</div>

@code {
[Parameter]
public string? Input { get; set; }

[Parameter]
public EventCallback TimerOut { get; set; }

private Timer timer = null!;
private int secondsToRun = 0;

// protected override void OnInitialized()
// {
// // Input = "00:00";
// timer = new System.Threading.Timer(async _ => // async void
// {
// Input =
// // we need StateHasChanged() because this is an async void handler
// // we need to Invoke it because we could be on the wrong Thread
// await InvokeAsync(StateHasChanged);
// }, null, 0, 1000);
// }
void StartStop()
{
if (string.IsNullOrEmpty(Input)) return;
Start(10);
}

void Reset()
{
Start(600);
}

public void Start(int secondsToRun)
{
if (secondsToRun > 0)
{
Input = TimeSpan.FromSeconds(secondsToRun).ToString(@"mm\:ss");
StateHasChanged();
timer.Start();
}
}

public void Stop()
{
timer.Stop();
}

protected override void OnInitialized()
{
timer = new Timer(1000);
timer.Elapsed += OnTimedEvent;
timer.AutoReset = true;
}

private async void OnTimedEvent(object? sender, ElapsedEventArgs e)
{
secondsToRun--;

await InvokeAsync(() =>
{
Input = TimeSpan.FromSeconds(secondsToRun).ToString(@"mm\:ss");
StateHasChanged();
});

if (secondsToRun <= 0)
{
timer.Stop();
await TimerOut.InvokeAsync();
}
}

public void Dispose()
{
timer.Dispose();
}

}
Empty file.
109 changes: 109 additions & 0 deletions src/Utility/Components/TimerControl/TimerControl.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
@using System.Timers
@implements IDisposable

<div class="container">
<div class="row">
<div class="col">
<h2><i class="far fa-hourglass"></i> Timer</h2>
</div>
</div>

<div class="row">
<div class="col">
<input id="input" name="input" class="form-control" @bind="Input" placeholder="00:00" />
</div>
</div>

<div class="row">
<div class="col">
<button id="btnStartStop" name="btnStartStop" class="btn btn-success" @onclick="StartStop"><i class="fas fa-play"></i><i class="fas fa-stop"></i></button>
<button id="btnReset" name="btnReset" class="btn btn-info float-right" @onclick="Reset"><i class="fas fa-sync"></i></button>
</div>
</div>

@* <div class="row"> *@
@* <div class="col"> *@
@* <p>Inspired from <a href="" target="_blank"></a></p> *@
@* </div> *@
@* </div> *@

</div>

@code {
[Parameter]
public string? Input { get; set; }

[Parameter]
public EventCallback TimerOut { get; set; }

private Timer timer = null!;
private int secondsToRun = 0;

// protected override void OnInitialized()
// {
// // Input = "00:00";
// timer = new System.Threading.Timer(async _ => // async void
// {
// Input =
// // we need StateHasChanged() because this is an async void handler
// // we need to Invoke it because we could be on the wrong Thread
// await InvokeAsync(StateHasChanged);
// }, null, 0, 1000);
// }
void StartStop()
{
if (string.IsNullOrEmpty(Input)) return;

}

void Reset()
{

}

public void Start(int secondsToRun)
{
if (secondsToRun > 0)
{
Input = TimeSpan.FromSeconds(secondsToRun).ToString(@"mm\:ss");
StateHasChanged();
timer.Start();
}
}

public void Stop()
{
timer.Stop();
}

protected override void OnInitialized()
{
timer = new Timer(1000);
timer.Elapsed += OnTimedEvent;
timer.AutoReset = true;
}

private async void OnTimedEvent(object? sender, ElapsedEventArgs e)
{
secondsToRun--;

await InvokeAsync(() =>
{
Input = TimeSpan.FromSeconds(secondsToRun).ToString(@"mm\:ss");
StateHasChanged();
});

if (secondsToRun <= 0)
{
timer.Stop();
await TimerOut.InvokeAsync();
}
}

public void Dispose()
{
timer.Dispose();
}

}
Empty file.
12 changes: 12 additions & 0 deletions src/Utility/Pages/TimerStopwatch.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@page "/timerstopwatch"

@using Utility.Components.TimerControl
@using Utility.Components.Stopwatch

<PageTitle>️⏲️ Timer / ⏱️ Stopwatch</PageTitle>

<TimerControl Input="5m 00s" />

<hr />

<Stopwatch Input="0s 00" />
Empty file.
5 changes: 5 additions & 0 deletions src/Utility/Shared/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@
<span class="oi oi-arrow-thick-bottom" aria-hidden="true"></span> Markdown
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="timerstopwatch">
<span class="oi oi-timer" aria-hidden="true"></span> Timer / Stopwatch
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="ascii">
<span class="oi oi-text" aria-hidden="true"></span> Ascii
Expand Down

0 comments on commit 60d1263

Please sign in to comment.