Merge pull request 'campaign' (#4) from campaign into master
All checks were successful
continuous-integration/drone/push Build is passing

Reviewed-on: #4
This commit is contained in:
michele 2021-09-24 10:29:48 +00:00
commit 96b0fb986f
15 changed files with 99 additions and 50 deletions

View File

@ -6,13 +6,13 @@ namespace Sledgemapper.Api.Commands
public class InvitePlayerToCampaignCommand : IRequest<bool> public class InvitePlayerToCampaignCommand : IRequest<bool>
{ {
public double Timestamp { get; private set; } public double Timestamp { get; private set; }
public string CampaignName { get; private set; } public Guid CampaignId { get; private set; }
public string Email { get; private set; } public string Email { get; private set; }
public string UserId { get; private set; } public string UserId { get; private set; }
public InvitePlayerToCampaignCommand(string campaingName, string email, string userId) public InvitePlayerToCampaignCommand(Guid campaignId, string email, string userId)
{ {
Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
CampaignName = campaingName; CampaignId = campaignId;
UserId = userId; UserId = userId;
Email = email; Email = email;
} }

View File

@ -48,10 +48,10 @@ namespace Sledgemapper.Api.Controllers
} }
[HttpPost] [HttpPost]
[Route("{campaignName}/players/{email}")] [Route("{campaignId}/players/{email}")]
public async Task<bool> Invite(string campaignName, string email) public async Task<bool> Invite(Guid campaignId, string email)
{ {
var result = await _mediator.Send(new InvitePlayerToCampaignCommand(campaignName, email, UserId)); var result = await _mediator.Send(new InvitePlayerToCampaignCommand(campaignId, email, UserId));
return result; return result;
} }

View File

@ -29,7 +29,18 @@ namespace Sledgemapper.Api.Handlers
var user = await _dbcontext.Users.FindAsync(command.UserId); var user = await _dbcontext.Users.FindAsync(command.UserId);
_dbcontext.Attach(user); _dbcontext.Attach(user);
var campaign = await _dbcontext.Campaigns.Where(campaign => campaign.CampaignId == command.CampaignId && campaign.OwnerId == command.UserId).Include(campaign => campaign.InvitedUsers).FirstAsync();
var campaign = await _dbcontext
.Campaigns
.Where(campaign => campaign.CampaignId == command.CampaignId)
.Include(c => c.InvitedUsers)
.Include(c => c.Owner)
.Where(campaign => campaign.OwnerId == command.UserId || campaign.InvitedUsers.Contains(user)).FirstAsync();
//var campaign = await _dbcontext.Campaigns.Where(campaign => campaign.CampaignId == command.CampaignId && campaign.OwnerId == command.UserId).Include(campaign => campaign.InvitedUsers).FirstAsync();
var players = campaign.InvitedUsers.Select(user => new Player { Initials = user.Initials, UserName = user.UserName , UserId = new Guid(user.Id)}).ToList(); var players = campaign.InvitedUsers.Select(user => new Player { Initials = user.Initials, UserName = user.UserName , UserId = new Guid(user.Id)}).ToList();
return players; return players;

View File

@ -1,43 +1,53 @@
using MediatR;
using Microsoft.EntityFrameworkCore;
using Sledgemapper.Api.Commands;
using Sledgemapper.Api.Infrastructure.Data;
using System; using System;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Sledgemapper.Api.Commands;
using Sledgemapper.Api.Infrastructure.Data;
namespace Sledgemapper.Api.Handlers namespace Sledgemapper.Api.Handlers
{ {
public class InvitePlayerToCampaignCommandHandler : IRequestHandler<InvitePlayerToCampaignCommand, bool> public class InvitePlayerToCampaignCommandHandler : IRequestHandler<InvitePlayerToCampaignCommand, bool>
{ {
private readonly SledgemapperDbContext _dbContext;
private readonly IMediator _mediator; private readonly IMediator _mediator;
private readonly SledgemapperDbContext _dbcontext;
public InvitePlayerToCampaignCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) public InvitePlayerToCampaignCommandHandler(IMediator mediator, SledgemapperDbContext dbContext)
{ {
_mediator = mediator; _mediator = mediator;
_dbcontext = dbcontext; _dbContext = dbContext;
} }
public async Task<bool> Handle(InvitePlayerToCampaignCommand command, CancellationToken cancellationToken) public async Task<bool> Handle(InvitePlayerToCampaignCommand command, CancellationToken cancellationToken)
{ {
try try
{ {
var user = await _dbcontext.Users.FindAsync(command.UserId); var user = await _dbContext.Users.FindAsync(command.UserId);
var campaign = await _dbcontext.Campaigns.Where(campaign=>campaign.CampaignName==command.CampaignName && campaign.OwnerId==command.UserId).Include(campaign=>campaign.InvitedUsers).FirstAsync(); var campaign = await _dbContext
var invitedUser = await _dbcontext.Users.FirstOrDefaultAsync(user=>user.Email==command.Email); .Campaigns
_dbcontext.Attach(invitedUser); .Where(campaign => campaign.CampaignId == command.CampaignId)
_dbcontext.Attach(campaign); .Include(c => c.InvitedUsers)
.Where(campaign => campaign.OwnerId == command.UserId || campaign.InvitedUsers.Contains(user))
.FirstAsync(cancellationToken);
var invitedUser =
await _dbContext.Users.FirstOrDefaultAsync(iUser => iUser.Email == command.Email,
cancellationToken);
_dbContext.Attach(invitedUser);
_dbContext.Attach(campaign);
campaign.InvitedUsers.Add(invitedUser); campaign.InvitedUsers.Add(invitedUser);
_dbcontext.Campaigns.Update(campaign);
await _dbcontext.SaveChangesAsync(); await _dbContext.SaveChangesAsync(cancellationToken);
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
{ {
} }
return false; return false;
} }
} }

View File

@ -23,7 +23,7 @@ namespace Sledgemapper.Api.Handlers
{ {
try try
{ {
var user = await _dbcontext.Users.FindAsync(notification.UserId, cancellationToken); var user = await _dbcontext.Users.FindAsync(new object[] { notification.UserId }, cancellationToken);
_dbcontext.Attach(user); _dbcontext.Attach(user);
var campaign = new Core.Entities.Campaign var campaign = new Core.Entities.Campaign
{ {
@ -39,7 +39,7 @@ namespace Sledgemapper.Api.Handlers
} }
catch (Exception ex) catch (Exception ex)
{ {
} }
return false; return false;

View File

@ -9,19 +9,19 @@
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.1" /> <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.1" />
<PackageReference Include="mediatr" Version="9.0.0" /> <PackageReference Include="mediatr" Version="9.0.0" />
<PackageReference Include="mediatr.extensions.microsoft.dependencyinjection" Version="9.0.0" /> <PackageReference Include="mediatr.extensions.microsoft.dependencyinjection" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="5.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="5.0.10" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.6" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.10" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.6"> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.10">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.10" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.4" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.2" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.11.1" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.12.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.6" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.10" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>

View File

@ -301,7 +301,16 @@ namespace Sledgemapper
Program.helper.SaveUnencryptedTokenCache(JsonSerializer.SerializeToUtf8Bytes(_authenticateResponse)); Program.helper.SaveUnencryptedTokenCache(JsonSerializer.SerializeToUtf8Bytes(_authenticateResponse));
await Connection.StopAsync();
State.Instance.CampaignId=Guid.Empty;
State.Instance.CampaignName = string.Empty;
State.Instance.SessionId = Guid.Empty;
State.Instance.MapId = Guid.Empty;
State.Instance.MapName = string.Empty;
SessionData.SessionId = Guid.Empty;
SessionData.SessionName = string.Empty;
SessionData.Players.Clear();
return _authenticateResponse; return _authenticateResponse;
} }

View File

@ -42,15 +42,15 @@ namespace Sledgemapper
Task<List<Player>> GetPlayers(Guid campaignName); Task<List<Player>> GetPlayers(Guid campaignName);
[Get("/campaign/{campaignName}/maps")] [Get("/campaign/{campaignId}/maps")]
Task<List<Session>> GetMaps(Guid campaignName); Task<List<Session>> GetMaps(Guid campaignId);
[Get("/map/{campaignName}/{mapName}")] [Get("/map/{campaignId}/{mapId}")]
Task<Session> GetMap(Guid campaignName, Guid mapName); Task<Session> GetMap(Guid campaignId, Guid mapId);
[Post("/campaign/{campaignName}/players/{email}")] [Post("/campaign/{campaignId}/players/{email}")]
Task InvitePlayer(string campaignName, string email); Task InvitePlayer(Guid campaignId, string email);

View File

@ -57,6 +57,7 @@ namespace Sledgemapper
MyraEnvironment.Game = this; MyraEnvironment.Game = this;
_sessionData = new Session(); _sessionData = new Session();
IsFixedTimeStep = true; IsFixedTimeStep = true;
TargetElapsedTime = TimeSpan.FromSeconds(1d / 30d); TargetElapsedTime = TimeSpan.FromSeconds(1d / 30d);

View File

@ -58,7 +58,7 @@
<PackageReference Include="polly" Version="7.2.2" /> <PackageReference Include="polly" Version="7.2.2" />
<PackageReference Include="polly.extensions.http" Version="3.0.0" /> <PackageReference Include="polly.extensions.http" Version="3.0.0" />
<PackageReference Include="Refit.HttpClientFactory" Version="6.0.94" /> <PackageReference Include="Refit.HttpClientFactory" Version="6.0.94" />
<PackageReference Include="Sentry" Version="3.9.2" /> <PackageReference Include="Sentry" Version="3.9.3" />
<PackageReference Include="TinyMessenger" Version="1.4.0-alpha3"> <PackageReference Include="TinyMessenger" Version="1.4.0-alpha3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>

View File

@ -100,6 +100,7 @@ namespace Sledgemapper.UI
_authResponse = await CommunicationManager.Login(new AuthenticateModel _authResponse = await CommunicationManager.Login(new AuthenticateModel
{ {
Username = TxtEmail.Text, Username = TxtEmail.Text,
Email = TxtEmail.Text,
Password = TxtPassword.Text Password = TxtPassword.Text
}); });
successful = true; successful = true;

View File

@ -229,7 +229,13 @@ namespace Sledgemapper.UI
//MenuConnectJoin.Enabled = true; //MenuConnectJoin.Enabled = true;
MenuCampaignOpen.Enabled = true; MenuCampaignOpen.Enabled = true;
MenuCampaingNew.Enabled = true; MenuCampaingNew.Enabled = true;
MenuMapNew.Enabled = false;
MenuMapOpen.Enabled = false;
MenuCampaignPlayers.Enabled = false;
lblCampaign.Text = "n/a";
lblMap.Text = "n/a";
CommunicationManager.SessionData.MapEntityAdded -= OnMapEntityAdded;
CommunicationManager.SessionData.MapEntityDeleted -= OnMapEntityDeleted;
lblUsername.Text = $"{obj.Initials}"; lblUsername.Text = $"{obj.Initials}";
} }
@ -297,7 +303,7 @@ namespace Sledgemapper.UI
{ {
if (!((MenuItem)sender).Enabled) return; if (!((MenuItem)sender).Enabled) return;
var content = new PlayerList(CommunicationManager); var content = new PlayerList(CommunicationManager, Messenger);
if (await content.LoadPlayers()) if (await content.LoadPlayers())
{ {
content.ShowInModalWindow(Desktop, "Players"); content.ShowInModalWindow(Desktop, "Players");

View File

@ -1,15 +1,20 @@
/* Generated by MyraPad at 28/08/2021 19:49:08 */ /* Generated by MyraPad at 28/08/2021 19:49:08 */
using System.Threading.Tasks; using System.Threading.Tasks;
using TinyMessenger;
namespace Sledgemapper.UI namespace Sledgemapper.UI
{ {
public partial class PlayerList public partial class PlayerList
{ {
protected readonly CommunicationManager CommunicationManager; protected CommunicationManager CommunicationManager { get; }
protected TinyMessengerHub Messenger { get; }
public PlayerList(CommunicationManager communicationManager) public PlayerList(CommunicationManager communicationManager, TinyMessenger.TinyMessengerHub messenger)
{ {
CommunicationManager = communicationManager;
Messenger = messenger;
BuildUI(); BuildUI();
CommunicationManager = communicationManager; CommunicationManager = communicationManager;
BtnInvitePlayer.Click += (s, e) => BtnInvitePlayer.Click += (s, e) =>
@ -38,7 +43,7 @@ namespace Sledgemapper.UI
private void ShowAddPLayerWindow() private void ShowAddPLayerWindow()
{ {
new PlayerWindow(CommunicationManager).ShowInModalWindow(Desktop, "Invite player"); new PlayerWindow(CommunicationManager, Messenger).ShowInModalWindow(Desktop, "Invite player");
} }
} }
} }

View File

@ -1,17 +1,21 @@
/* Generated by MyraPad at 28/08/2021 22:04:11 */ /* Generated by MyraPad at 28/08/2021 22:04:11 */
using Myra.Graphics2D.UI; using Myra.Graphics2D.UI;
using Sentry; using Sentry;
using Sledgemapper.Messages;
using System; using System;
using TinyMessenger;
namespace Sledgemapper.UI namespace Sledgemapper.UI
{ {
public partial class PlayerWindow public partial class PlayerWindow
{ {
protected readonly CommunicationManager CommunicationManager; protected CommunicationManager CommunicationManager { get; }
protected TinyMessengerHub Messenger { get; }
public PlayerWindow(CommunicationManager communicationManager) public PlayerWindow(CommunicationManager communicationManager, TinyMessenger.TinyMessengerHub messenger)
{ {
CommunicationManager = communicationManager; CommunicationManager = communicationManager;
Messenger = messenger;
BuildUI(); BuildUI();
BtnNewCampaign.Click += OnButtonInvitePlayerClicked; BtnNewCampaign.Click += OnButtonInvitePlayerClicked;
@ -29,11 +33,13 @@ namespace Sledgemapper.UI
var successful = false; var successful = false;
try try
{ {
await CommunicationManager.Api.InvitePlayer(State.Instance.CampaignName, localContent.Content.TxtCampaign.Text); await CommunicationManager.Api.InvitePlayer(State.Instance.CampaignId, localContent.Content.TxtCampaign.Text);
} }
catch (Exception ex) catch (Exception ex)
{ {
Messenger.Publish(new ErrorMessage(this, "Error inviting player"));
SentrySdk.CaptureException(ex); SentrySdk.CaptureException(ex);
} }
this.GetContainingWindow().Close(); this.GetContainingWindow().Close();
} }

View File

@ -45,7 +45,7 @@ namespace Sledgemapper.UI
grid1.Widgets.Add(TxtCampaign); grid1.Widgets.Add(TxtCampaign);
BtnNewCampaign = new TextButton(); BtnNewCampaign = new TextButton();
BtnNewCampaign.Text = "New"; BtnNewCampaign.Text = "Invite";
BtnNewCampaign.Padding = new Thickness(10, 5); BtnNewCampaign.Padding = new Thickness(10, 5);
BtnNewCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; BtnNewCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center;
BtnNewCampaign.Id = "BtnNewCampaign"; BtnNewCampaign.Id = "BtnNewCampaign";