Update componente loading con stima fake

This commit is contained in:
Samuele Locatelli
2023-07-28 19:03:12 +02:00
parent 9bc8473d64
commit 90560b4024
4 changed files with 262 additions and 0 deletions
@@ -0,0 +1,14 @@
@page "/TestLoading"
<h3>TestLoading</h3>
<div>
<label class="form-label">Tempo sim</label>
<input css="form-control" @bind="@expTime" type="number" />
</div>
<div>
<label class="form-label">Num steps</label>
<input css="form-control" @bind="@numSteps" type="number" />
</div>
<button class="btn btn-success" @onclick="StartLongTimer">Start</button>
<ProgressDisplay RefreshInterval="100" Title="@titleMsg" MaxVal="@maxVal" CurrVal="@currVal" NextVal="@nextVal" ExpTimeMSec="@expTimeMSec"></ProgressDisplay>
@@ -0,0 +1,58 @@
namespace EgwCoreLib.BlazorTest.Pages
{
public partial class TestLoading
{
#region Protected Properties
protected double expTime { get; set; } = 20;
protected int numSteps { get; set; } = 4;
#endregion Protected Properties
#region Protected Methods
protected async Task StartLongTimer()
{
double stdWait = expTime / numSteps;
int nextWait = 1000;
int stepVal = maxVal / numSteps;
// imposto i valori x progress..
maxVal = 100;
expTimeMSec = stdWait * 1000;
//nextVal = stepVal;
//currVal = 0;
for (int currStep = 1; currStep <= numSteps; currStep++)
{
//await Task.Delay(1);
// aggiorno valori
currVal = (currStep - 1) * stepVal;
nextVal = currStep * stepVal;
// se max mi fermo...
if (nextVal > maxVal)
{
nextVal = maxVal;
}
await InvokeAsync(StateHasChanged);
nextWait = (int)(rnd.Next(2000, 2500) * stdWait);
// attendo step successivi...
await Task.Delay(nextWait);
}
await Task.Delay(1);
currVal = maxVal;
await InvokeAsync(StateHasChanged);
}
#endregion Protected Methods
#region Private Fields
private int currVal = 100;
private double expTimeMSec = 10000;
private int maxVal = 100;
private int nextVal = 100;
private Random rnd = new Random();
private string titleMsg = "Test Progress";
#endregion Private Fields
}
}
+33
View File
@@ -0,0 +1,33 @@
@*<div class="row p-3 m-2">
<div class="col-12 text-center mt-5 py-5 alert alert-primary">
<h3>loading data</h3>
<i class="fas fa-spinner fa-spin fa-5x"></i>
</div>
</div>
*@
@if (IsLoading)
{
<dialog class="modal fade show" tabindex="-1" style="display:block; background-color: rgba(10,10,10,.6);" aria-modal="true" role="dialog">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="col-12 text-center my-0 py-2 @modalCss">
<div class="d-flex justify-content-around py-5">
<div>
<h2>@Title</h2>
<i>@DisplayMsg</i>
</div>
</div>
@* <div class="d-flex justify-content-around py-2">
<div><i class="fas fa-circle-notch fa-spin fa-5x"></i></div>
</div>*@
<div class="w-100">
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width: @currWidth"></div>
</div>
</div>
</div>
</div>
</div>
</dialog>
}
+157
View File
@@ -0,0 +1,157 @@
using Microsoft.AspNetCore.Components;
namespace EgwCoreLib.Razor
{
public partial class ProgressDisplay : IDisposable
{
#region Public Properties
[Parameter]
public double CurrVal
{
get => ActVal;
set
{
ActVal = value;
StartVal = value;
IsLoading = ActVal < MaxVal;
}
}
[Parameter]
public double ExpTimeMSec { get; set; } = 10000;
[Parameter]
public bool IsLoading { get; set; } = false;
[Parameter]
public double MaxVal { get; set; } = 100;
[Parameter]
public double NextVal { get; set; } = 100;
[Parameter]
public string Title { get; set; } = "Progress";
#endregion Public Properties
#region Public Methods
public void Dispose()
{
periodicTimer?.Dispose();
}
#endregion Public Methods
#region Protected Fields
protected PeriodicTimer? periodicTimer = null;
#endregion Protected Fields
#region Protected Properties
protected string currWidth { get; set; } = "";
protected string modalCss { get; set; } = "alert alert-success";
#endregion Protected Properties
#region Protected Methods
#if false
protected override void OnInitialized()
{
RunTimer(); // fire-and-forget
}
#endif
protected override async Task OnParametersSetAsync()
{
// salvo valori aggiornamento...
if (ExpTimeMSec > 0)
{
lastUpdate = DateTime.Now;
nextUpdate = lastUpdate.AddMilliseconds(ExpTimeMSec);
await RefreshDisplay();
}
if(IsLoading)
{
periodicTimer?.Dispose();
periodicTimer = new PeriodicTimer(TimeSpan.FromMilliseconds(RefInt));
RunTimer();
}
else
{
periodicTimer = null;
}
}
protected async Task RefreshDisplay()
{
currWidth = $"{(double)ActVal / MaxVal:P0}";
DisplayMsg = $"{ActVal / MaxVal:P2}";
await InvokeAsync(StateHasChanged);
}
#endregion Protected Methods
#region Private Fields
[Parameter]
public int RefreshInterval
{
get => RefInt;
set
{
if (RefInt != value && value > 0)
{
RefInt = value;
#if false
periodicTimer?.Dispose();
periodicTimer = new PeriodicTimer(TimeSpan.FromMilliseconds(value));
RunTimer();
#endif
}
}
}
private int RefInt { get; set; } = 100;
#endregion Private Fields
#region Private Properties
private double ActVal { get; set; } = 100;
private string DisplayMsg { get; set; } = "Loading...";
private DateTime lastUpdate { get; set; } = DateTime.Now.AddMinutes(-1);
private DateTime nextUpdate { get; set; } = DateTime.Now;
private double StartVal { get; set; } = 100;
#endregion Private Properties
#region Private Methods
private async void RunTimer()
{
while (periodicTimer!=null && await periodicTimer.WaitForNextTickAsync())
{
if (IsLoading)
{
DateTime adesso = DateTime.Now;
if (nextUpdate <= adesso)
{
nextUpdate = adesso.AddMilliseconds(RefreshInterval);
}
// calcolo delta ms...
var deltaMs = adesso.Subtract(lastUpdate).TotalMilliseconds;
var denomMs = nextUpdate.Subtract(lastUpdate).TotalMilliseconds;
// aggiorno display...
ActVal = StartVal + (NextVal - StartVal) * (deltaMs / denomMs);
await RefreshDisplay();
}
}
}
#endregion Private Methods
}
}