Merge pull request #5 from DrMboga/dev

Merge dev to master
This commit is contained in:
DrMboga authored and GitHub committed 2021-11-24 17:02:37 +03:00
commit ce3c7aa207
14 files changed
+156 -10

No files matched your search

@@ -6,6 +6,12 @@ namespace WotBlitzStatisticsPro.Blazor.Helpers
{
public static class DateDifferenceHelper
{
public static DateTime ConvertToLocalTime(this DateTimeOffset dateToConvert)
{
var specifiedTimeConvert = DateTime.SpecifyKind(dateToConvert.DateTime, DateTimeKind.Utc);
return specifiedTimeConvert.ToLocalTime();
}
public static string SinceTime(this int timeInLinuxTimeStamp, IStringLocalizer<App> localizer)
{
var currentDate = DateTime.Now;
@@ -25,6 +31,11 @@ namespace WotBlitzStatisticsPro.Blazor.Helpers
}
public static string SinceTime(this DateTimeOffset time, IStringLocalizer<App> localizer)
{
return time.DateTime.SinceTime(localizer);
}
public static string SinceTime(this DateTime time, IStringLocalizer<App> localizer)
{
var currentDate = DateTime.Now;
@@ -41,6 +52,7 @@ namespace WotBlitzStatisticsPro.Blazor.Helpers
return $"{difference.value} {ago}";
}
public static (int value, TimeInterval interval) ParseTheDifference(TimeSpan difference)
{
if (difference.TotalHours < 1)
@@ -0,0 +1,81 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WotBlitzStatisticsPro.Blazor.GraphQl;
namespace WotBlitzStatisticsPro.Blazor.Helpers
{
public static class TanksHelper
{
public static ITank FindMostRelevantTank(this IReadOnlyList<ITank> allTanks)
{
const int topTanksToMerge = 6;
if (allTanks.Count == 1)
{
return allTanks.First();
}
// Merge 6 tanks with max battles with 6 tanks with max Wn7, then with 6 tanks with max AvgDamage then with 6 tanks with Max Win rate. And sort result by max AvgXp and take first
var topByBattles = allTanks
.OrderByDescending(t => t.Battles)
.Take(topTanksToMerge)
.Select(t => t.TankId)
.ToList();
var topByWn7 = allTanks
.Where(t => topByBattles.Contains(t.TankId))
.OrderByDescending(t => t.Wn7)
.Take(topTanksToMerge)
.Select(t => t.TankId)
.ToList();
var topByDamage = allTanks
.Where(t => topByBattles.Contains(t.TankId))
.OrderByDescending(t => t.AvgDamage)
.Take(topTanksToMerge)
.Select(t => t.TankId)
.ToList();
var topByWinRate = allTanks
.Where(t => topByBattles.Contains(t.TankId))
.OrderByDescending(t => t.WinRate)
.Take(topTanksToMerge)
.Select(t => t.TankId)
.ToList();
var firstIntersection = topByBattles.Intersect(topByWn7).ToList();
if (!firstIntersection.Any())
{
return allTanks.First(t => t.TankId == topByBattles.First());
}
if(firstIntersection.Count() == 1)
{
return allTanks.First(t => t.TankId == firstIntersection.First());
}
var secondIntersection = topByDamage.Intersect(firstIntersection).ToList();
if (!secondIntersection.Any())
{
return allTanks.First(t => t.TankId == firstIntersection.First());
}
if (secondIntersection.Count() == 1)
{
return allTanks.First(t => t.TankId == secondIntersection.First());
}
var thirdIntersection = topByWinRate.Intersect(secondIntersection).ToList();
if (!thirdIntersection.Any())
{
return allTanks.First(t => t.TankId == secondIntersection.First());
}
if (thirdIntersection.Count() == 1)
{
return allTanks.First(t => t.TankId == thirdIntersection.First());
}
return allTanks
.Where(t => thirdIntersection.Contains(t.TankId))
.OrderByDescending(t => t.AvgXp)
.First();
}
}
}
@@ -17,7 +17,7 @@
<small>@Localize["Created"]: <b>@AccountInfo.CreatedAt.ToString("d") | @AccountInfo.CreatedAt.SinceTime(Localize)</b></small>
</div>
<div>
@Localize["Last battle"]: <b>@AccountInfo.LastBattleTime.ToString("g") | @AccountInfo.LastBattleTime.SinceTime(Localize)</b>
@Localize["Last battle"]: <b>@AccountInfo.LastBattleTime.ConvertToLocalTime().ToString("g") | @AccountInfo.LastBattleTime.ConvertToLocalTime().SinceTime(Localize)</b>
</div>
</div>
<RadzenTabs >
@@ -29,6 +29,7 @@
<PlayerInfoStatistics TanksList="@AccountInfo.Tanks"></PlayerInfoStatistics>
</RadzenTabsItem>
<RadzenTabsItem Icon="agriculture">
@*TODO: In case of @SmallScreen == true, then show new tanks list component - mobile version *@
<PlayerInfoTanksList TanksList="@AccountInfo.Tanks"></PlayerInfoTanksList>
</RadzenTabsItem>
<RadzenTabsItem Icon="military_tech">
@@ -22,6 +22,9 @@ namespace WotBlitzStatisticsPro.Blazor.Pages
[Inject]
public INotificationsService Notifications { get; set; }
[Inject]
public IMediaQueriesService MediaQueriesService { get; set; }
[Parameter]
public long AccountId { get; set; }
@@ -32,12 +35,16 @@ namespace WotBlitzStatisticsPro.Blazor.Pages
public IReadOnlyList<ISection> AchievementsBySection { get; set; }
public bool SmallScreen { get; set; }
protected override async Task OnInitializedAsync()
{
var loggedInInfo = await LocalStorageService.GetItemAsync<LoginInfo>(Constants.LoginInfoLocalStorageKey);
var settings = await LocalStorageService.ReadSettings();
CurrentRealmType = settings.RealmType;
SmallScreen = await MediaQueriesService.IsScreenWidthLessThen(1000);
try
{
// Maybe add refresh button instead of calling mutation each time
@@ -53,7 +53,7 @@
<TankCard Tank=@MaxXpTank></TankCard>
}
</div>
<div class="col-md-3 col-lg-3 align-items-center d-flex">
<div class="col-md-3 col-lg-3 align-items-center d-flex">
<div style="width: 100px; margin: 3px;">
@Localize["Tank with Max frags"] (@AccountInfo.MaxFrags):
</div>
@@ -76,7 +76,7 @@
protected override void OnInitialized()
{
MostRelevantTank = AccountInfo?.Tanks?.Where(t => t.Battles > 50).OrderByDescending(t => t.Wn7).FirstOrDefault();
MostRelevantTank = AccountInfo?.Tanks?.FindMostRelevantTank();
MaxXpTank = AccountInfo?.Tanks?.FirstOrDefault(t => t.TankId == AccountInfo.MaxXpTankId);
MaxFragsTank = AccountInfo?.Tanks?.FirstOrDefault(t => t.TankId == AccountInfo.MaxFragsTankId);
}
@@ -94,7 +94,7 @@
</RadzenDataGridColumn>
<RadzenDataGridColumn TItem="ITank" Property="Battles" Filterable="false" Sortable="true" Title="⚔" Frozen="false" Width="70px" TextAlign="TextAlign.Center">
<FooterTemplate>
<b>@TotalBattles.ToString("N0")</b>
<b>@TotalBattles.ToString("N0")</b>
</FooterTemplate>
</RadzenDataGridColumn>
<RadzenDataGridColumn TItem="ITank" Property="WinRate"
@@ -105,7 +105,7 @@
Width="50px"
TextAlign="TextAlign.Center">
<Template Context="data">
@data.WinRate.ToString("N0")%
<span title="@($"{data.Wins:N0} / {data.Battles:N0}")">@data.WinRate.ToString("N0")%</span>
<div style="background-color: @data.WinRate.ScaleColor(); width: 100%; height: 5px; margin-left: 2px; margin-right: 2px;"></div>
</Template>
<FooterTemplate>
@@ -119,8 +119,7 @@
Title="@Localize["Wn7"]"
Frozen="false"
Width="80px"
TextAlign="TextAlign.Center"
>
TextAlign="TextAlign.Center">
<Template Context="data">
@data.Wn7.ToString("N0")
<div style="background-color: @data.Wn7.Wn7ScaleColor(); width: 100%; height: 5px; margin-left: 2px; margin-right: 2px;"></div>
@@ -161,7 +160,7 @@
Frozen="false"
Width="80px"
TextAlign="TextAlign.Center"
FormatString="{0:N0}"/>
FormatString="{0:N0}" />
<RadzenDataGridColumn TItem="ITank" Property="SurvivalRate"
Filterable="false"
Sortable="true"
@@ -182,7 +181,11 @@
Width="100px"
TextAlign="TextAlign.Center"
FormatString="{0:d}"
SortOrder="SortOrder.Descending"/>
SortOrder="SortOrder.Descending">
<Template Context="data">
@data.LastBattleTime.ConvertToLocalTime().ToString("g")
</Template>
</RadzenDataGridColumn>
</Columns>
</RadzenDataGrid>
+1
View File
@@ -30,6 +30,7 @@ namespace WotBlitzStatisticsPro.Blazor
builder.Services.AddScoped<TooltipService>();
builder.Services.AddScoped<ISearchDialogService, SearchDialogService>();
builder.Services.AddScoped<IChartsService, ChartService>();
builder.Services.AddScoped<IMediaQueriesService, MediaQueriesService>();
builder.Services.AddMediatR(typeof(Program));
@@ -0,0 +1,9 @@
using System.Threading.Tasks;
namespace WotBlitzStatisticsPro.Blazor.Services
{
public interface IMediaQueriesService
{
ValueTask<bool> IsScreenWidthLessThen(long widthInPx);
}
}
@@ -0,0 +1,20 @@
using Microsoft.JSInterop;
using System.Threading.Tasks;
namespace WotBlitzStatisticsPro.Blazor.Services
{
public class MediaQueriesService : IMediaQueriesService
{
private readonly IJSRuntime _jsRuntime;
public MediaQueriesService(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}
public ValueTask<bool> IsScreenWidthLessThen(long widthInPx)
{
return _jsRuntime.InvokeAsync<bool>("mediaQueries.IsScreenWidthLessThen", widthInPx);
}
}
}
@@ -42,7 +42,7 @@
</RadzenSidebar>
<RadzenFooter>
<ChildContent>
<RadzenLabel Text="WOT Blitz statistics, Copyright &copy; 2021">
<RadzenLabel Text=@($"WOT Blitz statistics {@Version} © 2021")>
</RadzenLabel>
<RadzenLink Text="DrMboga" Path="https://github.com/DrMboga/WotBlitzStatisticsBlazor" Target="_blank" Style="margin-left:5px;vertical-align:bottom;" />
</ChildContent>
@@ -8,6 +8,7 @@ using Radzen.Blazor;
using WotBlitzStatisticsPro.Blazor.Messages;
using WotBlitzStatisticsPro.Blazor.Model;
using WotBlitzStatisticsPro.Blazor.Services;
using System.Reflection;
namespace WotBlitzStatisticsPro.Blazor.Shared
{
@@ -27,6 +28,8 @@ namespace WotBlitzStatisticsPro.Blazor.Shared
public bool SidebarExpanded { get; set; } = false;
public bool BodyExpanded { get; set; } = true;
public string Version { get; set; }
public Dictionary<string, CultureInfo> CultureInfos { get; set; } = new()
{
{ "en-US", new CultureInfo("en-US", false)},
@@ -63,6 +66,7 @@ namespace WotBlitzStatisticsPro.Blazor.Shared
//}
NotificationsService.MessageArrived += NotificationsService_MessageArrived;
Version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
private void NotificationsService_MessageArrived()
@@ -4,6 +4,7 @@
<TargetFramework>net5.0</TargetFramework>
<ServiceWorkerAssetsManifest>service-worker-assets.js</ServiceWorkerAssetsManifest>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
<AssemblyVersion>1.0.0.1</AssemblyVersion>
</PropertyGroup>
<ItemGroup>
@@ -26,6 +26,7 @@
<script src="_content/Radzen.Blazor/Radzen.Blazor.js"></script>
<script src="echarts/echarts.js"></script>
<script src="echarts/echarts-interop.js"></script>
<script src="media-queries.js"></script>
<script>navigator.serviceWorker.register('service-worker.js');</script>
</body>
@@ -0,0 +1,6 @@
var mediaQueries = mediaQueries || {};
mediaQueries.IsScreenWidthLessThen = function (width) {
let mql = window.matchMedia(`(max-width: ${width}px)`);
return mql.matches;
};