From 43d7391df201487f62afdd4e275f835f02e858bc Mon Sep 17 00:00:00 2001 From: Jonathan McCaffrey Date: Mon, 25 Apr 2022 12:43:23 -0400 Subject: [PATCH] feat(DataCollection) Added opt-in data collection --- Components/Display/DevOnlyComponent.razor | 1 + Components/Feedback/ToastComponent.razor | 1 + Components/Form/FormCheckboxComponent.razor | 1 + Components/Form/FormGuessComponent.razor | 1 + Components/Form/FormTextAreaComponent.razor | 1 + Components/Form/FormTextComponent.razor | 1 + Components/Form/FormToggleComponent.razor | 23 ++-- Components/Inputs/ButtonGroupComponent.razor | 1 + .../Navigation/DesktopNavComponent.razor | 1 + .../Navigation/DesktopNavLinkComponent.razor | 10 +- Components/Shared/DisplayableRoute.razor | 1 + IGP/App.razor | 12 +- IGP/Database.db | Bin 278528 -> 278528 bytes IGP/Dialog/ConfirmationDialogComponent.razor | 114 +++++++++++++++++ IGP/Dialog/EntityDialogComponent.razor | 1 + IGP/Dialog/SearchDialogComponent.razor | 5 +- IGP/IGP.csproj | 1 + IGP/Index.razor | 5 +- IGP/PageLayout.razor | 52 +++++--- IGP/Pages/AboutPage.razor | 5 + IGP/Pages/Agile/AgilePage.razor | 19 +-- IGP/Pages/BasePage.razor | 38 ++++++ .../BuildCalculator/BuildCalculatorPage.razor | 75 ++++++----- .../BuildCalculator/Parts/ArmyComponent.razor | 1 + .../BuildCalculator/Parts/BankComponent.razor | 1 + .../Parts/BuildChartComponent.razor | 1 + .../Parts/BuildOrderComponent.razor | 1 + .../Parts/EntityClickViewComponent.razor | 1 + .../Parts/HighlightsComponent.razor | 1 + .../Parts/HotkeyViewerComponent.razor | 118 +++++++++++------- .../Parts/InputPanelComponent.razor | 19 ++- .../Parts/OptionsComponent.razor | 1 + .../Parts/TimelineComponent.razor | 1 + .../Parts/TimingComponent.razor | 1 + IGP/Pages/ChangeLogPage.razor | 20 +-- IGP/Pages/Comparision/ComparisionPage.razor | 4 +- .../Parts/BuildLoaderComponent.razor | 1 + .../Comparision/Parts/SandComponent.razor | 1 + IGP/Pages/ContactPage.razor | 3 + IGP/Pages/DataCollectionPage.razor | 3 + IGP/Pages/Database/DatabasePage.razor | 20 +-- IGP/Pages/Database/DatabaseSinglePage.razor | 36 ++++-- .../Entity/Parts/EntityWeaponsComponent.razor | 1 + .../Parts/EntityFilterComponent.razor | 1 + .../DocumentationIndexPage.razor | 14 ++- .../Documentation/DocumentationPage.razor | 18 +-- .../EconomyComparisonPage.razor | 3 + .../Parts/ChartComponent.razor | 1 + .../Parts/EconomyDifferenceComponent.razor | 1 + .../Parts/EconomyInputComponent.razor | 1 + IGP/Pages/HarassCalculatorPage.razor | 4 + IGP/Pages/Home/HomePage.razor | 2 + IGP/Pages/MakingOf/MakingOfPage.razor | 4 + IGP/Pages/MemoryTester/MemoryTesterPage.razor | 2 + IGP/Pages/MemoryTester/Parts/UnitMemory.razor | 1 + .../Parts/UnitMemoryManager.razor | 1 + IGP/Pages/Notes/NotesIndexPage.razor | 17 ++- IGP/Pages/Notes/NotesPage.razor | 21 ++-- IGP/Pages/PermissionsPage.razor | 68 +++++++--- IGP/Pages/RawDatabase.razor | 4 +- IGP/Pages/RoadMap/RoadMapPage.razor | 4 + IGP/Pages/StoragePage.razor | 4 + IGP/Pages/StreamsPage.razor | 2 + IGP/Portals/ConfirmationDialogPortal.razor | 25 ++++ IGP/Portals/EntityDialogPortal.razor | 1 + IGP/Portals/SearchPortal.razor | 21 ++-- IGP/Portals/ToastPortal.razor | 1 + IGP/Program.cs | 68 +++++----- IGP/_Imports.razor | 5 +- IGP/wwwroot/generated/AgileTaskModels.json | 2 +- IGP/wwwroot/generated/WebPageModels.json | 2 +- IGP/wwwroot/index.html | 1 + Services/IServices.cs | 19 ++- Services/Immortal/BuildOrderService.cs | 13 +- Services/Services.csproj | 11 +- Services/Website/DataCollectionService.cs | 50 ++++++++ Services/Website/DialogService.cs | 63 ++++++++++ Services/Website/PermissionService.cs | 14 ++- Services/Website/StorageService.cs | 16 --- 79 files changed, 802 insertions(+), 287 deletions(-) create mode 100644 IGP/Dialog/ConfirmationDialogComponent.razor create mode 100644 IGP/Pages/BasePage.razor create mode 100644 IGP/Portals/ConfirmationDialogPortal.razor create mode 100644 Services/Website/DataCollectionService.cs create mode 100644 Services/Website/DialogService.cs diff --git a/Components/Display/DevOnlyComponent.razor b/Components/Display/DevOnlyComponent.razor index 06a8524..842f368 100644 --- a/Components/Display/DevOnlyComponent.razor +++ b/Components/Display/DevOnlyComponent.razor @@ -68,6 +68,7 @@ protected override void OnInitialized() { + base.OnInitialized(); isOnDev = NavigationManager.BaseUri.Contains("https://localhost"); } diff --git a/Components/Feedback/ToastComponent.razor b/Components/Feedback/ToastComponent.razor index 3150eff..7728a8e 100644 --- a/Components/Feedback/ToastComponent.razor +++ b/Components/Feedback/ToastComponent.razor @@ -76,6 +76,7 @@ else protected override void OnInitialized() { + base.OnInitialized(); toastService.Subscribe(OnUpdate); } diff --git a/Components/Form/FormCheckboxComponent.razor b/Components/Form/FormCheckboxComponent.razor index 626084b..1c34b55 100644 --- a/Components/Form/FormCheckboxComponent.razor +++ b/Components/Form/FormCheckboxComponent.razor @@ -70,6 +70,7 @@ protected override void OnInitialized() { + base.OnInitialized(); labelId = Label.ToLower().Replace(" ", "_"); } diff --git a/Components/Form/FormGuessComponent.razor b/Components/Form/FormGuessComponent.razor index 074176e..c11b50c 100644 --- a/Components/Form/FormGuessComponent.razor +++ b/Components/Form/FormGuessComponent.razor @@ -96,6 +96,7 @@ protected override void OnInitialized() { + base.OnInitialized(); labelId = Label.ToLower().Replace(" ", "_") + MemoryQuestion.Id; MemoryTesterService.Subscribe(OnMemoryEvent); diff --git a/Components/Form/FormTextAreaComponent.razor b/Components/Form/FormTextAreaComponent.razor index f1dfeff..a51ae2a 100644 --- a/Components/Form/FormTextAreaComponent.razor +++ b/Components/Form/FormTextAreaComponent.razor @@ -87,6 +87,7 @@ protected override void OnInitialized() { + base.OnInitialized(); labelId = Label.ToLower().Replace(" ", "_"); } diff --git a/Components/Form/FormTextComponent.razor b/Components/Form/FormTextComponent.razor index 9f960e8..5e99fa3 100644 --- a/Components/Form/FormTextComponent.razor +++ b/Components/Form/FormTextComponent.razor @@ -85,6 +85,7 @@ protected override void OnInitialized() { + base.OnInitialized(); labelId = Label.ToLower().Replace(" ", "_"); } diff --git a/Components/Form/FormToggleComponent.razor b/Components/Form/FormToggleComponent.razor index bd9823a..412f2eb 100644 --- a/Components/Form/FormToggleComponent.razor +++ b/Components/Form/FormToggleComponent.razor @@ -7,6 +7,7 @@ @@ -83,15 +84,15 @@ border-radius: 50%; } - input:checked + .slider { - background-color: #7838df; - } - - input:checked + .slider:before { - -webkit-transform: translateX(26px); - -ms-transform: translateX(26px); - transform: translateX(26px); - } + .checked + .slider { + background-color: #7838df; + } + + .checked + .slider:before { + -webkit-transform: translateX(26px); + -ms-transform: translateX(26px); + transform: translateX(26px); + } @@ -114,9 +115,11 @@ private string labelId = ""; + private string ClassStyle => Value ? "checked" : ""; + protected override void OnInitialized() { + base.OnInitialized(); labelId = Label.ToLower().Replace(" ", "_"); } - } \ No newline at end of file diff --git a/Components/Inputs/ButtonGroupComponent.razor b/Components/Inputs/ButtonGroupComponent.razor index db6dba4..11a940d 100644 --- a/Components/Inputs/ButtonGroupComponent.razor +++ b/Components/Inputs/ButtonGroupComponent.razor @@ -81,6 +81,7 @@ protected override void OnInitialized() { + base.OnInitialized(); } void OnChangeChoice(string choice) diff --git a/Components/Navigation/DesktopNavComponent.razor b/Components/Navigation/DesktopNavComponent.razor index 17d4bd6..3585812 100644 --- a/Components/Navigation/DesktopNavComponent.razor +++ b/Components/Navigation/DesktopNavComponent.razor @@ -168,6 +168,7 @@ protected override void OnInitialized() { + base.OnInitialized(); navigationService.Subscribe(StateHasChanged); } diff --git a/Components/Navigation/DesktopNavLinkComponent.razor b/Components/Navigation/DesktopNavLinkComponent.razor index e02787c..938b223 100644 --- a/Components/Navigation/DesktopNavLinkComponent.razor +++ b/Components/Navigation/DesktopNavLinkComponent.razor @@ -1,5 +1,5 @@ -@inject INavigationService navigationService; -@inject NavigationManager navigationManager; +@inject INavigationService NavigationService; +@inject NavigationManager NavigationManager; @if (isOnPage) { @@ -11,7 +11,7 @@ } else { - + @@ -71,7 +71,7 @@ else protected override Task OnParametersSetAsync() { - var uri = navigationManager.Uri.Remove(0, navigationManager.BaseUri.Count()).ToLower(); + var uri = NavigationManager.Uri.Remove(0, NavigationManager.BaseUri.Count()).ToLower(); isOnPage = Page.Href.ToLower().Equals(uri); return Task.CompletedTask; @@ -85,7 +85,7 @@ else void OnBack() { - navigationService.Back(); + NavigationService.Back(); } } \ No newline at end of file diff --git a/Components/Shared/DisplayableRoute.razor b/Components/Shared/DisplayableRoute.razor index 27b7911..21b0b82 100644 --- a/Components/Shared/DisplayableRoute.razor +++ b/Components/Shared/DisplayableRoute.razor @@ -21,6 +21,7 @@ else protected override void OnInitialized() { + base.OnInitialized(); var page = MyNavigationManager.Uri.Remove(0, MyNavigationManager.BaseUri.Length); isDisplayable = WebDeploymentModel.Get().Contains(page); } diff --git a/IGP/App.razor b/IGP/App.razor index 68d92e5..b802602 100644 --- a/IGP/App.razor +++ b/IGP/App.razor @@ -1,6 +1,6 @@ -@using Microsoft.AspNetCore.Components.ProtectedBrowserStorage -@inject IVariableService VariableService +@inject IVariableService VariableService @inject IStorageService StorageService +@inject IPermissionService PermissionService @@ -22,6 +22,14 @@ + + + +@if (PermissionService.GetIsDataCollectionEnabled()) +{ + +} + +} + + +@code { + + protected override void OnInitialized() + { + base.OnInitialized(); + + DialogService.Subscribe(StateHasChanged); + } + + void IDisposable.Dispose() + { + DialogService.Unsubscribe(StateHasChanged); + } + + + public void CloseDialog() + { + DialogService.Hide(); + } + + +} \ No newline at end of file diff --git a/IGP/Dialog/EntityDialogComponent.razor b/IGP/Dialog/EntityDialogComponent.razor index 39d4cf3..28c0b63 100644 --- a/IGP/Dialog/EntityDialogComponent.razor +++ b/IGP/Dialog/EntityDialogComponent.razor @@ -145,6 +145,7 @@ protected override void OnInitialized() { + base.OnInitialized(); entity = DATA.Get()[entityDialogService.GetEntityId() ?? string.Empty]; entityDialogService.Subscribe(OnUpdate); diff --git a/IGP/Dialog/SearchDialogComponent.razor b/IGP/Dialog/SearchDialogComponent.razor index baeff94..bbcd215 100644 --- a/IGP/Dialog/SearchDialogComponent.razor +++ b/IGP/Dialog/SearchDialogComponent.razor @@ -50,7 +50,7 @@ filter: blur(2px); } -.searchBackground { +.confirmDialogBackground { position: fixed; top: 0; left: 0; @@ -84,7 +84,7 @@ } -.searchContainer { +.confirmDialogContainer { margin-left: auto; margin-right: auto; margin-top: 64px; @@ -120,6 +120,7 @@ protected override void OnInitialized() { + base.OnInitialized(); searchService.Subscribe(OnSearchChanged); timer = new Timer(200); diff --git a/IGP/IGP.csproj b/IGP/IGP.csproj index 71c0d12..054460b 100644 --- a/IGP/IGP.csproj +++ b/IGP/IGP.csproj @@ -20,6 +20,7 @@ + diff --git a/IGP/Index.razor b/IGP/Index.razor index 4e94a39..e0bbd08 100644 --- a/IGP/Index.razor +++ b/IGP/Index.razor @@ -1,9 +1,12 @@ @page "/" +@inject ITrackingNavigationState TrackingNavigationState +@inject IAnalytics GlobalTracking + @layout PageLayout - + \ No newline at end of file diff --git a/IGP/PageLayout.razor b/IGP/PageLayout.razor index 3e7b62a..d5ea13f 100644 --- a/IGP/PageLayout.razor +++ b/IGP/PageLayout.razor @@ -1,13 +1,16 @@ -@inherits LayoutComponentBase; -@inject IJSRuntime jsRuntime +@inherits LayoutComponentBase +@inject IJSRuntime JsRuntime -@inject ISearchService searchService -@inject IWebsiteService webService; -@implements IDisposable; +@inject ISearchService SearchService +@inject IWebsiteService WebService +@inject IDataCollectionService DataCollectionService +@inject NavigationManager NavigationManager +@using Services.Website +@implements IDisposable
- @if (!webService.IsLoaded()) + @if (!WebService.IsLoaded()) { } @@ -18,12 +21,12 @@
- - - + + + }
@@ -33,12 +36,29 @@ protected override void OnInitialized() { - webService.Subscribe(HasChanged); + base.OnInitialized(); + WebService.Subscribe(HasChanged); + + CollectFirstPageLoaded(); + } + + private void CollectFirstPageLoaded() + { + var skipBaseUri = NavigationManager.Uri.Substring(NavigationManager.BaseUri.Length, + NavigationManager.Uri.Length - NavigationManager.BaseUri.Length); + var rootUrl = skipBaseUri.Split("/").First(); + if (rootUrl.Trim().Equals("")) + { + rootUrl = "home"; + } + + DataCollectionService.SendEvent(DataCollectionKeys.FirstPage, + new Dictionary { { "page", rootUrl } }); } protected override async Task OnInitializedAsync() { - await webService.Load(); + await WebService.Load(); await Focus(); } @@ -55,7 +75,7 @@ void IDisposable.Dispose() { - webService.Unsubscribe(HasChanged); + WebService.Unsubscribe(HasChanged); } void HasChanged() @@ -67,7 +87,7 @@ { if ((keyboardEventArgs.CtrlKey || keyboardEventArgs.MetaKey) && keyboardEventArgs.Key.ToLower() == "k") { - searchService.Show(); + SearchService.Show(); } } diff --git a/IGP/Pages/AboutPage.razor b/IGP/Pages/AboutPage.razor index 034e219..9e06c15 100644 --- a/IGP/Pages/AboutPage.razor +++ b/IGP/Pages/AboutPage.razor @@ -1,5 +1,10 @@ @layout PageLayout +@inherits BasePage + +@inject IDataCollectionService DataCollectionService + + @page "/about" diff --git a/IGP/Pages/Agile/AgilePage.razor b/IGP/Pages/Agile/AgilePage.razor index 25f4769..989a107 100644 --- a/IGP/Pages/Agile/AgilePage.razor +++ b/IGP/Pages/Agile/AgilePage.razor @@ -1,11 +1,12 @@ @implements IDisposable; -@inject IAgileService agileService; +@inject IAgileService AgileService; @layout PageLayout +@inherits BasePage @page "/agile" -@if (!agileService.IsLoaded()) +@if (!AgileService.IsLoaded()) { } @@ -14,7 +15,7 @@ else Agile
- @foreach (var sprint in agileService.AgileSprintModels! + @foreach (var sprint in AgileService.AgileSprintModels! .OrderBy(e => e.EndDate).Reverse()) {
{ { "page", rootUrl }}; + if (splitData.Length > 1) + { + eventData["inner-page"] = splitData.Last(); + } + + DataCollectionService.SendEvent(DataCollectionKeys.PageInitialized, eventData); + } + +} \ No newline at end of file diff --git a/IGP/Pages/BuildCalculator/BuildCalculatorPage.razor b/IGP/Pages/BuildCalculator/BuildCalculatorPage.razor index 3d96608..6fe5630 100644 --- a/IGP/Pages/BuildCalculator/BuildCalculatorPage.razor +++ b/IGP/Pages/BuildCalculator/BuildCalculatorPage.razor @@ -1,16 +1,20 @@ @layout PageLayout -@inject IStringLocalizer locale +@inherits BasePage -@inject IKeyService keyService -@inject IImmortalSelectionService filterService -@inject IBuildOrderService buildOrderService -@inject IEconomyService economyService -@inject IToastService toastService -@inject ITimingService timingService +@inject IStringLocalizer Locale + +@inject IKeyService KeyService +@inject IImmortalSelectionService FilterService +@inject IBuildOrderService BuildOrderService +@inject IEconomyService EconomyService +@inject IToastService ToastService +@inject ITimingService TimingService +@inject IDataCollectionService DataCollectionService @page "/build-calculator" +@using Services.Website @implements IDisposable @@ -29,18 +33,18 @@
Clear Build Order - + - + - + @@ -49,7 +53,7 @@
- + @@ -57,7 +61,7 @@
- + @@ -66,7 +70,7 @@
- + @@ -74,7 +78,7 @@
- + @@ -82,7 +86,7 @@
- + @@ -90,7 +94,7 @@
- + @@ -98,7 +102,7 @@
- + @@ -216,32 +220,39 @@ protected override void OnInitialized() { - economyService.Calculate(buildOrderService, timingService, 0); - - keyService.Subscribe(HandleClick); + base.OnInitialized(); + + EconomyService.Calculate(BuildOrderService, TimingService, 0); + + KeyService.Subscribe(HandleClick); + + DataCollectionService.SendEvent( + DataCollectionKeys.PageInitialized, + new Dictionary {{"page", "build-calculator"}} + ); } void IDisposable.Dispose() { - keyService.Unsubscribe(HandleClick); + KeyService.Unsubscribe(HandleClick); } private void OnResetClicked() { - toastService.AddToast(new ToastModel + ToastService.AddToast(new ToastModel { SeverityType = SeverityType.Success, Message = "Build order has been cleared.", Title = "Reset" }); - buildOrderService.Reset(); + BuildOrderService.Reset(); } private void HandleClick() { - var hotkey = keyService.GetHotkey(); + var hotkey = KeyService.GetHotkey(); if (hotkey == "") { @@ -250,15 +261,15 @@ if (hotkey == "`") { - buildOrderService.RemoveLast(); - economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval()); + BuildOrderService.RemoveLast(); + EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval()); return; } - var hotkeyGroup = keyService.GetHotkeyGroup(); - var isHoldSpace = keyService.IsHoldingSpace(); - var faction = filterService.GetFaction(); - var immortal = filterService.GetImmortal(); + var hotkeyGroup = KeyService.GetHotkeyGroup(); + var isHoldSpace = KeyService.IsHoldingSpace(); + var faction = FilterService.GetFaction(); + var immortal = FilterService.GetImmortal(); var entity = EntityModel.GetFrom(hotkey!, hotkeyGroup, isHoldSpace, faction, immortal); @@ -267,9 +278,9 @@ return; } - if (buildOrderService.Add(entity, economyService)) + if (BuildOrderService.Add(entity, EconomyService)) { - economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval()); + EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval()); } } diff --git a/IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor b/IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor index 20f4c4c..d21d09e 100644 --- a/IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor @@ -67,6 +67,7 @@ protected override void OnInitialized() { + base.OnInitialized(); buildOrder.Subscribe(OnBuildOrderChanged); timingService.Subscribe(StateHasChanged); } diff --git a/IGP/Pages/BuildCalculator/Parts/BankComponent.razor b/IGP/Pages/BuildCalculator/Parts/BankComponent.razor index 23a86d7..f3946a8 100644 --- a/IGP/Pages/BuildCalculator/Parts/BankComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/BankComponent.razor @@ -75,6 +75,7 @@ protected override void OnInitialized() { + base.OnInitialized(); BuildOrderService.Subscribe(OnBuildOrderChanged); } diff --git a/IGP/Pages/BuildCalculator/Parts/BuildChartComponent.razor b/IGP/Pages/BuildCalculator/Parts/BuildChartComponent.razor index 4448bd1..5fb74a6 100644 --- a/IGP/Pages/BuildCalculator/Parts/BuildChartComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/BuildChartComponent.razor @@ -81,6 +81,7 @@ else protected override void OnInitialized() { + base.OnInitialized(); buildOrderService.Subscribe(OnBuilderOrderChanged); timingService.Subscribe(OnBuilderOrderChanged); diff --git a/IGP/Pages/BuildCalculator/Parts/BuildOrderComponent.razor b/IGP/Pages/BuildCalculator/Parts/BuildOrderComponent.razor index e270cc1..1e29c20 100644 --- a/IGP/Pages/BuildCalculator/Parts/BuildOrderComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/BuildOrderComponent.razor @@ -15,6 +15,7 @@ protected override void OnInitialized() { + base.OnInitialized(); buildOrderService.Subscribe(StateHasChanged); } diff --git a/IGP/Pages/BuildCalculator/Parts/EntityClickViewComponent.razor b/IGP/Pages/BuildCalculator/Parts/EntityClickViewComponent.razor index 5cc0628..c73f5ee 100644 --- a/IGP/Pages/BuildCalculator/Parts/EntityClickViewComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/EntityClickViewComponent.razor @@ -29,6 +29,7 @@ protected override void OnInitialized() { + base.OnInitialized(); KeyService.Subscribe(HandleClick); StorageService.Subscribe(RefreshDefaults); diff --git a/IGP/Pages/BuildCalculator/Parts/HighlightsComponent.razor b/IGP/Pages/BuildCalculator/Parts/HighlightsComponent.razor index 52f6a59..6c874da 100644 --- a/IGP/Pages/BuildCalculator/Parts/HighlightsComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/HighlightsComponent.razor @@ -60,6 +60,7 @@ protected override void OnInitialized() { + base.OnInitialized(); economyService.Subscribe(StateHasChanged); buildOrderService.Subscribe(StateHasChanged); } diff --git a/IGP/Pages/BuildCalculator/Parts/HotkeyViewerComponent.razor b/IGP/Pages/BuildCalculator/Parts/HotkeyViewerComponent.razor index 8aaa580..bb4654e 100644 --- a/IGP/Pages/BuildCalculator/Parts/HotkeyViewerComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/HotkeyViewerComponent.razor @@ -1,12 +1,14 @@ -@inject IJSRuntime jsRuntime; +@inject IJSRuntime JsRuntime; +@using Services.Website @implements IDisposable -@inject IKeyService keyService -@inject IBuildOrderService buildOrderService -@inject IImmortalSelectionService filterService +@inject IKeyService KeyService +@inject IBuildOrderService BuildOrderService +@inject IImmortalSelectionService FilterService -@inject IEconomyService economyService -@inject ITimingService timingService -@inject IToastService toastService +@inject IEconomyService EconomyService +@inject ITimingService TimingService +@inject IToastService ToastService +@inject IDataCollectionService DataCollectionService @@ -18,7 +20,7 @@ continue; } - var color = hotkey.KeyText.Equals("SPACE") && keyService.IsHoldingSpace() || keyService.GetAllPressedKeys().Contains(hotkey.KeyText) + var color = hotkey.KeyText.Equals("SPACE") && KeyService.IsHoldingSpace() || KeyService.GetAllPressedKeys().Contains(hotkey.KeyText) ? "#0a0f12" : hotkey.GetColor(); var x = hotkey.PositionX * Size; @@ -34,7 +36,7 @@ border = "5px solid green"; } - if (hotkey.KeyText.Equals("SPACE") && keyService.IsHoldingSpace()) + if (hotkey.KeyText.Equals("SPACE") && KeyService.IsHoldingSpace()) { border = "5px solid green"; } @@ -46,7 +48,7 @@ width: 0px; height: 0px;"> -
ButtonClicked(e, hotkey))" style="background-color:@color; border: @border; width: @Size.ToString()px; height: @Size.ToString()px; @@ -73,7 +75,7 @@ var isVanguard = entity.VanguardAdded() != null; var style = isVanguard ? "font-weight: bold;" : ""; - if (buildOrderService.WillMeetRequirements(entity) == null) + if (BuildOrderService.WillMeetRequirements(entity) == null) { style += "color:gray; font-style: italic;"; } @@ -122,25 +124,25 @@ { base.OnInitialized(); - keyService.Subscribe(OnKeyPressed); - filterService.Subscribe(StateHasChanged); - buildOrderService.Subscribe(OnBuilderOrderChanged); + KeyService.Subscribe(OnKeyPressed); + FilterService.Subscribe(StateHasChanged); + BuildOrderService.Subscribe(OnBuilderOrderChanged); } void IDisposable.Dispose() { - keyService.Unsubscribe(OnKeyPressed); - filterService.Unsubscribe(StateHasChanged); - buildOrderService.Unsubscribe(OnBuilderOrderChanged); + KeyService.Unsubscribe(OnKeyPressed); + FilterService.Unsubscribe(StateHasChanged); + BuildOrderService.Unsubscribe(OnBuilderOrderChanged); } int completedTimeCount = 0; void OnBuilderOrderChanged() { - if (buildOrderService.UniqueCompletedTimes.Count != completedTimeCount) + if (BuildOrderService.UniqueCompletedTimes.Count != completedTimeCount) { - completedTimeCount = buildOrderService.UniqueCompletedTimes.Count; + completedTimeCount = BuildOrderService.UniqueCompletedTimes.Count; StateHasChanged(); } } @@ -148,7 +150,7 @@ protected override bool ShouldRender() { #if DEBUG - jsRuntime.InvokeVoidAsync("console.time", "HotKeyViewerComponent"); + JsRuntime.InvokeVoidAsync("console.time", "HotKeyViewerComponent"); #endif return true; @@ -157,14 +159,14 @@ protected override void OnAfterRender(bool firstRender) { #if DEBUG - jsRuntime.InvokeVoidAsync("console.timeEnd", "HotKeyViewerComponent"); + JsRuntime.InvokeVoidAsync("console.timeEnd", "HotKeyViewerComponent"); #endif } // Move to Filter Service bool InvalidFaction(EntityModel entity) { - if (entity.Faction() != null && entity.Faction()?.Faction != filterService.GetFaction() && filterService.GetFaction() != DataType.Any) + if (entity.Faction() != null && entity.Faction()?.Faction != FilterService.GetFaction() && FilterService.GetFaction() != DataType.Any) { return true; } @@ -176,8 +178,8 @@ bool InvalidVanguard(EntityModel entity) { if (entity.VanguardAdded() != null - && entity.VanguardAdded()?.ImmortalId != filterService.GetImmortal() - && filterService.GetImmortal() != DataType.Any) + && entity.VanguardAdded()?.ImmortalId != FilterService.GetImmortal() + && FilterService.GetImmortal() != DataType.Any) { return true; } @@ -192,7 +194,7 @@ { foreach (var replaced in entity.Replaceds()) { - if (filterService.GetImmortal() == replaced.ImmortalId) + if (FilterService.GetImmortal() == replaced.ImmortalId) { return true; } @@ -241,7 +243,7 @@ bool InvalidHoldSpace(EntityModel entity) { - if (entity.Hotkey()?.HoldSpace == keyService.IsHoldingSpace()) + if (entity.Hotkey()?.HoldSpace == KeyService.IsHoldingSpace()) { return false; } @@ -254,44 +256,44 @@ var keyWas = key; - if (keyService.GetAllPressedKeys().Contains("Z")) + if (KeyService.GetAllPressedKeys().Contains("Z")) { controlGroup = "Z"; } - if (keyService.GetAllPressedKeys().Contains("TAB")) + if (KeyService.GetAllPressedKeys().Contains("TAB")) { controlGroup = "TAB"; } - if (keyService.GetAllPressedKeys().Contains("C")) + if (KeyService.GetAllPressedKeys().Contains("C")) { controlGroup = "C"; } - if (keyService.GetAllPressedKeys().Contains("D")) + if (KeyService.GetAllPressedKeys().Contains("D")) { controlGroup = "D"; } - if (keyService.GetAllPressedKeys().Contains("1")) + if (KeyService.GetAllPressedKeys().Contains("1")) { controlGroup = "1"; } //TODO This could be better. Duplicated code - if (keyService.GetAllPressedKeys().Contains("2")) + if (KeyService.GetAllPressedKeys().Contains("2")) { controlGroup = "2"; } - if (keyService.GetAllPressedKeys().Contains("SHIFT")) + if (KeyService.GetAllPressedKeys().Contains("SHIFT")) { controlGroup = "SHIFT"; } - if (keyService.GetAllPressedKeys().Contains("CONTROL")) + if (KeyService.GetAllPressedKeys().Contains("CONTROL")) { controlGroup = "CONTROL"; } - if (keyService.GetAllPressedKeys().Count > 0) + if (KeyService.GetAllPressedKeys().Count > 0) { - key = keyService.GetAllPressedKeys().First(); + key = KeyService.GetAllPressedKeys().First(); } if (controlGroupWas != controlGroup || keyWas != key) @@ -303,7 +305,7 @@ private void HandleClick() { - var hotkey = keyService.GetHotkey(); + var hotkey = KeyService.GetHotkey(); if (hotkey == "") { @@ -312,15 +314,15 @@ if (hotkey == "`") { - buildOrderService.RemoveLast(); - economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval()); + BuildOrderService.RemoveLast(); + EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval()); return; } - var hotkeyGroup = keyService.GetHotkeyGroup(); - var isHoldSpace = keyService.IsHoldingSpace(); - var faction = filterService.GetFaction(); - var immortal = filterService.GetImmortal(); + var hotkeyGroup = KeyService.GetHotkeyGroup(); + var isHoldSpace = KeyService.IsHoldingSpace(); + var faction = FilterService.GetFaction(); + var immortal = FilterService.GetImmortal(); var entity = EntityModel.GetFrom(hotkey!, hotkeyGroup, isHoldSpace, faction, immortal); @@ -329,9 +331,35 @@ return; } - if (buildOrderService.Add(entity, economyService)) + if (BuildOrderService.Add(entity, EconomyService)) { - economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval()); + EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval()); + } + } + + private void ButtonClicked(MouseEventArgs mouseEventArgs, HotkeyModel hotkey) + { + DataCollectionService.SendEvent( + DataCollectionKeys.BuildCalcInput, + new Dictionary {{"key", hotkey.KeyText.ToLower()}, {"input-source", "mouse"}} + ); + + + if (hotkey.KeyText.Equals(HotKeyType.SPACE.ToString())) + { + if (KeyService.IsHoldingSpace()) + { + KeyService.RemovePressedKey(hotkey.KeyText); + } + else + { + KeyService.AddPressedKey(hotkey.KeyText); + } + } + else + { + KeyService.AddPressedKey(hotkey.KeyText); + KeyService.RemovePressedKey(hotkey.KeyText); } } diff --git a/IGP/Pages/BuildCalculator/Parts/InputPanelComponent.razor b/IGP/Pages/BuildCalculator/Parts/InputPanelComponent.razor index 3d763e5..8a5439c 100644 --- a/IGP/Pages/BuildCalculator/Parts/InputPanelComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/InputPanelComponent.razor @@ -1,6 +1,8 @@ -@inject IKeyService keyService +@using Services.Website +@inject IKeyService KeyService -@inject IJSRuntime jsRuntime; +@inject IDataCollectionService DataCollectionService +@inject IJSRuntime JsRuntime
{{"key", e.Key.ToLower()}, {"input-source", "keyboard"}} + ); + + KeyService.AddPressedKey(e.Key); } private void HandleKeyUp(KeyboardEventArgs e) { - keyService.RemovePressedKey(e.Key); + KeyService.RemovePressedKey(e.Key); } protected override bool ShouldRender() { #if DEBUG - jsRuntime.InvokeVoidAsync("console.time", "InputPanelComponent"); + JsRuntime.InvokeVoidAsync("console.time", "InputPanelComponent"); #endif return true; @@ -39,7 +46,7 @@ protected override void OnAfterRender(bool firstRender) { #if DEBUG - jsRuntime.InvokeVoidAsync("console.timeEnd", "InputPanelComponent"); + JsRuntime.InvokeVoidAsync("console.timeEnd", "InputPanelComponent"); #endif } diff --git a/IGP/Pages/BuildCalculator/Parts/OptionsComponent.razor b/IGP/Pages/BuildCalculator/Parts/OptionsComponent.razor index 3ca58ba..40c62d3 100644 --- a/IGP/Pages/BuildCalculator/Parts/OptionsComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/OptionsComponent.razor @@ -52,6 +52,7 @@ protected override void OnInitialized() { + base.OnInitialized(); TimingService.Subscribe(RefreshDefaults); RefreshDefaults(); diff --git a/IGP/Pages/BuildCalculator/Parts/TimelineComponent.razor b/IGP/Pages/BuildCalculator/Parts/TimelineComponent.razor index bbb9599..825d7f3 100644 --- a/IGP/Pages/BuildCalculator/Parts/TimelineComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/TimelineComponent.razor @@ -58,6 +58,7 @@ protected override void OnInitialized() { + base.OnInitialized(); economyService.Subscribe(StateHasChanged); buildOrderService.Subscribe(StateHasChanged); } diff --git a/IGP/Pages/BuildCalculator/Parts/TimingComponent.razor b/IGP/Pages/BuildCalculator/Parts/TimingComponent.razor index 9cdab07..c2e4850 100644 --- a/IGP/Pages/BuildCalculator/Parts/TimingComponent.razor +++ b/IGP/Pages/BuildCalculator/Parts/TimingComponent.razor @@ -33,6 +33,7 @@ protected override void OnInitialized() { + base.OnInitialized(); timingService.Subscribe(StateHasChanged); } diff --git a/IGP/Pages/ChangeLogPage.razor b/IGP/Pages/ChangeLogPage.razor index 8b4b247..62c5611 100644 --- a/IGP/Pages/ChangeLogPage.razor +++ b/IGP/Pages/ChangeLogPage.razor @@ -1,11 +1,16 @@ @page "/changelog" @implements IDisposable; -@inject IGitService gitService; +@inject IGitService GitService; + +@inherits BasePage + +@inject IDataCollectionService DataCollectionService + @layout PageLayout -@if (gitService.IsLoaded()) +@if (GitService.IsLoaded()) { Change Log @@ -90,21 +95,22 @@ else @code { - private IEnumerable Patches => gitService.GitPatchModels; + private IEnumerable Patches => GitService.GitPatchModels; - private List Changes => gitService.GitChangeModels; + private List Changes => GitService.GitChangeModels; private bool isViewImportant = true; protected override void OnInitialized() { - gitService.Subscribe(HasChanged); + base.OnInitialized(); + GitService.Subscribe(HasChanged); } void IDisposable.Dispose() { - gitService.Unsubscribe(HasChanged); + GitService.Unsubscribe(HasChanged); } @@ -121,7 +127,7 @@ else protected override async Task OnInitializedAsync() { - await gitService.Load(); + await GitService.Load(); } } \ No newline at end of file diff --git a/IGP/Pages/Comparision/ComparisionPage.razor b/IGP/Pages/Comparision/ComparisionPage.razor index 49da43f..8545166 100644 --- a/IGP/Pages/Comparision/ComparisionPage.razor +++ b/IGP/Pages/Comparision/ComparisionPage.razor @@ -1,7 +1,8 @@ @layout PageLayout +@inherits BasePage @implements IDisposable -@inject IToastService toastService +@inject IToastService ToastService
protected override void OnInitialized() { + base.OnInitialized(); KeyService.Subscribe(HandleClick); FilterService.Subscribe(StateHasChanged); EconomyService.Subscribe(StateHasChanged); diff --git a/IGP/Pages/Comparision/Parts/BuildLoaderComponent.razor b/IGP/Pages/Comparision/Parts/BuildLoaderComponent.razor index 0c222f6..229efff 100644 --- a/IGP/Pages/Comparision/Parts/BuildLoaderComponent.razor +++ b/IGP/Pages/Comparision/Parts/BuildLoaderComponent.razor @@ -20,6 +20,7 @@ protected override void OnInitialized() { + base.OnInitialized(); BuildComparisionService.Subscribe(StateHasChanged); } diff --git a/IGP/Pages/Comparision/Parts/SandComponent.razor b/IGP/Pages/Comparision/Parts/SandComponent.razor index 1dae56d..e8fac2b 100644 --- a/IGP/Pages/Comparision/Parts/SandComponent.razor +++ b/IGP/Pages/Comparision/Parts/SandComponent.razor @@ -13,6 +13,7 @@ protected override void OnInitialized() { + base.OnInitialized(); BuildComparisonService.Subscribe(StateHasChanged); } diff --git a/IGP/Pages/ContactPage.razor b/IGP/Pages/ContactPage.razor index 862a328..5bf660e 100644 --- a/IGP/Pages/ContactPage.razor +++ b/IGP/Pages/ContactPage.razor @@ -1,5 +1,8 @@ @layout PageLayout +@inject IDataCollectionService DataCollectionService +@inherits BasePage + @page "/contact" diff --git a/IGP/Pages/DataCollectionPage.razor b/IGP/Pages/DataCollectionPage.razor index 8d4fa5a..577b25e 100644 --- a/IGP/Pages/DataCollectionPage.razor +++ b/IGP/Pages/DataCollectionPage.razor @@ -1,5 +1,8 @@ @page "/data-collection" +@inject IDataCollectionService DataCollectionService +@inherits BasePage + @layout PageLayout diff --git a/IGP/Pages/Database/DatabasePage.razor b/IGP/Pages/Database/DatabasePage.razor index 0e0cc55..3d9d702 100644 --- a/IGP/Pages/Database/DatabasePage.razor +++ b/IGP/Pages/Database/DatabasePage.razor @@ -1,11 +1,12 @@ @layout PageLayout - +@inherits BasePage @page "/database" @implements IDisposable -@inject IEntityDisplayService entityDisplayService -@inject IVariableService variableService +@inject IEntityDisplayService EntityDisplayService +@inject IVariableService VariableService + Database @@ -13,13 +14,13 @@ - Game Patch: @variableService.Variables["GamePatch"] + Game Patch: @VariableService.Variables["GamePatch"]
- +
@@ -31,7 +32,7 @@ @foreach (var entity in searches) { - + @@ -67,7 +68,7 @@ Is this database updated to the latest version? - Maybe. Check this @variableService.Variables["GamePatch"] version number, and compare it to the number on discord, in the #game-updates channel. That should give a general sense of how out of date the data is. + Maybe. Check this @VariableService.Variables["GamePatch"] version number, and compare it to the number on discord, in the #game-updates channel. That should give a general sense of how out of date the data is. @@ -134,16 +135,17 @@ protected override void OnInitialized() { + base.OnInitialized(); RefreshFactionSearch(); EntityFilterService.Subscribe(OnChange); - entityDisplayService.Subscribe(StateHasChanged); + EntityDisplayService.Subscribe(StateHasChanged); } void IDisposable.Dispose() { EntityFilterService.Unsubscribe(OnChange); - entityDisplayService.Unsubscribe(StateHasChanged); + EntityDisplayService.Unsubscribe(StateHasChanged); } void OnChange(EntityFilterEvent filterEntityEvent) diff --git a/IGP/Pages/Database/DatabaseSinglePage.razor b/IGP/Pages/Database/DatabaseSinglePage.razor index 030916a..478dc71 100644 --- a/IGP/Pages/Database/DatabaseSinglePage.razor +++ b/IGP/Pages/Database/DatabaseSinglePage.razor @@ -1,24 +1,27 @@ @layout PageLayout +@inherits BasePage + @page "/database/{text}" -@inject IEntityDisplayService entityDisplayService +@inject IEntityDisplayService EntityDisplayService +@inject IVariableService VariableService -@inject IVariableService variableService @implements IDisposable + - Game Patch: @variableService.Variables["GamePatch"] + Game Patch: @VariableService.Variables["GamePatch"]
- +
@@ -33,7 +36,7 @@
} - else if (entity == null) + else if (_entity == null) {
Invalid entity name entered: @Text
@@ -44,8 +47,8 @@ else { - - + + @@ -62,17 +65,28 @@ [Parameter] public string? Text { get; set; } - private EntityModel? entity; + private EntityModel? _entity; protected override void OnInitialized() { - entityDisplayService.Subscribe(StateHasChanged); + EntityDisplayService.Subscribe(StateHasChanged); + } + protected override void OnParametersSet() + { + base.OnParametersSet(); + base.OnInitialized(); + + FocusEntity(); + } + + private void FocusEntity() + { foreach (var e in DATA.Get().Values) { if (e.Info().Name.ToLower().Equals(Text!.ToLower())) { - entity = e; + _entity = e; return; } } @@ -80,7 +94,7 @@ void IDisposable.Dispose() { - entityDisplayService.Unsubscribe(StateHasChanged); + EntityDisplayService.Unsubscribe(StateHasChanged); } } \ No newline at end of file diff --git a/IGP/Pages/Database/Entity/Parts/EntityWeaponsComponent.razor b/IGP/Pages/Database/Entity/Parts/EntityWeaponsComponent.razor index 451b7df..b5d7cf2 100644 --- a/IGP/Pages/Database/Entity/Parts/EntityWeaponsComponent.razor +++ b/IGP/Pages/Database/Entity/Parts/EntityWeaponsComponent.razor @@ -244,6 +244,7 @@ protected override void OnInitialized() { + base.OnInitialized(); StorageService.Subscribe(RefreshDefaults); } diff --git a/IGP/Pages/Database/Parts/EntityFilterComponent.razor b/IGP/Pages/Database/Parts/EntityFilterComponent.razor index cc3c3c4..f93436f 100644 --- a/IGP/Pages/Database/Parts/EntityFilterComponent.razor +++ b/IGP/Pages/Database/Parts/EntityFilterComponent.razor @@ -213,6 +213,7 @@ protected override void OnInitialized() { + base.OnInitialized(); } void OnChangeFaction(string clickedFaction) diff --git a/IGP/Pages/Documentation/DocumentationIndexPage.razor b/IGP/Pages/Documentation/DocumentationIndexPage.razor index 9ed77b0..52b9588 100644 --- a/IGP/Pages/Documentation/DocumentationIndexPage.razor +++ b/IGP/Pages/Documentation/DocumentationIndexPage.razor @@ -1,11 +1,12 @@ @layout PageLayout +@inherits BasePage -@inject IDocumentationService documentationService +@inject IDocumentationService DocumentationService @implements IDisposable @page "/docs" -@if (!documentationService.IsLoaded()) +@if (!DocumentationService.IsLoaded()) { } @@ -13,7 +14,7 @@ else { - @foreach (var docSection in documentationService.DocSectionModels) + @foreach (var docSection in DocumentationService.DocSectionModels) {
@docSection.Name
@@ -102,14 +103,15 @@ else protected override void OnInitialized() { - documentationService.Subscribe(StateHasChanged); + base.OnInitialized(); + DocumentationService.Subscribe(StateHasChanged); - documentationService.Load(); + DocumentationService.Load(); } void IDisposable.Dispose() { - documentationService.Unsubscribe(StateHasChanged); + DocumentationService.Unsubscribe(StateHasChanged); } } \ No newline at end of file diff --git a/IGP/Pages/Documentation/DocumentationPage.razor b/IGP/Pages/Documentation/DocumentationPage.razor index 3db1bb4..cde5e63 100644 --- a/IGP/Pages/Documentation/DocumentationPage.razor +++ b/IGP/Pages/Documentation/DocumentationPage.razor @@ -1,12 +1,13 @@ @layout PageLayout +@inherits BasePage -@inject IDocumentationService documentationService +@inject IDocumentationService DocumentationService @implements IDisposable @page "/docs/{href1}/{href2?}/{href3?}/{href4?}/{href5?}" -@if (!documentationService.IsLoaded()) +@if (!DocumentationService.IsLoaded()) { } @@ -15,12 +16,12 @@ else + Connections="DocumentationService.DocConnectionModels" + Documents="DocumentationService.DocContentModels"/> - @foreach (var doc in documentationService.DocContentModels) + @foreach (var doc in DocumentationService.DocContentModels) { if (!doc.Href.Equals(Href)) { @@ -108,14 +109,15 @@ else protected override void OnInitialized() { - documentationService.Subscribe(StateHasChanged); + base.OnInitialized(); + DocumentationService.Subscribe(StateHasChanged); - documentationService.Load(); + DocumentationService.Load(); } void IDisposable.Dispose() { - documentationService.Unsubscribe(StateHasChanged); + DocumentationService.Unsubscribe(StateHasChanged); } } \ No newline at end of file diff --git a/IGP/Pages/EconomyComparison/EconomyComparisonPage.razor b/IGP/Pages/EconomyComparison/EconomyComparisonPage.razor index 8564799..227ffc8 100644 --- a/IGP/Pages/EconomyComparison/EconomyComparisonPage.razor +++ b/IGP/Pages/EconomyComparison/EconomyComparisonPage.razor @@ -1,5 +1,7 @@ @page "/economy-comparison" +@inherits BasePage + @implements IDisposable @inject IEconomyComparisonService EconomyComparisonService @layout PageLayout @@ -40,6 +42,7 @@ @code { protected override void OnInitialized() { + base.OnInitialized(); EconomyComparisonService.Subscribe(StateHasChanged); } diff --git a/IGP/Pages/EconomyComparison/Parts/ChartComponent.razor b/IGP/Pages/EconomyComparison/Parts/ChartComponent.razor index 14d2b39..8c360c3 100644 --- a/IGP/Pages/EconomyComparison/Parts/ChartComponent.razor +++ b/IGP/Pages/EconomyComparison/Parts/ChartComponent.razor @@ -62,6 +62,7 @@ protected override void OnInitialized() { + base.OnInitialized(); economyComparisonService.Subscribe(OnBuilderOrderChanged); OnBuilderOrderChanged(); diff --git a/IGP/Pages/EconomyComparison/Parts/EconomyDifferenceComponent.razor b/IGP/Pages/EconomyComparison/Parts/EconomyDifferenceComponent.razor index 6f5f158..324d0b2 100644 --- a/IGP/Pages/EconomyComparison/Parts/EconomyDifferenceComponent.razor +++ b/IGP/Pages/EconomyComparison/Parts/EconomyDifferenceComponent.razor @@ -72,6 +72,7 @@ protected override void OnInitialized() { + base.OnInitialized(); economyComparisonService.Subscribe(CalculateDifferences); } diff --git a/IGP/Pages/EconomyComparison/Parts/EconomyInputComponent.razor b/IGP/Pages/EconomyComparison/Parts/EconomyInputComponent.razor index 6f62884..6451254 100644 --- a/IGP/Pages/EconomyComparison/Parts/EconomyInputComponent.razor +++ b/IGP/Pages/EconomyComparison/Parts/EconomyInputComponent.razor @@ -49,6 +49,7 @@ protected override void OnInitialized() { + base.OnInitialized(); economyComparisonService.Subscribe(StateHasChanged); } diff --git a/IGP/Pages/HarassCalculatorPage.razor b/IGP/Pages/HarassCalculatorPage.razor index da13b9d..0363c68 100644 --- a/IGP/Pages/HarassCalculatorPage.razor +++ b/IGP/Pages/HarassCalculatorPage.razor @@ -1,5 +1,8 @@ @layout PageLayout +@inject IDataCollectionService DataCollectionService +@inherits BasePage + @page "/harass-calculator" @using Model @@ -261,6 +264,7 @@ protected override void OnInitialized() { + base.OnInitialized(); Calculate(); } diff --git a/IGP/Pages/Home/HomePage.razor b/IGP/Pages/Home/HomePage.razor index 9109b5d..67e08a6 100644 --- a/IGP/Pages/Home/HomePage.razor +++ b/IGP/Pages/Home/HomePage.razor @@ -1,5 +1,7 @@ @layout PageLayout; +@inherits BasePage + @page "/immortal-home" diff --git a/IGP/Pages/MakingOf/MakingOfPage.razor b/IGP/Pages/MakingOf/MakingOfPage.razor index 8b9a9d9..6a58e9d 100644 --- a/IGP/Pages/MakingOf/MakingOfPage.razor +++ b/IGP/Pages/MakingOf/MakingOfPage.razor @@ -1,5 +1,9 @@ @page "/makingof" +@inherits BasePage + +@inject IDataCollectionService DataCollectionService + @layout PageLayout diff --git a/IGP/Pages/MemoryTester/MemoryTesterPage.razor b/IGP/Pages/MemoryTester/MemoryTesterPage.razor index 3812188..b5d720c 100644 --- a/IGP/Pages/MemoryTester/MemoryTesterPage.razor +++ b/IGP/Pages/MemoryTester/MemoryTesterPage.razor @@ -1,5 +1,7 @@ @layout PageLayout +@inherits BasePage + @page "/memory-tester" diff --git a/IGP/Pages/MemoryTester/Parts/UnitMemory.razor b/IGP/Pages/MemoryTester/Parts/UnitMemory.razor index b146c56..ed6becc 100644 --- a/IGP/Pages/MemoryTester/Parts/UnitMemory.razor +++ b/IGP/Pages/MemoryTester/Parts/UnitMemory.razor @@ -62,6 +62,7 @@ protected override void OnInitialized() { + base.OnInitialized(); MemoryTesterService.Subscribe(OnMemoryEvent); OnRefresh(); diff --git a/IGP/Pages/MemoryTester/Parts/UnitMemoryManager.razor b/IGP/Pages/MemoryTester/Parts/UnitMemoryManager.razor index 525abea..2900c96 100644 --- a/IGP/Pages/MemoryTester/Parts/UnitMemoryManager.razor +++ b/IGP/Pages/MemoryTester/Parts/UnitMemoryManager.razor @@ -64,6 +64,7 @@ protected override void OnInitialized() { + base.OnInitialized(); MemoryTesterService.Subscribe(OnMemoryEvent); MemoryTesterService.GenerateQuiz(); diff --git a/IGP/Pages/Notes/NotesIndexPage.razor b/IGP/Pages/Notes/NotesIndexPage.razor index 56ead8b..f32a826 100644 --- a/IGP/Pages/Notes/NotesIndexPage.razor +++ b/IGP/Pages/Notes/NotesIndexPage.razor @@ -1,12 +1,16 @@ @layout PageLayout -@inject INoteService noteService +@inherits BasePage + +@inject INoteService NoteService @implements IDisposable +@inject IDataCollectionService DataCollectionService + @page "/notes" -@if (!noteService.IsLoaded()) +@if (!NoteService.IsLoaded()) { } @@ -15,7 +19,7 @@ else - @foreach (var noteSection in noteService.NoteSectionModels) + @foreach (var noteSection in NoteService.NoteSectionModels) {
@noteSection.Name
@@ -119,15 +123,16 @@ else protected override void OnInitialized() { - noteService.Subscribe(StateHasChanged); + base.OnInitialized(); + NoteService.Subscribe(StateHasChanged); - noteService.Load(); + NoteService.Load(); } void IDisposable.Dispose() { - noteService.Unsubscribe(StateHasChanged); + NoteService.Unsubscribe(StateHasChanged); } diff --git a/IGP/Pages/Notes/NotesPage.razor b/IGP/Pages/Notes/NotesPage.razor index 3c8c100..a9e9936 100644 --- a/IGP/Pages/Notes/NotesPage.razor +++ b/IGP/Pages/Notes/NotesPage.razor @@ -1,12 +1,16 @@ @layout PageLayout -@inject INoteService noteService +@inherits BasePage + +@inject INoteService NoteService @implements IDisposable +@inject IDataCollectionService DataCollectionService + @page "/notes/{href1}/{href2?}/{href3?}/{href4?}/{href5?}" -@if (!noteService.IsLoaded()) +@if (!NoteService.IsLoaded()) { } @@ -15,12 +19,12 @@ else + Connections="NoteService.NoteConnectionModels" + Notes="NoteService.NoteContentModels"/> - @foreach (var note in noteService.NoteContentModels) + @foreach (var note in NoteService.NoteContentModels) { if (!note.Href.Equals(Href)) { @@ -107,14 +111,15 @@ else protected override void OnInitialized() { - noteService.Subscribe(StateHasChanged); + base.OnInitialized(); + NoteService.Subscribe(StateHasChanged); - noteService.Load(); + NoteService.Load(); } void IDisposable.Dispose() { - noteService.Unsubscribe(StateHasChanged); + NoteService.Unsubscribe(StateHasChanged); } } \ No newline at end of file diff --git a/IGP/Pages/PermissionsPage.razor b/IGP/Pages/PermissionsPage.razor index 97430bb..9652676 100644 --- a/IGP/Pages/PermissionsPage.razor +++ b/IGP/Pages/PermissionsPage.razor @@ -2,24 +2,27 @@ @inject IPermissionService PermissionService @layout PageLayout -@using Services.Website -@inject Blazored.LocalStorage.ILocalStorageService LocalStorage +@inject IDialogService DialogService + +@inherits BasePage +@using Services.Website @implements IDisposable - - @@ -44,7 +47,10 @@ What data does this website collect? - This website usages Google Analytics to collect data enabled on the Analytics page. + This website usages Google Analytics to collect data on usage of this website. +

+ Items include: if people use keyboard or mouse in build calculator, what pages people visit, and other usages. +
@@ -58,38 +64,60 @@ @code { private bool _storageEnabled = false; private bool _dataCollectionEnabled = false; - + protected override void OnInitialized() { PermissionService.Subscribe(Update); Update(); } - + void Update() { _storageEnabled = PermissionService.GetIsStorageEnabled(); _dataCollectionEnabled = PermissionService.GetIsDataCollectionEnabled(); - StateHasChanged(); } - + void IDisposable.Dispose() { PermissionService.Unsubscribe(Update); } - - private void StoragePermissionChanged(ChangeEventArgs obj) { - PermissionService.SetIsStorageEnabled((bool)obj.Value!); + PermissionService.SetIsStorageEnabled(!PermissionService.GetIsStorageEnabled()); } + private void DataCollectionPermissionChanged(ChangeEventArgs obj) { - PermissionService.SetIsDataCollectionEnabled((bool)obj.Value!); + void OnDataCollectionConfirmClicked(MouseEventArgs mouseEventArgs) + { + PermissionService.SetIsDataCollectionEnabled(!PermissionService.GetIsDataCollectionEnabled()); + DialogService.Hide(); + } + + void OnDataCollectionCancelClicked(MouseEventArgs mouseEventArgs) + { + DialogService.Hide(); + } + + if (_storageEnabled && !PermissionService.GetIsDataCollectionEnabled()) + { + DialogService.Show(new DialogContents + { + Title = "Permission Request", + Message = "Are you sure you want to enable data collection? This feature is implemented with Google Analytics, and your data will be used to gauge interests, find bugs, and optimize updates in IGP Fan Reference.", + OnConfirm = new EventCallback(this, OnDataCollectionConfirmClicked), + OnCancel = new EventCallback(this, OnDataCollectionCancelClicked), + ConfirmButtonLabel = "Enable Data Collection" + }); + } + else + { + PermissionService.SetIsDataCollectionEnabled(!PermissionService.GetIsDataCollectionEnabled()); + } } - } \ No newline at end of file diff --git a/IGP/Pages/RawDatabase.razor b/IGP/Pages/RawDatabase.razor index 2d76508..5424025 100644 --- a/IGP/Pages/RawDatabase.razor +++ b/IGP/Pages/RawDatabase.razor @@ -1,4 +1,6 @@ -@page "/raw-database" +@inherits BasePage + +@page "/raw-database"
diff --git a/IGP/Pages/RoadMap/RoadMapPage.razor b/IGP/Pages/RoadMap/RoadMapPage.razor index cc7ea5d..2deeb68 100644 --- a/IGP/Pages/RoadMap/RoadMapPage.razor +++ b/IGP/Pages/RoadMap/RoadMapPage.razor @@ -1,5 +1,9 @@ @layout PageLayout +@inherits BasePage + +@inject IDataCollectionService DataCollectionService + @page "/roadmap" diff --git a/IGP/Pages/StoragePage.razor b/IGP/Pages/StoragePage.razor index cfe6c7c..ba86ca0 100644 --- a/IGP/Pages/StoragePage.razor +++ b/IGP/Pages/StoragePage.razor @@ -1,5 +1,7 @@ @page "/storage" + +@inherits BasePage @inject IStorageService StorageService @using Services.Website @implements IDisposable @@ -145,6 +147,8 @@ protected override void OnInitialized() { + base.OnInitialized(); + _enabledPermissions = StorageService.GetValue(StorageKeys.EnabledStorage); RefreshDefaults(); diff --git a/IGP/Pages/StreamsPage.razor b/IGP/Pages/StreamsPage.razor index d9a7732..fea5ba2 100644 --- a/IGP/Pages/StreamsPage.razor +++ b/IGP/Pages/StreamsPage.razor @@ -1,5 +1,7 @@ @page "/streams" +@inherits BasePage + @layout PageLayout diff --git a/IGP/Portals/ConfirmationDialogPortal.razor b/IGP/Portals/ConfirmationDialogPortal.razor new file mode 100644 index 0000000..bf998ba --- /dev/null +++ b/IGP/Portals/ConfirmationDialogPortal.razor @@ -0,0 +1,25 @@ +@implements IDisposable; + +@inject IDialogService DialogService + + + +@code { + + protected override void OnInitialized() + { + base.OnInitialized(); + DialogService.Subscribe(OnUpdate); + } + + void IDisposable.Dispose() + { + DialogService.Unsubscribe(OnUpdate); + } + + void OnUpdate() + { + StateHasChanged(); + } + +} \ No newline at end of file diff --git a/IGP/Portals/EntityDialogPortal.razor b/IGP/Portals/EntityDialogPortal.razor index dbe7963..e7eedc6 100644 --- a/IGP/Portals/EntityDialogPortal.razor +++ b/IGP/Portals/EntityDialogPortal.razor @@ -12,6 +12,7 @@ protected override void OnInitialized() { + base.OnInitialized(); entityDialogService.Subscribe(OnUpdate); } diff --git a/IGP/Portals/SearchPortal.razor b/IGP/Portals/SearchPortal.razor index edb81e2..e9a969d 100644 --- a/IGP/Portals/SearchPortal.razor +++ b/IGP/Portals/SearchPortal.razor @@ -1,29 +1,28 @@ @implements IDisposable; -@inject ISearchService searchService -@inject IJSRuntime jsRuntime +@inject ISearchService SearchService +@inject IJSRuntime JsRuntime @code { - private string test = "Q"; - protected override void OnInitialized() { - searchService.Subscribe(OnUpdate); + base.OnInitialized(); + SearchService.Subscribe(OnUpdate); } protected override async Task OnInitializedAsync() { - await searchService.Load(); - await jsRuntime.InvokeVoidAsync("SetDotnetReference", DotNetObjectReference.Create(this)); + await SearchService.Load(); + await JsRuntime.InvokeVoidAsync("SetDotnetReference", DotNetObjectReference.Create(this)); } void IDisposable.Dispose() { - searchService.Unsubscribe(OnUpdate); + SearchService.Unsubscribe(OnUpdate); } void OnUpdate() @@ -36,13 +35,13 @@ { if (code.ToLower().Equals("k") && (ctrlKey || shiftKey || altKey || metaKey)) { - if (searchService.IsVisible) + if (SearchService.IsVisible) { - searchService.Hide(); + SearchService.Hide(); } else { - searchService.Show(); + SearchService.Show(); } } } diff --git a/IGP/Portals/ToastPortal.razor b/IGP/Portals/ToastPortal.razor index 48330a0..39d56e6 100644 --- a/IGP/Portals/ToastPortal.razor +++ b/IGP/Portals/ToastPortal.razor @@ -31,6 +31,7 @@ protected override void OnInitialized() { + base.OnInitialized(); toastService.Subscribe(OnUpdate); ageTimer = new Timer(10); diff --git a/IGP/Program.cs b/IGP/Program.cs index 9215e57..ba42259 100644 --- a/IGP/Program.cs +++ b/IGP/Program.cs @@ -1,6 +1,7 @@ using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; +using Blazor.Analytics; using Blazored.LocalStorage; using IGP; using Microsoft.AspNetCore.Components.Web; @@ -9,6 +10,7 @@ using Services; using Services.Development; using Services.Immortal; using Services.Website; + CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US"); @@ -19,8 +21,10 @@ builder.Logging.SetMinimumLevel(LogLevel.Warning); builder.RootComponents.Add("#app"); builder.RootComponents.Add("head::after"); -builder.Services.AddSingleton(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); -builder.Services.AddSingleton(); + + +builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); +builder.Services.AddScoped(); builder.Services.AddProtectedBrowserStorage(); @@ -37,32 +41,40 @@ builder.Services.AddBlazoredLocalStorageAsSingleton(config => config.JsonSerializerOptions.WriteIndented = false; }); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); - -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); - -builder.Services.AddSingleton(); - -builder.Services.AddSingleton(new HttpClient +#if DEBUG +builder.Services.AddGoogleAnalytics("G-S96LW7TVFY"); +#else +builder.Services.AddGoogleAnalytics(builder.Configuration["GA-Tag"]); +#endif + +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +builder.Services.AddScoped(); + + +builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); diff --git a/IGP/_Imports.razor b/IGP/_Imports.razor index 22c0c1c..74a4d0a 100644 --- a/IGP/_Imports.razor +++ b/IGP/_Imports.razor @@ -58,4 +58,7 @@ @using Services.Immortal @using System.Globalization @using System.Reflection -@using System.Timers \ No newline at end of file +@using System.Timers +@using Blazor.Analytics +@using Blazor.Analytics.Components +@using Blazor.Analytics.Abstractions diff --git a/IGP/wwwroot/generated/AgileTaskModels.json b/IGP/wwwroot/generated/AgileTaskModels.json index af482e7..66a9b0a 100644 --- a/IGP/wwwroot/generated/AgileTaskModels.json +++ b/IGP/wwwroot/generated/AgileTaskModels.json @@ -1 +1 @@ -[{"Id":1,"AgileSprintModelId":null,"Name":"Support Safari","Description":"Consider other web browsers.","Notes":"Added","Status":"Todo","Priority":"Low","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":2,"AgileSprintModelId":2,"Name":"Filter Patch Notes","Description":"You should be showing people what they really want to see in the patch notes.","Notes":"Added","Status":"Done","Priority":"Blocker","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":3,"AgileSprintModelId":5,"Name":"Consider Pyre","Description":"Add Pyre Income. Make it so you can take Pyre Camps and Pyre Miners","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-18T00:00:00"},{"Id":4,"AgileSprintModelId":5,"Name":"Optimizations","Description":"Build Calculator should be usable.","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-13T00:00:00"},{"Id":5,"AgileSprintModelId":5,"Name":"Change Attack Timing Interval","Description":"Be able to set attack timing.","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-15T00:00:00"},{"Id":6,"AgileSprintModelId":5,"Name":"Add Pyre Spells","Description":"Make Pyre Spells castable and consume Pyre on build order","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-18T00:00:00"},{"Id":7,"AgileSprintModelId":null,"Name":"Default builds (Rush Thrones)","Description":"Add a dropdown list of default builds.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":8,"AgileSprintModelId":null,"Name":"Load older builds","Description":"Be able to load older builds. How are you going to handle auto correct to current patch?","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":9,"AgileSprintModelId":null,"Name":"How to use Build Calculator step by step","Description":"Need docs","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":10,"AgileSprintModelId":null,"Name":"Compare Health and Damage","Description":"Refer to community example spreadsheet.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":11,"AgileSprintModelId":null,"Name":"Compare Unit\u0027s Damage with it\u0027s own costs","Description":"Refer to community example spreadsheet.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":12,"AgileSprintModelId":4,"Name":"View one unit stats from a link. Make YAML copy and paste","Description":"Design so people can easily copy and paste data into discord","Notes":"Ended up not using exact Yaml. Button in Database controls Detailed vs Plain display ","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":13,"AgileSprintModelId":2,"Name":"Look into SQL","Description":"You really should be using SQL.","Notes":"Agile and Change log pages now use SQL","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":14,"AgileSprintModelId":1,"Name":"Mobile Menu","Description":"You need a real mobile menu. Viewers don\u0027t scroll below the fold, so no one is going to know what happens when you click a button on phones.","Notes":"Added smaller menus for tablets and phones.","Status":"Done","Priority":"High","Task":"Feature","OrderPriority":3,"Created":"2022-02-18T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":15,"AgileSprintModelId":2,"Name":"Acropolis Consume Mote","Description":"The Mote is suppose to be consumed when making a Town Hall.","Notes":"Fixed","Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-02-18T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":16,"AgileSprintModelId":5,"Name":"Multiple Travel Time in Harass Calculator","Description":"Travel time should be based on the amount of bases used. 3 bases is 3 travel times.","Notes":"Add notes...","Status":"Done","Priority":"Low","Task":"Feature","OrderPriority":3,"Created":"2022-02-18T00:00:00","Finished":"2022-04-18T00:00:00"},{"Id":17,"AgileSprintModelId":1,"Name":"Update Database to 0.0.6.8375a","Description":"Xacal tech change, and Hallower damage change. Update Godhead text.","Notes":"Done","Status":"Done","Priority":"None","Task":"Feature","OrderPriority":3,"Created":"2022-02-18T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":18,"AgileSprintModelId":null,"Name":"Patch History Viewer","Description":"Add an ability to compare patches, to see all nerfs and buffs made between them.","Notes":"Inspired by Zkay\u0027s post on discord, where he details a possible \u0027patch history viewer\u0027 implementation.","Status":"Fun_Idea","Priority":"None","Task":"Feature","OrderPriority":5,"Created":"2022-02-16T00:00:00","Finished":null},{"Id":19,"AgileSprintModelId":1,"Name":"Twitch Page","Description":"Did a ~3 hour test stream, and was personal quite happy with the quality. Make Twitch page, and stream patch, sprint planning and development on Sunday.","Notes":"Page added under General, and named \u0022Streams\u0022.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-16T00:00:00","Finished":"2022-02-16T00:00:00"},{"Id":20,"AgileSprintModelId":1,"Name":"Finish the database","Description":"Add more descriptions for everything. Reduce any data duplication with ids. Add upgrade connections. Add ability connections. Add passives and passives connections.","Notes":"Good enough for now","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-11T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":21,"AgileSprintModelId":1,"Name":"Change Log View","Description":"Add a log to view last changes.","Notes":"Added changelog page. Shows Today, X Days Ago, or exact date if patch is over a week old.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-14T00:00:00","Finished":"2022-02-14T00:00:00"},{"Id":22,"AgileSprintModelId":1,"Name":"Agile View","Description":"Add the agile view.","Notes":"Finished.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-11T00:00:00","Finished":"2022-02-17T00:00:00"},{"Id":23,"AgileSprintModelId":1,"Name":"GUID for Ids","Description":"Stop using enums for ids, and start using guids. Enums are just too limited, I lose out on component and inheritance design with them. Replace all your enums with guids, rip off the bandaid.","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-11T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":24,"AgileSprintModelId":1,"Name":"Co-op overview","Description":"Write some sort of blog on co-op gameplay so you have something the feels very content-ish. Maybe make it a video.","Notes":"Finished and released early.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-11T00:00:00","Finished":"2022-02-12T00:00:00"},{"Id":25,"AgileSprintModelId":1,"Name":"Mobile UI","Description":"Make website work on mobile.","Notes":"Should be good. Will test on phone later.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-15T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":26,"AgileSprintModelId":1,"Name":"Add Making Of View","Description":"View to reference UI designs. Nicely encourages the pratice of making the UI code a lot cleaner.","Notes":"Good enough for now","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-11T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":27,"AgileSprintModelId":3,"Name":"Close Nav Menu on Navigation","Description":"Close Nav Menu on Navigation","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":28,"AgileSprintModelId":3,"Name":"Add Passive Descriptions and Passive","Description":"Have to guess on a bunch of passives","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-03-31T00:00:00"},{"Id":29,"AgileSprintModelId":3,"Name":"Tooltips that show referenced units","Description":"I should see any referenced unit by hovering over it","Notes":"Links can now go to links which can go to links.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-04-01T00:00:00"},{"Id":30,"AgileSprintModelId":null,"Name":"Update Logo for Website","Description":"After color scheme is picked","Notes":null,"Status":"Todo","Priority":"Low","Task":"Feature","OrderPriority":2,"Created":"2022-03-27T00:00:00","Finished":null},{"Id":31,"AgileSprintModelId":3,"Name":"Documentation page","Description":"Add documents on how to maintain website","Notes":"Added start of documents","Status":"Done","Priority":"Low","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":32,"AgileSprintModelId":6,"Name":"Test Automation","Description":"Selenium Tests","Notes":"Start adding IDs to everything","Status":"Todo","Priority":"Low","Task":"Feature","OrderPriority":2,"Created":"2022-03-27T00:00:00","Finished":null},{"Id":33,"AgileSprintModelId":6,"Name":"Unit Test","Description":"Add some unit tests","Notes":null,"Status":"Todo","Priority":"Low","Task":"Feature","OrderPriority":2,"Created":"2022-03-27T00:00:00","Finished":null},{"Id":34,"AgileSprintModelId":4,"Name":"Fully Transfer everything to SQL","Description":"Need to regenerate the database once everthing is fully transfered","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-04-09T00:00:00"},{"Id":35,"AgileSprintModelId":3,"Name":"Adding a loading Component","Description":"For JSON loading","Notes":"Added loading component to Agile and Changelog screens","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":36,"AgileSprintModelId":3,"Name":"Optimize Loading of Data","Description":"Currently loading non Agile stuff on Agile page","Notes":"Moved SQL database injection to app root","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":37,"AgileSprintModelId":3,"Name":"Convert Notes to Markdown","Description":"Using Markdown and generating the Note pages seems like a better solution to SQL or hardcoding data","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-04-01T00:00:00"},{"Id":38,"AgileSprintModelId":3,"Name":"Improve Entity Filter Options","Description":"The options I give you is strange, given it filers on Faction type","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-04-01T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":39,"AgileSprintModelId":4,"Name":"Refresh Database Bug","Description":"Database dialog UI isn\u0027t refreshing enough","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-04-03T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":40,"AgileSprintModelId":4,"Name":"Branding Stuff","Description":"Add a schedule, improving branding, etc, ","Notes":"Only improved Twitch overlays","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-03T00:00:00","Finished":"2022-04-10T00:00:00"},{"Id":41,"AgileSprintModelId":4,"Name":"Improve Documents/Notes UI","Description":"Should have a left navigation menu. And prev/next buttons","Notes":"Updated UI. Will added prev/next and breadcrumbs later","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-05T00:00:00","Finished":"2022-04-10T00:00:00"},{"Id":42,"AgileSprintModelId":5,"Name":"Add GitHub links instead of showing code","Description":"For all code examples","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-14T00:00:00"},{"Id":43,"AgileSprintModelId":5,"Name":"Research More used RTS calculations","Description":"What other calculators like the Harass Page can be added","Notes":"Do amount of hits to kill, between two units. Maybe time to regen spell uses","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-14T00:00:00"},{"Id":44,"AgileSprintModelId":5,"Name":"Add Error Toasts to Calculator","Description":"Not enough \u0022Ether\u0022","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-12T00:00:00"},{"Id":45,"AgileSprintModelId":5,"Name":"Handle Divide by Zero in Harass Calculator","Description":"addDescription","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-18T00:00:00"},{"Id":46,"AgileSprintModelId":null,"Name":"Harass Calculator first client experience","Description":"Navigate player though the harass calculator steps","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-10T00:00:00","Finished":null},{"Id":47,"AgileSprintModelId":5,"Name":"Training Queue","Description":"Add training queue times to the build calculator","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-24T00:00:00"},{"Id":48,"AgileSprintModelId":5,"Name":"Refresh Button for Build Calculator","Description":"Refresh to regenerate timeline and charts","Notes":"Adding a loading screen for charts. Remove redundant renders","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-13T00:00:00"},{"Id":49,"AgileSprintModelId":null,"Name":"Gameplay Warning State Toasts","Description":"\u0022You should upgrade your economy.\u0022 \u0022Your using too much ether, spend alloy\u0022","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-10T00:00:00","Finished":null},{"Id":50,"AgileSprintModelId":5,"Name":"Make desktop navigation buttons","Description":"It popping up all the time is a tad tedious","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-12T00:00:00"},{"Id":51,"AgileSprintModelId":5,"Name":"Working Timers","Description":"Toast dismiss timers not making sense. Look into proper Timers","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-13T00:00:00"},{"Id":52,"AgileSprintModelId":5,"Name":"Clean up Build Calculator code","Description":"Code needs to be easily readable so it can be updated, maintained, and optimized","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-12T00:00:00","Finished":null},{"Id":53,"AgileSprintModelId":0,"Name":"Armor Types","Description":"Explain Light, Medium and Heavy armor types, and damage works","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":54,"AgileSprintModelId":0,"Name":"Economy Overview","Description":"How long it takes bases to mine out. How good natruals area","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":55,"AgileSprintModelId":0,"Name":"Timing and Scouting","Description":"Attacking and reacting to what the enemy is doing","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":56,"AgileSprintModelId":0,"Name":"Families, Factions, and Immortal Vanguards","Description":"How factions could be viewed.","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":57,"AgileSprintModelId":0,"Name":"Immortals Spells and Pyre","Description":"Using your Immortal","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":58,"AgileSprintModelId":6,"Name":"Organize Sprint Order","Description":"Sprints should be ordered as, current sprint, previous sprint, backlog, easy tasks, future sprints, old sprints","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":59,"AgileSprintModelId":null,"Name":"Better Sorting Algorithms ","Description":"Be smarted with searching through and sorting lists","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":60,"AgileSprintModelId":6,"Name":"Settings Section","Description":"Add a settings area, for permission and cookie related content","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-14T00:00:00","Finished":"2022-04-24T00:00:00"},{"Id":61,"AgileSprintModelId":6,"Name":"Analytics","Description":"Track client going to each page.","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":62,"AgileSprintModelId":6,"Name":"Cookies","Description":"Cookies to remember a the client permission options ","Notes":"Using local storage instead of cookies.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-14T00:00:00","Finished":"2022-04-24T00:00:00"},{"Id":63,"AgileSprintModelId":6,"Name":"Permission Controls Page","Description":"Allow clients to enable cookies, analytics, and perhaps make things more granular. ","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-14T00:00:00","Finished":"2022-04-24T00:00:00"},{"Id":64,"AgileSprintModelId":6,"Name":"Defaults Page","Description":"Let clients set a cookie for Plain/Detailed view. Perhaps default Immortal. Etc.","Notes":"Calling it Storage Page","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-14T00:00:00","Finished":"2022-04-24T00:00:00"},{"Id":65,"AgileSprintModelId":6,"Name":"Analytics Page","Description":"Let\u0027s have a page that shows the analytics collected during a client\u0027s session","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":66,"AgileSprintModelId":5,"Name":"Economy Comparison","Description":"Compare different economies. Make this a page under resources","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-15T00:00:00","Finished":"2022-04-17T00:00:00"},{"Id":67,"AgileSprintModelId":5,"Name":"[Ctrl \u002B K] Search feature","Description":"WIP. Needs polish","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-16T00:00:00","Finished":"2022-04-16T00:00:00"},{"Id":68,"AgileSprintModelId":6,"Name":"Lighthouse Score","Description":"Lighthouse score is awful. Try to get to the green","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-16T00:00:00","Finished":null},{"Id":69,"AgileSprintModelId":6,"Name":"SEO","Description":"People might be trying to google this website instead of bookmarking it. Make sure its googleable","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-17T00:00:00","Finished":null},{"Id":70,"AgileSprintModelId":6,"Name":"AttacksPerSecond Format Setting","Description":"Make SunSpear\u0027s DPS formatting the default, and allow people to turn it off in settings, for people that don\u0027t like the SBA/APS swapping","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-17T00:00:00","Finished":null},{"Id":71,"AgileSprintModelId":5,"Name":"Fix Cancel Button Giving Money","Description":"Things can be built faster if you cancel","Notes":"addNotes","Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-04-17T00:00:00","Finished":"2022-04-18T00:00:00"},{"Id":72,"AgileSprintModelId":5,"Name":"Calculations Change Answers Over Time","Description":"Obviously a bug in the calculation logic","Notes":"addNotes","Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-04-17T00:00:00","Finished":"2022-04-18T00:00:00"}] \ No newline at end of file +[{"Id":1,"AgileSprintModelId":null,"Name":"Support Safari","Description":"Consider other web browsers.","Notes":"Added","Status":"Todo","Priority":"Low","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":2,"AgileSprintModelId":2,"Name":"Filter Patch Notes","Description":"You should be showing people what they really want to see in the patch notes.","Notes":"Added","Status":"Done","Priority":"Blocker","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":3,"AgileSprintModelId":5,"Name":"Consider Pyre","Description":"Add Pyre Income. Make it so you can take Pyre Camps and Pyre Miners","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-18T00:00:00"},{"Id":4,"AgileSprintModelId":5,"Name":"Optimizations","Description":"Build Calculator should be usable.","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-13T00:00:00"},{"Id":5,"AgileSprintModelId":5,"Name":"Change Attack Timing Interval","Description":"Be able to set attack timing.","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-15T00:00:00"},{"Id":6,"AgileSprintModelId":5,"Name":"Add Pyre Spells","Description":"Make Pyre Spells castable and consume Pyre on build order","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-18T00:00:00"},{"Id":7,"AgileSprintModelId":null,"Name":"Default builds (Rush Thrones)","Description":"Add a dropdown list of default builds.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":8,"AgileSprintModelId":null,"Name":"Load older builds","Description":"Be able to load older builds. How are you going to handle auto correct to current patch?","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":9,"AgileSprintModelId":null,"Name":"How to use Build Calculator step by step","Description":"Need docs","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":10,"AgileSprintModelId":null,"Name":"Compare Health and Damage","Description":"Refer to community example spreadsheet.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":11,"AgileSprintModelId":null,"Name":"Compare Unit\u0027s Damage with it\u0027s own costs","Description":"Refer to community example spreadsheet.","Notes":"Add notes...","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":12,"AgileSprintModelId":4,"Name":"View one unit stats from a link. Make YAML copy and paste","Description":"Design so people can easily copy and paste data into discord","Notes":"Ended up not using exact Yaml. Button in Database controls Detailed vs Plain display ","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":13,"AgileSprintModelId":2,"Name":"Look into SQL","Description":"You really should be using SQL.","Notes":"Agile and Change log pages now use SQL","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-20T00:00:00","Finished":null},{"Id":14,"AgileSprintModelId":1,"Name":"Mobile Menu","Description":"You need a real mobile menu. Viewers don\u0027t scroll below the fold, so no one is going to know what happens when you click a button on phones.","Notes":"Added smaller menus for tablets and phones.","Status":"Done","Priority":"High","Task":"Feature","OrderPriority":3,"Created":"2022-02-18T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":15,"AgileSprintModelId":2,"Name":"Acropolis Consume Mote","Description":"The Mote is suppose to be consumed when making a Town Hall.","Notes":"Fixed","Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-02-18T00:00:00","Finished":"2022-02-20T00:00:00"},{"Id":16,"AgileSprintModelId":5,"Name":"Multiple Travel Time in Harass Calculator","Description":"Travel time should be based on the amount of bases used. 3 bases is 3 travel times.","Notes":"Add notes...","Status":"Done","Priority":"Low","Task":"Feature","OrderPriority":3,"Created":"2022-02-18T00:00:00","Finished":"2022-04-18T00:00:00"},{"Id":17,"AgileSprintModelId":1,"Name":"Update Database to 0.0.6.8375a","Description":"Xacal tech change, and Hallower damage change. Update Godhead text.","Notes":"Done","Status":"Done","Priority":"None","Task":"Feature","OrderPriority":3,"Created":"2022-02-18T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":18,"AgileSprintModelId":null,"Name":"Patch History Viewer","Description":"Add an ability to compare patches, to see all nerfs and buffs made between them.","Notes":"Inspired by Zkay\u0027s post on discord, where he details a possible \u0027patch history viewer\u0027 implementation.","Status":"Fun_Idea","Priority":"None","Task":"Feature","OrderPriority":5,"Created":"2022-02-16T00:00:00","Finished":null},{"Id":19,"AgileSprintModelId":1,"Name":"Twitch Page","Description":"Did a ~3 hour test stream, and was personal quite happy with the quality. Make Twitch page, and stream patch, sprint planning and development on Sunday.","Notes":"Page added under General, and named \u0022Streams\u0022.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-16T00:00:00","Finished":"2022-02-16T00:00:00"},{"Id":20,"AgileSprintModelId":1,"Name":"Finish the database","Description":"Add more descriptions for everything. Reduce any data duplication with ids. Add upgrade connections. Add ability connections. Add passives and passives connections.","Notes":"Good enough for now","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-11T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":21,"AgileSprintModelId":1,"Name":"Change Log View","Description":"Add a log to view last changes.","Notes":"Added changelog page. Shows Today, X Days Ago, or exact date if patch is over a week old.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-14T00:00:00","Finished":"2022-02-14T00:00:00"},{"Id":22,"AgileSprintModelId":1,"Name":"Agile View","Description":"Add the agile view.","Notes":"Finished.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-11T00:00:00","Finished":"2022-02-17T00:00:00"},{"Id":23,"AgileSprintModelId":1,"Name":"GUID for Ids","Description":"Stop using enums for ids, and start using guids. Enums are just too limited, I lose out on component and inheritance design with them. Replace all your enums with guids, rip off the bandaid.","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-11T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":24,"AgileSprintModelId":1,"Name":"Co-op overview","Description":"Write some sort of blog on co-op gameplay so you have something the feels very content-ish. Maybe make it a video.","Notes":"Finished and released early.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-11T00:00:00","Finished":"2022-02-12T00:00:00"},{"Id":25,"AgileSprintModelId":1,"Name":"Mobile UI","Description":"Make website work on mobile.","Notes":"Should be good. Will test on phone later.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-15T00:00:00","Finished":"2022-02-18T00:00:00"},{"Id":26,"AgileSprintModelId":1,"Name":"Add Making Of View","Description":"View to reference UI designs. Nicely encourages the pratice of making the UI code a lot cleaner.","Notes":"Good enough for now","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-02-11T00:00:00","Finished":"2022-02-19T00:00:00"},{"Id":27,"AgileSprintModelId":3,"Name":"Close Nav Menu on Navigation","Description":"Close Nav Menu on Navigation","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":28,"AgileSprintModelId":3,"Name":"Add Passive Descriptions and Passive","Description":"Have to guess on a bunch of passives","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-03-31T00:00:00"},{"Id":29,"AgileSprintModelId":3,"Name":"Tooltips that show referenced units","Description":"I should see any referenced unit by hovering over it","Notes":"Links can now go to links which can go to links.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-04-01T00:00:00"},{"Id":30,"AgileSprintModelId":null,"Name":"Update Logo for Website","Description":"After color scheme is picked","Notes":null,"Status":"Todo","Priority":"Low","Task":"Feature","OrderPriority":2,"Created":"2022-03-27T00:00:00","Finished":null},{"Id":31,"AgileSprintModelId":3,"Name":"Documentation page","Description":"Add documents on how to maintain website","Notes":"Added start of documents","Status":"Done","Priority":"Low","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":32,"AgileSprintModelId":6,"Name":"Test Automation","Description":"Selenium Tests","Notes":"Start adding IDs to everything","Status":"Todo","Priority":"Low","Task":"Feature","OrderPriority":2,"Created":"2022-03-27T00:00:00","Finished":null},{"Id":33,"AgileSprintModelId":6,"Name":"Unit Test","Description":"Add some unit tests","Notes":null,"Status":"Todo","Priority":"Low","Task":"Feature","OrderPriority":2,"Created":"2022-03-27T00:00:00","Finished":null},{"Id":34,"AgileSprintModelId":4,"Name":"Fully Transfer everything to SQL","Description":"Need to regenerate the database once everthing is fully transfered","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-04-09T00:00:00"},{"Id":35,"AgileSprintModelId":3,"Name":"Adding a loading Component","Description":"For JSON loading","Notes":"Added loading component to Agile and Changelog screens","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":36,"AgileSprintModelId":3,"Name":"Optimize Loading of Data","Description":"Currently loading non Agile stuff on Agile page","Notes":"Moved SQL database injection to app root","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-03-27T00:00:00"},{"Id":37,"AgileSprintModelId":3,"Name":"Convert Notes to Markdown","Description":"Using Markdown and generating the Note pages seems like a better solution to SQL or hardcoding data","Notes":null,"Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-03-27T00:00:00","Finished":"2022-04-01T00:00:00"},{"Id":38,"AgileSprintModelId":3,"Name":"Improve Entity Filter Options","Description":"The options I give you is strange, given it filers on Faction type","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-04-01T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":39,"AgileSprintModelId":4,"Name":"Refresh Database Bug","Description":"Database dialog UI isn\u0027t refreshing enough","Notes":null,"Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-04-03T00:00:00","Finished":"2022-04-03T00:00:00"},{"Id":40,"AgileSprintModelId":4,"Name":"Branding Stuff","Description":"Add a schedule, improving branding, etc, ","Notes":"Only improved Twitch overlays","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-03T00:00:00","Finished":"2022-04-10T00:00:00"},{"Id":41,"AgileSprintModelId":4,"Name":"Improve Documents/Notes UI","Description":"Should have a left navigation menu. And prev/next buttons","Notes":"Updated UI. Will added prev/next and breadcrumbs later","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-05T00:00:00","Finished":"2022-04-10T00:00:00"},{"Id":42,"AgileSprintModelId":5,"Name":"Add GitHub links instead of showing code","Description":"For all code examples","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-14T00:00:00"},{"Id":43,"AgileSprintModelId":5,"Name":"Research More used RTS calculations","Description":"What other calculators like the Harass Page can be added","Notes":"Do amount of hits to kill, between two units. Maybe time to regen spell uses","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-14T00:00:00"},{"Id":44,"AgileSprintModelId":5,"Name":"Add Error Toasts to Calculator","Description":"Not enough \u0022Ether\u0022","Notes":"Add notes...","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-12T00:00:00"},{"Id":45,"AgileSprintModelId":5,"Name":"Handle Divide by Zero in Harass Calculator","Description":"addDescription","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-18T00:00:00"},{"Id":46,"AgileSprintModelId":null,"Name":"Harass Calculator first client experience","Description":"Navigate player though the harass calculator steps","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-10T00:00:00","Finished":null},{"Id":47,"AgileSprintModelId":5,"Name":"Training Queue","Description":"Add training queue times to the build calculator","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-24T00:00:00"},{"Id":48,"AgileSprintModelId":5,"Name":"Refresh Button for Build Calculator","Description":"Refresh to regenerate timeline and charts","Notes":"Adding a loading screen for charts. Remove redundant renders","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-13T00:00:00"},{"Id":49,"AgileSprintModelId":null,"Name":"Gameplay Warning State Toasts","Description":"\u0022You should upgrade your economy.\u0022 \u0022Your using too much ether, spend alloy\u0022","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-10T00:00:00","Finished":null},{"Id":50,"AgileSprintModelId":5,"Name":"Make desktop navigation buttons","Description":"It popping up all the time is a tad tedious","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-12T00:00:00"},{"Id":51,"AgileSprintModelId":5,"Name":"Working Timers","Description":"Toast dismiss timers not making sense. Look into proper Timers","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-10T00:00:00","Finished":"2022-04-13T00:00:00"},{"Id":52,"AgileSprintModelId":5,"Name":"Clean up Build Calculator code","Description":"Code needs to be easily readable so it can be updated, maintained, and optimized","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-12T00:00:00","Finished":null},{"Id":53,"AgileSprintModelId":0,"Name":"Armor Types","Description":"Explain Light, Medium and Heavy armor types, and damage works","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":54,"AgileSprintModelId":0,"Name":"Economy Overview","Description":"How long it takes bases to mine out. How good natruals area","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":55,"AgileSprintModelId":0,"Name":"Timing and Scouting","Description":"Attacking and reacting to what the enemy is doing","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":56,"AgileSprintModelId":0,"Name":"Families, Factions, and Immortal Vanguards","Description":"How factions could be viewed.","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":57,"AgileSprintModelId":0,"Name":"Immortals Spells and Pyre","Description":"Using your Immortal","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Document","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":58,"AgileSprintModelId":6,"Name":"Organize Sprint Order","Description":"Sprints should be ordered as, current sprint, previous sprint, backlog, easy tasks, future sprints, old sprints","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":59,"AgileSprintModelId":null,"Name":"Better Sorting Algorithms ","Description":"Be smarted with searching through and sorting lists","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-13T00:00:00","Finished":null},{"Id":60,"AgileSprintModelId":6,"Name":"Settings Section","Description":"Add a settings area, for permission and cookie related content","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-14T00:00:00","Finished":"2022-04-24T00:00:00"},{"Id":61,"AgileSprintModelId":6,"Name":"Analytics","Description":"Track client going to each page.","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-14T00:00:00","Finished":"2022-04-25T00:00:00"},{"Id":62,"AgileSprintModelId":6,"Name":"Cookies","Description":"Cookies to remember a the client permission options ","Notes":"Using local storage instead of cookies.","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-14T00:00:00","Finished":"2022-04-24T00:00:00"},{"Id":63,"AgileSprintModelId":6,"Name":"Permission Controls Page","Description":"Allow clients to enable cookies, analytics, and perhaps make things more granular. ","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-14T00:00:00","Finished":"2022-04-24T00:00:00"},{"Id":64,"AgileSprintModelId":6,"Name":"Defaults Page","Description":"Let clients set a cookie for Plain/Detailed view. Perhaps default Immortal. Etc.","Notes":"Calling it Storage Page","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-14T00:00:00","Finished":"2022-04-24T00:00:00"},{"Id":65,"AgileSprintModelId":null,"Name":"Analytics Page","Description":"Let\u0027s have a page that shows the analytics collected during a client\u0027s session","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-14T00:00:00","Finished":null},{"Id":66,"AgileSprintModelId":5,"Name":"Economy Comparison","Description":"Compare different economies. Make this a page under resources","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-15T00:00:00","Finished":"2022-04-17T00:00:00"},{"Id":67,"AgileSprintModelId":5,"Name":"[Ctrl \u002B K] Search feature","Description":"WIP. Needs polish","Notes":"addNotes","Status":"Done","Priority":"Medium","Task":"Feature","OrderPriority":3,"Created":"2022-04-16T00:00:00","Finished":"2022-04-16T00:00:00"},{"Id":68,"AgileSprintModelId":6,"Name":"Lighthouse Score","Description":"Lighthouse score is awful. Try to get to the green","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-16T00:00:00","Finished":null},{"Id":69,"AgileSprintModelId":6,"Name":"SEO","Description":"People might be trying to google this website instead of bookmarking it. Make sure its googleable","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-17T00:00:00","Finished":null},{"Id":70,"AgileSprintModelId":6,"Name":"AttacksPerSecond Format Setting","Description":"Make SunSpear\u0027s DPS formatting the default, and allow people to turn it off in settings, for people that don\u0027t like the SBA/APS swapping","Notes":"addNotes","Status":"Todo","Priority":"Medium","Task":"Feature","OrderPriority":2,"Created":"2022-04-17T00:00:00","Finished":null},{"Id":71,"AgileSprintModelId":5,"Name":"Fix Cancel Button Giving Money","Description":"Things can be built faster if you cancel","Notes":"addNotes","Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-04-17T00:00:00","Finished":"2022-04-18T00:00:00"},{"Id":72,"AgileSprintModelId":5,"Name":"Calculations Change Answers Over Time","Description":"Obviously a bug in the calculation logic","Notes":"addNotes","Status":"Done","Priority":"High","Task":"Bug","OrderPriority":3,"Created":"2022-04-17T00:00:00","Finished":"2022-04-18T00:00:00"}] \ No newline at end of file diff --git a/IGP/wwwroot/generated/WebPageModels.json b/IGP/wwwroot/generated/WebPageModels.json index 752ac0d..dac45f8 100644 --- a/IGP/wwwroot/generated/WebPageModels.json +++ b/IGP/wwwroot/generated/WebPageModels.json @@ -1 +1 @@ -[{"Id":1,"WebSectionModelId":2,"Name":"Database","Description":"Database of game information","Href":"database","IsPrivate":"False"},{"Id":2,"WebSectionModelId":1,"Name":"Build Calculator","Description":"Build order calculator for determining army timings","Href":"build-calculator","IsPrivate":"False"},{"Id":3,"WebSectionModelId":1,"Name":"Harass Calculator","Description":"Alloy harassment calculator","Href":"harass-calculator","IsPrivate":"False"},{"Id":4,"WebSectionModelId":1,"Name":"Memory Tester","Description":"Testing memory","Href":"memory-tester","IsPrivate":"False"},{"Id":5,"WebSectionModelId":1,"Name":"Comparion Charts","Description":"Ecnomy charts to compare build orders","Href":"comparison-charts","IsPrivate":"True"},{"Id":6,"WebSectionModelId":2,"Name":"Notes","Description":"General player notes","Href":"notes","IsPrivate":"False"},{"Id":7,"WebSectionModelId":2,"Name":"Key Mapping","Description":"General key mapping info","Href":"keymapping","IsPrivate":"True"},{"Id":8,"WebSectionModelId":4,"Name":"Road Map","Description":"Plans for this website","Href":"roadmap","IsPrivate":"False"},{"Id":9,"WebSectionModelId":4,"Name":"Change Log","Description":"Past updates to the website","Href":"changelog","IsPrivate":"False"},{"Id":10,"WebSectionModelId":4,"Name":"Agile","Description":"Showing agile view of this website","Href":"agile","IsPrivate":"False"},{"Id":11,"WebSectionModelId":4,"Name":"Making Of","Description":"Explaining development details of this website","Href":"makingof","IsPrivate":"False"},{"Id":12,"WebSectionModelId":2,"Name":"Documentation","Description":"Explaining how to use this website","Href":"documentation","IsPrivate":"True"},{"Id":13,"WebSectionModelId":3,"Name":"About","Description":"Answering general questions on the website","Href":"about","IsPrivate":"False"},{"Id":14,"WebSectionModelId":3,"Name":"Contact","Description":"My contact info","Href":"contact","IsPrivate":"False"},{"Id":15,"WebSectionModelId":3,"Name":"Streams","Description":"Stream info","Href":"streams","IsPrivate":"False"},{"Id":16,"WebSectionModelId":4,"Name":"Documentation","Description":"Development information","Href":"docs","IsPrivate":"False"},{"Id":17,"WebSectionModelId":5,"Name":"Permissions","Description":"Permission Settings","Href":"permissions","IsPrivate":"False"},{"Id":18,"WebSectionModelId":5,"Name":"Data Collection","Description":"Data Collection Settings","Href":"data-collection","IsPrivate":"False"},{"Id":19,"WebSectionModelId":5,"Name":"Storage","Description":"Storage Settings","Href":"storage","IsPrivate":"False"},{"Id":20,"WebSectionModelId":1,"Name":"Economy Comparison","Description":"Compare economies","Href":"economy-comparison","IsPrivate":"False"}] \ No newline at end of file +[{"Id":1,"WebSectionModelId":2,"Name":"Database","Description":"Database of game information","Href":"database","IsPrivate":"False"},{"Id":2,"WebSectionModelId":1,"Name":"Build Calculator","Description":"Build order calculator for determining army timings","Href":"build-calculator","IsPrivate":"False"},{"Id":3,"WebSectionModelId":1,"Name":"Harass Calculator","Description":"Alloy harassment calculator","Href":"harass-calculator","IsPrivate":"False"},{"Id":4,"WebSectionModelId":1,"Name":"Memory Tester","Description":"Testing memory","Href":"memory-tester","IsPrivate":"False"},{"Id":5,"WebSectionModelId":1,"Name":"Comparion Charts","Description":"Ecnomy charts to compare build orders","Href":"comparison-charts","IsPrivate":"True"},{"Id":6,"WebSectionModelId":2,"Name":"Notes","Description":"General player notes","Href":"notes","IsPrivate":"False"},{"Id":7,"WebSectionModelId":2,"Name":"Key Mapping","Description":"General key mapping info","Href":"keymapping","IsPrivate":"True"},{"Id":8,"WebSectionModelId":4,"Name":"Road Map","Description":"Plans for this website","Href":"roadmap","IsPrivate":"False"},{"Id":9,"WebSectionModelId":4,"Name":"Change Log","Description":"Past updates to the website","Href":"changelog","IsPrivate":"False"},{"Id":10,"WebSectionModelId":4,"Name":"Agile","Description":"Showing agile view of this website","Href":"agile","IsPrivate":"False"},{"Id":11,"WebSectionModelId":4,"Name":"Making Of","Description":"Explaining development details of this website","Href":"makingof","IsPrivate":"False"},{"Id":12,"WebSectionModelId":2,"Name":"Documentation","Description":"Explaining how to use this website","Href":"documentation","IsPrivate":"True"},{"Id":13,"WebSectionModelId":3,"Name":"About","Description":"Answering general questions on the website","Href":"about","IsPrivate":"False"},{"Id":14,"WebSectionModelId":3,"Name":"Contact","Description":"My contact info","Href":"contact","IsPrivate":"False"},{"Id":15,"WebSectionModelId":3,"Name":"Streams","Description":"Stream info","Href":"streams","IsPrivate":"False"},{"Id":16,"WebSectionModelId":4,"Name":"Documentation","Description":"Development information","Href":"docs","IsPrivate":"False"},{"Id":17,"WebSectionModelId":5,"Name":"Permissions","Description":"Permission Settings","Href":"permissions","IsPrivate":"False"},{"Id":18,"WebSectionModelId":5,"Name":"Data Collection","Description":"Data Collection Settings","Href":"data-collection","IsPrivate":"True"},{"Id":19,"WebSectionModelId":5,"Name":"Storage","Description":"Storage Settings","Href":"storage","IsPrivate":"False"},{"Id":20,"WebSectionModelId":1,"Name":"Economy Comparison","Description":"Compare economies","Href":"economy-comparison","IsPrivate":"False"}] \ No newline at end of file diff --git a/IGP/wwwroot/index.html b/IGP/wwwroot/index.html index fbeb2d0..1537ee3 100644 --- a/IGP/wwwroot/index.html +++ b/IGP/wwwroot/index.html @@ -31,6 +31,7 @@ integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js"> +