Ajout gestion des toasts sur Blazor

This commit is contained in:
YuukanOO 2021-04-28 15:03:29 +02:00
parent cb3821e5ed
commit 5c98a14d91
14 changed files with 212 additions and 26 deletions

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Client
{
/// <summary>
/// Service permettant d'afficher des toasts dans l'application.
/// </summary>
public class NotificationManager
{
private Queue<string> _messages = new Queue<string>();
public IReadOnlyList<string> Messages => _messages.ToArray();
public event Action OnChange;
public void Add(string message)
{
_messages.Enqueue(message);
Task.Run(async () =>
{
await Task.Delay(3000);
_messages.Dequeue();
OnChange?.Invoke();
});
OnChange?.Invoke();
}
}
}

View File

@ -1,16 +0,0 @@
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}

View File

@ -0,0 +1,58 @@
@page "/links/{id:guid}"
@inject LinksClient Links
@inject CommentsClient Comments
@inject NotificationManager Notification
@if (_link == null)
{
<Title Value="Loading link detail..." />
<p>Loading link detail...</p>
}
else
{
<Title Value="@($"Viewing link {_link.Url}")" />
<h1>Viewing link @_link.Url</h1>
@if(_comments == null)
{
<p>Loading link comments...</p>
}
else if (_comments.Count == 0)
{
<p>No comments yet.</p>
}
else
{
<ul>
@foreach (var comment in _comments)
{
<li>@comment.Content</li>
}
</ul>
}
<CommentForm OnSubmit="PublishComment" />
}
@code {
[Parameter]
public Guid Id { get; set; }
private LinkDTO _link;
private ICollection<CommentDTO> _comments;
protected override async Task OnInitializedAsync()
{
_link = await Links.GetByIdAsync(Id);
_comments = await Links.CommentsAsync(Id);
}
private async Task PublishComment(PublishCommentCommand cmd)
{
cmd.LinkId = Id;
await Comments.CreateAsync(cmd);
Notification.Add("Your comment was published!");
_comments = await Links.CommentsAsync(Id);
}
}

View File

@ -1,6 +1,8 @@
@page "/" @page "/"
@inject LinksClient Links @inject LinksClient Links
<Title Value="Latest links" />
<h1>Latest links</h1> <h1>Latest links</h1>
@if (_links == null) { @if (_links == null) {

View File

@ -1,6 +1,7 @@
@page "/links/new" @page "/links/new"
@inject LinksClient Links @inject LinksClient Links
@inject NavigationManager Navigation @inject NavigationManager Navigation
@inject NotificationManager Notification
@using System.ComponentModel.DataAnnotations @using System.ComponentModel.DataAnnotations
<h1>Publish a new link!</h1> <h1>Publish a new link!</h1>
@ -29,6 +30,7 @@
try try
{ {
await Links.CreateAsync(_model.Command); await Links.CreateAsync(_model.Command);
Notification.Add("Your link was published!");
Navigation.NavigateTo("/"); Navigation.NavigateTo("/");
} }
catch(Exception ex) catch(Exception ex)

View File

@ -0,0 +1,20 @@
@page "/sandbox"
<p>Current count: @currentCount</p>
<Counter @bind-Count="currentCount" />
@* <CascadingValue Value="45">
<Composant1 />
</CascadingValue>
<Composant2 /> *@
@code {
private int currentCount = 0;
/*
[CascadingParameter]
public int Valeur { get; set; }
*/
}

View File

@ -19,6 +19,8 @@ namespace Client
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.Configuration["BaseUrl"]) }); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.Configuration["BaseUrl"]) });
builder.Services.AddScoped<LinksClient>(); builder.Services.AddScoped<LinksClient>();
builder.Services.AddScoped<CommentsClient>();
builder.Services.AddSingleton<NotificationManager>();
await builder.Build().RunAsync(); await builder.Build().RunAsync();
} }

View File

@ -0,0 +1,22 @@
<EditForm Model="_model" OnValidSubmit="OnValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<label for="content">Your comment</label>
<InputTextArea id="content" @bind-Value="_model.Content" />
<button type="submit">Post your comment</button>
</EditForm>
@code {
[Parameter]
public EventCallback<PublishCommentCommand> OnSubmit { get; set; }
private PublishCommentCommand _model = new PublishCommentCommand();
private async Task OnValidSubmit()
{
await OnSubmit.InvokeAsync(_model);
_model = new PublishCommentCommand();
}
}

View File

@ -0,0 +1,22 @@
<p>Current count in component: @Count</p>
<button @onclick="Increment">+</button>
<button @onclick="Decrement">-</button>
@code {
[Parameter]
public int Count { get; set; }
[Parameter]
public EventCallback<int> CountChanged { get; set; }
private void Increment()
{
CountChanged.InvokeAsync(Count + 1);
}
private void Decrement()
{
CountChanged.InvokeAsync(Count - 1);
}
}

View File

@ -1,6 +1,7 @@
<article> <article>
<h2>@Item.Url</h2> <h2>@Item.Url</h2>
<p> <p>
<NavLink href="@($"/links/{Item.Id}")">Show</NavLink>
- Published at @Item.CreatedAt.DateTime.ToLongDateString() - Published at @Item.CreatedAt.DateTime.ToLongDateString()
- 🗨 @Item.CommentsCount - 🗨 @Item.CommentsCount
- 👍 @Item.UpvotesCount / 👎 @Item.DownvotesCount - 👍 @Item.UpvotesCount / 👎 @Item.DownvotesCount

View File

@ -11,6 +11,8 @@
</div> </div>
<div class="content px-4"> <div class="content px-4">
<Notifications />
@Body @Body
</div> </div>
</div> </div>

View File

@ -0,0 +1,21 @@
@inject NotificationManager Notification
@implements IDisposable
<div>
@foreach (var msg in Notification.Messages)
{
<p class="alert alert-success">@msg</p>
}
</div>
@code {
protected override void OnInitialized()
{
Notification.OnChange += StateHasChanged;
}
public void Dispose()
{
Notification.OnChange -= StateHasChanged;
}
}

View File

@ -0,0 +1,11 @@
@inject IJSRuntime JS
@code {
[Parameter]
public string Value { get; set; }
protected override void OnInitialized()
{
JS.InvokeVoidAsync("setTitle", Value);
}
}

View File

@ -1,9 +1,11 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<title>Client</title> <title>Client</title>
<base href="/" /> <base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" /> <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
@ -19,7 +21,12 @@
<a href="" class="reload">Reload</a> <a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a> <a class="dismiss">🗙</a>
</div> </div>
<script type="text/javascript">
function setTitle(title) {
document.title = title;
}
</script>
<script src="_framework/blazor.webassembly.js"></script> <script src="_framework/blazor.webassembly.js"></script>
</body> </body>
</html> </html>