using Microsoft.AspNetCore.Components; namespace EgwCoreLib.Razor { public partial class ProgressDisplay : IDisposable { #region Public Enums public enum ModalSize { Small, Medium, Large } #endregion Public Enums #region Public Properties /// /// Valore corrente /// [Parameter] public double CurrVal { get => actVal; set { actVal = value; startVal = value; isLoading = actVal < MaxVal; } } /// /// Dimensioni attese modale /// default: ModalSize.Medium /// [Parameter] public ModalSize DisplaySize { get; set; } = ModalSize.Medium; /// /// Tempo atteso per prossimo step /// default: 10000 /// [Parameter] public int ExpTimeMSec { get; set; } = 10000; /// /// Valore massimo ammesso /// default: 100 /// [Parameter] public double MaxVal { get; set; } = 100; /// /// Style modale /// default: card /// alternative: card alert-primary /// [Parameter] public string ModalCss { get; set; } = "card"; /// /// Prossimo valore ammesso (fino al max) /// default: 100 /// [Parameter] public double NextVal { get; set; } = 100; /// /// Style progressbar /// default: progress-bar progress-bar-striped progress-bar-animated /// [Parameter] public string ProgressCss { get; set; } = "progress-bar progress-bar-striped progress-bar-animated"; /// /// Intervallo interno per refresh percentuale avanzamento /// default: 100ms /// [Parameter] public int RefreshInterval { get; set; } = 100; /// /// Indica se mostrare la percentuale vanzamento /// default: true /// [Parameter] public bool ShowPercent { get; set; } = true; /// /// Limite per anticipo slowdown (% della durata di ExpTimeMSec) /// [Parameter] public double SlowLimit { get; set; } = 0.5; /// /// Numero di secondi prima (rispetto valore ExpTimeMsec) da cui iniziare rallentamento /// private int slowWindowMSec { get => (int)(ExpTimeMSec * SlowLimit); } /// /// Titolo da mostrare (se "" NON lo mostra) /// [Parameter] public string Title { get; set; } = "Progress"; #endregion Public Properties #region Public Methods public void Dispose() { uiTimer?.Dispose(); } #endregion Public Methods #region Protected Properties protected string modalDialogCss { get { string answ = "modal-dialog"; switch (DisplaySize) { case ModalSize.Small: answ = "modal-dialog modal-sm"; break; case ModalSize.Large: answ = "modal-dialog modal-xl"; break; case ModalSize.Medium: default: break; } return answ; } } #endregion Protected Properties #region Protected Methods protected override async Task OnParametersSetAsync() { // salvo valori aggiornamento... if (ExpTimeMSec > 0) { lastUpdate = DateTime.Now; nextUpdate = lastUpdate.AddMilliseconds(ExpTimeMSec); await RefreshDisplay(); } if (isLoading) { uiTimer?.Dispose(); uiTimer = new PeriodicTimer(TimeSpan.FromMilliseconds(RefreshInterval)); RunTimer(); } else { uiTimer = null; } } #endregion Protected Methods #region Private Fields private PeriodicTimer? uiTimer = null; #endregion Private Fields #region Private Properties private double actVal { get; set; } = 100; private string currWidth { get; set; } = ""; private string displayMsg { get; set; } = "Loading..."; private bool isLoading { get; set; } = false; 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 Task RefreshDisplay() { currWidth = $"{(double)actVal / MaxVal:P0}"; if (ShowPercent) { displayMsg = $"{actVal / MaxVal:P2}"; } await InvokeAsync(StateHasChanged); } private async void RunTimer() { while (uiTimer != null && await uiTimer.WaitForNextTickAsync()) { if (isLoading) { DateTime adesso = DateTime.Now; if (nextUpdate <= adesso.AddMilliseconds(slowWindowMSec)) { nextUpdate = adesso.AddMilliseconds(RefreshInterval*2); } // calcolo delta ms... var numMs = adesso.Subtract(lastUpdate).TotalMilliseconds; var denMs = nextUpdate.Subtract(lastUpdate).TotalMilliseconds; denMs = denMs > 0 ? denMs : 1; // aggiorno display... actVal = startVal + (NextVal - startVal) * (numMs / denMs); await RefreshDisplay(); } } } #endregion Private Methods } }