Added TimeZone Functionality
This commit is contained in:
parent
c298f4d20e
commit
c215ed058f
9 changed files with 129 additions and 48 deletions
|
@ -40,6 +40,7 @@ namespace Lieb.Data
|
|||
GuildWars2Account bloodseeker = new GuildWars2Account() { AccountName = "Bloodseeker.2043" };
|
||||
var users = new LiebUser[]
|
||||
{
|
||||
//new LiebUser{DiscordUserId=0, Name="Sarah", Birthday=DateTime.Parse("1992-01-15"), GuildWars2Accounts = new List<GuildWars2Account>(){ linaith, sarah} },
|
||||
new LiebUser{DiscordUserId=194863625477816321, Name="Sarah", Birthday=DateTime.Parse("1992-01-15"), GuildWars2Accounts = new List<GuildWars2Account>(){ linaith, sarah} },
|
||||
#if DEBUG
|
||||
new LiebUser{DiscordUserId=1, Name="Lisa", GuildWars2Accounts = new List<GuildWars2Account>(){ hierpiepts}},
|
||||
|
@ -96,9 +97,9 @@ namespace Lieb.Data
|
|||
Guild = "LIEB",
|
||||
Organizer = "Sarah",
|
||||
RaidType = RaidType.RandomWithBoons,
|
||||
Date = DateTime.Now.Date,
|
||||
StartTime = DateTime.Now,
|
||||
EndTime = DateTime.Now.AddHours(2),
|
||||
StartTimeUTC = DateTime.UtcNow,
|
||||
EndTimeUTC = DateTime.UtcNow.AddHours(2),
|
||||
FreeForAllTimeUTC = DateTime.UtcNow.AddHours(-2),
|
||||
VoiceChat = "ts.lieb.games",
|
||||
Roles = new [] { ele, scourge}
|
||||
};
|
||||
|
@ -115,7 +116,7 @@ namespace Lieb.Data
|
|||
context.RaidSignUps.AddRange(signUps);
|
||||
context.SaveChanges();
|
||||
|
||||
GuildWars2Build healTempest = new GuildWars2Build() { BuildName = "HealTempest", Class = GuildWars2Class.Elementalist, EliteSpecialization = EliteSpecialization.Tempest, Heal = 5, Might = 10 };
|
||||
GuildWars2Build healTempest = new GuildWars2Build() { BuildName = "HealTempest", Class = GuildWars2Class.Elementalist, EliteSpecialization = EliteSpecialization.Tempest, Heal = 5, Might = 5 };
|
||||
GuildWars2Build condiScourge = new GuildWars2Build() { BuildName = "CondiScourge", Class = GuildWars2Class.Necromancer, EliteSpecialization = EliteSpecialization.Scourge };
|
||||
GuildWars2Build quickBrand = new GuildWars2Build() { BuildName = "QuickBrand", Class = GuildWars2Class.Guard, EliteSpecialization = EliteSpecialization.Firebrand, Heal = 5, Quickness = 5 };
|
||||
GuildWars2Build alacregate = new GuildWars2Build() { BuildName = "Alacregate", Class = GuildWars2Class.Revenant, EliteSpecialization = EliteSpecialization.Renegade, Alacrity = 5 };
|
||||
|
|
|
@ -65,14 +65,16 @@ namespace Lieb.Data
|
|||
.FirstOrDefaultAsync(r => r.RaidId == raid.RaidId);
|
||||
raidToChange.Title = raid.Title;
|
||||
raidToChange.Description = raid.Description;
|
||||
raidToChange.Date = raid.Date;
|
||||
raidToChange.StartTime = raid.StartTime;
|
||||
raidToChange.EndTime = raid.EndTime;
|
||||
raidToChange.StartTimeUTC = raid.StartTimeUTC;
|
||||
raidToChange.EndTimeUTC = raid.EndTimeUTC;
|
||||
raidToChange.TimeZone = raid.TimeZone;
|
||||
raidToChange.Organizer = raid.Organizer;
|
||||
raidToChange.Guild = raid.Guild;
|
||||
raidToChange.VoiceChat = raid.VoiceChat;
|
||||
raidToChange.RaidType = raid.RaidType;
|
||||
raidToChange.Frequency = raid.Frequency;
|
||||
raidToChange.RequiredRole = raid.RequiredRole;
|
||||
raidToChange.FreeForAllTimeUTC = raid.FreeForAllTimeUTC;
|
||||
raidToChange.DiscordMessageId = raid.DiscordMessageId;
|
||||
raidToChange.DiscordChannelId = raid.DiscordChannelId;
|
||||
raidToChange.DiscordGuildId = raid.DiscordGuildId;
|
||||
|
@ -315,13 +317,6 @@ namespace Lieb.Data
|
|||
return false;
|
||||
}
|
||||
|
||||
DateTime freeForAllTime = raid.FreeForAllDate.Date + raid.FreeForAllTime.TimeOfDay;
|
||||
if (!string.IsNullOrEmpty(raid.RequiredRole) && !user.RoleAssignments.Where(a => a.LiebRole.RoleName == raid.RequiredRole).Any() || freeForAllTime > DateTimeOffset.Now)
|
||||
{
|
||||
errorMessage = $"The raid is still locked for {raid.RequiredRole}.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (user.GuildWars2Accounts.Count == 0)
|
||||
{
|
||||
errorMessage = "No Guild Wars 2 account found.";
|
||||
|
@ -334,6 +329,12 @@ namespace Lieb.Data
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(raid.RequiredRole) && !user.RoleAssignments.Where(a => a.LiebRole.RoleName == raid.RequiredRole).Any() || raid.FreeForAllTimeUTC.UtcDateTime > DateTimeOffset.UtcNow)
|
||||
{
|
||||
errorMessage = $"The raid is still locked for {raid.RequiredRole}.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
44
Lieb/Data/TimeZoneService.cs
Normal file
44
Lieb/Data/TimeZoneService.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Lieb.Data
|
||||
{
|
||||
public class TimeZoneService
|
||||
{
|
||||
private readonly IJSRuntime _jsRuntime;
|
||||
|
||||
private TimeSpan? _userOffset;
|
||||
private int _offsetInMinutes;
|
||||
|
||||
public TimeZoneService(IJSRuntime jsRuntime)
|
||||
{
|
||||
_jsRuntime = jsRuntime;
|
||||
}
|
||||
|
||||
public async ValueTask<DateTimeOffset> GetLocalDateTime(DateTimeOffset dateTime)
|
||||
{
|
||||
if (_userOffset == null)
|
||||
{
|
||||
_offsetInMinutes = await _jsRuntime.InvokeAsync<int>("GetTimezoneValue");
|
||||
_userOffset = TimeSpan.FromMinutes(-_offsetInMinutes);
|
||||
}
|
||||
|
||||
return dateTime.ToOffset(_userOffset.Value);
|
||||
}
|
||||
|
||||
public async ValueTask<DateTimeOffset> GetUTCDateTime(DateTimeOffset dateTime)
|
||||
{
|
||||
if (_userOffset == null)
|
||||
{
|
||||
_offsetInMinutes = await _jsRuntime.InvokeAsync<int>("GetTimezoneValue");
|
||||
_userOffset = TimeSpan.FromMinutes(-_offsetInMinutes);
|
||||
}
|
||||
|
||||
return new DateTimeOffset(dateTime.DateTime.AddMinutes(_offsetInMinutes), new TimeSpan(0));
|
||||
}
|
||||
|
||||
public async ValueTask<string> GetUserTimeZone()
|
||||
{
|
||||
return await _jsRuntime.InvokeAsync<string>("GetTimezone");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,13 +23,12 @@ namespace Lieb.Models.GuildWars2.Raid
|
|||
public string Description { get; set; } = String.Empty;
|
||||
|
||||
[Required]
|
||||
public DateTime Date { get; set; } = DateTime.Now;
|
||||
public DateTimeOffset StartTimeUTC { get; set; } = DateTime.Now;
|
||||
|
||||
[Required]
|
||||
public DateTimeOffset StartTime { get; set; }
|
||||
public DateTimeOffset EndTimeUTC { get; set; }
|
||||
|
||||
[Required]
|
||||
public DateTimeOffset EndTime { get; set; }
|
||||
public string TimeZone { get; set; } = String.Empty;
|
||||
|
||||
[Required]
|
||||
[StringLength(50, ErrorMessage = "Organizer too long (50 character limit).")]
|
||||
|
@ -52,9 +51,7 @@ namespace Lieb.Models.GuildWars2.Raid
|
|||
|
||||
public string RequiredRole { get; set; } = String.Empty;
|
||||
|
||||
public DateTime FreeForAllDate { get; set; } = DateTime.Now;
|
||||
|
||||
public DateTimeOffset FreeForAllTime { get; set; }
|
||||
public DateTimeOffset FreeForAllTimeUTC { get; set; }
|
||||
|
||||
//role name, number of spots
|
||||
public ICollection<PlannedRaidRole> Roles { get; set; } = new HashSet<PlannedRaidRole>();
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
@using Lieb.Models.GuildWars2.Raid
|
||||
@inject UserService UserService
|
||||
@inject RaidService RaidService
|
||||
@inject TimeZoneService TimeZoneService
|
||||
@inject RaidRandomizerService RaidRandomizerService
|
||||
|
||||
<body>
|
||||
|
@ -17,11 +18,11 @@
|
|||
<div >
|
||||
<div class="times">
|
||||
<h5>Date</h5>
|
||||
<p>@_raid.Date.ToLongDateString()</p>
|
||||
<p>@_startTime.DateTime.ToLongDateString()</p>
|
||||
</div>
|
||||
<div class="times">
|
||||
<h5>Time</h5>
|
||||
<p>from: @_raid.StartTime.LocalDateTime.ToShortTimeString() to: @_raid.EndTime.LocalDateTime.ToShortTimeString()</p>
|
||||
<p>from: @_startTime.LocalDateTime.ToShortTimeString() to: @_endTime.LocalDateTime.ToShortTimeString()</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -72,7 +73,6 @@
|
|||
</body>
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public Raid _raid { get; set; }
|
||||
|
||||
|
@ -83,9 +83,17 @@
|
|||
|
||||
string _errorMessage;
|
||||
|
||||
private DateTimeOffset _startTime;
|
||||
private DateTimeOffset _endTime;
|
||||
private DateTimeOffset _freeForAllTime;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_isRaidSignUpAllowed = _user != null && RaidService.IsRaidSignUpAllowed(_user.LiebUserId, _raid.RaidId, out string _errorMessage);
|
||||
|
||||
_startTime = await TimeZoneService.GetLocalDateTime(_raid.StartTimeUTC);
|
||||
_endTime = await TimeZoneService.GetLocalDateTime(_raid.EndTimeUTC);
|
||||
_freeForAllTime = await TimeZoneService.GetLocalDateTime(_raid.FreeForAllTimeUTC);
|
||||
}
|
||||
|
||||
async Task SignUpClicked(PlannedRaidRole role, LiebUser liebUser, bool isSignedUp, SignUpType signUpType)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
@using Lieb.Models.GuildWars2.Raid
|
||||
@using System.ComponentModel.DataAnnotations
|
||||
@inject RaidService RaidService
|
||||
@inject TimeZoneService TimeZoneService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IJSRuntime JsRuntime
|
||||
|
||||
|
@ -13,7 +14,6 @@
|
|||
<AuthorizeView Policy="@Constants.Roles.RaidLead" Context="authorizationContext">
|
||||
<EditForm Model="@_raid" OnValidSubmit="@HandleValidSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
@{
|
||||
bool _isEdit = _raid.RaidId != 0;
|
||||
}
|
||||
|
@ -44,20 +44,20 @@
|
|||
<p>
|
||||
<label>
|
||||
Date:
|
||||
<InputDate @bind-Value="_raid.Date" />
|
||||
<InputDate @bind-Value="_raidDate" />
|
||||
</label>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<label>
|
||||
Start Time:
|
||||
<input type="time" @bind="@_raid.StartTime" />
|
||||
<input type="time" @bind="_startTime" />
|
||||
</label>
|
||||
</p>
|
||||
<p>
|
||||
<label>
|
||||
End Time:
|
||||
<input type="time" @bind="@_raid.EndTime" />
|
||||
<input type="time" @bind="_endTime" />
|
||||
</label>
|
||||
</p>
|
||||
|
||||
|
@ -110,6 +110,8 @@
|
|||
</p>
|
||||
}
|
||||
|
||||
<ValidationSummary />
|
||||
<label class="validation-message" >@_errosMessage</label>
|
||||
<button type="submit">Submit</button>
|
||||
|
||||
</EditForm>
|
||||
|
@ -124,12 +126,26 @@
|
|||
|
||||
public Raid _raid;
|
||||
|
||||
private string _errosMessage = string.Empty;
|
||||
|
||||
private DateTimeOffset _raidDate = DateTime.Now.Date;
|
||||
private DateTimeOffset _startTime;
|
||||
private DateTimeOffset _endTime;
|
||||
private DateTimeOffset _freeForAllDate = DateTime.Now.Date;
|
||||
private DateTimeOffset _freeForAllTime;
|
||||
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if(!string.IsNullOrEmpty(raidId) && int.TryParse(raidId, out int parsedId))
|
||||
{
|
||||
_raid = RaidService.GetRaid(parsedId);
|
||||
_startTime = await TimeZoneService.GetLocalDateTime(_raid.StartTimeUTC);
|
||||
_endTime = await TimeZoneService.GetLocalDateTime(_raid.EndTimeUTC);
|
||||
_raidDate = _startTime.Date;
|
||||
_freeForAllTime = await TimeZoneService.GetLocalDateTime(_raid.FreeForAllTimeUTC);
|
||||
_freeForAllDate = _freeForAllTime.Date;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -160,8 +176,9 @@
|
|||
|
||||
private async Task HandleValidSubmit()
|
||||
{
|
||||
if(_raid.RaidType != RaidType.Planned && _raid.Roles.Count == 0)
|
||||
if(_raid.RaidType != RaidType.Planned)
|
||||
{
|
||||
_raid.Roles.Clear();
|
||||
_raid.Roles.Add(new PlannedRaidRole()
|
||||
{
|
||||
Spots = 10,
|
||||
|
@ -170,6 +187,25 @@
|
|||
});
|
||||
}
|
||||
|
||||
if(_raid.Roles.Count == 0)
|
||||
{
|
||||
_errosMessage = "Roles are needed for a raid.";
|
||||
return;
|
||||
}
|
||||
|
||||
_raid.TimeZone = await TimeZoneService.GetUserTimeZone();
|
||||
|
||||
_raid.StartTimeUTC = await TimeZoneService.GetUTCDateTime(_raidDate.Date + _startTime.TimeOfDay);
|
||||
if(_startTime.TimeOfDay > _endTime.TimeOfDay)
|
||||
{
|
||||
_raid.EndTimeUTC = await TimeZoneService.GetUTCDateTime(_raidDate.Date + _endTime.TimeOfDay);
|
||||
}
|
||||
else
|
||||
{
|
||||
_raid.EndTimeUTC = await TimeZoneService.GetUTCDateTime(_raidDate.Date.AddDays(1) + _endTime.TimeOfDay);
|
||||
}
|
||||
_raid.FreeForAllTimeUTC = await TimeZoneService.GetUTCDateTime(_freeForAllDate.Date + _freeForAllTime.TimeOfDay);
|
||||
|
||||
await RaidService.AddOrEditRaid(_raid);
|
||||
NavigationManager.NavigateTo("raidoverview");
|
||||
}
|
||||
|
|
|
@ -7,3 +7,14 @@
|
|||
|
||||
@(await Html.RenderComponentAsync<App>(RenderMode.Server))
|
||||
<!--<component type="typeof(App)" render-mode="ServerPrerendered" />-->
|
||||
<script>
|
||||
function GetTimezoneValue() {
|
||||
// Returns the time difference in minutes between UTC time and local time.
|
||||
return new Date().getTimezoneOffset();
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
function GetTimezone() {
|
||||
return new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
}
|
||||
</script>
|
|
@ -1,18 +0,0 @@
|
|||
<environment names="Development">
|
||||
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
|
||||
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
|
||||
</environment>
|
||||
<environment names="Staging,Production">
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.17.0/jquery.validate.min.js"
|
||||
asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.validator"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-rZfj/ogBloos6wzLGpPkkOr/gpkBNLZ6b6yLy4o+ok+t/SAKlL5mvXLr0OXNi1Hp">
|
||||
</script>
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.9/jquery.validate.unobtrusive.min.js"
|
||||
asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-ifv0TYDWxBHzvAk2Z0n8R434FL1Rlv/Av18DXE43N/1rvHyOG4izKst0f2iSLdds">
|
||||
</script>
|
||||
</environment>
|
|
@ -25,6 +25,7 @@ builder.Services.AddScoped<UserService>();
|
|||
builder.Services.AddScoped<GuildWars2AccountService>();
|
||||
builder.Services.AddScoped<GuildWars2BuildService>();
|
||||
builder.Services.AddScoped<RaidRandomizerService>();
|
||||
builder.Services.AddScoped<TimeZoneService>();
|
||||
|
||||
|
||||
builder.Services.AddAuthentication(opt =>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue