diff --git a/BeReadyBackend.sln.DotSettings.user b/BeReadyBackend.sln.DotSettings.user index 95ef1f5..da97fdf 100644 --- a/BeReadyBackend.sln.DotSettings.user +++ b/BeReadyBackend.sln.DotSettings.user @@ -1,2 +1,3 @@  + ForceIncluded ForceIncluded \ No newline at end of file diff --git a/BeReadyBackend/BeReadyBackend.csproj b/BeReadyBackend/BeReadyBackend.csproj index 1697993..a7df42c 100644 --- a/BeReadyBackend/BeReadyBackend.csproj +++ b/BeReadyBackend/BeReadyBackend.csproj @@ -15,6 +15,7 @@ + all diff --git a/BeReadyBackend/Endpoints/Groups/GetGroupRankingEndpoint.cs b/BeReadyBackend/Endpoints/Groups/GetGroupRankingEndpoint.cs index dbc50bf..6ffd46c 100644 --- a/BeReadyBackend/Endpoints/Groups/GetGroupRankingEndpoint.cs +++ b/BeReadyBackend/Endpoints/Groups/GetGroupRankingEndpoint.cs @@ -36,7 +36,12 @@ public class GetGroupRankingEndpoint( foreach (UserGroup member in group.UserGroups!) { if (member.Proof is null) member.Score -= 2; + + if (!member.VotedProofId.HasValue) continue; + User? votedUser = await usersRepository.SingleOrDefaultAsync(new GetUserByIdSpec(member.VotedProofId.Value), ct); + if (votedUser is not null) votedUser.Score++; } + await usersRepository.SaveChangesAsync(ct); await userGroupsRepository.SaveChangesAsync(ct); List groupScore = await userGroupsRepository.ProjectToListAsync(new GetGroupRankSpec(req.Id), ct); diff --git a/BeReadyBackend/Endpoints/Groups/PatchGroupUserProofEndpoint.cs b/BeReadyBackend/Endpoints/Groups/PatchGroupUserProofEndpoint.cs index 1d25495..035b3fd 100644 --- a/BeReadyBackend/Endpoints/Groups/PatchGroupUserProofEndpoint.cs +++ b/BeReadyBackend/Endpoints/Groups/PatchGroupUserProofEndpoint.cs @@ -1,8 +1,10 @@ -using BeReadyBackend.Models; +using BeReadyBackend.Hubs; +using BeReadyBackend.Models; using BeReadyBackend.Repositories; using BeReadyBackend.Services; using BeReadyBackend.Specifications.Groups; using FastEndpoints; +using Microsoft.AspNetCore.SignalR; namespace BeReadyBackend.Endpoints.Groups; @@ -12,7 +14,7 @@ public class UserProofRequest public string? Proof { get; set; } } -public class PatchGroupUserProofEndpoint(UserGroupsRepository userGroupsRepository, UserService userService) : Endpoint +public class PatchGroupUserProofEndpoint(UserGroupsRepository userGroupsRepository, UserService userService, IHubContext hubContext) : Endpoint { public override void Configure() { @@ -35,7 +37,7 @@ public class PatchGroupUserProofEndpoint(UserGroupsRepository userGroupsReposito await Send.StringAsync("Vous avez déjà déposé une photo", 400, cancellation: ct); return; } - + if (member.Group!.IsFinished) { await Send.StringAsync("Ce défi est terminé", 400, cancellation: ct); @@ -44,6 +46,9 @@ public class PatchGroupUserProofEndpoint(UserGroupsRepository userGroupsReposito member.Proof = req.Proof; await userGroupsRepository.SaveChangesAsync(ct); + + await hubContext.Clients.Group($"group-{req.GroupId}").SendAsync("ReceiveProof", req.Proof, cancellationToken: ct); + await Send.OkAsync(ct); } } \ No newline at end of file diff --git a/BeReadyBackend/Endpoints/Groups/StartVoteEndpoint.cs b/BeReadyBackend/Endpoints/Groups/StartVoteEndpoint.cs index f3ad82a..15f8303 100644 --- a/BeReadyBackend/Endpoints/Groups/StartVoteEndpoint.cs +++ b/BeReadyBackend/Endpoints/Groups/StartVoteEndpoint.cs @@ -1,8 +1,10 @@ -using BeReadyBackend.Models; +using BeReadyBackend.Hubs; +using BeReadyBackend.Models; using BeReadyBackend.Repositories; using BeReadyBackend.Services; using BeReadyBackend.Specifications.Groups; using FastEndpoints; +using Microsoft.AspNetCore.SignalR; using Group = BeReadyBackend.Models.Group; namespace BeReadyBackend.Endpoints.Groups; @@ -12,20 +14,21 @@ public class GroupVoteRequest public int Id { get; set; } } -public class StartVoteEndpoint(UserGroupsRepository userGroupsRepository, GroupsRepository groupsRepository, UserService userService) : Endpoint +public class StartVoteEndpoint(UserGroupsRepository userGroupsRepository, GroupsRepository groupsRepository, UserService userService, IHubContext hubContext) + : Endpoint { public override void Configure() { Post("/Groups/{@Id}/Vote/", x => new { x.Id }); } - + public override async Task HandleAsync(GroupVoteRequest req, CancellationToken ct) { Group? group = await groupsRepository.SingleOrDefaultAsync(new GetGroupByIdSpec(req.Id), ct); - + if (group is null) { - await Send.NotFoundAsync(ct); + await Send.NotFoundAsync(ct); return; } @@ -33,23 +36,23 @@ public class StartVoteEndpoint(UserGroupsRepository userGroupsRepository, Groups if (userGroup?.Grade != "Admin") { - await Send.StringAsync("Vous ne pouvez pas lancer le vote", 400, cancellation: ct); + await Send.StringAsync("Vous ne pouvez pas lancer le vote", 400, cancellation: ct); return; } if (group.IsFinished) { - await Send.StringAsync("Le défi est terminé", 400, cancellation: ct); + await Send.StringAsync("Le défi est terminé", 400, cancellation: ct); return; } if (group.CreationDate.AddHours(group.Duration) > DateTime.Now) { - await Send.StringAsync("Le défi n'est pas terminé", 400, cancellation: ct); + await Send.StringAsync("Le défi n'est pas terminé", 400, cancellation: ct); return; } - + + await hubContext.Clients.Group($"group-{req.Id}").SendAsync("StartVote", cancellationToken: ct); await Send.OkAsync(ct); } - } \ No newline at end of file diff --git a/BeReadyBackend/Hubs/GroupHub.cs b/BeReadyBackend/Hubs/GroupHub.cs new file mode 100644 index 0000000..79d3536 --- /dev/null +++ b/BeReadyBackend/Hubs/GroupHub.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNetCore.SignalR; +using Microsoft.Extensions.Primitives; + +namespace BeReadyBackend.Hubs; + +public class GroupHub : Hub +{ + public async Task SendProofToGroup(int groupId, string proofUrl) + { + await Clients.Group($"group-{groupId}").SendAsync("ReceiveProof", proofUrl); + } + + public async Task SendMessageToGroup(int groupId, string message) + { + await Clients.Group($"group-{groupId}").SendAsync("ReceiveMessage", message); + } + + public async Task StartVoteIntoGroup(int groupId) + { + await Clients.Group($"group-{groupId}").SendAsync("StartVote"); + } + + public override async Task OnConnectedAsync() + { + HttpContext? httpContext = Context.GetHttpContext(); + if (httpContext!.Request.Query.TryGetValue("groupId", out StringValues groupId)) + { + await Groups.AddToGroupAsync(Context.ConnectionId, $"group-{groupId}"); + } + await base.OnConnectedAsync(); + } +} \ No newline at end of file diff --git a/BeReadyBackend/Program.cs b/BeReadyBackend/Program.cs index 6e0f8a7..9806d32 100644 --- a/BeReadyBackend/Program.cs +++ b/BeReadyBackend/Program.cs @@ -1,6 +1,7 @@ using AutoMapper; using AutoMapper.EquivalencyExpression; using BeReadyBackend; +using BeReadyBackend.Hubs; using BeReadyBackend.MappingProfiles; using FastEndpoints; using FastEndpoints.Swagger; @@ -27,10 +28,7 @@ builder.Services .WithExposedHeaders(HeaderNames.ContentDisposition); }); }) - .SwaggerDocument(options => - { - options.ShortSchemaNames = true; - }); + .SwaggerDocument(options => { options.ShortSchemaNames = true; }); builder.Services.AddDbContext(); @@ -45,6 +43,8 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddSignalR(); + builder.Services.AddHttpContextAccessor(); builder.Services.AddScoped(); @@ -70,6 +70,8 @@ app.UseAuthentication() }) .UseSwaggerGen(); +app.MapHub("/groupHub"); + // app.UseHttpsRedirection(); // app.UseCors();