Blazored / Toast

A JavaScript free toast library for Blazor and Razor Component applications
https://blazored.github.io/Toast/
MIT License
663 stars 92 forks source link

[Feature Request] ShowToast can return handle to toast instance in order to close or update it. #97

Open Liero opened 3 years ago

Liero commented 3 years ago

SCENARIO

I would like to show toasts instead of wait overlays in different scenarios.

For example when user click a button, I'm sending some emails in the background and during the process I would like to show a toast with messing "Sending emails..". When done sending, I would like to either close the toast, or update it to "Emails sent".

Example

var toastReference = await toastService.ShowToastAsync(ToastLevel.Info, "Sending emails");
await Task.Delay(1000);
toastReference.Timeout = TimeSpan.MaxValue; //or TimeSpan.Zero or null?
toastReference.Level = ToastLevel.Success;
toastReference.Message = "Emails sent!";
toastReference.ResetTimeout(TimeSpan.FromSeconds(2));
toastReference.Close();

I can do PR once agreed on the design

chrissainty commented 3 years ago

Thanks for raising this @Liero. It is actually already being worked on as part of the next major version! I'll tag this issue as part of that milestone so we make sure we don't overlook anything.

Liero commented 3 years ago

Hi @chrissainty, is there any progress on this?

I'm sure you are quite busy, so let me know if you need help.

I need customizable timeout per toast instance. Is it realistic, it will be released this year? Otherwise I will need to fork the repo.

chrissainty commented 3 years ago

I'm just in the last stages with my book and I'm just getting it finalised for the publishers. Once that is done, I'll have some time back again and I can start getting some of these issues sorted. If you can just bare with me a little longer.

adamashton commented 2 years ago

I am looking to close a toast automatically once a long running task has completed. It would be great to reference a toast/id a close the specific one via the ToastService.

Cvijo commented 1 year ago

What about if ShowToast methods return ToastInstance class (need to change to public class), set all properties to internal except for maybe Guid, and create a new public void Close() method

something like this:


public class ToastInstance
{
    internal event Action? OnClose;  
internal ToastInstance(RenderFragment message, ToastLevel level, ToastSettings toastSettings) { Message = message; Level = level; ToastSettings = toastSettings; } internal ToastInstance(RenderFragment customComponent, ToastSettings settings) { CustomComponent = customComponent; ToastSettings = settings; } public Guid Id { get; } = Guid.NewGuid(); internal DateTime TimeStamp { get; } = DateTime.Now; internal RenderFragment? Message { get; } internal ToastLevel Level { get; } internal ToastSettings ToastSettings { get; } internal RenderFragment? CustomComponent { get; }
public void Close() { OnClose?.Invoke(Id); } }

inside BlazoredToasts.cs on ShowToast


    private ToastInstance ShowToast(ToastLevel level, RenderFragment message, Action? toastSettings)
    {

        var settings = BuildToastSettings(level, message, toastSettings);
        var toast = new ToastInstance(message, level, settings);
        toast.OnClose += RemoveToast; 
        InvokeAsync(() =>
        {

            if (ToastList.Count < MaxToastCount)
            {
                ToastList.Add(toast);
                StateHasChanged();
            }
            else
            {
                ToastWaitingQueue.Enqueue(toast);
            }
        });
        return toast; 
    }

using it would be something like:

        var instance = toastService.ShowToast(ToastLevel.Warning, "message to toast", settings => settings.DisableTimeout= true);
        await Task.Delay(2000); //<-- waiting for some task to complete
        instance.Close();

Another thing maybe to consider is to have something like an instance.SetMessage() to be able to change the message, for example, if you are waiting some multiple task and you show a toast with DisableTimeout = true and to update message "task 1 done" .. "task 2 done", "last task in progress" and then instance.Close() might be useful in some cases.

chrissainty commented 1 year ago

@Cvijo I think this could be a good starting point. Do you want to raise a PR based on your suggestion and then we can see how it looks in reality?

Liero commented 1 year ago

I've already done it, see ToastService.cs and ToastReference.cs.

I use the same approach for updating the toast (for example I change title, content, severity etc of existing toast)

Feel free to inspire