Browse Source

Merge branch 'develop' into main

main
Jonathan McCaffrey 4 years ago
parent
commit
8c06fdd120
  1. 11
      .vscode/launch.json
  2. 41
      .vscode/tasks.json
  3. 2
      Components/Display/CodeComponent.razor
  4. 10
      Components/Display/DevOnlyComponent.razor
  5. 4
      Components/Display/EntityDisplayComponent.razor
  6. 5
      Components/Display/InfoTooltipComponent.razor
  7. 10
      Components/Display/MakingOfComponent.razor
  8. 4
      Components/Display/MakingOfSectionComponent.razor
  9. 10
      Components/Display/PaperComponent.razor
  10. 4
      Components/Form/FormDisplayComponent.razor
  11. 4
      Components/Form/FormEscapeCodeComponent.razor
  12. 12
      Components/Form/FormGuessComponent.razor
  13. 6
      Components/Inputs/ButtonComponent.razor
  14. 4
      Components/Inputs/ButtonGroupComponent.razor
  15. 6
      Components/Inputs/EntityLabelComponent.razor
  16. 58
      Components/Layout/LayoutWithSidebarComponent.razor
  17. 2
      Components/Layout/PageContainerComponent.razor
  18. 17
      Components/MarkdownContent/MarkdownContent.razor
  19. 8
      Components/Navigation/DesktopNavComponent.razor
  20. 36
      Components/Navigation/MobileNavComponent.razor
  21. 11
      Components/Navigation/NavLinkComponent.razor
  22. 4
      Components/Navigation/NavSectionComponent.razor
  23. 16
      Components/Navigation/TabletNavComponent.razor
  24. 6
      Components/Shared/DisplayableContent.razor
  25. 4
      Components/Shared/DisplayableRoute.razor
  26. 4
      Components/Shared/MathDivisionComponent.razor
  27. 6
      Components/Shared/MathLoopSumComponent.razor
  28. 2
      Components/Shared/SpoilerTextComponent.razor
  29. 34
      Contexts/DatabaseContext.cs
  30. 33
      IGP/App.razor
  31. BIN
      IGP/Database.db
  32. 52
      IGP/Dialog/EntityDialogComponent.razor
  33. 27
      IGP/IGP.csproj
  34. 4
      IGP/Index.razor
  35. 53
      IGP/PageLayout.razor
  36. 77
      IGP/Pages/Agile/AgilePage.razor
  37. 2
      IGP/Pages/Agile/AgilePage.razor.css
  38. 29
      IGP/Pages/Agile/Parts/BacklogComponent.razor
  39. 46
      IGP/Pages/Agile/Parts/SprintComponent.razor
  40. 106
      IGP/Pages/BuildCalculator/BuildCalculatorPage.razor
  41. 37
      IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor
  42. 16
      IGP/Pages/BuildCalculator/Parts/BankComponent.razor
  43. 19
      IGP/Pages/BuildCalculator/Parts/BuildOrderComponent.razor
  44. 61
      IGP/Pages/BuildCalculator/Parts/ChartComponent.razor
  45. 28
      IGP/Pages/BuildCalculator/Parts/EntityClickViewComponent.razor
  46. 18
      IGP/Pages/BuildCalculator/Parts/FilterComponent.razor
  47. 30
      IGP/Pages/BuildCalculator/Parts/HighlightsComponent.razor
  48. 131
      IGP/Pages/BuildCalculator/Parts/HotkeyViewerComponent.razor
  49. 10
      IGP/Pages/BuildCalculator/Parts/InputPanelComponent.razor
  50. 16
      IGP/Pages/BuildCalculator/Parts/TimelineComponent.razor
  51. 27
      IGP/Pages/BuildCalculator/Parts/TimingComponent.razor
  52. 54
      IGP/Pages/ChangeLogPage.razor
  53. 31
      IGP/Pages/Comparision/ComparisionPage.razor
  54. 11
      IGP/Pages/Comparision/Parts/BuildLoaderComponent.razor
  55. 8
      IGP/Pages/Comparision/Parts/SandComponent.razor
  56. 2
      IGP/Pages/ContactPage.razor
  57. 108
      IGP/Pages/Database/DatabasePage.razor
  58. 39
      IGP/Pages/Database/DatabaseSinglePage.razor
  59. 7
      IGP/Pages/Database/Entity/EntityViewComponent.razor
  60. 64
      IGP/Pages/Database/Entity/Parts/EntityAbilitiesComponent.razor
  61. 19
      IGP/Pages/Database/Entity/Parts/EntityHeaderComponent.razor
  62. 41
      IGP/Pages/Database/Entity/Parts/EntityInfoComponent.razor
  63. 10
      IGP/Pages/Database/Entity/Parts/EntityMechanicsComponent.razor
  64. 72
      IGP/Pages/Database/Entity/Parts/EntityPassivesComponent.razor
  65. 249
      IGP/Pages/Database/Entity/Parts/EntityProductionComponent.razor
  66. 40
      IGP/Pages/Database/Entity/Parts/EntityPyreSpellsComponent.razor
  67. 149
      IGP/Pages/Database/Entity/Parts/EntityStatsComponent.razor
  68. 21
      IGP/Pages/Database/Entity/Parts/EntityUpgradesComponent.razor
  69. 30
      IGP/Pages/Database/Entity/Parts/EntityVanguardAddedComponent.razor
  70. 23
      IGP/Pages/Database/Entity/Parts/EntityVanguardsComponent.razor
  71. 322
      IGP/Pages/Database/Entity/Parts/EntityWeaponsComponent.razor
  72. 57
      IGP/Pages/Database/Parts/EntityFilterComponent.razor
  73. 115
      IGP/Pages/Documentation/DocumentationIndexPage.razor
  74. 112
      IGP/Pages/Documentation/DocumentationPage.razor
  75. 35
      IGP/Pages/Documentation/Parts/DocumentComponent.razor
  76. 70
      IGP/Pages/Documentation/Parts/DocumentInnerNavComponent.razor
  77. 46
      IGP/Pages/Documentation/Parts/DocumentNavComponent.razor
  78. 33
      IGP/Pages/HarassCalculatorPage.razor
  79. 82
      IGP/Pages/Home/HomePage.razor
  80. 76
      IGP/Pages/Home/Parts/ContentHighlightComponent.razor
  81. 149
      IGP/Pages/HomePage.razor
  82. 26
      IGP/Pages/MakingOf/Parts/MakingOfColours.razor
  83. 2
      IGP/Pages/MakingOf/Parts/MakingOfDialogs.razor
  84. 9
      IGP/Pages/MakingOf/Parts/MakingOfDisplays.razor
  85. 2
      IGP/Pages/MakingOf/Parts/MakingOfFeedback.razor
  86. 40
      IGP/Pages/MemoryTester/Parts/UnitMemory.razor
  87. 31
      IGP/Pages/MemoryTester/Parts/UnitMemoryManager.razor
  88. 140
      IGP/Pages/Notes/NotesIndexPage.razor
  89. 126
      IGP/Pages/Notes/NotesPage.razor
  90. 35
      IGP/Pages/Notes/Parts/NoteComponent.razor
  91. 75
      IGP/Pages/Notes/Parts/NoteInnerNavComponent.razor
  92. 43
      IGP/Pages/Notes/Parts/NoteNavComponent.razor
  93. 3
      IGP/Pages/RoadMap/Parts/RoadMapComponent.razor
  94. 3
      IGP/Pages/RoadMap/RoadMapPage.razor
  95. 229
      IGP/Pages/SandboxPage.razor
  96. 9
      IGP/Portals/EntityDialogPortal.razor
  97. 15
      IGP/Program.cs
  98. 44
      IGP/_Imports.razor
  99. 6
      IGP/wwwroot/css/app.css
  100. 1
      IGP/wwwroot/generated/AgileSprintModels.json
  101. Some files were not shown because too many files have changed in this diff Show More

11
.vscode/launch.json vendored

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch and Debug Standalone Blazor WebAssembly App",
"type": "blazorwasm",
"request": "launch",
"cwd": "${workspaceFolder}/IGP"
}
]
}

41
.vscode/tasks.json vendored

@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/IGP/IGP.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/IGP/IGP.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/IGP/IGP.csproj"
],
"problemMatcher": "$msCompile"
}
]
}

2
Components/Display/CodeComponent.razor

@ -22,6 +22,6 @@
@code { @code {
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
} }

10
Components/Display/DevOnlyComponent.razor

@ -1,4 +1,4 @@
@if (IsOnDev) { @if (isOnDev) {
<div class="devOnlyContainer"> <div class="devOnlyContainer">
<div class="devOnlyTitleContainer"> <div class="devOnlyTitleContainer">
<div class="devOnlyTitle"> <div class="devOnlyTitle">
@ -58,15 +58,15 @@
@code { @code {
[Inject] [Inject]
NavigationManager NavigationManager { get; set; } NavigationManager NavigationManager { get; set; } = default!;
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
bool IsOnDev; bool isOnDev;
protected override void OnInitialized() { protected override void OnInitialized() {
IsOnDev = NavigationManager.BaseUri.Contains("https://localhost"); isOnDev = NavigationManager.BaseUri.Contains("https://localhost");
} }
} }

4
Components/Display/EntityDisplayComponent.razor

@ -70,9 +70,9 @@
@code { @code {
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
[Parameter] [Parameter]
public string Title { get; set; } public string Title { get; set; } = default!;
} }

5
Components/Display/InfoTooltipComponent.razor

@ -50,15 +50,16 @@
margin-bottom: 20px; margin-bottom: 20px;
position: absolute; position: absolute;
} }
}
</style> </style>
@code { @code {
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
[Parameter] [Parameter]
public string InfoText { get; set; } public string InfoText { get; set; } = default!;
[Parameter] [Parameter]
public int? Margin { get; set; } public int? Margin { get; set; }

10
Components/Display/MakingOfComponent.razor

@ -98,19 +98,19 @@
@code { @code {
[Parameter] [Parameter]
public RenderFragment Title { get; set; } public RenderFragment Title { get; set; } = default!;
[Parameter] [Parameter]
public RenderFragment Description { get; set; } public RenderFragment Description { get; set; } = default!;
[Parameter] [Parameter]
public RenderFragment Example { get; set; } public RenderFragment Example { get; set; } = default!;
[Parameter] [Parameter]
public RenderFragment Usage { get; set; } public RenderFragment Usage { get; set; } = default!;
[Parameter] [Parameter]
public RenderFragment Code { get; set; } public RenderFragment Code { get; set; } = default!;
} }

4
Components/Display/MakingOfSectionComponent.razor

@ -23,10 +23,10 @@
@code { @code {
[Parameter] [Parameter]
public string Title { get; set; } public string Title { get; set; } = default!;
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
} }

10
Components/Display/PaperComponent.razor

@ -1,29 +1,27 @@
<div class="paper"> <div class="paperDisplay">
@ChildContent @ChildContent
</div> </div>
<style> <style>
.paper { .paperDisplay {
padding-top: 24px; padding-top: 24px;
padding-left: 24px; padding-left: 24px;
padding-right: 24px; padding-right: 24px;
padding-bottom: 24px; padding-bottom: 24px;
margin: auto;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
border: 4px solid var(--paper-border); border: 4px solid var(--paper-border);
background-color: var(--paper); background-color: var(--paper);
box-shadow: 0px 6px var(--paper-border); box-shadow: 0px 6px var(--paper-border);
width: 100%;
} }
</style> </style>
@code { @code {
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
[Parameter] [Parameter]
public string Title { get; set; } public string Title { get; set; } = default!;
} }

4
Components/Form/FormDisplayComponent.razor

@ -35,10 +35,10 @@
@code { @code {
//TODO Clean up //TODO Clean up
[Parameter] [Parameter]
public string Label { get; set; } public string Label { get; set; } = default!;
[Parameter] [Parameter]
public string Info { get; set; } public string Info { get; set; } = default!;
[Parameter] [Parameter]
public RenderFragment? Display { get; set; } public RenderFragment? Display { get; set; }

4
Components/Form/FormEscapeCodeComponent.razor

@ -21,8 +21,8 @@
string Output = ""; string Output = "";
public void OnChange(ChangeEventArgs changeEventArgs) { public void OnChange(ChangeEventArgs changeEventArgs) {
var encoded = HttpUtility.HtmlEncode(changeEventArgs.Value.ToString()); var encoded = HttpUtility.HtmlEncode(changeEventArgs.Value!.ToString());
Output = encoded.Replace("@", "@@"); Output = encoded?.Replace("@", "@@")!;
Output = Output.Replace("\n", "<br />"); Output = Output.Replace("\n", "<br />");
} }

12
Components/Form/FormGuessComponent.razor

@ -1,6 +1,6 @@
@using Services @using Services
@using Services.Immortal @using Services.Immortal
@using Model.Immortal.MemoryTester @using Model.MemoryTester
@implements IDisposable @implements IDisposable
@inject IMemoryTesterService MemoryTesterService @inject IMemoryTesterService MemoryTesterService
@ -13,7 +13,7 @@
} }
<div> <div>
<input readonly="@MemoryQuestion.IsRevealed" <input readonly="@MemoryQuestion.IsRevealed"
class="formTextInput @(MemoryQuestion.IsRevealed ? "revealed" : IsSubmitted == false ? "guess" : int.Parse(guess) == MemoryQuestion.Answer ? "correct" : "wrong")" class="formTextInput @(MemoryQuestion.IsRevealed ? "revealed" : IsSubmitted == false ? "guess" : int.Parse(guess ?? string.Empty) == MemoryQuestion.Answer ? "correct" : "wrong")"
placeholder="guess..." placeholder="guess..."
type="number" type="number"
value="@guess" value="@guess"
@ -80,16 +80,16 @@
public string Info { get; set; } = ""; public string Info { get; set; } = "";
[Parameter] [Parameter]
public EventCallback<AnswerEventArgs> OnChange { get; set; } public EventCallback<AnswerEventArgs> OnChange { get; set; } = default!;
[Parameter] [Parameter]
public MemoryQuestionModel MemoryQuestion { get; set; } public MemoryQuestionModel MemoryQuestion { get; set; } = default!;
[Parameter] [Parameter]
public bool IsSubmitted { get; set; } public bool IsSubmitted { get; set; }
private string guess { get; set; } = ""; private string? guess = "";
private string labelId = ""; private string labelId = "";
@ -142,7 +142,7 @@
} }
void OnGuessChanged(ChangeEventArgs changeEventArgs) { void OnGuessChanged(ChangeEventArgs changeEventArgs) {
guess = changeEventArgs.Value.ToString(); guess = changeEventArgs.Value!.ToString()!;
OnChange.InvokeAsync(new AnswerEventArgs { OnChange.InvokeAsync(new AnswerEventArgs {
Name = MemoryQuestion.Name, Name = MemoryQuestion.Name,

6
Components/Inputs/ButtonComponent.razor

@ -37,13 +37,13 @@
@code { @code {
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
[Parameter] [Parameter]
public EventCallback<EventArgs> OnClick { get; set; } public EventCallback<EventArgs> OnClick { get; set; } = default!;
[Parameter] [Parameter]
public ButtonType ButtonType { get; set; } public ButtonType ButtonType { get; set; } = default!;
private void ButtonClicked(EventArgs eventArgs) { private void ButtonClicked(EventArgs eventArgs) {
OnClick.InvokeAsync(eventArgs); OnClick.InvokeAsync(eventArgs);

4
Components/Inputs/ButtonGroupComponent.razor

@ -68,10 +68,10 @@
@code { @code {
[Parameter] [Parameter]
public string Choice { get; set; } public string Choice { get; set; } = default!;
[Parameter] [Parameter]
public List<string> Choices { get; set; } public List<string> Choices { get; set; } = default!;
[Parameter] [Parameter]
public EventCallback<string> OnClick { get; set; } public EventCallback<string> OnClick { get; set; }

6
Components/Inputs/EntityLabelComponent.razor

@ -1,7 +1,7 @@
@using Model.Immortal.Entity @using Model.Entity
@using Services.Website @using Services.Website
@using System.ComponentModel.DataAnnotations @using System.ComponentModel.DataAnnotations
@using Model.Immortal.Entity.Data @using Model.Entity.Data
@using Services @using Services
@inject IEntityDialogService entityDialogService @inject IEntityDialogService entityDialogService
@ -18,7 +18,7 @@ else
@code { @code {
[Parameter] public string EntityId { get; set; } [Parameter] public string EntityId { get; set; } = default!;
private EntityModel Entity => DATA.Get()[EntityId]; private EntityModel Entity => DATA.Get()[EntityId];

58
Components/Layout/LayoutWithSidebarComponent.razor

@ -0,0 +1,58 @@

<div class="layoutWithSidebar">
<div class="layoutSidebar">
@Sidebar
</div>
<div class="layoutContent">
@Content
</div>
</div>
<style scoped>
.layoutWithSidebar {
display: grid;
gap: 16px;
width: 65%;
min-width: 1000px;
margin-left: auto;
margin-right: auto;
padding-top: 10px;
padding-bottom: 30px;
grid-template-columns: 412px 1fr;
}
.layoutSidebar {
background: var(--paper);
padding: 16px;
}
.layoutContent {
}
@@media only screen and (max-width: 1025px) {
.layoutWithSidebar {
flex-direction: column-reverse;
width: 100%;
min-width: 350px;
}
}
@@media only screen and (min-width: 1024px) {
.layoutWithSidebar {
margin-top: 50px;
}
}
</style>
@code {
[Parameter]
public RenderFragment Sidebar { get; set; } = default!;
[Parameter]
public RenderFragment Content { get; set; } = default!;
}

2
Components/Layout/PageContainerComponent.razor

@ -25,6 +25,6 @@
@code { @code {
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
} }

17
Components/MarkdownContent/MarkdownContent.razor

@ -1,22 +1,15 @@
@if (Markdown == null) { @((MarkupString)MarkdownText)
<div>Loading...</div>
}
else {
@((MarkupString)Markdown)
}
@code { @code {
[Inject] [Inject]
protected HttpClient Http { get; set; } protected HttpClient Http { get; set; } = default!;
[Parameter] [Parameter]
public string MarkdownFileName { get; set; } public string MarkdownFileName { get; set; } = default!;
public string Markdown { get; set; } private string MarkdownText { get; set; } = "";
protected override async Task OnInitializedAsync() { protected override async Task OnInitializedAsync() {
Markdown = Markdig.Markdown.ToHtml(await Http.GetStringAsync($"markdown/{MarkdownFileName}.md")); MarkdownText = Markdig.Markdown.ToHtml(await Http.GetStringAsync($"markdown/{MarkdownFileName}.md"));
} }
} }

8
Components/Navigation/DesktopNavComponent.razor

@ -100,17 +100,17 @@
#if NO_SQL #if NO_SQL
[Parameter] [Parameter]
public List<WebSectionModel> WebSections { get; set; } public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter] [Parameter]
public List<WebPageModel> WebPages { get; set; } public List<WebPageModel> WebPages { get; set; } = default!;
#else #else
[Parameter] [Parameter]
public DbSet<WebSectionModel> WebSections { get; set; } public DbSet<WebSectionModel> WebSections { get; set; } = default!;
[Parameter] [Parameter]
public DbSet<WebPageModel> WebPages { get; set; } public DbSet<WebPageModel> WebPages { get; set; } = default!;
#endif #endif
protected override void OnInitialized() { protected override void OnInitialized() {

36
Components/Navigation/MobileNavComponent.razor

@ -4,10 +4,10 @@
@using Microsoft.EntityFrameworkCore @using Microsoft.EntityFrameworkCore
<div class="mobileFooter"> <div class="mobileFooter">
<div class="mobileNavSectionsContainer"> <div class="mobileNavSectionsContainer">
@foreach (var _section in WebSections) { @foreach (var webSection in WebSections) {
<div class="mobileNavSectionButton" @onclick="() => OnSectionClicked(_section)" @onclick:preventDefault="true" @onclick:stopPropagation="true"> <div class="mobileNavSectionButton" @onclick="() => OnSectionClicked(webSection)" @onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavSectionButtonText"> <div class="mobileNavSectionButtonText">
@_section.Name @webSection?.Name
</div> </div>
</div> </div>
} }
@ -17,18 +17,18 @@
</div> </div>
@if (selectedSection != null) { @if (selectedSection != null) {
var pages = (from page in WebPages List<WebPageModel?> webPages = (from page in WebPages
where page.WebSectionModelId == selectedSection.Id where page.WebSectionModelId == selectedSection.Id
select page).ToList(); select page).ToList()!;
<div class="mobileNavPagesContainer"> <div class="mobileNavPagesContainer">
@foreach (var _page in pages) { @foreach (var webPage in webPages) {
if (_page.IsPrivate.Equals("True")) { if (webPage!.IsPrivate.Equals("True")) {
continue; continue;
} }
<div class="mobileNavPageButton" @onclick="() => OnPageLinkClicked(_page)" @onclick:preventDefault="true" @onclick:stopPropagation="true"> <div class="mobileNavPageButton" @onclick="() => OnPageLinkClicked(webPage)" @onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavPageButtonText"> <div class="mobileNavPageButtonText">
@_page.Name @webPage.Name
</div> </div>
</div> </div>
} }
@ -38,7 +38,7 @@
<style> <style>
fullPageButton { .fullPageButton {
position: fixed; position: fixed;
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
@ -140,10 +140,10 @@
@code { @code {
#if NO_SQL #if NO_SQL
[Parameter] [Parameter]
public List<WebSectionModel> WebSections { get; set; } public List<WebSectionModel?> WebSections { get; set; } = default!;
[Parameter] [Parameter]
public List<WebPageModel> WebPages { get; set; } public List<WebPageModel> WebPages { get; set; } = default!;
#else #else
[Parameter] [Parameter]
@ -154,22 +154,22 @@
#endif #endif
[Inject] [Inject]
public NavigationManager NavigationManager { get; set; } public NavigationManager NavigationManager { get; set; } = default!;
public WebSectionModel selectedSection; private WebSectionModel? selectedSection;
public WebPageModel selectedPage; private WebPageModel? selectedPage;
void OnSectionClicked(WebSectionModel webSection) { void OnSectionClicked(WebSectionModel? webSection) {
selectedSection = webSection; selectedSection = webSection;
} }
void OnPageLinkClicked(WebPageModel webPage) { void OnPageLinkClicked(WebPageModel? webPage) {
selectedPage = webPage; selectedPage = webPage;
selectedSection = null; selectedSection = null;
NavigationManager.NavigateTo(webPage.Href); NavigationManager.NavigateTo(webPage?.Href!);
} }
void OnPageClicked(EventArgs eventArgs) { void OnPageClicked(EventArgs eventArgs) {

11
Components/Navigation/NavLinkComponent.razor

@ -5,7 +5,7 @@
@inject NavigationManager NavigationManager; @inject NavigationManager NavigationManager;
@if (IsOnPage) { @if (isOnPage) {
<NavLink href="@Page.Href" class="navContainer navLink navSelected"> <NavLink href="@Page.Href" class="navContainer navLink navSelected">
<div class="navName"> <div class="navName">
@Page.Name @Page.Name
@ -62,14 +62,15 @@ else {
@code { @code {
[Parameter] [Parameter]
public WebPageModel Page { get; set; } public WebPageModel Page { get; set; } = default!;
bool IsOnPage = false; bool isOnPage = false;
protected override async Task OnParametersSetAsync() { 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); isOnPage = Page.Href.ToLower().Equals(uri);
return Task.CompletedTask;
} }

4
Components/Navigation/NavSectionComponent.razor

@ -50,9 +50,9 @@
@code { @code {
[Parameter] [Parameter]
public WebSectionModel? Section { get; set; } public WebSectionModel Section { get; set; } = default!;
[Parameter] [Parameter]
public List<WebPageModel>? Children { get; set; } public List<WebPageModel> Children { get; set; } = default!;
} }

16
Components/Navigation/TabletNavComponent.razor

@ -16,11 +16,11 @@
</div> </div>
<div class="fullPageButton @NavOpen" @onclick="OnNavClicked" @onclick:stopPropagation="false" @onclick:preventDefault="false"> <div class="fullPageButton @navOpen" @onclick="OnNavClicked" @onclick:stopPropagation="false" @onclick:preventDefault="false">
</div> </div>
<div class="tabletNav @NavOpen"> <div class="tabletNav @navOpen">
@foreach (var _section in WebSections) { @foreach (var _section in WebSections) {
var pages = (from page in WebPages var pages = (from page in WebPages
where page.WebSectionModelId == _section.Id where page.WebSectionModelId == _section.Id
@ -144,11 +144,11 @@
#if NO_SQL #if NO_SQL
[Parameter] [Parameter]
public List<WebSectionModel> WebSections { get; set; } public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter] [Parameter]
public List<WebPageModel> WebPages { get; set; } public List<WebPageModel> WebPages { get; set; } = default!;
#else #else
[Parameter] [Parameter]
public DbSet<WebSectionModel> WebSections { get; set; } public DbSet<WebSectionModel> WebSections { get; set; }
@ -159,15 +159,15 @@
bool NavOpen = true; bool navOpen = true;
void OnNavClicked(EventArgs eventArgs) { void OnNavClicked(EventArgs eventArgs) {
NavOpen = !NavOpen; navOpen = !navOpen;
} }
void OnPageClicked(EventArgs eventArgs) { void OnPageClicked(EventArgs eventArgs) {
NavOpen = false; navOpen = false;
} }
} }

6
Components/Shared/DisplayableContent.razor

@ -7,13 +7,13 @@
@code { @code {
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
[Parameter] [Parameter]
public WebDeploymentType DeploymentType { get; set; } public WebDeploymentType DeploymentType { get; set; } = default!;
[Inject] [Inject]
public NavigationManager MyNavigationManager { get; set; } public NavigationManager MyNavigationManager { get; set; } = default!;
bool isDisplayable; bool isDisplayable;

4
Components/Shared/DisplayableRoute.razor

@ -11,10 +11,10 @@ else {
@code { @code {
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
[Inject] [Inject]
public NavigationManager MyNavigationManager { get; set; } public NavigationManager MyNavigationManager { get; set; } = default!;
bool isDisplayable; bool isDisplayable;

4
Components/Shared/MathDivisionComponent.razor

@ -11,9 +11,9 @@
@code { @code {
[Parameter] [Parameter]
public RenderFragment Dividee { get; set; } public RenderFragment Dividee { get; set; } = default!;
[Parameter] [Parameter]
public RenderFragment Divider { get; set; } public RenderFragment Divider { get; set; } = default!;
} }

6
Components/Shared/MathLoopSumComponent.razor

@ -13,12 +13,12 @@
@code { @code {
[Parameter] [Parameter]
public RenderFragment LoopEnd { get; set; } public RenderFragment LoopEnd { get; set; } = default!;
[Parameter] [Parameter]
public RenderFragment LoopStart { get; set; } public RenderFragment LoopStart { get; set; } = default!;
[Parameter] [Parameter]
public RenderFragment IndexSymbol { get; set; } public RenderFragment IndexSymbol { get; set; } = default!;
} }

2
Components/Shared/SpoilerTextComponent.razor

@ -23,6 +23,6 @@
@code { @code {
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
} }

34
Contexts/DatabaseContext.cs

@ -3,10 +3,10 @@
#else #else
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Model.Documentation; using Model.Doc;
using Model.Immortal.Notes; using Model.Notes;
using Model.Website; using Model.Website;
using Model.Work.Git; using Model.Development.Git;
using Model.Work.Tasks; using Model.Work.Tasks;
namespace Contexts; namespace Contexts;
@ -16,22 +16,18 @@ public class DatabaseContext : DbContext {
Database.EnsureCreated(); Database.EnsureCreated();
} }
public DbSet<SprintModel> SprintModels { get; set; } public DbSet<AgileSprintModel> AgileSprintModels { get; set; } = default!;
public DbSet<TaskModel> TaskModels { get; set; } public DbSet<AgileTaskModel> AgileTaskModels { get; set; } = default!;
public DbSet<ChangeModel> ChangeModels { get; set; } public DbSet<GitChangeModel> GitChangeModels { get; set; } = default!;
public DbSet<PatchModel> PatchModels { get; set; } public DbSet<GitPatchModel> GitPatchModels { get; set; } = default!;
public DbSet<WebPageModel> WebPageModels { get; set; } public DbSet<WebPageModel> WebPageModels { get; set; } = default!;
public DbSet<WebSectionModel> WebSectionModels { get; set; } public DbSet<WebSectionModel> WebSectionModels { get; set; } = default!;
public DbSet<DocContentModel> DocContentModels { get; set; } = default!;
public DbSet<DocumentationModel> DocumentationModels { get; set; } public DbSet<DocConnectionModel> DocConnectionModels { get; set; } = default!;
public DbSet<NoteModel> NoteModels { get; set; } public DbSet<DocSectionModel> DocSectionModels { get; set; } = default!;
public DbSet<NoteContentModel> NoteContentModels { get; set; } = default!;
protected override void OnModelCreating(ModelBuilder modelBuilder) { public DbSet<NoteConnectionModel> NoteConnectionModels { get; set; } = default!;
modelBuilder.Entity<PatchModel>(); public DbSet<NoteSectionModel> NoteSectionModels { get; set; } = default!;
modelBuilder.Entity<TaskModel>();
base.OnModelCreating(modelBuilder);
}
} }
#endif #endif

33
IGP/App.razor

@ -17,21 +17,48 @@
<style> <style>
a { a {
color: #8fc5ff; color: white;
font-weight: 700; font-weight: 700;
} }
a:hover { a:hover {
color: #d2f0ff; color: white;
text-decoration: underline; text-decoration: underline;
text-decoration-color: #8fc5ff; text-decoration-color: #8fc5ff;
text-decoration-thickness: 3px; text-decoration-thickness: 3px;
} }
:root {
/* Duplicate Code, to deal with cache issues. See wwwroot/css/app.css for proper :root */
--accent: #432462;
--primary: #4308a3;
--primary-border: #2c0b62;
--primary-hover: #5e00f7;
--primary-border-hover: #a168ff;
--background: #161618;
--secondary: #23133e;
--secondary-hover: #2a0070;
--secondary-border-hover: #a168ff;
--paper: #252526;
--paper-border: #151516;
--paper-hover: #52366f;
--paper-border-hover: #653497;
--info: #451376;
--info-border: #210b36;
--dialog-border-color: black;
--dialog-border-width: 2px;
--dialog-radius: 6px;
}
</style> </style>
@code { @code {
#if NO_SQL #if NO_SQL
#else #else
[Inject] [Inject]

BIN
IGP/Database.db

Binary file not shown.

52
IGP/Dialog/EntityDialogComponent.razor

@ -3,9 +3,9 @@
<div class="dialogBackground" onclick="@CloseDialog"> <div class="dialogBackground" onclick="@CloseDialog">
<div class="dialogContainer" <div class="dialogContainer"
@onclick:preventDefault="true" @onclick:preventDefault="true"
@onclick:stopPropagation="true"> @onclick:stopPropagation="true">
@if (entity == null) @if (entity == null)
{ {
<div>Entity is null</div> <div>Entity is null</div>
@ -26,26 +26,26 @@
</div> </div>
<div class="dialogContent"> <div class="dialogContent">
<CascadingValue Value="@entity"> <CascadingValue Value="@entity">
<EntityVanguardAddedComponent /> <EntityVanguardAddedComponent/>
<EntityInfoComponent /> <EntityInfoComponent/>
<EntityVanguardsComponent /> <EntityVanguardsComponent/>
<EntityProductionComponent /> <EntityProductionComponent/>
<EntityStatsComponent /> <EntityStatsComponent/>
<EntityMechanicsComponent /> <EntityMechanicsComponent/>
<EntityPassivesComponent /> <EntityPassivesComponent/>
<EntityPyreSpellsComponent /> <EntityPyreSpellsComponent/>
<EntityUpgradesComponent /> <EntityUpgradesComponent/>
<EntityWeaponsComponent /> <EntityWeaponsComponent/>
<EntityAbilitiesComponent /> <EntityAbilitiesComponent/>
</CascadingValue> </CascadingValue>
</div> </div>
<div class="dialogFooter"></div> <div class="dialogFooter"></div>
} }
</div> </div>
</div> </div>
<style> <style>
@ -133,19 +133,20 @@
</style> </style>
@code { @code {
EntityModel entity = null; EntityModel entity = default!;
private int refresh = 0; private int refresh = 0;
protected override void OnInitialized() protected override void OnInitialized()
{ {
entity = DATA.Get()[entityDialogService.GetEntityId()]; entity = DATA.Get()[entityDialogService.GetEntityId() ?? string.Empty];
entityDialogService.Subscribe(OnUpdate); entityDialogService.Subscribe(OnUpdate);
} }
public void Dispose() { public void Dispose()
{
entityDialogService.Unsubscribe(OnUpdate); entityDialogService.Unsubscribe(OnUpdate);
} }
@ -157,11 +158,10 @@
Console.WriteLine("OnUpdate()"); Console.WriteLine("OnUpdate()");
StateHasChanged(); StateHasChanged();
} }
public void CloseDialog() public void CloseDialog()
{ {
entityDialogService.CloseDialog(); entityDialogService.CloseDialog();
} }
} }

27
IGP/IGP.csproj

@ -8,32 +8,37 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>TRACE;NO_SQL</DefineConstants> <DefineConstants>TRACE;NO_SQL</DefineConstants>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>TRACE;NO_SQL</DefineConstants> <DefineConstants>TRACE;NO_SQL</DefineConstants>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Markdig" Version="0.28.1" /> <PackageReference Include="Markdig" Version="0.28.1"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.0-preview.2.22153.2" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.0-preview.2.22153.2"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.0-preview.2.22153.2" PrivateAssets="all" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.0-preview.2.22153.2" PrivateAssets="all"/>
<!-- <!--
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0-preview.2.22153.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0-preview.2.22153.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="7.0.0-preview.2.22153.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="7.0.0-preview.2.22153.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0-preview.2.22153.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0-preview.2.22153.1" />
<NativeFileReference Include="e_sqlite3.o" /> --> <NativeFileReference Include="e_sqlite3.o" /> -->
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" /> <ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Components\Components.csproj" /> <ProjectReference Include="..\Components\Components.csproj"/>
<ProjectReference Include="..\Contexts\Contexts.csproj" /> <ProjectReference Include="..\Contexts\Contexts.csproj"/>
<ProjectReference Include="..\Model\Model.csproj" /> <ProjectReference Include="..\Model\Model.csproj"/>
<ProjectReference Include="..\Services\Services.csproj" /> <ProjectReference Include="..\Services\Services.csproj"/>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\generated"/>
</ItemGroup>
</Project> </Project>

4
IGP/Index.razor

@ -2,4 +2,8 @@
@layout PageLayout @layout PageLayout
<DevOnlyComponent>
<DocumentationIndexPage></DocumentationIndexPage>
</DevOnlyComponent>
<HomePage></HomePage> <HomePage></HomePage>

53
IGP/PageLayout.razor

@ -1,26 +1,26 @@
@inherits LayoutComponentBase; @inherits LayoutComponentBase;
@inject IWebsiteService WebService; @inject IWebsiteService webService;
@implements IDisposable; @implements IDisposable;
<div class="layoutContainer" @onclick="OnPageClicked"> <div class="layoutContainer">
@if (!WebService.IsLoaded()) { @if (!webService.IsLoaded())
<LoadingComponent></LoadingComponent> {
} else { <LoadingComponent/>
}
else
{
<div class="content"> <div class="content">
@Body @Body
</div> </div>
<DesktopNavComponent WebSections=WebService.WebSectionModels <DesktopNavComponent WebSections=webService.WebSectionModels
WebPages=WebService.WebPageModels /> WebPages=webService.WebPageModels/>
<TabletNavComponent WebSections=WebService.WebSectionModels <TabletNavComponent WebSections=webService.WebSectionModels
WebPages=WebService.WebPageModels /> WebPages=webService.WebPageModels/>
<MobileNavComponent WebSections=WebService.WebSectionModels <MobileNavComponent WebSections=webService.WebSectionModels
WebPages=WebService.WebPageModels /> WebPages=webService.WebPageModels/>
} }
</div> </div>
@ -32,32 +32,29 @@
[Inject] [Inject]
DatabaseContext Database { get; set; } DatabaseContext Database { get; set; }
#endif #endif
bool NavOpen = true;
void OnPageClicked(EventArgs eventArgs) {
NavOpen = false;
}
protected override void OnInitialized() { protected override void OnInitialized()
WebService.Subscribe(HasChanged); {
webService.Subscribe(HasChanged);
} }
protected override async Task OnInitializedAsync() { protected override async Task OnInitializedAsync()
{
#if NO_SQL #if NO_SQL
await WebService.Load(); await webService.Load();
#else #else
await WebService.Load(Database); await WebService.Load(Database);
#endif #endif
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
WebService.Unsubscribe(HasChanged); {
webService.Unsubscribe(HasChanged);
} }
void HasChanged() { void HasChanged()
{
StateHasChanged(); StateHasChanged();
} }

77
IGP/Pages/Agile/AgilePage.razor

@ -5,34 +5,39 @@
@page "/agile" @page "/agile"
@if (AgileService.IsLoaded()) { @if (AgileService.IsLoaded())
{
<LayoutMediumContentComponent> <LayoutMediumContentComponent>
<WebsiteTitleComponent>Agile</WebsiteTitleComponent> <WebsiteTitleComponent>Agile</WebsiteTitleComponent>
<div class="agileViewContainer"> <div class="agileViewContainer">
@foreach (var sprint in AgileService.SprintModels.OrderBy(e => e.EndDate).Reverse()) { @foreach (var sprint in AgileService.AgileSprintModels!.OrderBy(e => e.EndDate).Reverse())
{
<details class="sprintDisplayContainer @sprint.GetSprintType().ToLower()" open="@(sprint.GetSprintType() == SprintType.Current)"> <details class="sprintDisplayContainer @sprint.GetSprintType().ToLower()" open="@(sprint.GetSprintType() == SprintType.Current)">
<summary class="sprintSummary"> <summary class="sprintSummary">
<div class="sprintTitle">@sprint.Name</div> <div class="sprintTitle">@sprint.Name</div>
<div style="flex: 1; flex-grow: 1;"></div> <div style="flex: 1; flex-grow: 1;"></div>
<div class="sprintDates"> <div class="sprintDates">
<div class="sprintStartDate"> <div class="sprintStartDate">
@if (sprint.StartDate != null) @if (sprint.StartDate != null)
{ {
<b>Start: </b>@sprint.StartDate.Value.ToString("dd/MM/yyyy") <b>Start: </b>
} @sprint.StartDate.Value.ToString("dd/MM/yyyy")
}
</div> </div>
<div class="sprintEndDate"> <div class="sprintEndDate">
@if (sprint.EndDate != null) @if (sprint.EndDate != null)
{ {
<b>End: </b>@sprint.EndDate.Value.ToString("dd/MM/yyyy") <b>End: </b>
} @sprint.EndDate.Value.ToString("dd/MM/yyyy")
}
</div> </div>
</div> </div>
</summary> </summary>
<SprintComponent Sprint=sprint Tasks=AgileService.TaskModels></SprintComponent> <SprintComponent AgileSprint="sprint"></SprintComponent>
</details> </details>
} }
@ -49,29 +54,31 @@
<ContentDividerComponent></ContentDividerComponent> <ContentDividerComponent></ContentDividerComponent>
<InfoBodyComponent> <PaperComponent>
<InfoQuestionComponent>What is Agile?</InfoQuestionComponent>
<InfoAnswerComponent> <InfoBodyComponent>
Agile is a work methodology for determing task assignment and release deadlines. <InfoQuestionComponent>What is Agile?</InfoQuestionComponent>
<br/><br/> <InfoAnswerComponent>
My agile practice will be creating tasks in a backlog. Assigning them to weekly sprints. And completing all tasks in the allotted time frame. Agile is a work methodology for determing task assignment and release deadlines.
<br/><br/> <br/><br/>
Any unfinished tasks are moved into the next sprint, or the sprint will be extended by a week. My agile practice will be creating tasks in a backlog. Assigning them to weekly sprints. And completing all tasks in the allotted time frame.
</InfoAnswerComponent> <br/><br/>
</InfoBodyComponent> Any unfinished tasks are moved into the next sprint, or the sprint will be extended by a week.
</InfoAnswerComponent>
</InfoBodyComponent>
</PaperComponent>
</LayoutMediumContentComponent> </LayoutMediumContentComponent>
} }
else { else
<LoadingComponent></LoadingComponent> {
<LoadingComponent/>
} }
@code { @code {
#if NO_SQL #if NO_SQL
public List<TaskModel> Tasks => AgileService.TaskModels;
public List<SprintModel> Sprints => AgileService.SprintModels;
#else #else
[Inject] [Inject]
DatabaseContext Database { get; set; } DatabaseContext Database { get; set; }
@ -83,21 +90,26 @@ else {
public DbSet<SprintModel> Sprints { get; set; } public DbSet<SprintModel> Sprints { get; set; }
#endif #endif
private readonly List<TaskModel> backlog = new(); private readonly List<AgileTaskModel> backlog = new();
protected override void OnInitialized() { protected override void OnInitialized()
{
AgileService.Subscribe(HasChanged); AgileService.Subscribe(HasChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
AgileService.Unsubscribe(HasChanged); AgileService.Unsubscribe(HasChanged);
} }
void HasChanged() { void HasChanged()
{
backlog.Clear(); backlog.Clear();
foreach (var task in Tasks) { foreach (var task in AgileService.AgileTaskModels!)
if (task.SprintModelId == null) { {
if (task.AgileSprintModelId == null)
{
backlog.Add(task); backlog.Add(task);
} }
} }
@ -105,7 +117,8 @@ else {
StateHasChanged(); StateHasChanged();
} }
protected override async Task OnInitializedAsync() { protected override async Task OnInitializedAsync()
{
#if NO_SQL #if NO_SQL
await AgileService.Load(); await AgileService.Load();
#else #else

2
IGP/Pages/Agile/AgilePage.razor.css

@ -7,7 +7,7 @@
.sprintDisplayContainer { .sprintDisplayContainer {
border: 4px solid var(--paper); border: 4px solid var(--paper);
box-shadow: 0px 2px 12px rgba(0,0,0,0.2); box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.2);
border-radius: 2px; border-radius: 2px;
padding: 25px; padding: 25px;
margin: auto; margin: auto;

29
IGP/Pages/Agile/Parts/BacklogComponent.razor

@ -1,6 +1,7 @@
<div class="sprintContainer"> <div class="sprintContainer">
<div class="tasksContainer"> <div class="tasksContainer">
@foreach (var task in Backlog) { @foreach (var task in Backlog)
{
<div class="taskContainer @task.Status.ToLower()"> <div class="taskContainer @task.Status.ToLower()">
<div class="taskName">@task.Name</div> <div class="taskName">@task.Name</div>
<div class="taskDetails"> <div class="taskDetails">
@ -17,7 +18,8 @@
</div> </div>
</LayoutColumnComponent> </LayoutColumnComponent>
<LayoutColumnComponent> <LayoutColumnComponent>
@if (task.Finished != null) { @if (task.Finished != null)
{
<div class="taskFinished"> <div class="taskFinished">
<b>Finished: </b>@task.Finished <b>Finished: </b>@task.Finished
</div> </div>
@ -49,19 +51,6 @@
padding-top: 16px; padding-top: 16px;
} }
.sprintDescription {
grid-area: description;
}
.sprintStartDate {
}
.sprintEndDate {
}
.sprintNotes {
}
@@media only screen and (max-width: 1025px) { @@media only screen and (max-width: 1025px) {
.sprintContainer { .sprintContainer {
@ -73,14 +62,6 @@
box-shadow: none; box-shadow: none;
padding: 8px; padding: 8px;
} }
.sprintStartDate {
text-align: left;
}
.sprintEndDate {
text-align: left;
}
} }
.tasksContainer { .tasksContainer {
@ -197,6 +178,6 @@
@code { @code {
[Parameter] [Parameter]
public List<TaskModel> Backlog { get; set; } public List<AgileTaskModel> Backlog { get; set; } = default!;
} }

46
IGP/Pages/Agile/Parts/SprintComponent.razor

@ -1,16 +1,18 @@
<div class="sprintContainer"> <div class="sprintContainer">
<div class="sprintStatus"> <div class="sprintStatus">
<b>Status: </b>@Sprint.GetSprintType() <b>Status: </b>@AgileSprint.GetSprintType()
</div> </div>
<div class="sprintDescription"> <div class="sprintDescription">
<b>Description: </b>@Sprint.Description <b>Description: </b>@AgileSprint.Description
</div> </div>
<div class="sprintNotes"> <div class="sprintNotes">
<b>Notes: </b>@Sprint.Notes <b>Notes: </b>@AgileSprint.Notes
</div> </div>
<div class="tasksContainer"> <div class="tasksContainer">
@if (selectedTasks.Count > 0) { @if (AgileSprint.AgileTaskModels.Count > 0)
@foreach (var task in selectedTasks) { {
@foreach (var task in AgileSprint.AgileTaskModels)
{
<div class="taskContainer @task.Status.ToLower() @task.Task.ToLower()"> <div class="taskContainer @task.Status.ToLower() @task.Task.ToLower()">
<div class="taskName">@task.Name</div> <div class="taskName">@task.Name</div>
<div class="taskDetails"> <div class="taskDetails">
@ -28,13 +30,14 @@
</LayoutColumnComponent> </LayoutColumnComponent>
<LayoutColumnComponent> <LayoutColumnComponent>
@if (task.Finished != null) { @if (task.Finished != null)
{
<div class="taskFinished"> <div class="taskFinished">
<b>Finished: </b>@task.Finished.Value.ToString("dd/MM/yyyy") <b>Finished: </b>@task.Finished.Value.ToString("dd/MM/yyyy")
</div> </div>
} }
<div class="taskCreated"> <div class="taskCreated">
<b>Created: </b>@task.Created.Value.ToString("dd/MM/yyyy") <b>Created: </b>@task.Created!.Value.ToString("dd/MM/yyyy")
</div> </div>
</LayoutColumnComponent> </LayoutColumnComponent>
</LayoutRowComponent> </LayoutRowComponent>
@ -48,7 +51,8 @@
</div> </div>
} }
} }
else { else
{
<div>Add Tasks...</div> <div>Add Tasks...</div>
} }
</div> </div>
@ -66,14 +70,6 @@
grid-area: description; grid-area: description;
} }
.sprintStartDate {
}
.sprintEndDate {
}
.sprintNotes {
}
@@media only screen and (max-width: 1025px) { @@media only screen and (max-width: 1025px) {
@ -221,23 +217,7 @@
@code { @code {
#if NO_SQL
[Parameter] [Parameter]
public List<TaskModel> Tasks { get; set; } public AgileSprintModel AgileSprint { get; set; } = default!;
#else
[Parameter]
public DbSet<TaskModel> Tasks { get; set; }
#endif
[Parameter]
public SprintModel Sprint { get; set; }
private List<TaskModel> selectedTasks { get; set; }
protected override void OnInitialized() {
selectedTasks = (from task in Tasks
where task.SprintModelId == Sprint.Id
select task).OrderBy(x => x.Created).OrderBy(x => x.Finished).Reverse().OrderBy(x => x.Status).ToList();
}
} }

106
IGP/Pages/BuildCalculator/BuildCalculatorPage.razor

@ -2,6 +2,12 @@
@layout PageLayout @layout PageLayout
@inject IKeyService keyService
@inject IImmortalSelectionService filterService
@inject IBuildOrderService buildOrderService
@inject IEconomyService economyService
@inject ITimingService timingService
@page "/build-calculator" @page "/build-calculator"
<LayoutLargeContentComponent> <LayoutLargeContentComponent>
@ -20,19 +26,15 @@
<div class="calculatorGrid"> <div class="calculatorGrid">
<div style="grid-area: timing;" class="gridItem"> <div style="grid-area: timing;" class="gridItem">
<InfoTooltipComponent InfoText="Enter build details. <InfoTooltipComponent InfoText="">
<b>Timing Interval:</b> set the max interval length for the build. <i>Ex. 240 (seconds) is 4 minutes, a possible timing for Thrum build order.</i>
<b>Name:</b> the name of the build for saving purposes. <i>Ex. 'Safe Thrum Opener'</i>
<b>Notes:</b> additional notes of the build for saving purposes. <i>Ex. 'Thrums are for harassing and defending against a ground Q'Rath army.'</i>
<b>Color:</b> value to color charts when comparing builds. Not currently implemented.">
<TimingComponent></TimingComponent> <TimingComponent></TimingComponent>
</InfoTooltipComponent> </InfoTooltipComponent>
</div> </div>
@if (true) { @if (true)
{
<div style="grid-area: chart;" class="gridItem"> <div style="grid-area: chart;" class="gridItem">
<InfoTooltipComponent InfoText="Shows economy at each game interval. Use to determine if spending additional resourcses on harvesters will help or hinder overall timing attack."> <InfoTooltipComponent InfoText="Shows economy at each game interval. Use to determine if spending additional resourcses on harvesters will help or hinder overall timing attack.">
<ChartComponent></ChartComponent> <ChartComponent></ChartComponent>
@ -70,18 +72,15 @@
<div class="gridItem gridKeys"> <div class="gridItem gridKeys">
<InfoTooltipComponent InfoText="Click on the desired entity to build it. <i>You cannot build entities you cannot afford, construct an ether extractor before spending ether.</i> <InfoTooltipComponent InfoText="">
You can also use the default Immortal hotkeys, but the above hotkey UI must have focus for this to work. <i>I.e. click on it if hotkeys aren't working, and a white border should appear after key input to indicate focus.</i>
Additionally, more entities will appear as you build the required technology. You can click or press ` to remove the last made entity. <i>But you cannot remove the starting entities at interval 0.</i>">
<HotkeyViewerComponent Size="80"></HotkeyViewerComponent> <HotkeyViewerComponent Size="80"></HotkeyViewerComponent>
</InfoTooltipComponent> </InfoTooltipComponent>
</div> </div>
@if (false) { @if (false)
{
<div style="grid-area: timeline;" class="gridItem"> <div style="grid-area: timeline;" class="gridItem">
<TimelineComponent></TimelineComponent> <TimelineComponent></TimelineComponent>
</div> </div>
@ -216,72 +215,59 @@ Additionally, more entities will appear as you build the required technology. Yo
@code { @code {
protected override void OnInitialized()
[Inject] {
IKeyService KeyService { get; set; } keyService.Subscribe(HandleClick);
filterService.Subscribe(StateHasChanged);
[Inject] economyService.Subscribe(StateHasChanged);
IImmortalSelectionService FilterService { get; set; } timingService.Subscribe(HandleTimingChanged);
economyService.Calculate(buildOrderService, timingService, 0);
[Inject]
IBuildOrderService BuildOrderService { get; set; }
[Inject]
IEconomyService EconomyService { get; set; }
[Inject]
ITimingService TimingService { get; set; }
Dictionary<int, List<EntityModel>> completedEntities = new();
List<EntityModel> entities = EntityModel.GetListOnlyHotkey();
protected override void OnInitialized() {
KeyService.Subscribe(HandleClick);
FilterService.Subscribe(StateHasChanged);
EconomyService.Subscribe(StateHasChanged);
TimingService.Subscribe(HandleTimingChanged);
EconomyService.Calculate(BuildOrderService, TimingService, 0);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
KeyService.Unsubscribe(HandleClick); {
FilterService.Unsubscribe(StateHasChanged); keyService.Unsubscribe(HandleClick);
TimingService.Unsubscribe(StateHasChanged); filterService.Unsubscribe(StateHasChanged);
EconomyService.Unsubscribe(StateHasChanged); timingService.Unsubscribe(StateHasChanged);
economyService.Unsubscribe(StateHasChanged);
} }
private void HandleTimingChanged()
protected void HandleTimingChanged() { {
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval()); economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
} }
protected void HandleClick() { private void HandleClick()
var hotkey = KeyService.GetHotkey(); {
var hotkey = keyService.GetHotkey();
if (hotkey == "") { if (hotkey == "")
{
return; return;
} }
if (hotkey == "`") { if (hotkey == "`")
BuildOrderService.RemoveLast(); {
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval()); buildOrderService.RemoveLast();
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
StateHasChanged(); StateHasChanged();
return; return;
} }
var hotkeyGroup = KeyService.GetHotkeyGroup(); var hotkeyGroup = keyService.GetHotkeyGroup();
var isHoldSpace = KeyService.IsHoldingSpace(); var isHoldSpace = keyService.IsHoldingSpace();
var faction = FilterService.GetFactionType(); var faction = filterService.GetFactionType();
var immortal = FilterService.GetImmortalType(); var immortal = filterService.GetImmortalType();
var entity = EntityModel.GetFrom(hotkey, hotkeyGroup, isHoldSpace, faction, immortal); var entity = EntityModel.GetFrom(hotkey, hotkeyGroup, isHoldSpace, faction, immortal);
if (entity == null) { if (entity == null)
{
return; return;
} }
if (BuildOrderService.Add(entity, EconomyService)) { if (buildOrderService.Add(entity, economyService))
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval()); {
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
} }
} }

37
IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor

@ -2,12 +2,13 @@
<FormLayoutComponent> <FormLayoutComponent>
<FormDisplayComponent Label="Army ready at"> <FormDisplayComponent Label="Army ready at">
<Display>@LastInterval | T @Interval.ToTime(LastInterval)</Display> <Display>@lastInterval | T @Interval.ToTime(lastInterval)</Display>
</FormDisplayComponent> </FormDisplayComponent>
<FormDisplayComponent Label="Army units built"> <FormDisplayComponent Label="Army units built">
<Display> <Display>
<div style="display: flex; width: 100%; gap: 12px; flex-wrap: wrap;"> <div style="display: flex; width: 100%; gap: 12px; flex-wrap: wrap;">
@foreach (var unit in armyCount) { @foreach (var unit in armyCount)
{
<div style="width:90px; height: 60px; border: 1px solid gray; padding: 8px;"> <div style="width:90px; height: 60px; border: 1px solid gray; padding: 8px;">
<div>@unit.Value.ToString()x</div> <div>@unit.Value.ToString()x</div>
<div>@unit.Key</div> <div>@unit.Key</div>
@ -22,38 +23,46 @@
@code { @code {
[Inject] [Inject]
public IBuildOrderService BuildOrder { get; set; } public IBuildOrderService BuildOrder { get; set; } = default!;
int LastInterval; private int lastInterval;
readonly Dictionary<string, int> armyCount = new(); readonly Dictionary<string, int> armyCount = new();
List<EntityModel> army = new(); List<EntityModel> army = new();
protected override void OnInitialized() { protected override void OnInitialized()
{
BuildOrder.Subscribe(OnBuildOrderChanged); BuildOrder.Subscribe(OnBuildOrderChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
BuildOrder.Unsubscribe(OnBuildOrderChanged); BuildOrder.Unsubscribe(OnBuildOrderChanged);
} }
void OnBuildOrderChanged() { void OnBuildOrderChanged()
{
armyCount.Clear(); armyCount.Clear();
LastInterval = 0; lastInterval = 0;
var entitiesOverTime = BuildOrder.GetOrders(); var entitiesOverTime = BuildOrder.GetOrders();
foreach (var entitiesAtTime in entitiesOverTime) { foreach (var entitiesAtTime in entitiesOverTime)
foreach (var entity in entitiesAtTime.Value) { {
if (entity.EntityType == EntityType.Army) { foreach (var entity in entitiesAtTime.Value)
if (!armyCount.TryAdd(entity.Info().Name, 1)) { {
if (entity.EntityType == EntityType.Army)
{
if (!armyCount.TryAdd(entity.Info().Name, 1))
{
armyCount[entity.Info().Name]++; armyCount[entity.Info().Name]++;
} }
if (entity.Production() != null && entity.Production().BuildTime + entitiesAtTime.Key > LastInterval) { if (entity.Production() != null && entity.Production().BuildTime + entitiesAtTime.Key > lastInterval)
LastInterval = entity.Production().BuildTime + entitiesAtTime.Key; {
lastInterval = entity.Production().BuildTime + entitiesAtTime.Key;
} }
} }
} }

16
IGP/Pages/BuildCalculator/Parts/BankComponent.razor

@ -23,27 +23,30 @@
@code { @code {
[Inject] [Inject]
IBuildOrderService BuildOrderService { get; set; } IBuildOrderService BuildOrderService { get; set; } = default!;
[Inject] [Inject]
IEconomyService EconomyService { get; set; } IEconomyService EconomyService { get; set; } = default!;
EconomyModel economy = new(); EconomyModel economy = new();
int supplyGranted; int supplyGranted;
int supplyTaken; int supplyTaken;
int extraBuildings; int extraBuildings;
protected override void OnInitialized() { protected override void OnInitialized()
{
BuildOrderService.Subscribe(OnBuildOrderChanged); BuildOrderService.Subscribe(OnBuildOrderChanged);
EconomyService.Subscribe(OnBuildOrderChanged); EconomyService.Subscribe(OnBuildOrderChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
BuildOrderService.Unsubscribe(OnBuildOrderChanged); BuildOrderService.Unsubscribe(OnBuildOrderChanged);
EconomyService.Subscribe(OnBuildOrderChanged); EconomyService.Subscribe(OnBuildOrderChanged);
} }
void OnBuildOrderChanged() { void OnBuildOrderChanged()
{
economy = EconomyService.GetEconomy(BuildOrderService.GetLastRequestInterval()); economy = EconomyService.GetEconomy(BuildOrderService.GetLastRequestInterval());
var ordersOverTime = BuildOrderService.GetOrders(); var ordersOverTime = BuildOrderService.GetOrders();
@ -61,7 +64,8 @@
select order.Supply().Grants).Sum(); select order.Supply().Grants).Sum();
extraBuildings = 0; extraBuildings = 0;
if (supplyGranted > 160) { if (supplyGranted > 160)
{
extraBuildings = (supplyGranted - 160) / 16; extraBuildings = (supplyGranted - 160) / 16;
supplyGranted = 160; supplyGranted = 160;
} }

19
IGP/Pages/BuildCalculator/Parts/BuildOrderComponent.razor

@ -1,23 +1,24 @@
@implements IDisposable @inject IBuildOrderService buildOrderService
@implements IDisposable
<FormLayoutComponent> <FormLayoutComponent>
<FormTextAreaComponent Label="JSON Data" <FormTextAreaComponent Label="JSON Data"
Rows="14" Rows="14"
Value="@BuildOrderService.AsJson()"> Value="@buildOrderService.AsJson()">
</FormTextAreaComponent> </FormTextAreaComponent>
</FormLayoutComponent> </FormLayoutComponent>
@code { @code {
[Inject] protected override void OnInitialized()
IBuildOrderService BuildOrderService { get; set; } {
buildOrderService.Subscribe(StateHasChanged);
protected override void OnInitialized() {
BuildOrderService.Subscribe(StateHasChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
BuildOrderService.Unsubscribe(StateHasChanged); {
buildOrderService.Unsubscribe(StateHasChanged);
} }
} }

61
IGP/Pages/BuildCalculator/Parts/ChartComponent.razor

@ -1,10 +1,12 @@
@implements IDisposable @implements IDisposable
<div class="chartsContainer"> <div class="chartsContainer">
@foreach (var chart in charts) { @foreach (var chart in charts)
{
<div style="width: @chart.IntervalDisplayMax.ToString()px; height: @chart.ValueDisplayMax.ToString()px"> <div style="width: @chart.IntervalDisplayMax.ToString()px; height: @chart.ValueDisplayMax.ToString()px">
<div style="position: relative; border: 2px solid gray; border-radius:2px; width: @chart.IntervalDisplayMax.ToString()px; height: @chart.ValueDisplayMax.ToString()px"> <div style="position: relative; border: 2px solid gray; border-radius:2px; width: @chart.IntervalDisplayMax.ToString()px; height: @chart.ValueDisplayMax.ToString()px">
@foreach (var point in chart.Points) { @foreach (var point in chart.Points)
{
<div style="position: absolute; <div style="position: absolute;
bottom:@point.GetValue(chart.HighestValuePoint, chart.ValueDisplayMax)px; bottom:@point.GetValue(chart.HighestValuePoint, chart.ValueDisplayMax)px;
left:@point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax)px; left:@point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax)px;
@ -51,10 +53,10 @@
@code { @code {
[Inject] [Inject]
IEconomyService EconomyService { get; set; } IEconomyService EconomyService { get; set; } = default!;
[Inject] [Inject]
IBuildOrderService BuildOrderService { get; set; } IBuildOrderService BuildOrderService { get; set; } = default!;
int height = 100; int height = 100;
@ -70,43 +72,50 @@
float highestPyrePoint; float highestPyrePoint;
float highestArmyPoint; float highestArmyPoint;
protected override void OnInitialized() { protected override void OnInitialized()
{
EconomyService.Subscribe(GenerateChart); EconomyService.Subscribe(GenerateChart);
BuildOrderService.Subscribe(GenerateChart); BuildOrderService.Subscribe(GenerateChart);
GenerateChart(); GenerateChart();
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
EconomyService.Unsubscribe(GenerateChart); EconomyService.Unsubscribe(GenerateChart);
BuildOrderService.Unsubscribe(GenerateChart); BuildOrderService.Unsubscribe(GenerateChart);
} }
void GenerateChart() { void GenerateChart()
{
var economyOverTime = EconomyService.GetOverTime(); var economyOverTime = EconomyService.GetOverTime();
charts.Clear(); charts.Clear();
var alloyChart = new ChartModel { var alloyChart = new ChartModel
{
IntervalDisplayMax = width, IntervalDisplayMax = width,
ValueDisplayMax = 100, ValueDisplayMax = 100,
ChartColor = "Cyan" ChartColor = "Cyan"
}; };
var etherChart = new ChartModel { var etherChart = new ChartModel
{
Offset = width, Offset = width,
IntervalDisplayMax = width, IntervalDisplayMax = width,
ValueDisplayMax = 100, ValueDisplayMax = 100,
ChartColor = "LightGreen" ChartColor = "LightGreen"
}; };
var pyreChart = new ChartModel { var pyreChart = new ChartModel
{
Offset = width * 2, Offset = width * 2,
IntervalDisplayMax = width, IntervalDisplayMax = width,
ValueDisplayMax = 100, ValueDisplayMax = 100,
ChartColor = "Red" ChartColor = "Red"
}; };
var armyChart = new ChartModel { var armyChart = new ChartModel
{
Offset = width * 3, Offset = width * 3,
IntervalDisplayMax = width, IntervalDisplayMax = width,
ValueDisplayMax = 100, ValueDisplayMax = 100,
@ -118,13 +127,15 @@
highestPyrePoint = 0; highestPyrePoint = 0;
highestArmyPoint = 0; highestArmyPoint = 0;
for (var interval = 0; interval < economyOverTime.Count(); interval++) { for (var interval = 0; interval < economyOverTime.Count(); interval++)
{
var army = from unit in BuildOrderService.GetCompletedBefore(interval) var army = from unit in BuildOrderService.GetCompletedBefore(interval)
where unit.EntityType == EntityType.Army where unit.EntityType == EntityType.Army
select unit; select unit;
var armyValue = 0; var armyValue = 0;
foreach (var unit in army) { foreach (var unit in army)
{
armyValue += unit.Production().Alloy + unit.Production().Ether; armyValue += unit.Production().Alloy + unit.Production().Ether;
} }
@ -135,7 +146,8 @@
} }
for (var interval = 0; interval < economyOverTime.Count(); interval++) { for (var interval = 0; interval < economyOverTime.Count(); interval++)
{
var alloyPoint = new PointModel { Interval = interval }; var alloyPoint = new PointModel { Interval = interval };
var etherPoint = new PointModel { Interval = interval }; var etherPoint = new PointModel { Interval = interval };
var pyrePoint = new PointModel { Interval = interval }; var pyrePoint = new PointModel { Interval = interval };
@ -167,26 +179,32 @@
float economySpending = 0; float economySpending = 0;
foreach (var alloyAutoHarvester in alloyAutomaticHarvesters) { foreach (var alloyAutoHarvester in alloyAutomaticHarvesters)
{
autoAlloy += alloyAutoHarvester.Harvest().Slots * alloyAutoHarvester.Harvest().HarvestedPerInterval; autoAlloy += alloyAutoHarvester.Harvest().Slots * alloyAutoHarvester.Harvest().HarvestedPerInterval;
var production = alloyAutoHarvester.Production(); var production = alloyAutoHarvester.Production();
if (production != null) { if (production != null)
{
economySpending += production.Alloy; economySpending += production.Alloy;
} }
} }
foreach (var alloyWorkerHarvester in alloyWorkerHarvesters) { foreach (var alloyWorkerHarvester in alloyWorkerHarvesters)
{
workerSlots += alloyWorkerHarvester.Harvest().Slots; workerSlots += alloyWorkerHarvester.Harvest().Slots;
var production = alloyWorkerHarvester.Production(); var production = alloyWorkerHarvester.Production();
if (production != null) { if (production != null)
{
economySpending += production.Alloy; economySpending += production.Alloy;
} }
} }
foreach (var etherWorkerHarvester in etherAutomaticHarvesters) { foreach (var etherWorkerHarvester in etherAutomaticHarvesters)
{
autoEther += etherWorkerHarvester.Harvest().Slots * etherWorkerHarvester.Harvest().HarvestedPerInterval; autoEther += etherWorkerHarvester.Harvest().Slots * etherWorkerHarvester.Harvest().HarvestedPerInterval;
var production = etherWorkerHarvester.Production(); var production = etherWorkerHarvester.Production();
if (production != null) { if (production != null)
{
economySpending += production.Alloy; economySpending += production.Alloy;
} }
} }
@ -200,7 +218,8 @@
etherPoint.Value = autoEther; etherPoint.Value = autoEther;
if (interval > 0) { if (interval > 0)
{
alloyPoint.TempValue += alloyChart.Points.Last().TempValue; alloyPoint.TempValue += alloyChart.Points.Last().TempValue;
etherPoint.Value += etherChart.Points.Last().Value; etherPoint.Value += etherChart.Points.Last().Value;
pyrePoint.Value = pyreChart.Points.Last().Value + 1; pyrePoint.Value = pyreChart.Points.Last().Value + 1;

28
IGP/Pages/BuildCalculator/Parts/EntityClickViewComponent.razor

@ -1,35 +1,39 @@
@implements IDisposable @implements IDisposable
<div style="overflow-y: scroll; width: 100%; overflow-x: hidden; height: 550px;"> <div style="overflow-y: scroll; width: 100%; overflow-x: hidden; height: 550px;">
@if (Entity != null) { @if (entity != null)
{
<EntityViewComponent Entity=Entity></EntityViewComponent> <EntityViewComponent Entity=Entity></EntityViewComponent>
} }
</div> </div>
@code { @code {
EntityModel Entity; private EntityModel entity = default!;
[Inject] [Inject]
IKeyService KeyService { get; set; } IKeyService KeyService { get; set; } = default!;
[Inject] [Inject]
IImmortalSelectionService FilterService { get; set; } IImmortalSelectionService FilterService { get; set; } = default!;
[Inject] [Inject]
IBuildOrderService BuildOrderService { get; set; } IBuildOrderService BuildOrderService { get; set; } = default!;
protected override void OnInitialized() { protected override void OnInitialized()
{
KeyService.Subscribe(HandleClick); KeyService.Subscribe(HandleClick);
BuildOrderService.Subscribe(OnBuildOrderChanged); BuildOrderService.Subscribe(OnBuildOrderChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
KeyService.Unsubscribe(HandleClick); KeyService.Unsubscribe(HandleClick);
BuildOrderService.Unsubscribe(OnBuildOrderChanged); BuildOrderService.Unsubscribe(OnBuildOrderChanged);
} }
protected void HandleClick() { protected void HandleClick()
{
var hotkey = KeyService.GetHotkey(); var hotkey = KeyService.GetHotkey();
var hotkeyGroup = KeyService.GetHotkeyGroup(); var hotkeyGroup = KeyService.GetHotkeyGroup();
var isHoldSpace = KeyService.IsHoldingSpace(); var isHoldSpace = KeyService.IsHoldingSpace();
@ -38,13 +42,15 @@
var foundEntity = EntityModel.GetFrom(hotkey, hotkeyGroup, isHoldSpace, faction, immortal); var foundEntity = EntityModel.GetFrom(hotkey, hotkeyGroup, isHoldSpace, faction, immortal);
if (foundEntity != null) { if (foundEntity != null)
Entity = foundEntity; {
entity = foundEntity;
StateHasChanged(); StateHasChanged();
} }
} }
void OnBuildOrderChanged() { void OnBuildOrderChanged()
{
StateHasChanged(); StateHasChanged();
} }

18
IGP/Pages/BuildCalculator/Parts/FilterComponent.razor

@ -10,11 +10,13 @@
<FormSelectComponent OnChange="@OnImmortalChanged"> <FormSelectComponent OnChange="@OnImmortalChanged">
<FormLabelComponent>Immortal</FormLabelComponent> <FormLabelComponent>Immortal</FormLabelComponent>
<ChildContent> <ChildContent>
@if (FilterService.GetFactionType() == FactionType.QRath) { @if (FilterService.GetFactionType() == FactionType.QRath)
{
<option value="@ImmortalType.Orzum" selected>Orzum</option> <option value="@ImmortalType.Orzum" selected>Orzum</option>
<option value="@ImmortalType.Ajari">Ajari</option> <option value="@ImmortalType.Ajari">Ajari</option>
} }
@if (FilterService.GetFactionType() == FactionType.Aru) { @if (FilterService.GetFactionType() == FactionType.Aru)
{
<option value="@ImmortalType.Mala" selected>Mala</option> <option value="@ImmortalType.Mala" selected>Mala</option>
<option value="@ImmortalType.Xol">Xol</option> <option value="@ImmortalType.Xol">Xol</option>
} }
@ -25,14 +27,16 @@
@code { @code {
[Inject] [Inject]
public IImmortalSelectionService FilterService { get; set; } public IImmortalSelectionService FilterService { get; set; } = default!;
void OnFactionChanged(ChangeEventArgs e) { void OnFactionChanged(ChangeEventArgs e)
FilterService.SelectFactionType(e.Value.ToString()); {
FilterService.SelectFactionType(e.Value!.ToString()!);
} }
void OnImmortalChanged(ChangeEventArgs e) { void OnImmortalChanged(ChangeEventArgs e)
FilterService.SelectImmortalType(e.Value.ToString()); {
FilterService.SelectImmortalType(e.Value!.ToString()!);
} }
} }

30
IGP/Pages/BuildCalculator/Parts/HighlightsComponent.razor

@ -4,9 +4,12 @@
<div> <div>
<div>Requested</div> <div>Requested</div>
@for (var i = TimingService.GetTiming() - 1; i >= 0; i--) { @for (var i = TimingService.GetTiming() - 1; i >= 0; i--)
@foreach (var order in BuildOrderService.GetOrdersAt(i)) { {
if (order.EntityType == EntityType.Worker) { @foreach (var order in BuildOrderService.GetOrdersAt(i))
{
if (order.EntityType == EntityType.Worker)
{
continue; continue;
} }
<div> <div>
@ -22,9 +25,12 @@
<div> <div>
<div>Finished</div> <div>Finished</div>
@for (var i = TimingService.GetTiming() - 1; i >= 0; i--) { @for (var i = TimingService.GetTiming() - 1; i >= 0; i--)
@foreach (var order in BuildOrderService.GetCompletedAt(i)) { {
if (order.EntityType == EntityType.Worker) { @foreach (var order in BuildOrderService.GetCompletedAt(i))
{
if (order.EntityType == EntityType.Worker)
{
continue; continue;
} }
<div> <div>
@ -54,20 +60,22 @@
@code { @code {
[Inject] [Inject]
IEconomyService EconomyService { get; set; } IEconomyService EconomyService { get; set; } = default!;
[Inject] [Inject]
IBuildOrderService BuildOrderService { get; set; } IBuildOrderService BuildOrderService { get; set; } = default!;
[Inject] [Inject]
ITimingService TimingService { get; set; } ITimingService TimingService { get; set; } = default!;
protected override void OnInitialized() { protected override void OnInitialized()
{
EconomyService.Subscribe(StateHasChanged); EconomyService.Subscribe(StateHasChanged);
BuildOrderService.Subscribe(StateHasChanged); BuildOrderService.Subscribe(StateHasChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
EconomyService.Unsubscribe(StateHasChanged); EconomyService.Unsubscribe(StateHasChanged);
BuildOrderService.Unsubscribe(StateHasChanged); BuildOrderService.Unsubscribe(StateHasChanged);
} }

131
IGP/Pages/BuildCalculator/Parts/HotkeyViewerComponent.razor

@ -2,8 +2,10 @@
<InputPanelComponent> <InputPanelComponent>
<div class="keyContainer"> <div class="keyContainer">
@foreach (var hotkey in hotkeys) { @foreach (var hotkey in hotkeys)
if (hotkey.IsHidden) { {
if (hotkey.IsHidden)
{
continue; continue;
} }
@ -14,14 +16,17 @@
var y = hotkey.PositionY * Size; var y = hotkey.PositionY * Size;
var border = "1px solid black"; var border = "1px solid black";
if (hotkey.KeyText.Equals(_key)) { if (hotkey.KeyText.Equals(_key))
{
border = "5px solid black"; border = "5px solid black";
} }
if (hotkey.KeyText.Equals(_controlGroup)) { if (hotkey.KeyText.Equals(_controlGroup))
{
border = "5px solid green"; border = "5px solid green";
} }
if (hotkey.KeyText.Equals("SPACE") && KeyService.IsHoldingSpace()) { if (hotkey.KeyText.Equals("SPACE") && KeyService.IsHoldingSpace())
{
border = "5px solid green"; border = "5px solid green";
} }
@ -39,16 +44,20 @@
overflow: hidden; overflow: hidden;
padding: 4px;"> padding: 4px;">
@hotkey.KeyText @hotkey.KeyText
@foreach (var entity in data.Values) { @foreach (var entity in data.Values)
if (!BuildOrderService.MeetsRequirements(entity, 9000)) { {
if (!BuildOrderService.MeetsRequirements(entity, 9000))
{
continue; continue;
} }
if (InvalidKey(entity, hotkey) || InvalidKeyGroup(entity, hotkey) || InvalidHoldSpace(entity)) { if (InvalidKey(entity, hotkey) || InvalidKeyGroup(entity, hotkey) || InvalidHoldSpace(entity))
{
continue; continue;
} }
if (InvalidFaction(entity) || InvalidVanguard(entity) || InvalidNonVanguard(entity)) { if (InvalidFaction(entity) || InvalidVanguard(entity) || InvalidNonVanguard(entity))
{
continue; continue;
} }
@ -77,7 +86,7 @@
@@media only screen and (max-width: 1025px) { @@media only screen and (max-width: 1025px) {
.keyContainer { .keyContainer {
transform: scale(0.85) translateX(-20px); transform: scale(0.85) translateX(-20px);
background-color: none; background-color: transparent;
outline: none; outline: none;
} }
} }
@ -89,13 +98,13 @@
public int Size { get; set; } = 100; public int Size { get; set; } = 100;
[Inject] [Inject]
public IKeyService KeyService { get; set; } public IKeyService KeyService { get; set; } = default!;
[Inject] [Inject]
public IBuildOrderService BuildOrderService { get; set; } public IBuildOrderService BuildOrderService { get; set; } = default!;
[Inject] [Inject]
public IImmortalSelectionService FilterService { get; set; } public IImmortalSelectionService FilterService { get; set; } = default!;
readonly Dictionary<string, EntityModel> data = EntityModel.GetDictionary(); readonly Dictionary<string, EntityModel> data = EntityModel.GetDictionary();
readonly List<HotkeyModel> hotkeys = HotkeyModel.GetAll(); readonly List<HotkeyModel> hotkeys = HotkeyModel.GetAll();
@ -103,21 +112,25 @@
public string _controlGroup = "C"; public string _controlGroup = "C";
public string _key = ""; public string _key = "";
protected override void OnInitialized() { protected override void OnInitialized()
{
base.OnInitialized(); base.OnInitialized();
KeyService.Subscribe(OnKeyPressed); KeyService.Subscribe(OnKeyPressed);
FilterService.Subscribe(StateHasChanged); FilterService.Subscribe(StateHasChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
KeyService.Unsubscribe(OnKeyPressed); KeyService.Unsubscribe(OnKeyPressed);
FilterService.Unsubscribe(StateHasChanged); FilterService.Unsubscribe(StateHasChanged);
} }
// Move to Filter Service // Move to Filter Service
bool InvalidFaction(EntityModel entity) { bool InvalidFaction(EntityModel entity)
if (entity.Faction() != null && entity.Faction()?.Faction != FilterService.GetFactionType() && FilterService.GetFactionType() != FactionType.Any) { {
if (entity.Faction() != null && entity.Faction()?.Faction != FilterService.GetFactionType() && FilterService.GetFactionType() != FactionType.Any)
{
return true; return true;
} }
@ -125,8 +138,10 @@
} }
// Move to Filter Service // Move to Filter Service
bool InvalidVanguard(EntityModel entity) { bool InvalidVanguard(EntityModel entity)
if (entity.VanguardAdded() != null && entity.VanguardAdded()?.ImmortalId != FilterService.GetImmortalType() && FilterService.GetImmortalType() != ImmortalType.Any) { {
if (entity.VanguardAdded() != null && entity.VanguardAdded()?.ImmortalId != FilterService.GetImmortalType() && FilterService.GetImmortalType() != ImmortalType.Any)
{
return true; return true;
} }
@ -134,16 +149,21 @@
} }
// Move to Filter Service // Move to Filter Service
bool InvalidNonVanguard(EntityModel entity) { bool InvalidNonVanguard(EntityModel entity)
if (entity.Replaceds().Count > 0) { {
if (entity.Replaceds().Count > 0)
{
var isReplaced = false; var isReplaced = false;
foreach (var replaced in entity.Replaceds()) { foreach (var replaced in entity.Replaceds())
if (FilterService.GetImmortalType() == replaced.ImmortalId) { {
if (FilterService.GetImmortalType() == replaced.ImmortalId)
{
isReplaced = true; isReplaced = true;
break; break;
} }
} }
if (isReplaced) { if (isReplaced)
{
return true; return true;
} }
} }
@ -151,75 +171,96 @@
return false; return false;
} }
bool InvalidRequirements(EntityModel entity) { bool InvalidRequirements(EntityModel entity)
{
return !BuildOrderService.MeetsRequirements(entity, 9000); return !BuildOrderService.MeetsRequirements(entity, 9000);
} }
bool InvalidKey(EntityModel entity, HotkeyModel key) { bool InvalidKey(EntityModel entity, HotkeyModel key)
if (entity.Hotkey()?.Hotkey == key.KeyText) { {
if (entity.Hotkey()?.Hotkey == key.KeyText)
{
return false; return false;
} }
return true; return true;
} }
bool InvalidKeyGroup(EntityModel entity, HotkeyModel key) { bool InvalidKeyGroup(EntityModel entity, HotkeyModel key)
if (entity.Hotkey()?.HotkeyGroup == _controlGroup) { {
if (entity.Hotkey()?.HotkeyGroup == _controlGroup)
{
return false; return false;
} }
return true; return true;
} }
bool InvalidKey(EntityModel entity) { bool InvalidKey(EntityModel entity)
if (entity.Hotkey()?.Hotkey == _key) { {
if (entity.Hotkey()?.Hotkey == _key)
{
return false; return false;
} }
return true; return true;
} }
bool InvalidKeyGroup(EntityModel entity) { bool InvalidKeyGroup(EntityModel entity)
if (entity.Hotkey()?.HotkeyGroup == _controlGroup) { {
if (entity.Hotkey()?.HotkeyGroup == _controlGroup)
{
return false; return false;
} }
return true; return true;
} }
bool InvalidHoldSpace(EntityModel entity) { bool InvalidHoldSpace(EntityModel entity)
if (entity.Hotkey()?.HoldSpace == KeyService.IsHoldingSpace()) { {
if (entity.Hotkey()?.HoldSpace == KeyService.IsHoldingSpace())
{
return false; return false;
} }
return true; return true;
} }
void OnKeyPressed() { void OnKeyPressed()
if (KeyService.GetAllPressedKeys().Contains("Z")) { {
if (KeyService.GetAllPressedKeys().Contains("Z"))
{
_controlGroup = "Z"; _controlGroup = "Z";
} }
if (KeyService.GetAllPressedKeys().Contains("TAB")) { if (KeyService.GetAllPressedKeys().Contains("TAB"))
{
_controlGroup = "TAB"; _controlGroup = "TAB";
} }
if (KeyService.GetAllPressedKeys().Contains("C")) { if (KeyService.GetAllPressedKeys().Contains("C"))
{
_controlGroup = "C"; _controlGroup = "C";
} }
if (KeyService.GetAllPressedKeys().Contains("D")) { if (KeyService.GetAllPressedKeys().Contains("D"))
{
_controlGroup = "D"; _controlGroup = "D";
} }
if (KeyService.GetAllPressedKeys().Contains("1")) { if (KeyService.GetAllPressedKeys().Contains("1"))
{
_controlGroup = "1"; _controlGroup = "1";
} }
//TODO This could be better. Duplicated code //TODO This could be better. Duplicated code
if (KeyService.GetAllPressedKeys().Contains("2")) { if (KeyService.GetAllPressedKeys().Contains("2"))
{
_controlGroup = "2"; _controlGroup = "2";
} }
if (KeyService.GetAllPressedKeys().Contains("SHIFT")) { if (KeyService.GetAllPressedKeys().Contains("SHIFT"))
{
_controlGroup = "SHIFT"; _controlGroup = "SHIFT";
} }
if (KeyService.GetAllPressedKeys().Contains("CONTROL")) { if (KeyService.GetAllPressedKeys().Contains("CONTROL"))
{
_controlGroup = "CONTROL"; _controlGroup = "CONTROL";
} }
if (KeyService.GetAllPressedKeys().Count > 0) { if (KeyService.GetAllPressedKeys().Count > 0)
{
_key = KeyService.GetAllPressedKeys().First(); _key = KeyService.GetAllPressedKeys().First();
} }

10
IGP/Pages/BuildCalculator/Parts/InputPanelComponent.razor

@ -10,16 +10,18 @@
@code { @code {
[Parameter] [Parameter]
public RenderFragment ChildContent { get; set; } public RenderFragment ChildContent { get; set; } = default!;
[Inject] [Inject]
public IKeyService KeyService { get; set; } public IKeyService KeyService { get; set; } = default!;
private void HandleKeyDown(KeyboardEventArgs e) { private void HandleKeyDown(KeyboardEventArgs e)
{
KeyService.AddPressedKey(e.Key); KeyService.AddPressedKey(e.Key);
} }
private void HandleKeyUp(KeyboardEventArgs e) { private void HandleKeyUp(KeyboardEventArgs e)
{
KeyService.RemovePressedKey(e.Key); KeyService.RemovePressedKey(e.Key);
} }

16
IGP/Pages/BuildCalculator/Parts/TimelineComponent.razor

@ -24,12 +24,14 @@
<br/> <br/>
</div> </div>
<div> <div>
@foreach (var order in BuildOrderService.GetOrdersAt(economyAtSecond.Interval)) { @foreach (var order in BuildOrderService.GetOrdersAt(economyAtSecond.Interval))
{
<div> <div>
Requested: @order.Info().Name Requested: @order.Info().Name
</div> </div>
} }
@foreach (var order in BuildOrderService.GetCompletedAt(economyAtSecond.Interval)) { @foreach (var order in BuildOrderService.GetCompletedAt(economyAtSecond.Interval))
{
<div> <div>
New: @order.Info().Name New: @order.Info().Name
</div> </div>
@ -42,17 +44,19 @@
@code { @code {
[Inject] [Inject]
IEconomyService EconomyService { get; set; } IEconomyService EconomyService { get; set; } = default!;
[Inject] [Inject]
IBuildOrderService BuildOrderService { get; set; } IBuildOrderService BuildOrderService { get; set; } = default!;
protected override void OnInitialized() { protected override void OnInitialized()
{
EconomyService.Subscribe(StateHasChanged); EconomyService.Subscribe(StateHasChanged);
BuildOrderService.Subscribe(StateHasChanged); BuildOrderService.Subscribe(StateHasChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
EconomyService.Unsubscribe(StateHasChanged); EconomyService.Unsubscribe(StateHasChanged);
BuildOrderService.Unsubscribe(StateHasChanged); BuildOrderService.Unsubscribe(StateHasChanged);
} }

27
IGP/Pages/BuildCalculator/Parts/TimingComponent.razor

@ -20,31 +20,36 @@
@code { @code {
[Inject] [Inject]
public ITimingService TimingService { get; set; } public ITimingService TimingService { get; set; } = default!;
[Inject] [Inject]
public IBuildOrderService BuildOrderService { get; set; } public IBuildOrderService BuildOrderService { get; set; } = default!;
void OnTimingChanged(ChangeEventArgs changeEventArgs) { void OnTimingChanged(ChangeEventArgs changeEventArgs)
TimingService.SetTiming(int.Parse(changeEventArgs.Value.ToString())); {
TimingService.SetTiming(int.Parse(changeEventArgs.Value!.ToString()!));
} }
void OnTimingChanged(int value) { void OnTimingChanged(int value)
{
TimingService.SetTiming(value); TimingService.SetTiming(value);
} }
void OnNameChanged(ChangeEventArgs changeEventArgs) { void OnNameChanged(ChangeEventArgs changeEventArgs)
BuildOrderService.SetName(changeEventArgs.Value.ToString()); {
BuildOrderService.SetName(changeEventArgs.Value!.ToString()!);
} }
void OnColorChanged(ChangeEventArgs changeEventArgs) { void OnColorChanged(ChangeEventArgs changeEventArgs)
BuildOrderService.SetColor(changeEventArgs.Value.ToString()); {
BuildOrderService.SetColor(changeEventArgs.Value!.ToString()!);
} }
void OnNotesChanged(ChangeEventArgs changeEventArgs) { void OnNotesChanged(ChangeEventArgs changeEventArgs)
BuildOrderService.SetNotes(changeEventArgs.Value.ToString()); {
BuildOrderService.SetNotes(changeEventArgs.Value!.ToString()!);
} }
} }

54
IGP/Pages/ChangeLogPage.razor

@ -5,7 +5,8 @@
@layout PageLayout @layout PageLayout
@if (GitService.IsLoaded()) { @if (GitService.IsLoaded())
{
<LayoutMediumContentComponent> <LayoutMediumContentComponent>
<WebsiteTitleComponent>Change Log</WebsiteTitleComponent> <WebsiteTitleComponent>Change Log</WebsiteTitleComponent>
@ -20,8 +21,10 @@
</PaperComponent> </PaperComponent>
<PaperComponent> <PaperComponent>
@foreach (var patch in Patches.OrderBy(x => x.Date).Reverse()) { @foreach (var patch in Patches.OrderBy(x => x.Date).Reverse())
@if (!patch.Important.Equals("True") && isViewImportant) { {
@if (!patch.Important.Equals("True") && isViewImportant)
{
continue; continue;
} }
@ -33,21 +36,26 @@
@patch.Name @patch.Name
</div> </div>
<div> <div>
@if (daysAgo == 0) { @if (daysAgo == 0)
{
<i>Today</i> <i>Today</i>
} }
else if (daysAgo < 8) { else if (daysAgo < 8)
{
<i>@daysAgo days ago</i> <i>@daysAgo days ago</i>
} }
else { else
{
<i>@patch.Date.ToString("dd/MM/yyyy")</i> <i>@patch.Date.ToString("dd/MM/yyyy")</i>
} }
</div> </div>
</div> </div>
<div> <div>
@foreach (var change in Changes.FindAll(e => e.PatchModelId == patch.Id)) { @foreach (var change in Changes.FindAll(e => e.GitPatchModelId == patch.Id))
@if (!change.Important.Equals("True") && isViewImportant) { {
@if (!change.Important.Equals("True") && isViewImportant)
{
continue; continue;
} }
@ -57,7 +65,8 @@
<b> <b>
<span>- @change.Name </span> <span>- @change.Name </span>
@if (change.Commit != CommitType.None) { @if (change.Commit != CommitType.None)
{
<span>(@change.Commit)</span> <span>(@change.Commit)</span>
} }
<span>: </span> <span>: </span>
@ -68,23 +77,23 @@
} }
</div> </div>
</div> </div>
} }
</PaperComponent> </PaperComponent>
</LayoutMediumContentComponent> </LayoutMediumContentComponent>
} }
else { else
<LoadingComponent></LoadingComponent> {
<LoadingComponent/>
} }
@code { @code {
#if NO_SQL #if NO_SQL
public List<PatchModel> Patches => GitService.PatchModels; public List<GitPatchModel> Patches => GitService.GitPatchModels;
public List<ChangeModel> Changes => GitService.ChangeModels; public List<GitChangeModel> Changes => GitService.GitChangeModels;
#else #else
[Inject] [Inject]
DatabaseContext Database { get; set; } DatabaseContext Database { get; set; }
@ -99,24 +108,29 @@ else {
private bool isViewImportant = true; private bool isViewImportant = true;
protected override void OnInitialized() { protected override void OnInitialized()
{
GitService.Subscribe(HasChanged); GitService.Subscribe(HasChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
GitService.Unsubscribe(HasChanged); GitService.Unsubscribe(HasChanged);
} }
void OnChangeClicked(ChangeEventArgs changeEventArgs) { void OnChangeClicked(ChangeEventArgs changeEventArgs)
isViewImportant = (bool)changeEventArgs.Value; {
isViewImportant = (bool)changeEventArgs.Value!;
} }
void HasChanged() { void HasChanged()
{
StateHasChanged(); StateHasChanged();
} }
protected override async Task OnInitializedAsync() { protected override async Task OnInitializedAsync()
{
#if NO_SQL #if NO_SQL
GitService.Load(); GitService.Load();
#else #else

31
IGP/Pages/Comparision/ComparisionPage.razor

@ -28,19 +28,19 @@ grid-template-areas: 'loader sand compare compare' ;">
@code { @code {
[Inject] [Inject]
IKeyService KeyService { get; set; } IKeyService KeyService { get; set; } = default!;
[Inject] [Inject]
IImmortalSelectionService FilterService { get; set; } IImmortalSelectionService FilterService { get; set; } = default!;
[Inject] [Inject]
IBuildOrderService BuildOrderService { get; set; } IBuildOrderService BuildOrderService { get; set; } = default!;
[Inject] [Inject]
IEconomyService EconomyService { get; set; } IEconomyService EconomyService { get; set; } = default!;
[Inject] [Inject]
ITimingService TimingService { get; set; } ITimingService TimingService { get; set; } = default!;
Dictionary<int, List<EntityModel>> completedEntities = new(); Dictionary<int, List<EntityModel>> completedEntities = new();
@ -48,7 +48,8 @@ grid-template-areas: 'loader sand compare compare' ;">
List<EntityModel> entities = EntityModel.GetListOnlyHotkey(); List<EntityModel> entities = EntityModel.GetListOnlyHotkey();
protected override void OnInitialized() { protected override void OnInitialized()
{
KeyService.Subscribe(HandleClick); KeyService.Subscribe(HandleClick);
FilterService.Subscribe(StateHasChanged); FilterService.Subscribe(StateHasChanged);
EconomyService.Subscribe(StateHasChanged); EconomyService.Subscribe(StateHasChanged);
@ -56,7 +57,8 @@ grid-template-areas: 'loader sand compare compare' ;">
EconomyService.Calculate(BuildOrderService, TimingService, 0); EconomyService.Calculate(BuildOrderService, TimingService, 0);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
KeyService.Unsubscribe(HandleClick); KeyService.Unsubscribe(HandleClick);
FilterService.Unsubscribe(StateHasChanged); FilterService.Unsubscribe(StateHasChanged);
TimingService.Unsubscribe(StateHasChanged); TimingService.Unsubscribe(StateHasChanged);
@ -64,18 +66,21 @@ grid-template-areas: 'loader sand compare compare' ;">
} }
protected void HandleTimingChanged() { protected void HandleTimingChanged()
{
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval()); EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
} }
protected void HandleClick() { protected void HandleClick()
{
var hotkey = KeyService.GetHotkey(); var hotkey = KeyService.GetHotkey();
var hotkeyGroup = KeyService.GetHotkeyGroup(); var hotkeyGroup = KeyService.GetHotkeyGroup();
var isHoldSpace = KeyService.IsHoldingSpace(); var isHoldSpace = KeyService.IsHoldingSpace();
var faction = FilterService.GetFactionType(); var faction = FilterService.GetFactionType();
var immortal = FilterService.GetImmortalType(); var immortal = FilterService.GetImmortalType();
if (hotkey == "`") { if (hotkey == "`")
{
BuildOrderService.RemoveLast(); BuildOrderService.RemoveLast();
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval()); EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
StateHasChanged(); StateHasChanged();
@ -83,10 +88,12 @@ grid-template-areas: 'loader sand compare compare' ;">
} }
var entity = EntityModel.GetFrom(hotkey, hotkeyGroup, isHoldSpace, faction, immortal); var entity = EntityModel.GetFrom(hotkey, hotkeyGroup, isHoldSpace, faction, immortal);
if (entity == null) { if (entity == null)
{
return; return;
} }
if (BuildOrderService.Add(entity, EconomyService)) { if (BuildOrderService.Add(entity, EconomyService))
{
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval()); EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
} }
} }

11
IGP/Pages/Comparision/Parts/BuildLoaderComponent.razor

@ -16,17 +16,20 @@
string buildData = ""; string buildData = "";
[Inject] [Inject]
IBuildComparisonService BuildComparisionService { get; set; } IBuildComparisonService BuildComparisionService { get; set; } = default!;
protected override void OnInitialized() { protected override void OnInitialized()
{
BuildComparisionService.Subscribe(StateHasChanged); BuildComparisionService.Subscribe(StateHasChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
BuildComparisionService.Unsubscribe(StateHasChanged); BuildComparisionService.Unsubscribe(StateHasChanged);
} }
void OnLoad() { void OnLoad()
{
BuildComparisionService.LoadJson(buildData); BuildComparisionService.LoadJson(buildData);
} }

8
IGP/Pages/Comparision/Parts/SandComponent.razor

@ -9,13 +9,15 @@
@code { @code {
[Inject] [Inject]
IBuildComparisonService BuildComparisonService { get; set; } IBuildComparisonService BuildComparisonService { get; set; } = default!;
protected override void OnInitialized() { protected override void OnInitialized()
{
BuildComparisonService.Subscribe(StateHasChanged); BuildComparisonService.Subscribe(StateHasChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
BuildComparisonService.Unsubscribe(StateHasChanged); BuildComparisonService.Unsubscribe(StateHasChanged);
} }

2
IGP/Pages/ContactPage.razor

@ -11,7 +11,7 @@
How do I contact you for feature requests and bug reports? How do I contact you for feature requests and bug reports?
</InfoQuestionComponent> </InfoQuestionComponent>
<InfoAnswerComponent> <InfoAnswerComponent>
You can direct message me at <b>Iremirror#3544</b> on the <a href="https://discord.gg/uMq8bMGeeN" target="_blank">IGP Fan Reference</a> discord. You can message me at <b>JonathanMcCaffrey#3544</b> on my <a href="https://discord.gg/uMq8bMGeeN" target="_blank">Discord</a> channel.
</InfoAnswerComponent> </InfoAnswerComponent>
</InfoBodyComponent> </InfoBodyComponent>
</PaperComponent> </PaperComponent>

108
IGP/Pages/Database/DatabasePage.razor

@ -10,27 +10,29 @@
<WebsiteTitleComponent>Database</WebsiteTitleComponent> <WebsiteTitleComponent>Database</WebsiteTitleComponent>
<PaperComponent> <PaperComponent>
<FormDisplayComponent Label="Patch"> <FormDisplayComponent Label="Patch">
<Display> <Display>
Game Patch: @EntityModel.GameVersion Game Patch: @EntityModel.GameVersion
</Display> </Display>
</FormDisplayComponent> </FormDisplayComponent>
</PaperComponent> </PaperComponent>
<div style="margin-left: 8px"> <div style="margin-left: 8px">
<ButtonGroupComponent OnClick="((choice => { entityDisplayService.SetDisplayType(choice); }))" Choice="@entityDisplayService.GetDisplayType()" Choices="@entityDisplayService.DefaultChoices()"></ButtonGroupComponent> <ButtonGroupComponent OnClick="choice => { entityDisplayService.SetDisplayType(choice); }" Choice="@entityDisplayService.GetDisplayType()" Choices="@entityDisplayService.DefaultChoices()"></ButtonGroupComponent>
</div> </div>
<PaperComponent> <PaperComponent>
<EntityFilterComponent></EntityFilterComponent> <EntityFilterComponent></EntityFilterComponent>
@if (searches != null) { @if (searches != null)
{
<div class="databaseItems"> <div class="databaseItems">
@foreach (var entity in searches) { @foreach (var entity in searches)
{
<CascadingValue Value="entity"> <CascadingValue Value="entity">
<CascadingValue Value="@entityDisplayService.GetDisplayType()"> <CascadingValue Value="@entityDisplayService.GetDisplayType()">
<EntityViewComponent></EntityViewComponent> <EntityViewComponent></EntityViewComponent>
</CascadingValue> </CascadingValue>
</CascadingValue> </CascadingValue>
} }
</div> </div>
@ -112,16 +114,16 @@
@code { @code {
[Inject] [Inject]
public IEntityFilterService EntityFilterService { get; set; } public IEntityFilterService EntityFilterService { get; set; } = default!;
readonly List<EntityModel> defaults = (from entity in EntityModel.GetList() readonly List<EntityModel> defaults = (from entity in EntityModel.GetList()
where entity.IsSpeculative == false where entity.IsSpeculative == false
select entity).ToList(); select entity).ToList();
List<EntityModel> factions; List<EntityModel> factions = default!;
List<EntityModel> immortals; List<EntityModel> immortals = default!;
List<EntityModel> entities; List<EntityModel> entities = default!;
List<EntityModel> searches; List<EntityModel> searches = default!;
string selectedFactionType = FactionType.Any; string selectedFactionType = FactionType.Any;
@ -129,44 +131,54 @@
string selectedEntityType = EntityType.Army; string selectedEntityType = EntityType.Army;
string searchText = ""; string searchText = "";
protected override void OnInitialized() { protected override void OnInitialized()
{
RefreshFactionSearch(); RefreshFactionSearch();
EntityFilterService.Subscribe(OnChange); EntityFilterService.Subscribe(OnChange);
entityDisplayService.Subscribe(StateHasChanged); entityDisplayService.Subscribe(StateHasChanged);
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
EntityFilterService.Unsubscribe(OnChange); EntityFilterService.Unsubscribe(OnChange);
entityDisplayService.Unsubscribe(StateHasChanged); entityDisplayService.Unsubscribe(StateHasChanged);
} }
void OnChange(EntityFilterEvent filterEntityEvent) { void OnChange(EntityFilterEvent filterEntityEvent)
if (filterEntityEvent == EntityFilterEvent.OnRefreshFaction) { {
if (filterEntityEvent == EntityFilterEvent.OnRefreshFaction)
{
RefreshFactionSearch(); RefreshFactionSearch();
} }
if (filterEntityEvent == EntityFilterEvent.OnRefreshImmortal) { if (filterEntityEvent == EntityFilterEvent.OnRefreshImmortal)
{
RefreshImmortalSearch(); RefreshImmortalSearch();
} }
if (filterEntityEvent == EntityFilterEvent.OnRefreshEntity) { if (filterEntityEvent == EntityFilterEvent.OnRefreshEntity)
{
RefreshEntitySearch(); RefreshEntitySearch();
} }
if (filterEntityEvent == EntityFilterEvent.OnRefreshSearch) { if (filterEntityEvent == EntityFilterEvent.OnRefreshSearch)
{
RefreshTextSearch(); RefreshTextSearch();
} }
} }
void RefreshFactionSearch() { void RefreshFactionSearch()
{
selectedFactionType = EntityFilterService.GetFactionType(); selectedFactionType = EntityFilterService.GetFactionType();
if (selectedFactionType == FactionType.Any) { if (selectedFactionType == FactionType.Any)
{
factions = defaults.ToList(); factions = defaults.ToList();
} }
else { else
{
factions = (from entity in defaults factions = (from entity in defaults
where entity.Faction() != null && entity.Faction().Faction == selectedFactionType where entity.Faction() != null && entity.Faction().Faction == selectedFactionType
select entity).ToList(); select entity).ToList();
@ -176,18 +188,22 @@
} }
void OnImmortalChanged(ChangeEventArgs e) { void OnImmortalChanged(ChangeEventArgs e)
selectedImmortalType = e.Value.ToString(); {
selectedImmortalType = e.Value!.ToString()!;
RefreshImmortalSearch(); RefreshImmortalSearch();
} }
void RefreshImmortalSearch() { void RefreshImmortalSearch()
{
selectedImmortalType = EntityFilterService.GetImmortalType(); selectedImmortalType = EntityFilterService.GetImmortalType();
if (selectedImmortalType == ImmortalType.Any) { if (selectedImmortalType == ImmortalType.Any)
{
immortals = factions.ToList(); immortals = factions.ToList();
} }
else { else
{
immortals = (from entity in factions immortals = (from entity in factions
where entity.VanguardAdded() == null || entity.VanguardAdded().ImmortalId == selectedImmortalType where entity.VanguardAdded() == null || entity.VanguardAdded().ImmortalId == selectedImmortalType
select entity).ToList(); select entity).ToList();
@ -196,18 +212,22 @@
RefreshEntitySearch(); RefreshEntitySearch();
} }
void OnEntityChanged(ChangeEventArgs e) { void OnEntityChanged(ChangeEventArgs e)
selectedEntityType = e.Value.ToString(); {
selectedEntityType = e.Value!.ToString()!;
RefreshEntitySearch(); RefreshEntitySearch();
} }
void RefreshEntitySearch() { void RefreshEntitySearch()
{
selectedEntityType = EntityFilterService.GetEntityType(); selectedEntityType = EntityFilterService.GetEntityType();
if (selectedEntityType == EntityType.Any) { if (selectedEntityType == EntityType.Any)
{
entities = immortals.ToList(); entities = immortals.ToList();
} }
else { else
{
entities = (from entity in immortals entities = (from entity in immortals
where entity.EntityType == selectedEntityType where entity.EntityType == selectedEntityType
select entity).ToList(); select entity).ToList();
@ -216,18 +236,22 @@
RefreshTextSearch(); RefreshTextSearch();
} }
void OnSearchTextChanged(ChangeEventArgs e) { void OnSearchTextChanged(ChangeEventArgs e)
searchText = e.Value.ToString(); {
searchText = e.Value!.ToString()!;
RefreshTextSearch(); RefreshTextSearch();
} }
void RefreshTextSearch() { void RefreshTextSearch()
{
searchText = EntityFilterService.GetSearchText(); searchText = EntityFilterService.GetSearchText();
if (searchText.Trim() == "") { if (searchText.Trim() == "")
{
searches = entities.ToList(); searches = entities.ToList();
} }
else { else
{
searches = (from entity in entities searches = (from entity in entities
where entity.Info().Name.ToLower().Contains(searchText.ToLower()) where entity.Info().Name.ToLower().Contains(searchText.ToLower())
select entity).ToList(); select entity).ToList();

39
IGP/Pages/Database/DatabaseSinglePage.razor

@ -7,7 +7,7 @@
@implements IDisposable @implements IDisposable
<LayoutLargeContentComponent> <LayoutLargeContentComponent>
<PaperComponent> <PaperComponent>
<FormDisplayComponent Label="Patch"> <FormDisplayComponent Label="Patch">
<Display> <Display>
@ -15,18 +15,19 @@
</Display> </Display>
</FormDisplayComponent> </FormDisplayComponent>
</PaperComponent> </PaperComponent>
<div style="margin-left: 8px"> <div style="margin-left: 8px">
<ButtonGroupComponent OnClick="((choice => { entityDisplayService.SetDisplayType(choice); }))" Choice="@entityDisplayService.GetDisplayType()" Choices="@entityDisplayService.DefaultChoices()"></ButtonGroupComponent> <ButtonGroupComponent OnClick="choice => { entityDisplayService.SetDisplayType(choice); }" Choice="@entityDisplayService.GetDisplayType()" Choices="@entityDisplayService.DefaultChoices()"></ButtonGroupComponent>
</div> </div>
@if(Text.Trim().ToLower().Equals("walter")) @if (Text!.Trim().ToLower().Equals("walter"))
{ {
<PaperComponent> <PaperComponent>
<CodeComponent>Unhandled Exception: EXCEPTION_MEMORY_SIZE_VIOLATION <CodeComponent>
Unhandled Exception: EXCEPTION_MEMORY_SIZE_VIOLATION
UNIT_WALTER too powerful to be displayed. UNIT_WALTER too powerful to be displayed.
This SHOULD NEVER HAPPEN! This SHOULD NEVER HAPPEN!
</CodeComponent> </CodeComponent>
</PaperComponent> </PaperComponent>
@ -37,36 +38,35 @@
<div>Invalid entity name entered: @Text</div> <div>Invalid entity name entered: @Text</div>
<div>No such entity. Did you mean <b>"Throne"</b>?</div> <div>No such entity. Did you mean <b>"Throne"</b>?</div>
</PaperComponent> </PaperComponent>
} }
else else
{ {
<PaperComponent> <PaperComponent>
<CascadingValue Value="entity"> <CascadingValue Value="entity">
<CascadingValue Value="@entityDisplayService.GetDisplayType()"> <CascadingValue Value="@entityDisplayService.GetDisplayType()">
<EntityViewComponent></EntityViewComponent> <EntityViewComponent></EntityViewComponent>
</CascadingValue> </CascadingValue>
</CascadingValue> </CascadingValue>
</PaperComponent> </PaperComponent>
} }
</LayoutLargeContentComponent>
</LayoutLargeContentComponent>
@code { @code {
[Parameter] [Parameter]
public string? Text { get; set; } public string? Text { get; set; }
private EntityModel? entity = null; private EntityModel? entity;
protected override void OnInitialized() protected override void OnInitialized()
{ {
entityDisplayService.Subscribe(StateHasChanged); entityDisplayService.Subscribe(StateHasChanged);
foreach (var e in DATA.Get().Values) foreach (var e in DATA.Get().Values)
{ {
if (e.Info().Name.Equals(Text)) if (e.Info().Name.Equals(Text))
@ -76,8 +76,9 @@
} }
} }
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
entityDisplayService.Unsubscribe(StateHasChanged); entityDisplayService.Unsubscribe(StateHasChanged);
} }

7
IGP/Pages/Database/Entity/EntityViewComponent.razor

@ -1,4 +1,5 @@
@if (Entity != null) { @if (Entity != null)
{
var isVanguard = Entity.VanguardAdded() != null ? " vanguard" : ""; var isVanguard = Entity.VanguardAdded() != null ? " vanguard" : "";
<div class="enititiesContainer @isVanguard"> <div class="enititiesContainer @isVanguard">
@ -47,9 +48,11 @@
</style> </style>
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; }
[CascadingParameter] [CascadingParameter]
public string? StyleType { get; set; } public string? StyleType { get; set; }
} }

64
IGP/Pages/Database/Entity/Parts/EntityAbilitiesComponent.razor

@ -1,7 +1,9 @@
@if (Entity.IdAbilities().Count > 0) { @if (Entity!.IdAbilities().Count > 0)
{
@if (StyleType.Equals("Plain")) @if (StyleType.Equals("Plain"))
{ {
@foreach (var idAbility in Entity.IdAbilities()) { @foreach (var idAbility in Entity.IdAbilities())
{
var spell = EntityModel.Get(idAbility.Id); var spell = EntityModel.Get(idAbility.Id);
var info = spell.Info(); var info = spell.Info();
@ -14,26 +16,31 @@
<div> <div>
<b>- Description:</b> @((MarkupString)info.Description) <b>- Description:</b> @((MarkupString)info.Description)
</div> </div>
@if (!info.Notes.Trim().Equals("")) { @if (!info.Notes.Trim().Equals(""))
{
<div> <div>
<b>- Notes:</b> @((MarkupString)info.Notes) <b>- Notes:</b> @((MarkupString)info.Notes)
</div> </div>
} }
<div> <div>
@if (production != null) { @if (production != null)
if (production.Energy != 0) { {
if (production.Energy != 0)
{
<div> <div>
<b>- Energy: </b> @production.Energy <b>- Energy: </b> @production.Energy
</div> </div>
} }
if (production.BuildTime != 0) { if (production.BuildTime != 0)
{
<div> <div>
<b>- BuildTime: </b> @production.BuildTime <b>- BuildTime: </b> @production.BuildTime
</div> </div>
} }
if (production.Cooldown != 0) { if (production.Cooldown != 0)
{
<div> <div>
<b>- Cooldown: </b> @production.Cooldown <b>- Cooldown: </b> @production.Cooldown
</div> </div>
@ -42,13 +49,12 @@
</div> </div>
</div> </div>
} }
} }
else else
{ {
<EntityDisplayComponent Title="Abilities"> <EntityDisplayComponent Title="Abilities">
@foreach (var idAbility in Entity.IdAbilities()) { @foreach (var idAbility in Entity.IdAbilities())
{
var spell = EntityModel.Get(idAbility.Id); var spell = EntityModel.Get(idAbility.Id);
var info = spell.Info(); var info = spell.Info();
@ -61,26 +67,31 @@
<div> <div>
<b>Description:</b> @((MarkupString)info.Description) <b>Description:</b> @((MarkupString)info.Description)
</div> </div>
@if (!info.Notes.Trim().Equals("")) { @if (!info.Notes.Trim().Equals(""))
{
<div> <div>
<b>Notes:</b> @((MarkupString)info.Notes) <b>Notes:</b> @((MarkupString)info.Notes)
</div> </div>
} }
<div> <div>
@if (production != null) { @if (production != null)
if (production.Energy != 0) { {
if (production.Energy != 0)
{
<div> <div>
<b> Energy: </b> @production.Energy <b> Energy: </b> @production.Energy
</div> </div>
} }
if (production.BuildTime != 0) { if (production.BuildTime != 0)
{
<div> <div>
<b> BuildTime: </b> @production.BuildTime <b> BuildTime: </b> @production.BuildTime
</div> </div>
} }
if (production.Cooldown != 0) { if (production.Cooldown != 0)
{
<div> <div>
<b> Cooldown: </b> @production.Cooldown <b> Cooldown: </b> @production.Cooldown
</div> </div>
@ -89,19 +100,18 @@
</div> </div>
</div> </div>
} }
</EntityDisplayComponent> </EntityDisplayComponent>
} }
} }
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";
} }

19
IGP/Pages/Database/Entity/Parts/EntityHeaderComponent.razor

@ -1,11 +1,12 @@
@if (StyleType.Equals("Plain")) @if (StyleType.Equals("Plain"))
{ {
<div><b>@Entity?.Info().Name</b> <div>
@if (Entity?.Info().Descriptive != DescriptiveType.None) <b>@Entity?.Info().Name</b>
{ @if (Entity?.Info().Descriptive != DescriptiveType.None)
<span>, @Entity?.Info().Descriptive.Replace("_", " ")</span> {
} <span>, @Entity?.Info().Descriptive.Replace("_", " ")</span>
</div> }
</div>
} }
else else
{ {
@ -18,7 +19,7 @@ else
@if (Entity?.Info().Descriptive != DescriptiveType.None) @if (Entity?.Info().Descriptive != DescriptiveType.None)
{ {
<span> <span>
<b>:</b> @Entity.Info().Descriptive.Replace("_", " ") <b>:</b> @Entity!.Info().Descriptive.Replace("_", " ")
</span> </span>
} }
</div> </div>
@ -53,9 +54,9 @@ else
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";

41
IGP/Pages/Database/Entity/Parts/EntityInfoComponent.razor

@ -1,34 +1,38 @@
 @if (StyleType.Equals("Plain"))
@if (StyleType.Equals("Plain"))
{ {
@if (Entity.Info().Description != "") { @if (Entity!.Info().Description != "")
{
<div> <div>
<b>Description:</b> @((MarkupString)Entity.Info().Description) <b>Description:</b> @((MarkupString)Entity.Info().Description)
</div> </div>
} }
@if (Entity.Info().Notes != "") { @if (Entity.Info().Notes != "")
{
<div> <div>
<b>Notes:</b> @((MarkupString)Entity.Info().Notes) <b>Notes:</b> @((MarkupString)Entity.Info().Notes)
</div> </div>
} }
<div class="infoDisplayContainer"> <div class="infoDisplayContainer">
<div> <div>
@if (Entity.Faction() != null) { @if (Entity.Faction() != null)
{
<div> <div>
<b>Faction:</b> @Entity.Faction().Faction <b>Faction:</b> @Entity.Faction().Faction
</div> </div>
} }
@if (Entity.Tier() != null) { @if (Entity.Tier() != null)
{
<div> <div>
<b>Tier:</b> @Entity.Tier().Tier <b>Tier:</b> @Entity.Tier().Tier
</div> </div>
} }
</div> </div>
@if (Entity.Hotkey() != null) { @if (Entity.Hotkey() != null)
{
<div> <div>
<div> <div>
<b>Hotkey Group:</b> @Entity.Hotkey().HotkeyGroup <b>Hotkey Group:</b> @Entity.Hotkey().HotkeyGroup
@ -46,34 +50,39 @@
else else
{ {
<EntityDisplayComponent Title="Info"> <EntityDisplayComponent Title="Info">
@if (Entity.Info().Description != "") { @if (Entity!.Info().Description != "")
{
<div> <div>
<b>Description:</b> @((MarkupString)Entity.Info().Description) <b>Description:</b> @((MarkupString)Entity.Info().Description)
</div> </div>
} }
@if (Entity.Info().Notes != "") { @if (Entity.Info().Notes != "")
{
<div> <div>
<b>Notes:</b> @((MarkupString)Entity.Info().Notes) <b>Notes:</b> @((MarkupString)Entity.Info().Notes)
</div> </div>
} }
<div class="infoDisplayContainer"> <div class="infoDisplayContainer">
<div> <div>
@if (Entity.Faction() != null) { @if (Entity.Faction() != null)
{
<div> <div>
<b>Faction:</b> @Entity.Faction().Faction <b>Faction:</b> @Entity.Faction().Faction
</div> </div>
} }
@if (Entity.Tier() != null) { @if (Entity.Tier() != null)
{
<div> <div>
<b>Tier:</b> @Entity.Tier().Tier <b>Tier:</b> @Entity.Tier().Tier
</div> </div>
} }
</div> </div>
@if (Entity.Hotkey() != null) { @if (Entity.Hotkey() != null)
{
<div> <div>
<div> <div>
<b>Hotkey Group:</b> @Entity.Hotkey().HotkeyGroup <b>Hotkey Group:</b> @Entity.Hotkey().HotkeyGroup
@ -101,7 +110,7 @@ else
gap: 4px; gap: 4px;
} }
} }
</style> </style>
} }
@ -109,7 +118,7 @@ else
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";

10
IGP/Pages/Database/Entity/Parts/EntityMechanicsComponent.razor

@ -1,7 +1,9 @@
@if (Entity.Mechanics().Count > 0) { @if (Entity!.Mechanics().Count > 0)
{
<EntityDisplayComponent Title="Mechanics"> <EntityDisplayComponent Title="Mechanics">
<div> <div>
@foreach (var data in Entity.Mechanics()) { @foreach (var data in Entity.Mechanics())
{
<div> <div>
<div> <div>
<span> <span>
@ -22,8 +24,8 @@
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";

72
IGP/Pages/Database/Entity/Parts/EntityPassivesComponent.razor

@ -1,100 +1,106 @@
@if (Entity.IdPassives().Count > 0) { @if (Entity!.IdPassives().Count > 0)
{
@if (StyleType.Equals("Plain")) @if (StyleType.Equals("Plain"))
{ {
@foreach (var idPassive in Entity.IdPassives()) { @foreach (var idPassive in Entity.IdPassives())
{
var passive = EntityModel.Get(idPassive.Id); var passive = EntityModel.Get(idPassive.Id);
var info = passive.Info(); var info = passive.Info();
var production = passive.Production(); var production = passive.Production();
<div> <div>
<div> <div>
<b>Name:</b> @info.Name <b>Name:</b> @info.Name
</div> </div>
<div> <div>
<b>- Description:</b> @((MarkupString)info.Description) <b>- Description:</b> @((MarkupString)info.Description)
</div> </div>
@if (!info.Notes.Trim().Equals("")) { @if (!info.Notes.Trim().Equals(""))
{
<div> <div>
<b>- Description:</b> @((MarkupString)info.Notes) <b>- Description:</b> @((MarkupString)info.Notes)
</div> </div>
} }
</div> </div>
@if (production != null) { @if (production != null)
{
<div> <div>
@if (production.Pyre != 0) { @if (production.Pyre != 0)
{
<div> <div>
<b>- Pyre:</b> @production.Pyre <b>- Pyre:</b> @production.Pyre
</div> </div>
} }
@if (production.Cooldown != 0) { @if (production.Cooldown != 0)
{
<div> <div>
<b>- Cooldown:</b> @production.Cooldown.ToString()s <b>- Cooldown:</b> @production.Cooldown.ToString()s
</div> </div>
} }
</div> </div>
} }
} }
} }
else else
{ {
<EntityDisplayComponent Title="Passives"> <EntityDisplayComponent Title="Passives">
@foreach (var idPassive in Entity.IdPassives()) { @foreach (var idPassive in Entity.IdPassives())
{
var passive = EntityModel.Get(idPassive.Id); var passive = EntityModel.Get(idPassive.Id);
var info = passive.Info(); var info = passive.Info();
var production = passive.Production(); var production = passive.Production();
<div> <div>
<div> <div>
<b>Name:</b> <EntityLabelComponent EntityId="@passive.DataType"/> <b>Name:</b> <EntityLabelComponent EntityId="@passive.DataType"/>
</div> </div>
<div> <div>
<b>Description:</b> @((MarkupString)info.Description) <b>Description:</b> @((MarkupString)info.Description)
</div> </div>
@if (!info.Notes.Trim().Equals("")) { @if (!info.Notes.Trim().Equals(""))
{
<div> <div>
<b>Description:</b> @((MarkupString)info.Notes) <b>Description:</b> @((MarkupString)info.Notes)
</div> </div>
} }
</div> </div>
@if (production != null) { @if (production != null)
{
<div> <div>
@if (production.Pyre != 0) { @if (production.Pyre != 0)
{
<div> <div>
<b>Pyre:</b> @production.Pyre <b>Pyre:</b> @production.Pyre
</div> </div>
} }
@if (production.Cooldown != 0) { @if (production.Cooldown != 0)
{
<div> <div>
<b>Cooldown:</b> @production.Cooldown.ToString()s <b>Cooldown:</b> @production.Cooldown.ToString()s
</div> </div>
} }
</div> </div>
} }
} }
</EntityDisplayComponent> </EntityDisplayComponent>
} }
} }
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";

249
IGP/Pages/Database/Entity/Parts/EntityProductionComponent.razor

@ -1,16 +1,103 @@
@if (Production != null || Supply != null || Requirements.Count > 0) { @if (Production != null || Supply != null || Requirements.Count > 0)
{
@if (StyleType.Equals("Plain")) @if (StyleType.Equals("Plain"))
{ {
@if (Requirements.Count() > 0) { @if (Requirements.Count() > 0)
{
<div>
@foreach (var requirement in Requirements)
{
var replaced = DATA.Get()[requirement.DataType];
<div>
<span>
<b>@requirement.Requirement.Replace("_", " "):</b> @replaced.Info().Name
</span>
</div>
}
</div>
}
@if (Production != null && (!Production.Alloy.Equals(0)
|| !Production.Ether.Equals(0)
|| !Production.BuildTime.Equals(0)
|| !Production.Cooldown.Equals(0)))
{
<div>
@if (!Production.Alloy.Equals(0))
{
<div>
<b>Alloy:</b> @Production.Alloy
</div>
}
@if (!Production.Ether.Equals(0))
{
<div>
<b>Ether:</b> @Production.Ether
</div>
}
@if (!Production.Pyre.Equals(0))
{
<div>
<b>Pyre:</b> @Production.Pyre
</div>
}
@if (!Production.BuildTime.Equals(0))
{
<div>
<b>Build Time:</b> @Production.BuildTime.ToString()s
</div>
}
@if (!Production.Energy.Equals(0))
{
<div>
<b>Energy:</b> @Production.Energy
</div>
}
@if (!Production.Cooldown.Equals(0))
{
<div>
<b>Cooldown:</b> @Production.Cooldown.ToString()s
</div>
}
</div>
}
@if (Supply != null)
{
<div>
@if (!Supply.Grants.Equals(0))
{
<div>
<b>Grants:</b> @Supply.Grants
</div>
}
@if (!Supply.Takes.Equals(0))
{
<div>
<b>Takes:</b> @Supply.Takes Supply
</div>
}
</div>
}
}
else
{
<EntityDisplayComponent Title="Production">
<div class="ProductionContainer">
@if (Requirements.Count() > 0)
{
<div> <div>
@foreach (var requirement in Requirements) @foreach (var requirement in Requirements)
{ {
var replaced = DATA.Get()[requirement.DataType];
<div> <div>
<span> <span>
<b>@requirement.Requirement.Replace("_", " "):</b> @replaced.Info().Name <b>@requirement.Requirement.Replace("_", " "):</b> <EntityLabelComponent EntityId="@requirement.DataType"/>
</span> </span>
</div> </div>
} }
@ -20,127 +107,62 @@
@if (Production != null && (!Production.Alloy.Equals(0) @if (Production != null && (!Production.Alloy.Equals(0)
|| !Production.Ether.Equals(0) || !Production.Ether.Equals(0)
|| !Production.BuildTime.Equals(0) || !Production.BuildTime.Equals(0)
|| !Production.Cooldown.Equals(0))) { || !Production.Cooldown.Equals(0)))
<div> {
@if (!Production.Alloy.Equals(0)) {
<div>
<b>Alloy:</b> @Production.Alloy
</div>
}
@if (!Production.Ether.Equals(0)) {
<div>
<b>Ether:</b> @Production.Ether
</div>
}
@if (!Production.Pyre.Equals(0)) {
<div>
<b>Pyre:</b> @Production.Pyre
</div>
}
@if (!Production.BuildTime.Equals(0)) {
<div>
<b>Build Time:</b> @Production.BuildTime.ToString()s
</div>
}
@if (!Production.Energy.Equals(0)) {
<div>
<b>Energy:</b> @Production.Energy
</div>
}
@if (!Production.Cooldown.Equals(0)) {
<div>
<b>Cooldown:</b> @Production.Cooldown.ToString()s
</div>
}
</div>
}
@if (Supply != null) {
<div> <div>
@if (!Supply.Grants.Equals(0)) { @if (!Production.Alloy.Equals(0))
{
<div> <div>
<b>Grants:</b> @Supply.Grants <b>Alloy:</b> @Production.Alloy
</div> </div>
} }
@if (!Supply.Takes.Equals(0)) { @if (!Production.Ether.Equals(0))
{
<div> <div>
<b>Takes:</b> @Supply.Takes Supply <b>Ether:</b> @Production.Ether
</div>
}
@if (!Production.Pyre.Equals(0))
{
<div>
<b>Pyre:</b> @Production.Pyre
</div> </div>
} }
</div>
}
}
else @if (!Production.BuildTime.Equals(0))
{ {
<EntityDisplayComponent Title="Production">
<div class="ProductionContainer">
@if (Requirements.Count() > 0) {
<div>
@foreach (var requirement in Requirements) {
<div> <div>
<b>Build Time:</b> @Production.BuildTime.ToString()s
</div>
}
<span> @if (!Production.Energy.Equals(0))
<b>@requirement.Requirement.Replace("_", " "):</b> <EntityLabelComponent EntityId="@requirement.DataType"/> {
</span> <div>
<b>Energy:</b> @Production.Energy
</div>
}
@if (!Production.Cooldown.Equals(0))
{
<div>
<b>Cooldown:</b> @Production.Cooldown.ToString()s
</div> </div>
} }
</div> </div>
} }
@if (Supply != null)
@if (Production != null && (!Production.Alloy.Equals(0) {
|| !Production.Ether.Equals(0)
|| !Production.BuildTime.Equals(0)
|| !Production.Cooldown.Equals(0))) {
<div>
@if (!Production.Alloy.Equals(0)) {
<div>
<b>Alloy:</b> @Production.Alloy
</div>
}
@if (!Production.Ether.Equals(0)) {
<div>
<b>Ether:</b> @Production.Ether
</div>
}
@if (!Production.Pyre.Equals(0)) {
<div>
<b>Pyre:</b> @Production.Pyre
</div>
}
@if (!Production.BuildTime.Equals(0)) {
<div>
<b>Build Time:</b> @Production.BuildTime.ToString()s
</div>
}
@if (!Production.Energy.Equals(0)) {
<div>
<b>Energy:</b> @Production.Energy
</div>
}
@if (!Production.Cooldown.Equals(0)) {
<div>
<b>Cooldown:</b> @Production.Cooldown.ToString()s
</div>
}
</div>
}
@if (Supply != null) {
<div> <div>
@if (!Supply.Grants.Equals(0)) { @if (!Supply.Grants.Equals(0))
{
<div> <div>
<b>Grants:</b> @Supply.Grants <b>Grants:</b> @Supply.Grants
</div> </div>
} }
@if (!Supply.Takes.Equals(0)) { @if (!Supply.Takes.Equals(0))
{
<div> <div>
<b>Takes:</b> @Supply.Takes Supply <b>Takes:</b> @Supply.Takes Supply
</div> </div>
@ -149,8 +171,8 @@
} }
</div> </div>
</EntityDisplayComponent> </EntityDisplayComponent>
<style> <style>
.ProductionContainer { .ProductionContainer {
display: flex; display: flex;
@ -164,7 +186,6 @@
} }
} }
</style> </style>
} }
} }
@ -173,14 +194,14 @@
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; }
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";
private EntityProductionModel Production => Entity.Production(); private EntityProductionModel Production => Entity!.Production();
private List<EntityRequirementModel> Requirements => Entity.Requirements(); private List<EntityRequirementModel> Requirements => Entity!.Requirements();
private EntitySupplyModel Supply => Entity.Supply(); private EntitySupplyModel Supply => Entity!.Supply();
protected override void OnParametersSet() protected override void OnParametersSet()

40
IGP/Pages/Database/Entity/Parts/EntityPyreSpellsComponent.razor

@ -1,8 +1,9 @@
@if (Entity.IdPyreSpells().Count > 0) @if (Entity!.IdPyreSpells().Count > 0)
{ {
@if (StyleType.Equals("Plain")) @if (StyleType.Equals("Plain"))
{ {
@foreach (var pyreSpell in Entity.IdPyreSpells()) { @foreach (var pyreSpell in Entity.IdPyreSpells())
{
var spell = EntityModel.Get(pyreSpell.Id); var spell = EntityModel.Get(pyreSpell.Id);
var info = spell.Info(); var info = spell.Info();
@ -16,16 +17,20 @@
<b>- Description:</b> @((MarkupString)info.Description) <b>- Description:</b> @((MarkupString)info.Description)
</div> </div>
<div> <div>
@if (production != null) { @if (production != null)
if (production.Pyre != 0) { {
if (production.Pyre != 0)
{
<b>- Pyre: </b> <b>- Pyre: </b>
@production.Pyre @production.Pyre
} }
if (production.BuildTime != 0) { if (production.BuildTime != 0)
{
<b>- BuildTime: </b> <b>- BuildTime: </b>
@production.BuildTime @production.BuildTime
} }
if (production.Cooldown != 0) { if (production.Cooldown != 0)
{
<b>- Cooldown: </b> <b>- Cooldown: </b>
@production.Cooldown @production.Cooldown
} }
@ -33,12 +38,12 @@
</div> </div>
</div> </div>
} }
} }
else else
{ {
<EntityDisplayComponent Title="Pyre Spells"> <EntityDisplayComponent Title="Pyre Spells">
@foreach (var pyreSpell in Entity.IdPyreSpells()) { @foreach (var pyreSpell in Entity.IdPyreSpells())
{
var spell = EntityModel.Get(pyreSpell.Id); var spell = EntityModel.Get(pyreSpell.Id);
var info = spell.Info(); var info = spell.Info();
@ -52,16 +57,20 @@
<b>Description:</b> @((MarkupString)info.Description) <b>Description:</b> @((MarkupString)info.Description)
</div> </div>
<div> <div>
@if (production != null) { @if (production != null)
if (production.Pyre != 0) { {
if (production.Pyre != 0)
{
<b> Pyre: </b> <b> Pyre: </b>
@production.Pyre @production.Pyre
} }
if (production.BuildTime != 0) { if (production.BuildTime != 0)
{
<b> BuildTime: </b> <b> BuildTime: </b>
@production.BuildTime @production.BuildTime
} }
if (production.Cooldown != 0) { if (production.Cooldown != 0)
{
<b> Cooldown: </b> <b> Cooldown: </b>
@production.Cooldown @production.Cooldown
} }
@ -70,7 +79,6 @@
</div> </div>
} }
</EntityDisplayComponent> </EntityDisplayComponent>
} }
} }
@ -78,9 +86,9 @@
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";

149
IGP/Pages/Database/Entity/Parts/EntityStatsComponent.razor

@ -1,97 +1,112 @@
 @if (Vitality != null || Movement != null)
@if (Vitality != null || Movement != null) { {
@if (StyleType.Equals("Plain")) @if (StyleType.Equals("Plain"))
{ {
@if (Vitality != null) { @if (Vitality != null)
{
<div>
@if (!Vitality.DefenseLayer.Equals(0))
{
<div> <div>
@if (!Vitality.DefenseLayer.Equals(0)) { <b>Shield:</b> @Vitality.DefenseLayer
<div> </div>
<b>Shield:</b> @Vitality.DefenseLayer }
</div> @if (!Vitality.Health.Equals(0))
} {
@if (!Vitality.Health.Equals(0)) { <div>
<div> <b>Health:</b> @Vitality.Health
<b>Health:</b> @Vitality.Health </div>
</div> }
} @if (!Vitality.Energy.Equals(0))
@if (!Vitality.Energy.Equals(0)) { {
<div> <div>
<b>Energy:</b> @Vitality.Energy <b>Energy:</b> @Vitality.Energy
</div> </div>
} }
@if (Vitality.Armor != "") { @if (Vitality.Armor != "")
<div> {
<b>Armor:</b> @Vitality.Armor <div>
</div> <b>Armor:</b> @Vitality.Armor
} </div>
}
@if (Vitality.IsEtheric) { @if (Vitality.IsEtheric)
<div> {
<b> + Etheric</b> <div>
</div> <b> + Etheric</b>
} </div>
@if (Vitality.IsStructure) { }
<div> @if (Vitality.IsStructure)
<b> + Structure</b> {
</div> <div>
} <b> + Structure</b>
</div> </div>
} }
</div>
}
@if (Movement != null) { @if (Movement != null)
{
<div>
@if (!Movement.Speed.Equals(0))
{
<div> <div>
@if (!Movement.Speed.Equals(0)) { <b>Speed:</b> @Movement.Speed
<div> </div>
<b>Speed:</b> @Movement.Speed }
</div> else
} {
else { <div>
<div> <b>Speed:</b> Immobile
<b>Speed:</b> Immobile
</div>
}
<div>
<b>Move Type:</b> @Movement.Movement
</div>
</div> </div>
} }
<div>
<b>Move Type:</b> @Movement.Movement
</div>
</div>
}
} }
else else
{ {
<EntityDisplayComponent Title="Stats"> <EntityDisplayComponent Title="Stats">
<div class="statContainer"> <div class="statContainer">
@if (Vitality != null) { @if (Vitality != null)
{
<div> <div>
@if (!Vitality.DefenseLayer.Equals(0)) { @if (!Vitality.DefenseLayer.Equals(0))
{
<div> <div>
<b>Shield:</b> @Vitality.DefenseLayer <b>Shield:</b> @Vitality.DefenseLayer
</div> </div>
} }
@if (!Vitality.Health.Equals(0)) { @if (!Vitality.Health.Equals(0))
{
<div> <div>
<b>Health:</b> @Vitality.Health <b>Health:</b> @Vitality.Health
</div> </div>
} }
@if (!Vitality.Energy.Equals(0)) { @if (!Vitality.Energy.Equals(0))
{
<div> <div>
<b>Energy:</b> @Vitality.Energy <b>Energy:</b> @Vitality.Energy
</div> </div>
} }
@if (Vitality.Armor != "") { @if (Vitality.Armor != "")
{
<div> <div>
<b>Armor:</b> @Vitality.Armor <b>Armor:</b> @Vitality.Armor
</div> </div>
} }
@if (Vitality.IsEtheric) { @if (Vitality.IsEtheric)
{
<div> <div>
<b> + Etheric</b> <b> + Etheric</b>
</div> </div>
} }
@if (Vitality.IsStructure) { @if (Vitality.IsStructure)
{
<div> <div>
<b> + Structure</b> <b> + Structure</b>
</div> </div>
@ -100,14 +115,17 @@
} }
@if (Movement != null) { @if (Movement != null)
{
<div> <div>
@if (!Movement.Speed.Equals(0)) { @if (!Movement.Speed.Equals(0))
{
<div> <div>
<b>Speed:</b> @Movement.Speed <b>Speed:</b> @Movement.Speed
</div> </div>
} }
else { else
{
<div> <div>
<b>Speed:</b> Immobile <b>Speed:</b> Immobile
</div> </div>
@ -132,21 +150,20 @@
} }
} }
</style> </style>
} }
} }
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";
private EntityVitalityModel Vitality => Entity.Vitality(); private EntityVitalityModel Vitality => Entity!.Vitality();
private EntityMovementModel Movement => Entity.Movement(); private EntityMovementModel Movement => Entity!.Movement();
} }

21
IGP/Pages/Database/Entity/Parts/EntityUpgradesComponent.razor

@ -1,7 +1,9 @@
@if (Entity.IdUpgrades().Count > 0) { @if (Entity!.IdUpgrades().Count > 0)
{
@if (StyleType.Equals("Plain")) @if (StyleType.Equals("Plain"))
{ {
@foreach (var upgradeId in Entity.IdUpgrades()) { @foreach (var upgradeId in Entity.IdUpgrades())
{
var entity = EntityModel.Get(upgradeId.Id); var entity = EntityModel.Get(upgradeId.Id);
<div> <div>
<div> <div>
@ -12,13 +14,13 @@
</div> </div>
</div> </div>
} }
} }
else else
{ {
<EntityDisplayComponent Title="Upgrades"> <EntityDisplayComponent Title="Upgrades">
<div class="upgradesContainer"> <div class="upgradesContainer">
@foreach (var upgradeId in Entity.IdUpgrades()) { @foreach (var upgradeId in Entity.IdUpgrades())
{
var entity = EntityModel.Get(upgradeId.Id); var entity = EntityModel.Get(upgradeId.Id);
<div> <div>
<div> <div>
@ -30,9 +32,9 @@
</div> </div>
} }
</div> </div>
</EntityDisplayComponent> </EntityDisplayComponent>
<style> <style>
.upgradesContainer { .upgradesContainer {
display: flex; display: flex;
@ -47,16 +49,15 @@
} }
</style> </style>
} }
} }
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";

30
IGP/Pages/Database/Entity/Parts/EntityVanguardAddedComponent.razor

@ -1,17 +1,19 @@
@if (Vanguard != null) { @if (Vanguard != null)
{
var immortalId = Vanguard.ImmortalId; var immortalId = Vanguard.ImmortalId;
var immortal = DATA.Get()[immortalId]; var immortal = DATA.Get()[immortalId];
var replaced = DATA.Get()[Vanguard.ReplaceId]; var replaced = DATA.Get()[Vanguard.ReplaceId];
@if (StyleType.Equals("Plain")) @if (StyleType.Equals("Plain"))
{ {
<div> <div>
<b>Immortal:</b> @immortal.Info().Name <b>Immortal:</b> @immortal.Info().Name
</div> </div>
@if (!Vanguard.ReplaceId.Equals("")) { @if (!Vanguard.ReplaceId.Equals(""))
{
<div> <div>
<b>Replaces:</b> @replaced.Info().Name <b>Replaces:</b> @replaced.Info().Name
</div> </div>
} }
} }
@ -22,25 +24,27 @@
<div> <div>
<b>Immortal:</b> <EntityLabelComponent EntityId="@immortal.DataType"/> <b>Immortal:</b> <EntityLabelComponent EntityId="@immortal.DataType"/>
</div> </div>
@if (!Vanguard.ReplaceId.Equals("")) { @if (!Vanguard.ReplaceId.Equals(""))
{
<div> <div>
<b>Replaces:</b> <EntityLabelComponent EntityId="@Vanguard.ReplaceId"></EntityLabelComponent> <b>Replaces:</b> <EntityLabelComponent EntityId="@Vanguard.ReplaceId"></EntityLabelComponent>
</div> </div>
} }
</div> </div>
</EntityDisplayComponent> </EntityDisplayComponent>
} }
} }
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
private EntityVanguardAddedModel? Vanguard => Entity?.VanguardAdded(); private EntityVanguardAddedModel? Vanguard => Entity?.VanguardAdded();
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";
} }

23
IGP/Pages/Database/Entity/Parts/EntityVanguardsComponent.razor

@ -1,7 +1,9 @@
@if (Entity.IdVanguards().Count > 0) { @if (Entity!.IdVanguards().Count > 0)
{
@if (StyleType.Equals("Plain")) @if (StyleType.Equals("Plain"))
{ {
@foreach (var data in Entity.IdVanguards()) { @foreach (var data in Entity.IdVanguards())
{
var entity = EntityModel.Get(data.Id); var entity = EntityModel.Get(data.Id);
var requirements = entity.Requirements(); var requirements = entity.Requirements();
@ -9,7 +11,7 @@
var replaced = DATA.Get()[vanguardAdded.ReplaceId]; var replaced = DATA.Get()[vanguardAdded.ReplaceId];
var immortal = DATA.Get()[vanguardAdded.ImmortalId]; var immortal = DATA.Get()[vanguardAdded.ImmortalId];
var productionBuilding = (from building in requirements var productionBuilding = (from building in requirements
where building.Requirement == RequirementType.Production_Building where building.Requirement == RequirementType.Production_Building
select building).First().DataType; select building).First().DataType;
@ -22,7 +24,7 @@
<b>- Replaces:</b> @replaced.Info().Name <b>- Replaces:</b> @replaced.Info().Name
</div> </div>
<div> <div>
<b>- Built From:</b> @immortal.Info().Name <b>- Built From:</b> @immortal.Info().Name
</div> </div>
</div> </div>
} }
@ -30,7 +32,8 @@
else else
{ {
<EntityDisplayComponent Title="Vanguards"> <EntityDisplayComponent Title="Vanguards">
@foreach (var data in Entity.IdVanguards()) { @foreach (var data in Entity.IdVanguards())
{
var entity = EntityModel.Get(data.Id); var entity = EntityModel.Get(data.Id);
var requirements = entity.Requirements(); var requirements = entity.Requirements();
@ -44,7 +47,7 @@
<b>Name:</b> <EntityLabelComponent EntityId="@entity.DataType"/> <b>Name:</b> <EntityLabelComponent EntityId="@entity.DataType"/>
</div> </div>
<div> <div>
<b>Replaces:</b> <EntityLabelComponent EntityId="@vanguard.ReplaceId"/> <b>Replaces:</b> <EntityLabelComponent EntityId="@vanguard.ReplaceId"/>
</div> </div>
<div> <div>
<b>Built From:</b> <EntityLabelComponent EntityId="@productionBuilding"/> <b>Built From:</b> <EntityLabelComponent EntityId="@productionBuilding"/>
@ -52,17 +55,15 @@
</div> </div>
} }
</EntityDisplayComponent> </EntityDisplayComponent>
} }
} }
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";

322
IGP/Pages/Database/Entity/Parts/EntityWeaponsComponent.razor

@ -1,205 +1,204 @@
@if (Entity.Weapons().Count > 0) @if (Entity!.Weapons().Count > 0)
{ {
@if (StyleType.Equals("Plain")) @if (StyleType.Equals("Plain"))
{ {
int index = 0; var index = 0;
foreach (var data in Entity.Weapons()) foreach (var data in Entity.Weapons())
{ {
index++; index++;
<div>
<div> <div>
<div> <div class="damageContainer">
<div class="damageContainer">
<div>
<b>Weapon @index</b>
</div>
<div>
<b>- Damage:</b> @data.Damage
</div>
@if (data.LightDamage != 0)
{
<div class="alternateDamage">
<i>- vs Light: @data.LightDamage</i>&nbsp;
</div>
}
@if (data.MediumDamage != 0)
{
<div class="alternateDamage">
<i>- vs Medium: @data.MediumDamage</i>&nbsp;
</div>
}
@if (data.HeavyDamage != 0)
{
<div class="alternateDamage">
<i>- vs Heavy: @data.HeavyDamage</i>&nbsp;
</div>
}
@if (data.EthericDamageBonus != 0)
{
<div class="alternateDamage">
<i>- vs Etheric +@data.EthericDamageBonus</i>&nbsp;
</div>
}
@if (data.StructureDamageBonus != 0)
{
<div class="alternateDamage">
<i>- vs Structure: +@data.StructureDamageBonus</i>&nbsp;
</div>
}
</div>
</div>
<div>
<b>- Range:</b> @data.Range
</div>
@if (data.SecondsBetweenAttacks > 0)
{
<div>
<b>- AttacksPerSecond:</b> @(1 / data.SecondsBetweenAttacks)
</div>
<div> <div>
- (or <b>SecondsBetweenAttacks:</b> @data.SecondsBetweenAttacks) <b>Weapon @index</b>
</div>
}
else if (data.AttacksPerSecond > 0)
{
<div>
<b>- AttacksPerSecond:</b> @data.AttacksPerSecond
</div> </div>
<div> <div>
- (or <b>SecondsBetweenAttacks:</b> @(1 / data.AttacksPerSecond)) <b>- Damage:</b> @data.Damage
</div> </div>
}
<div>
<b>- Targets:</b> @data.Targets
</div>
@if (data.AttacksPerSecond != 0)
{
<span>
<b>- DPS:</b> @(Math.Round(data.Damage * data.AttacksPerSecond))&nbsp;
</span>
@if (data.LightDamage != 0) @if (data.LightDamage != 0)
{ {
<span> <div class="alternateDamage">
<i>- Light DPS: @(Math.Round(data.LightDamage * data.AttacksPerSecond))</i>&nbsp; <i>- vs Light: @data.LightDamage</i>&nbsp;
</span> </div>
} }
@if (data.MediumDamage != 0) @if (data.MediumDamage != 0)
{ {
<span> <div class="alternateDamage">
<i>- Medium DPS: @(Math.Round(data.MediumDamage * data.AttacksPerSecond))</i>&nbsp; <i>- vs Medium: @data.MediumDamage</i>&nbsp;
</span> </div>
} }
@if (data.HeavyDamage != 0) @if (data.HeavyDamage != 0)
{ {
<span> <div class="alternateDamage">
<i>- Heavy DPS: @(Math.Round(data.HeavyDamage * data.AttacksPerSecond))</i>&nbsp; <i>- vs Heavy: @data.HeavyDamage</i>&nbsp;
</span> </div>
}
@if (data.EthericDamageBonus != 0)
{
<div class="alternateDamage">
<i>- vs Etheric +@data.EthericDamageBonus</i>&nbsp;
</div>
} }
} @if (data.StructureDamageBonus != 0)
{
<div class="alternateDamage">
<i>- vs Structure: +@data.StructureDamageBonus</i>&nbsp;
</div>
}
</div>
</div> </div>
}
}
else
{
<EntityDisplayComponent Title="Weapons">
<div class="weaponsContainer">
@foreach (var data in Entity.Weapons())
{
<div> <div>
<b>- Range:</b> @data.Range
</div>
@if (data.SecondsBetweenAttacks > 0)
{
<div> <div>
<div class="damageContainer"> <b>- AttacksPerSecond:</b> @(1 / data.SecondsBetweenAttacks)
<div> </div>
<b>Damage:</b> @data.Damage <div>
</div> - (or <b>SecondsBetweenAttacks:</b> @data.SecondsBetweenAttacks)
@if (data.LightDamage != 0)
{
<div class="alternateDamage">
<i>vs Light: @data.LightDamage</i>&nbsp;
</div>
}
@if (data.MediumDamage != 0)
{
<div class="alternateDamage">
<i>vs Medium: @data.MediumDamage</i>&nbsp;
</div>
}
@if (data.HeavyDamage != 0)
{
<div class="alternateDamage">
<i>vs Heavy: @data.HeavyDamage</i>&nbsp;
</div>
}
@if (data.EthericDamageBonus != 0)
{
<div class="alternateDamage">
<i>vs Etheric +@data.EthericDamageBonus</i>&nbsp;
</div>
}
@if (data.StructureDamageBonus != 0)
{
<div class="alternateDamage">
<i>vs Structure: +@data.StructureDamageBonus</i>&nbsp;
</div>
}
</div>
</div> </div>
}
else if (data.AttacksPerSecond > 0)
{
<div> <div>
<b>Range:</b> @data.Range <b>- AttacksPerSecond:</b> @data.AttacksPerSecond
</div> </div>
@if (data.SecondsBetweenAttacks > 0) <div>
- (or <b>SecondsBetweenAttacks:</b> @(1 / data.AttacksPerSecond))
</div>
}
<div>
<b>- Targets:</b> @data.Targets
</div>
@if (data.AttacksPerSecond != 0)
{
<span>
<b>- DPS:</b> @(Math.Round(data.Damage * data.AttacksPerSecond))&nbsp;
</span>
@if (data.LightDamage != 0)
{ {
<div> <span>
<b>AttacksPerSecond:</b> @(1 / data.SecondsBetweenAttacks) <i>- Light DPS: @(Math.Round(data.LightDamage * data.AttacksPerSecond))</i>&nbsp;
</div> </span>
<div>
(or <b>SecondsBetweenAttacks:</b> @data.SecondsBetweenAttacks)
</div>
} }
else if (data.AttacksPerSecond > 0) @if (data.MediumDamage != 0)
{ {
<div> <span>
<b>AttacksPerSecond:</b> @data.AttacksPerSecond <i>- Medium DPS: @(Math.Round(data.MediumDamage * data.AttacksPerSecond))</i>&nbsp;
</div> </span>
<div>
(or <b>SecondsBetweenAttacks:</b> @(1 / data.AttacksPerSecond))
</div>
} }
@if (data.HeavyDamage != 0)
<div>
<b>Targets:</b> @data.Targets
</div>
@if (data.AttacksPerSecond != 0)
{ {
<span>
<i>- Heavy DPS: @(Math.Round(data.HeavyDamage * data.AttacksPerSecond))</i>&nbsp;
</span>
}
}
</div>
}
}
else
{
<EntityDisplayComponent Title="Weapons">
<div class="weaponsContainer">
@foreach (var data in Entity.Weapons())
{
<div>
<div> <div>
<b>DPS:</b> @(Math.Round(data.Damage * data.AttacksPerSecond))&nbsp; <div class="damageContainer">
<div>
<b>Damage:</b> @data.Damage
</div>
@if (data.LightDamage != 0)
{
<div class="alternateDamage">
<i>vs Light: @data.LightDamage</i>&nbsp;
</div>
}
@if (data.MediumDamage != 0)
{
<div class="alternateDamage">
<i>vs Medium: @data.MediumDamage</i>&nbsp;
</div>
}
@if (data.HeavyDamage != 0)
{
<div class="alternateDamage">
<i>vs Heavy: @data.HeavyDamage</i>&nbsp;
</div>
}
@if (data.EthericDamageBonus != 0)
{
<div class="alternateDamage">
<i>vs Etheric +@data.EthericDamageBonus</i>&nbsp;
</div>
}
@if (data.StructureDamageBonus != 0)
{
<div class="alternateDamage">
<i>vs Structure: +@data.StructureDamageBonus</i>&nbsp;
</div>
}
</div>
</div> </div>
@if (data.LightDamage != 0) <div>
<b>Range:</b> @data.Range
</div>
@if (data.SecondsBetweenAttacks > 0)
{ {
<div> <div>
<i>Light DPS: @(Math.Round(data.LightDamage * data.AttacksPerSecond))</i>&nbsp; <b>AttacksPerSecond:</b> @(1 / data.SecondsBetweenAttacks)
</div>
<div>
(or <b>SecondsBetweenAttacks:</b> @data.SecondsBetweenAttacks)
</div> </div>
} }
@if (data.MediumDamage != 0) else if (data.AttacksPerSecond > 0)
{ {
<div> <div>
<i>Medium DPS: @(Math.Round(data.MediumDamage * data.AttacksPerSecond))</i>&nbsp; <b>AttacksPerSecond:</b> @data.AttacksPerSecond
</div>
<div>
(or <b>SecondsBetweenAttacks:</b> @(1 / data.AttacksPerSecond))
</div> </div>
} }
@if (data.HeavyDamage != 0)
<div>
<b>Targets:</b> @data.Targets
</div>
@if (data.AttacksPerSecond != 0)
{ {
<div> <div>
<i>Heavy DPS: @(Math.Round(data.HeavyDamage * data.AttacksPerSecond))</i>&nbsp; <b>DPS:</b> @(Math.Round(data.Damage * data.AttacksPerSecond))&nbsp;
</div> </div>
@if (data.LightDamage != 0)
{
<div>
<i>Light DPS: @(Math.Round(data.LightDamage * data.AttacksPerSecond))</i>&nbsp;
</div>
}
@if (data.MediumDamage != 0)
{
<div>
<i>Medium DPS: @(Math.Round(data.MediumDamage * data.AttacksPerSecond))</i>&nbsp;
</div>
}
@if (data.HeavyDamage != 0)
{
<div>
<i>Heavy DPS: @(Math.Round(data.HeavyDamage * data.AttacksPerSecond))</i>&nbsp;
</div>
}
} }
} </div>
</div> }
} </div>
</div> </EntityDisplayComponent>
</EntityDisplayComponent>
<style> <style>
.weaponsContainer { .weaponsContainer {
@ -222,16 +221,15 @@
margin-bottom: 6px; margin-bottom: 6px;
} }
</style> </style>
}
}
} }
@code { @code {
[CascadingParameter] [CascadingParameter]
public EntityModel? Entity { get; set; } public EntityModel? Entity { get; set; } = default!;
[CascadingParameter] [CascadingParameter]
public string StyleType { get; set; } = "Detailed"; public string StyleType { get; set; } = "Detailed";

57
IGP/Pages/Database/Parts/EntityFilterComponent.razor

@ -2,23 +2,27 @@
<div class="desktopFiltersContainer"> <div class="desktopFiltersContainer">
<div class="filtersContainer"> <div class="filtersContainer">
<div class="filterContainer"> <div class="filterContainer">
@foreach (var choice in EntityFilterService.GetFactionChoices()) { @foreach (var choice in EntityFilterService.GetFactionChoices())
{
var styleClass = ""; var styleClass = "";
if (choice.Equals(EntityFilterService.GetFactionType())) { if (choice.Equals(EntityFilterService.GetFactionType()))
{
styleClass = "selected"; styleClass = "selected";
} }
<button @onclick="@(e => OnChangeFaction(choice))" class="choiceButton @styleClass">@choice</button> <button @onclick="@(e => OnChangeFaction(choice))" class="choiceButton @styleClass">@choice</button>
} }
</div> </div>
@if (EntityFilterService.GetFactionType() != "Any" && EntityFilterService.GetFactionType() != "None") { @if (EntityFilterService.GetFactionType() != "Any" && EntityFilterService.GetFactionType() != "None")
{
<div class="filterContainer"> <div class="filterContainer">
@foreach (var choice in EntityFilterService.GetImmortalChoices()) @foreach (var choice in EntityFilterService.GetImmortalChoices())
{ {
var name = DATA.Get()[choice].Info().Name; var name = DATA.Get()[choice].Info().Name;
var styleClass = ""; var styleClass = "";
if (choice.Equals(EntityFilterService.GetImmortalType())) { if (choice.Equals(EntityFilterService.GetImmortalType()))
{
styleClass = "selected"; styleClass = "selected";
} }
<button class="choiceButton @styleClass" @onclick="@(e => OnChangeImmortal(choice))">@name</button> <button class="choiceButton @styleClass" @onclick="@(e => OnChangeImmortal(choice))">@name</button>
@ -27,16 +31,18 @@
} }
</div> </div>
<div class="filterContainer"> <div class="filterContainer">
@foreach (var choice in EntityFilterService.GetEntityChoices()) { @foreach (var choice in EntityFilterService.GetEntityChoices())
{
var styleClass = ""; var styleClass = "";
if (choice.Equals(EntityFilterService.GetEntityType())) { if (choice.Equals(EntityFilterService.GetEntityType()))
{
styleClass = "selected"; styleClass = "selected";
} }
<button class="choiceButton @styleClass" @onclick="@(e => OnChangeEntity(choice))">@choice.Replace("_", " ")</button> <button class="choiceButton @styleClass" @onclick="@(e => OnChangeEntity(choice))">@choice.Replace("_", " ")</button>
} }
</div> </div>
<FormTextComponent Label="Search Label" Placeholder="Throne..." OnChange="@(e => EntityFilterService.EnterSearchText(e.Value.ToString()))"/> <FormTextComponent Label="Search Label" Placeholder="Throne..." OnChange="@(e => EntityFilterService.EnterSearchText(e.Value!.ToString()!))"/>
</div> </div>
</div> </div>
@ -199,40 +205,49 @@
@code { @code {
[Inject] [Inject]
public IEntityFilterService EntityFilterService { get; set; } public IEntityFilterService EntityFilterService { get; set; } = default!;
protected override void OnInitialized() { } protected override void OnInitialized()
{
}
void OnChangeFaction(string clickedFaction) { void OnChangeFaction(string clickedFaction)
{
EntityFilterService.SelectFactionType(clickedFaction); EntityFilterService.SelectFactionType(clickedFaction);
StateHasChanged(); StateHasChanged();
} }
void OnChangeImmortal(string clickedImmortal) { void OnChangeImmortal(string clickedImmortal)
{
EntityFilterService.SelectImmortalType(clickedImmortal); EntityFilterService.SelectImmortalType(clickedImmortal);
} }
void OnChangeEntity(string clickedEntity) { void OnChangeEntity(string clickedEntity)
{
EntityFilterService.SelectEntityType(clickedEntity); EntityFilterService.SelectEntityType(clickedEntity);
} }
void OnFactionChanged(ChangeEventArgs e) { void OnFactionChanged(ChangeEventArgs e)
EntityFilterService.SelectFactionType(e.Value.ToString()); {
EntityFilterService.SelectFactionType(e.Value!.ToString()!);
} }
void OnImmortalChanged(ChangeEventArgs e) { void OnImmortalChanged(ChangeEventArgs e)
EntityFilterService.SelectImmortalType(e.Value.ToString()); {
EntityFilterService.SelectImmortalType(e.Value!.ToString()!);
} }
void OnEntityChanged(ChangeEventArgs e) { void OnEntityChanged(ChangeEventArgs e)
EntityFilterService.SelectEntityType(e.Value.ToString()); {
EntityFilterService.SelectEntityType(e.Value!.ToString()!);
} }
void OnSearchTextChanged(ChangeEventArgs e) { void OnSearchTextChanged(ChangeEventArgs e)
EntityFilterService.EnterSearchText(e.Value.ToString()); {
EntityFilterService.EnterSearchText(e.Value!.ToString()!);
} }
} }

115
IGP/Pages/Documentation/DocumentationIndexPage.razor

@ -0,0 +1,115 @@
@layout PageLayout
@inject IDocumentationService documentationService
@implements IDisposable
@page "/docs"
@if (!documentationService.IsLoaded())
{
<LoadingComponent/>
}
else
{
<LayoutMediumContentComponent>
<PaperComponent>
@foreach (var docSection in documentationService.DocSectionModels)
{
<div class="docSectionContainer">
<div class="docSectionTitle">@docSection.Name</div>
<div class="docContentContainer">
@foreach (var docContent in docSection.DocumentationModels)
{
<NavLink class="docContentLink" href="@docContent.GetDocLink()">
<div class="docContentName">@docContent.Name</div>
<div class="docContentDescription">@docContent.Description</div>
</NavLink>
}
</div>
</div>
}
</PaperComponent>
</LayoutMediumContentComponent>
}
<style>
.docSectionContainer {
width: 100%;
padding: 8px;
}
.docSectionTitle {
font-size: 3rem;
font-weight: bold;
text-align: center;
margin-bottom: 32px;
}
.docContentContainer {
display: grid;
gap: 12px;
grid-template-columns: 1fr 1fr;
}
@@media only screen and (max-width: 1025px) {
.docContentContainer {
grid-template-columns: 1fr;
}
}
.docContentName {
font-weight: bold;
font-size: 1.6rem;
}
.docContentDescription {
font-weight: normal;
}
.docContentLink {
background-color: var(--paper);
border: 1px solid var(--paper-border);
border-radius: 2px;
padding-left: 12px;
padding-right: 12px;
padding-top: 24px;
padding-bottom: 24px;
color: white;
display: flex;
flex-direction: column;
gap: 12px;
text-align: center;
margin-left: 12px;
margin-right: 12px;
}
.docContentLink:hover {
background-color: var(--paper-hover);
border-color: var(--paper-border-hover);
text-decoration: none;
box-shadow: 0 4px 6px rgba(0,0,0,0.6);
transform: translateY(-2px) scale(1.01);
}
</style>
@code {
[Parameter]
public string? Text { get; set; }
protected override void OnInitialized()
{
documentationService.Subscribe(StateHasChanged);
documentationService.Load();
}
public void Dispose()
{
documentationService.Unsubscribe(StateHasChanged);
}
}

112
IGP/Pages/Documentation/DocumentationPage.razor

@ -1,69 +1,40 @@
@layout PageLayout @layout PageLayout
@inject IDocumentationService DocumentationService @inject IDocumentationService documentationService
@using Markdig
@implements IDisposable
@page "/docs/{text?}" @implements IDisposable
@page "/docs/{href1}/{href2?}/{href3?}/{href4?}/{href5?}"
@if (!DocumentationService.IsLoaded()) @if (!documentationService.IsLoaded())
{ {
<LoadingComponent></LoadingComponent> <LoadingComponent/>
} }
else else
{ {
<LayoutMediumContentComponent> <LayoutWithSidebarComponent>
<WebsiteTitleComponent>Documentation</WebsiteTitleComponent> <Sidebar>
<DocumentNavComponent
<div class="section"> Connections="documentationService.DocConnectionModels"
<div for="docSection">Section: </div> Documents="documentationService.DocContentModels"/>
<div style="flex: 1"></div> </Sidebar>
<select @oninput="OnSectionChanged" style="background-color: #36393F; width: 250px; margin-right: 16px;" name="docSection"> <Content>
<option value="All">All</option> <PaperComponent>
@foreach (var doc in documentationService.DocContentModels)
</select> {
</div> if (!doc.Href.Equals(Href))
{
<div class="docsContainer"> continue;
@foreach (var doc in DocumentationService.DocumentationModels) { }
if (selectedSection != "All" && doc.Section != selectedSection) { <DocumentComponent DocContentModel="doc"/>
continue;
} }
<PaperComponent> </PaperComponent>
<div style="display: flex; flex-direction: row;"> </Content>
<span style="font-weight: bold; font-style:italic;">@doc.Section</span> </LayoutWithSidebarComponent>
<div style="flex: 1"></div>
<span style="font-weight: bold; font-style:italic;">Last Updated on @doc.UpdatedDate.ToString("MM/dd/yyyy")</span>
</div>
<div>
<div id="@doc.Id" style="font-weight: bold; font-size: 1.4rem;">@doc.Name</div>
<div>@((MarkupString)Markdown.ToHtml(doc.Description))</div>
</div>
</PaperComponent>
}
</div>
</LayoutMediumContentComponent>
} }
<style> <style>
.section {
display: flex;
width: 500px;
flex-direction: row;
background-color: var(--paper);
justify-content: center;
padding: 24px;
border: 4px solid var(--paper-border);
box-shadow: 0px 6px var(--paper-border);
}
.docsContainer {
display: flex;
flex-direction: column;
gap: 16px;
}
pre code { pre code {
color: white; color: white;
@ -121,25 +92,32 @@ else
@code { @code {
[Parameter] [Parameter]
public string? Text { get; set; } public string? Href1 { get; set; }
string selectedSection = "All"; [Parameter]
public string? Href2 { get; set; }
[Parameter]
public string? Href3 { get; set; }
[Parameter]
public string? Href4 { get; set; }
[Parameter]
public string? Href5 { get; set; }
private string Href => Href5 ?? Href4 ?? Href3 ?? Href2 ?? Href1 ?? "";
protected override void OnInitialized() protected override void OnInitialized()
{ {
DocumentationService.Subscribe(StateHasChanged); documentationService.Subscribe(StateHasChanged);
DocumentationService.Load(); documentationService.Load();
} }
public void Dispose() public void Dispose()
{ {
DocumentationService.Unsubscribe(StateHasChanged); documentationService.Unsubscribe(StateHasChanged);
}
void OnSectionChanged(ChangeEventArgs e) {
selectedSection = e.Value.ToString();
StateHasChanged();
} }
} }

35
IGP/Pages/Documentation/Parts/DocumentComponent.razor

@ -0,0 +1,35 @@
<div class="doc">
<div class="docHeader">
<div class="docTitle">@DocContentModel.Name</div>
<div class="docDates">
<div class="docDateUpdated"><b>Updated</b>: @DocContentModel.UpdatedDate.ToString("MM/dd/yyyy")</div>
<div class="docDateCreated"><b>Created</b>: @DocContentModel.CreatedDate.ToString("MM/dd/yyyy")</div>
</div>
</div>
<div class="docContent">@((MarkupString)Markdown.ToHtml(DocContentModel.Content))</div>
</div>
<style>
.docTitle {
font-weight: bold;
}
.docHeader {
display: flex;
justify-content: space-between;
}
.docDates {
display: flex;
flex-direction: column;
}
</style>
@code {
[Parameter]
public DocContentModel DocContentModel { get; set; } = default!;
}

70
IGP/Pages/Documentation/Parts/DocumentInnerNavComponent.razor

@ -0,0 +1,70 @@
@if (Document!.DocumentationModels.Count > 0)
{
<div class="docInnerNavContainer">
@foreach (var innerDoc in Document.DocumentationModels)
{
var linkStyle = $"docInnerNavButton inner_{Layers}";
<NavLink class="@linkStyle" href="@innerDoc.GetDocLink()">@innerDoc.Name</NavLink>
<DocumentInnerNavComponent Document="@innerDoc" Layers="@IncrementLayers()"/>
}
</div>
}
<style>
.docInnerNavContainer {
display: flex;
flex-direction: column;
}
.docInnerNavButton a {
color: white;
}
.docInnerNavButton a:hover {
color: white;
}
.docInnerNavButton {
padding: 8px;
margin-left: 8px;
color: white;
}
.inner_1 {
margin-left: 8px;
}
.inner_2 {
margin-left: 16px;
}
.inner_3 {
margin-left: 24px;
}
</style>
@code {
[Parameter]
public DocContentModel? Document { get; set; } = default!;
[Parameter]
public int Layers { get; set; } = 1;
public int IncrementLayers()
{
return Layers + 1;
}
private string GetLink(DocContentModel doc)
{
return $"docs/{doc.Href}";
}
}

46
IGP/Pages/Documentation/Parts/DocumentNavComponent.razor

@ -0,0 +1,46 @@
<div class="docNavContainer">
@foreach (var doc in Documents)
{
if (doc.Parent == null)
{
<NavLink class="docNavButton" href="@doc.GetDocLink()">@doc.Name</NavLink>
<DocumentInnerNavComponent Document="@doc"/>
}
}
</div>
<style>
.docNavContainer {
display: flex;
flex-direction: column;
}
.docNavButton a {
color: white;
}
.docNavButton a:hover {
color: white;
}
.docNavButton {
padding: 8px;
color: white;
}
</style>
@code {
[Parameter]
public List<DocContentModel> Documents { get; set; } = default!;
[Parameter]
public List<DocConnectionModel> Connections { get; set; } = default!;
private string GetLink(DocContentModel doc)
{
return $"docs/{doc.Href}";
}
}

33
IGP/Pages/HarassCalculatorPage.razor

@ -31,19 +31,19 @@
<FormLayoutComponent> <FormLayoutComponent>
<FormNumberComponent Min="0" <FormNumberComponent Min="0"
Value="@((int)NumberOfWorkersLostToHarass)" Value="@((int)NumberOfWorkersLostToHarass)"
OnChange="@(e => { NumberOfWorkersLostToHarass = int.Parse(e.Value.ToString()); Calculate();})"> OnChange="@(e => { NumberOfWorkersLostToHarass = int.Parse(e.Value!.ToString()!); Calculate();})">
<FormLabelComponent>Number of workers lost to harass</FormLabelComponent> <FormLabelComponent>Number of workers lost to harass</FormLabelComponent>
</FormNumberComponent> </FormNumberComponent>
<FormNumberComponent Min="0" <FormNumberComponent Min="0"
Value="@((int)NumberOfTownHallsExisting)" Value="@((int)NumberOfTownHallsExisting)"
OnChange="@(e => { NumberOfTownHallsExisting = int.Parse(e.Value.ToString()); Calculate();})"> OnChange="@(e => { NumberOfTownHallsExisting = int.Parse(e.Value!.ToString()!); Calculate();})">
<FormLabelComponent>Number of townhalls existing</FormLabelComponent> <FormLabelComponent>Number of townhalls existing</FormLabelComponent>
</FormNumberComponent> </FormNumberComponent>
<FormNumberComponent Min="0" <FormNumberComponent Min="0"
Value="@((int)TravelTime)" Value="@((int)TravelTime)"
OnChange="@(e => { TravelTime = int.Parse(e.Value.ToString()); Calculate();})"> OnChange="@(e => { TravelTime = int.Parse(e.Value!.ToString()!); Calculate();})">
<FormLabelComponent>Travel time</FormLabelComponent> <FormLabelComponent>Travel time</FormLabelComponent>
</FormNumberComponent> </FormNumberComponent>
@ -230,42 +230,51 @@
float NumberOfWorkersLostToHarass = 1; float NumberOfWorkersLostToHarass = 1;
float NumberOfTownHallsExisting = 1; float NumberOfTownHallsExisting = 1;
float SimultaneousProductionFloor() { float SimultaneousProductionFloor()
if (NumberOfTownHallsExisting <= 0 || NumberOfWorkersLostToHarass <= 0) { {
if (NumberOfTownHallsExisting <= 0 || NumberOfWorkersLostToHarass <= 0)
{
return 0; return 0;
} }
return (float)Math.Floor(NumberOfWorkersLostToHarass / Math.Min(NumberOfTownHallsExisting, NumberOfWorkersLostToHarass)); return (float)Math.Floor(NumberOfWorkersLostToHarass / Math.Min(NumberOfTownHallsExisting, NumberOfWorkersLostToHarass));
} }
float LeftOverWorkersToProduceCount() { float LeftOverWorkersToProduceCount()
{
return NumberOfWorkersLostToHarass % Math.Min(NumberOfTownHallsExisting, NumberOfWorkersLostToHarass); return NumberOfWorkersLostToHarass % Math.Min(NumberOfTownHallsExisting, NumberOfWorkersLostToHarass);
} }
float WorkerReplacementCost() { float WorkerReplacementCost()
{
return CostOfWorker * NumberOfWorkersLostToHarass; return CostOfWorker * NumberOfWorkersLostToHarass;
} }
float DelayedMiningCost() { float DelayedMiningCost()
{
return TotalAlloyHarassment - WorkerReplacementCost(); return TotalAlloyHarassment - WorkerReplacementCost();
} }
void Calculate() { void Calculate()
{
TotalAlloyHarassment = WorkerReplacementCost(); TotalAlloyHarassment = WorkerReplacementCost();
for (var workerProductionIndex = 0; workerProductionIndex < SimultaneousProductionFloor(); workerProductionIndex++) { for (var workerProductionIndex = 0; workerProductionIndex < SimultaneousProductionFloor(); workerProductionIndex++)
{
TotalAlloyHarassment += AlloyMinedPerSecondByWorker * (TimeToProduceWorker + TravelTime) * (workerProductionIndex + 1); TotalAlloyHarassment += AlloyMinedPerSecondByWorker * (TimeToProduceWorker + TravelTime) * (workerProductionIndex + 1);
} }
TotalAlloyHarassment += LeftOverWorkersToProduceCount() * (TimeToProduceWorker + TravelTime) * AlloyMinedPerSecondByWorker; TotalAlloyHarassment += LeftOverWorkersToProduceCount() * (TimeToProduceWorker + TravelTime) * AlloyMinedPerSecondByWorker;
} }
protected override void OnInitialized() { protected override void OnInitialized()
{
Calculate(); Calculate();
} }
void ValueChanged(float test) { void ValueChanged(float test)
{
Calculate(); Calculate();
} }

82
IGP/Pages/Home/HomePage.razor

@ -0,0 +1,82 @@
@layout PageLayout;
@page "/immortal-home"
<LayoutMediumContentComponent>
<PaperComponent>
<div class="mainContainer">
<div class="mainTitle">
Fan Reference
</div>
<div>
Refer to various aspects of "IMMORTAL: Gates of Pyre" from this external reference!
</div>
</div>
</PaperComponent>
<ContentDividerComponent></ContentDividerComponent>
<PaperComponent>
<div class="heroesContainer">
<ContentHighlightComponent
Title="Database"
Description="Review the units!"
Href="/database"
ImageHref="image/hero/Database.png"/>
<ContentHighlightComponent
Title="Build Calculator"
Description="Make a build!"
Href="/build-calculator"
ImageHref="image/hero/Build.png"/>
<ContentHighlightComponent
Title="Notes"
Description="Read some notes!"
Href="/notes"
ImageHref="image/hero/Notes.png"/>
<ContentHighlightComponent
Title="Streams"
Description="Watch live development!"
Href="/streams"
ImageHref="image/hero/Streams.png"/>
</div>
</PaperComponent>
<ContentDividerComponent></ContentDividerComponent>
<AlertComponent>
<Title>Under Construction</Title>
<Message>Website is still being made. Check out <NavLink Href="/immortal-roadmap">Road Map</NavLink> for future plans, <NavLink Href="/immortal-agile">Agile</NavLink> for present tasks, and <NavLink Href="/immortal-changelog">Change Log</NavLink> for past changes.</Message>
</AlertComponent>
</LayoutMediumContentComponent>
<style>
.mainContainer {
padding-bottom: 32px;
}
.mainTitle {
font-size: 2.2rem;
font-weight: bold;
}
.heroesContainer {
display: grid;
gap: 64px;
justify-content: center;
margin: auto;
grid-template-columns: 1fr 1fr;
}
@@media only screen and (max-width: 1025px) {
.heroesContainer {
grid-template-columns: 1fr; }
}
</style>

76
IGP/Pages/Home/Parts/ContentHighlightComponent.razor

@ -0,0 +1,76 @@
<NavLink Href="@Href" class="contentHighlight">
<div class="contentHighlightTitle">
@Title
</div>
<img src="@ImageHref" class="contentHighlightImage" alt="@Title"/>
<div class="contentHighlightCallToAction">
@Description
</div>
</NavLink>
<style>
.contentHighlight {
background-color: var(--paper);
border: 1px solid var(--paper-border);
border-radius: 2px;
padding-left: 12px;
padding-right: 12px;
padding-top: 24px;
padding-bottom: 24px;
color: white;
display: flex;
flex-direction: column;
gap: 12px;
text-align: center;
margin-left: 12px;
margin-right: 12px;
}
.contentHighlight:hover {
background-color: var(--paper-hover);
border-color: var(--paper-border-hover);
text-decoration: none;
box-shadow: 0 4px 6px rgba(0,0,0,0.6);
transform: translateY(-2px) scale(1.01);
}
.contentHighlightTitle {
font-weight: 800;
font-size: 1.3rem;
margin: auto;
}
.contentHighlightImage {
border: 1px solid rgba(0,0,0,0.5);
box-shadow: 2px 2px 2px rgba(0,0,0,0.5);
height: 400px;
width: 400px;
margin: auto;
}
.contentHighlightCallToAction {
font-weight: 700;
font-size: 1.1rem;
margin: auto;
padding: 16px;
}
</style>
@code {
[Parameter]
public string Href { get; set; } = default!;
[Parameter]
public string Title { get; set; } = default!;
[Parameter]
public string Description { get; set; } = default!;
[Parameter]
public string ImageHref { get; set; } = default!;
}

149
IGP/Pages/HomePage.razor

@ -1,149 +0,0 @@
@layout PageLayout;
@page "/immortal-home"
<LayoutMediumContentComponent>
<div class="mainContainer">
<div class="mainTitle">
Fan Reference
</div>
<div>
Refer to various aspects of "IMMORTAL: Gates of Pyre" from this external reference!
</div>
</div>
<ContentDividerComponent></ContentDividerComponent>
<div class="herosContainer">
<div class="hero">
<div class="heroTitle">
Database
</div>
<img src="image/hero/Database.png" class="heroImage"/>
<NavLink Href="/database" class="heroCallToAction">
Review the units!
</NavLink>
</div>
<div class="hero">
<div class="heroTitle">
Build Calculator
</div>
<img src="image/hero/Build.png" class="heroImage"/>
<NavLink Href="/build-calculator" class="heroCallToAction">
Make a build!
</NavLink>
</div>
<div class="hero">
<div class="heroTitle">
Notes
</div>
<img src="image/hero/Notes.png" class="heroImage"/>
<NavLink Href="/notes" class="heroCallToAction">
Read some notes!
</NavLink>
</div>
<div class="hero">
<div class="heroTitle">
Streams
</div>
<img src="image/hero/Streams.png" class="heroImage"/>
<NavLink Href="/streams" class="heroCallToAction">
Watch live development!
</NavLink>
</div>
</div>
<ContentDividerComponent></ContentDividerComponent>
<AlertComponent>
<Title>Under Construction</Title>
<Message>Website is still being made. Check out <NavLink Href="/immortal-roadmap">Road Map</NavLink> for future plans, <NavLink Href="/immortal-agile">Agile</NavLink> for present tasks, and <NavLink Href="/immortal-changelog">Change Log</NavLink> for past changes.</Message>
</AlertComponent>
</LayoutMediumContentComponent>
<style>
.mainContainer {
padding-bottom: 32px;
}
.mainTitle {
font-size: 2.2rem;
font-weight: bold;
}
.quoteContainer {
display: flex;
flex-direction: column;
gap: 8px;
max-width: 600px;
margin: auto;
}
.quoteTitle {
font-weight: 800;
margin-bottom: 8px;
}
.quoteText {
margin: auto;
font-style: italic;
}
.herosContainer {
display: flex;
flex-wrap: wrap;
gap: 64px;
justify-content: center;
}
.hero {
padding: 32px;
display: flex;
flex-direction: column;
gap: 32px;
}
.heroTitle {
font-weight: 800;
font-size: 1.3rem;
margin: auto;
}
.heroImage {
border: 1px solid rgba(0,0,0,0.5);
box-shadow: 2px 2px 2px rgba(0,0,0,0.5);
height: 400px;
width: 400px;
margin: auto;
}
.heroCallToAction {
font-weight: 700;
font-size: 1.1rem;
margin: auto;
background-color: var(--primary);
border: 1px solid var(--primary);
padding: 16px;
cursor: pointer;
color: white;
}
.heroCallToAction:hover {
background-color: var(--primary-hover);
border-color: var(--primary-border-hover);
}
</style>

26
IGP/Pages/MakingOf/Parts/MakingOfColours.razor

@ -16,60 +16,60 @@
--info: @info; --info: @info;
--info-border: @info_border; --info-border: @info_border;
</CodeComponent> </CodeComponent>
<br /> <br/>
<div class="color accent"> <div class="color accent">
<div>Accent</div> <div>Accent</div>
<div> <div>
Base: <input type="color" value="@accent" @onchange="e => accent = e.Value.ToString()" /> Base: <input type="color" value="@accent" @onchange="e => accent = e.Value!.ToString()!"/>
</div> </div>
</div> </div>
<div class="color primary"> <div class="color primary">
<div>Primary</div> <div>Primary</div>
<div> <div>
Base: <input type="color" value="@primary" @onchange="e => primary = e.Value.ToString()" /> Base: <input type="color" value="@primary" @onchange="e => primary = e.Value!.ToString()!"/>
</div> </div>
<div> <div>
Border: <input type="color" value="@primary_border" @onchange="e => primary_border = e.Value.ToString()" /> Border: <input type="color" value="@primary_border" @onchange="e => primary_border = e.Value!.ToString()!"/>
</div> </div>
<div> <div>
Hover Base: <input type="color" value="@primary_hover" @onchange="e => primary_hover = e.Value.ToString()" /> Hover Base: <input type="color" value="@primary_hover" @onchange="e => primary_hover = e.Value!.ToString()!"/>
</div> </div>
<div> <div>
Hover Border: <input type="color" value="@primary_border_hover" @onchange="e => primary_border_hover = e.Value.ToString()" /> Hover Border: <input type="color" value="@primary_border_hover" @onchange="e => primary_border_hover = e.Value!.ToString()!"/>
</div> </div>
</div> </div>
<div class="color secondary"> <div class="color secondary">
<div>Secondary</div> <div>Secondary</div>
<div> <div>
Base: <input type="color" value="@secondary" @onchange="e => secondary = e.Value.ToString()" /> Base: <input type="color" value="@secondary" @onchange="e => secondary = e.Value!.ToString()!"/>
</div> </div>
<div> <div>
Hover Base: <input type="color" value="@secondary_hover" @onchange="e => secondary_hover = e.Value.ToString()" /> Hover Base: <input type="color" value="@secondary_hover" @onchange="e => secondary_hover = e.Value!.ToString()!"/>
</div> </div>
<div> <div>
Hover Border: <input type="color" value="@secondary_border_hover" @onchange="e => secondary_border_hover = e.Value.ToString()" /> Hover Border: <input type="color" value="@secondary_border_hover" @onchange="e => secondary_border_hover = e.Value!.ToString()!"/>
</div> </div>
</div> </div>
<div class="color paper"> <div class="color paper">
<div>Paper</div> <div>Paper</div>
<div> <div>
Base: <input type="color" value="@paper" @onchange="e => paper = e.Value.ToString()" /> Base: <input type="color" value="@paper" @onchange="e => paper = e.Value!.ToString()!"/>
</div> </div>
<div> <div>
Border: <input type="color" value="@paper_border" @onchange="e => paper_border = e.Value.ToString()" /> Border: <input type="color" value="@paper_border" @onchange="e => paper_border = e.Value!.ToString()!"/>
</div> </div>
</div> </div>
<div class="color background"> <div class="color background">
<div>Background</div> <div>Background</div>
<div> <div>
Base: <input type="color" value="@background" @onchange="e => background = e.Value.ToString()" /> Base: <input type="color" value="@background" @onchange="e => background = e.Value!.ToString()!"/>
</div> </div>
</div> </div>
<div class="color info"> <div class="color info">
<div>Info</div> <div>Info</div>
<div> <div>
Base: <input type="color" value="@info" @onchange="e => info = e.Value.ToString()" /> Base: <input type="color" value="@info" @onchange="e => info = e.Value!.ToString()!"/>
</div> </div>
</div> </div>
</div> </div>

2
IGP/Pages/MakingOf/Parts/MakingOfDialogs.razor

@ -2,7 +2,6 @@
<Title>Dialog</Title> <Title>Dialog</Title>
<Description>...</Description> <Description>...</Description>
<Example> <Example>
<DialogComponent></DialogComponent>
</Example> </Example>
<Usage> <Usage>
//TODO //TODO
@ -12,7 +11,6 @@
</Code> </Code>
</MakingOfComponent> </MakingOfComponent>
@code { @code {
} }

9
IGP/Pages/MakingOf/Parts/MakingOfDisplays.razor

@ -12,7 +12,8 @@
Example Entity Content Example Entity Content
</div> </div>
@for (var i = 0; i < 1; i++) { @for (var i = 0; i < 1; i++)
{
<div> <div>
-@i Example Entity Content -@i Example Entity Content
</div> </div>
@ -27,7 +28,8 @@
Example Entity Content Example Entity Content
</div> </div>
@for (var i = 0; i < 2; i++) { @for (var i = 0; i < 2; i++)
{
<div> <div>
-@i Example Entity Content -@i Example Entity Content
</div> </div>
@ -42,7 +44,8 @@
Example Entity Content Example Entity Content
</div> </div>
@for (var i = 0; i < 1; i++) { @for (var i = 0; i < 1; i++)
{
<div> <div>
-@i Example Entity Content -@i Example Entity Content
</div> </div>

2
IGP/Pages/MakingOf/Parts/MakingOfFeedback.razor

@ -12,7 +12,7 @@
<Example> <Example>
<div style="width: 300px; height: 450px;"> <div style="width: 300px; height: 450px;">
<LoadingComponent></LoadingComponent> <LoadingComponent/>
</div> </div>
</Example> </Example>
<Usage> <Usage>

40
IGP/Pages/MemoryTester/Parts/UnitMemory.razor

@ -7,14 +7,16 @@
<Display>@EntityMemory.Name</Display> <Display>@EntityMemory.Name</Display>
</FormDisplayComponent> </FormDisplayComponent>
@foreach (var question in questions) { @foreach (var question in questions)
{
var questionWrong = hasBeenSubmitted && !question.IsRevealed && question.Guess != question.Answer; var questionWrong = hasBeenSubmitted && !question.IsRevealed && question.Guess != question.Answer;
<FormGuessComponent IsSubmitted="hasBeenSubmitted" <FormGuessComponent IsSubmitted="hasBeenSubmitted"
OnChange="answerEventArgs => OnAnswerEntered(answerEventArgs, question)" OnChange="answerEventArgs => OnAnswerEntered(answerEventArgs, question)"
MemoryQuestion="question"/> MemoryQuestion="question"/>
@if (questionWrong) { @if (questionWrong)
{
<div class="wrongAnswer">The correct answer was @question.Answer</div> <div class="wrongAnswer">The correct answer was @question.Answer</div>
} }
} }
@ -48,9 +50,9 @@
@code { @code {
[Parameter] [Parameter]
public MemoryEntityModel EntityMemory { get; set; } public MemoryEntityModel EntityMemory { get; set; } = default!;
private List<MemoryQuestionModel> questions { get; set; } private List<MemoryQuestionModel> questions { get; set; } = default!;
private bool hasBeenSubmitted = false; private bool hasBeenSubmitted = false;
private bool isCorrect = false; private bool isCorrect = false;
@ -58,40 +60,49 @@
public int Guess { get; set; } public int Guess { get; set; }
protected override void OnInitialized() { protected override void OnInitialized()
{
MemoryTesterService.Subscribe(OnMemoryEvent); MemoryTesterService.Subscribe(OnMemoryEvent);
OnRefresh(); OnRefresh();
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
MemoryTesterService.Unsubscribe(OnMemoryEvent); MemoryTesterService.Unsubscribe(OnMemoryEvent);
} }
void OnMemoryEvent(MemoryTesterEvent memoryTesterEvent) { void OnMemoryEvent(MemoryTesterEvent memoryTesterEvent)
if (memoryTesterEvent == MemoryTesterEvent.OnVerify) { {
if (memoryTesterEvent == MemoryTesterEvent.OnVerify)
{
OnVerify(); OnVerify();
} }
if (memoryTesterEvent == MemoryTesterEvent.OnRefresh) { if (memoryTesterEvent == MemoryTesterEvent.OnRefresh)
{
OnRefresh(); OnRefresh();
} }
} }
public void OnAnswerEntered(AnswerEventArgs answerEventArgs, MemoryQuestionModel question) { public void OnAnswerEntered(AnswerEventArgs answerEventArgs, MemoryQuestionModel question)
{
question.Guess = answerEventArgs.Guess; question.Guess = answerEventArgs.Guess;
MemoryTesterService.Update(question); MemoryTesterService.Update(question);
} }
void OnVerify() { void OnVerify()
{
hasBeenSubmitted = true; hasBeenSubmitted = true;
isCorrect = true; isCorrect = true;
foreach (var question in questions) { foreach (var question in questions)
if (question.Answer != question.Guess) { {
if (question.Answer != question.Guess)
{
isCorrect = false; isCorrect = false;
isWrong = true; isWrong = true;
return; return;
@ -101,7 +112,8 @@
StateHasChanged(); StateHasChanged();
} }
void OnRefresh() { void OnRefresh()
{
hasBeenSubmitted = false; hasBeenSubmitted = false;
isCorrect = false; isCorrect = false;
isWrong = false; isWrong = false;

31
IGP/Pages/MemoryTester/Parts/UnitMemoryManager.razor

@ -4,8 +4,10 @@
<div class="quizContainer"> <div class="quizContainer">
<div class="quizListContainer"> <div class="quizListContainer">
@if (entities != null && questions != null) { @if (entities != null && questions != null)
@foreach (var entityMemory in entities) { {
@foreach (var entityMemory in entities)
{
<UnitMemory EntityMemory="entityMemory"></UnitMemory> <UnitMemory EntityMemory="entityMemory"></UnitMemory>
} }
} }
@ -57,25 +59,30 @@
@code { @code {
private List<MemoryEntityModel> entities; private List<MemoryEntityModel> entities = null!;
private List<MemoryQuestionModel> questions; private List<MemoryQuestionModel> questions = null!;
protected override void OnInitialized() { protected override void OnInitialized()
{
MemoryTesterService.Subscribe(OnMemoryEvent); MemoryTesterService.Subscribe(OnMemoryEvent);
MemoryTesterService.GenerateQuiz(); MemoryTesterService.GenerateQuiz();
} }
void IDisposable.Dispose() { void IDisposable.Dispose()
{
MemoryTesterService.Unsubscribe(OnMemoryEvent); MemoryTesterService.Unsubscribe(OnMemoryEvent);
} }
void OnMemoryEvent(MemoryTesterEvent memoryTesterEvent) { void OnMemoryEvent(MemoryTesterEvent memoryTesterEvent)
if (memoryTesterEvent == MemoryTesterEvent.OnVerify) { {
if (memoryTesterEvent == MemoryTesterEvent.OnVerify)
{
StateHasChanged(); StateHasChanged();
} }
if (memoryTesterEvent == MemoryTesterEvent.OnRefresh) { if (memoryTesterEvent == MemoryTesterEvent.OnRefresh)
{
entities = MemoryTesterService.GetEntities(); entities = MemoryTesterService.GetEntities();
questions = MemoryTesterService.GetQuestions(); questions = MemoryTesterService.GetQuestions();
@ -83,11 +90,13 @@
} }
} }
void OnSubmitQuiz(EventArgs eventArgs) { void OnSubmitQuiz(EventArgs eventArgs)
{
MemoryTesterService.Verify(); MemoryTesterService.Verify();
} }
void OnRefreshQuiz(EventArgs eventArgs) { void OnRefreshQuiz(EventArgs eventArgs)
{
MemoryTesterService.GenerateQuiz(); MemoryTesterService.GenerateQuiz();
} }

140
IGP/Pages/Notes/NotesIndexPage.razor

@ -0,0 +1,140 @@
@layout PageLayout
@inject INoteService noteService
@implements IDisposable
@page "/notes"
@if (!noteService.IsLoaded())
{
<LoadingComponent/>
}
else
{
<LayoutMediumContentComponent>
<PaperComponent>
@foreach (var noteSection in noteService.NoteSectionModels)
{
<div class="noteSectionContainer">
<div class="noteSectionTitle">@noteSection.Name</div>
<div class="noteContentContainer">
@foreach (var noteContent in noteSection.NoteContentModels)
{
<NavLink class="noteContentLink" href="@noteContent.GetNoteLink()">
<div class="noteContentName">@noteContent.Name</div>
<div class="noteContentDescription">@noteContent.Description</div>
</NavLink>
}
</div>
</div>
}
</PaperComponent>
</LayoutMediumContentComponent>
}
<style>
.noteSectionContainer {
width: 100%;
padding: 8px;
}
.noteSectionTitle {
font-size: 3rem;
font-weight: bold;
text-align: center;
margin-bottom: 32px;
}
.noteContentContainer {
display: grid;
gap: 12px;
grid-template-columns: 1fr 1fr;
}
@@media only screen and (max-width: 1025px) {
.noteContentContainer {
grid-template-columns: 1fr;
}
}
.noteContentName {
font-weight: bold;
font-size: 1.6rem;
}
.noteContentDescription {
font-weight: normal;
}
.noteContentLink {
background-color: var(--paper);
border: 1px solid var(--paper-border);
border-radius: 2px;
padding-left: 12px;
padding-right: 12px;
padding-top: 24px;
padding-bottom: 24px;
color: white;
display: flex;
flex-direction: column;
gap: 12px;
text-align: center;
margin-left: 12px;
margin-right: 12px;
}
.noteContentLink:hover {
background-color: var(--paper-hover);
border-color: var(--paper-border-hover);
text-decoration: none;
box-shadow: 0 4px 6px rgba(0,0,0,0.6);
transform: translateY(-2px) scale(1.01);
}
</style>
@code {
[Parameter]
public string? Href1 { get; set; }
[Parameter]
public string? Href2 { get; set; }
[Parameter]
public string? Href3 { get; set; }
[Parameter]
public string? Href4 { get; set; }
[Parameter]
public string? Href5 { get; set; }
private string Href => Href5 ?? Href4 ?? Href3 ?? Href2 ?? Href1 ?? "";
string selectedSection = "All";
protected override void OnInitialized()
{
noteService.Subscribe(StateHasChanged);
noteService.Load();
}
public void Dispose()
{
noteService.Unsubscribe(StateHasChanged);
}
void OnSectionChanged(ChangeEventArgs e)
{
selectedSection = e.Value!.ToString()!;
StateHasChanged();
}
}

126
IGP/Pages/Notes/NotesPage.razor

@ -1,109 +1,71 @@
@layout PageLayout @layout PageLayout
@inject INoteService NoteService @inject INoteService noteService
@implements IDisposable @implements IDisposable
@page "/notes" @page "/notes/{href1}/{href2?}/{href3?}/{href4?}/{href5?}"
@if (!NoteService.IsLoaded()) @if (!noteService.IsLoaded())
{ {
<LoadingComponent></LoadingComponent> <LoadingComponent/>
} }
else else
{ {
<LayoutMediumContentComponent> <LayoutWithSidebarComponent>
<WebsiteTitleComponent>Notes</WebsiteTitleComponent> <Sidebar>
<NoteNavComponent
<div class="section"> Connections="noteService.NoteConnectionModels"
<div for="noteSection">Section: </div> Notes="noteService.NoteContentModels"/>
<div style="flex: 1"></div> </Sidebar>
<select @oninput="OnSectionChanged" style="background-color: #36393F; width: 250px; margin-right: 16px;" name="noteSection"> <Content>
<option value="All">All</option> <PaperComponent>
@foreach (var note in noteService.NoteContentModels)
</select> {
</div> if (!note.Href.Equals(Href))
{
<div class="notesContainer"> continue;
@foreach (var note in NoteService.NoteModels) { }
if (note.IsHidden) { <NoteComponent NoteContentModel="note"/>
continue;
} }
if (selectedSection != "All" && note.Section != selectedSection) { </PaperComponent>
continue; </Content>
} </LayoutWithSidebarComponent>
@if (note.IsPreAlpha) {
<AlertComponent Type=SeverityType.Warning>
<Title>Pre Alpha</Title>
<Message>This note refers to content that is in pre-alpha. It won't be accurate in future updates to IGP.</Message>
</AlertComponent>
}
<PaperComponent>
<div style="display: flex; flex-direction: row;">
<span style="font-weight: bold; font-style:italic;">@note.Section</span>
<div style="flex: 1"></div>
<span style="font-weight: bold; font-style:italic;">Last Updated on @note.LastUpdated</span>
</div>
<div>
<div id="@note.DEPRECATED_Id()" style="font-weight: bold; font-size: 1.4rem;">@note.Name</div>
<div style="white-space:break-spaces;">@((MarkupString)note.Description)</div>
</div>
</PaperComponent>
}
</div>
</LayoutMediumContentComponent>
} }
<style>
.section {
display: flex;
width: 500px;
flex-direction: row;
background-color: var(--paper);
justify-content: center;
padding: 24px;
border: 4px solid var(--paper-border);
box-shadow: 0px 6px var(--paper-border);
}
.notesContainer { <style>
display: flex;
flex-direction: column;
gap: 16px;
}
.noteContainer {
padding: 24px;
border: 2px solid black;
margin: auto;
overflow-y: auto;
overflow-x: hidden;
background-color: var(--paper);
}
</style> </style>
@code { @code {
string selectedSection = "All"; [Parameter]
public string? Href1 { get; set; }
[Parameter]
public string? Href2 { get; set; }
[Parameter]
public string? Href3 { get; set; }
[Parameter]
public string? Href4 { get; set; }
[Parameter]
public string? Href5 { get; set; }
private string Href => Href5 ?? Href4 ?? Href3 ?? Href2 ?? Href1 ?? "";
protected override void OnInitialized() protected override void OnInitialized()
{ {
NoteService.Subscribe(StateHasChanged); noteService.Subscribe(StateHasChanged);
NoteService.Load(); noteService.Load();
} }
public void Dispose() public void Dispose()
{ {
NoteService.Unsubscribe(StateHasChanged); noteService.Unsubscribe(StateHasChanged);
} }
void OnSectionChanged(ChangeEventArgs e) {
selectedSection = e.Value.ToString();
StateHasChanged();
}
} }

35
IGP/Pages/Notes/Parts/NoteComponent.razor

@ -0,0 +1,35 @@
<div class="note">
<div class="noteHeader">
<div class="noteTitle">@NoteContentModel.Name</div>
<div class="noteDates">
<div class="noteDateUpdated"><b>Updated</b>: @NoteContentModel.UpdatedDate.ToString("MM/dd/yyyy")</div>
<div class="noteDateCreated"><b>Created</b>: @NoteContentModel.CreatedDate.ToString("MM/dd/yyyy")</div>
</div>
</div>
<div class="noteContent">@((MarkupString)Markdown.ToHtml(NoteContentModel.Content))</div>
</div>
<style>
.noteTitle {
font-weight: bold;
}
.noteHeader {
display: flex;
justify-content: space-between;
}
.noteDates {
display: flex;
flex-direction: column;
}
</style>
@code {
[Parameter]
public NoteContentModel NoteContentModel { get; set; } = default!;
}

75
IGP/Pages/Notes/Parts/NoteInnerNavComponent.razor

@ -0,0 +1,75 @@
@if (Note!.NoteContentModels.Count > 0)
{
<div class="noteInnerNavContainer">
@foreach (var innerNote in Note.NoteContentModels)
{
var linkStyle = $"noteInnerNavButton inner_{Layers}";
<NavLink class="@linkStyle" href="@innerNote.GetNoteLink()">@innerNote.Name</NavLink>
<NoteInnerNavComponent Note="@innerNote" Layers="@IncrementLayers()"/>
}
</div>
}
<style>
.noteInnerNavContainer {
display: flex;
flex-direction: column;
}
.noteInnerNavButton a {
color: white;
}
.noteInnerNavButton a:hover {
color: white;
}
.noteInnerNavButton {
padding: 8px;
margin-left: 8px;
color: white;
}
.noteInnerNavButton:hover {
}
.inner_1 {
margin-left: 8px;
}
.inner_2 {
margin-left: 16px;
}
.inner_3 {
margin-left: 24px;
}
</style>
@code {
[Parameter]
public NoteContentModel? Note { get; set; } = default!;
[Parameter]
public int Layers { get; set; } = 1;
public int IncrementLayers()
{
return Layers + 1;
}
private string GetLink(NoteContentModel note)
{
return $"notes/{note.Href}";
}
}

43
IGP/Pages/Notes/Parts/NoteNavComponent.razor

@ -0,0 +1,43 @@
<div class="noteNavContainer">
@foreach (var note in Notes)
{
if (note.Parent == null)
{
<NavLink class="noteNavButton" href="@note.GetNoteLink()">@note.Name</NavLink>
<NoteInnerNavComponent Note="@note"/>
}
}
</div>
<style>
.noteNavContainer {
display: flex;
flex-direction: column;
}
.noteNavButton a {
color: white;
}
.noteNavButton a:hover {
color: white;
background-color: var(--primary-hover);
}
.noteNavButton {
padding: 8px;
color: white;
}
</style>
@code {
[Parameter]
public List<NoteContentModel> Notes { get; set; } = default!;
[Parameter]
public List<NoteConnectionModel> Connections { get; set; } = default!;
}

3
IGP/Pages/RoadMap/Parts/RoadMapComponent.razor

@ -1,4 +1,4 @@
<div class="roadMapContainer @RoadMap.Status.ToLower()"> <div class="roadMapContainer @RoadMap!.Status.ToLower()">
<div class="roadMapTitle">@RoadMap.Name</div> <div class="roadMapTitle">@RoadMap.Name</div>
<div> <div>
<b>Priority:</b> @RoadMap.Priority.Replace("_", " ") <b>Priority:</b> @RoadMap.Priority.Replace("_", " ")
@ -53,6 +53,7 @@
</style> </style>
@code { @code {
[Parameter] [Parameter]
public ImmortalRoadMapModel? RoadMap { get; set; } public ImmortalRoadMapModel? RoadMap { get; set; }

3
IGP/Pages/RoadMap/RoadMapPage.razor

@ -6,7 +6,8 @@
<WebsiteTitleComponent>Road Map</WebsiteTitleComponent> <WebsiteTitleComponent>Road Map</WebsiteTitleComponent>
<div class="roadMapsContainer"> <div class="roadMapsContainer">
@foreach (var roadMap in data) { @foreach (var roadMap in data)
{
<RoadMapComponent RoadMap=roadMap/> <RoadMapComponent RoadMap=roadMap/>
} }
</div> </div>

229
IGP/Pages/SandboxPage.razor

@ -1,229 +0,0 @@
@layout PageLayout
@page "/sandbox"
@inject IJSRuntime JS
<LayoutLargeContentComponent>
<WebsiteTitleComponent>Sandbox</WebsiteTitleComponent>
<div>
Generic Page of Testing In Progress code
</div>
<button @onclick="() => DownloadFile(typeof(WebPageModel))">
WebPageModel
</button>
<button @onclick="() => DownloadFile(typeof(WebSectionModel))">
WebSectionModel
</button>
<button @onclick="() => DownloadFile(typeof(PatchModel))">
PatchModel
</button>
<button @onclick="() => DownloadFile(typeof(ChangeModel))">
ChangeModel
</button>
<button @onclick="() => DownloadFile(typeof(SprintModel))">
SprintModel
</button>
<button @onclick="() => DownloadFile(typeof(TaskModel))">
TaskModel
</button>
<FormLayoutComponent>
<FormTextAreaComponent Value="@infoText"></FormTextAreaComponent>
</FormLayoutComponent>
</LayoutLargeContentComponent>
@code {
readonly List<EntityModel> entities = EntityModel.GetList();
List<EntityInfoModel> infos = new();
string infoText = "";
string weaponText = "";
readonly List<ChangeModel> changes = new();
readonly List<PatchModel> patches = new();
private async Task DownloadFile(Type type) {
var fileName = $"{type.ToString().Split(".").Last()}s.csv";
var objectData =
type == typeof(PatchModel) ? new List<object>(patches)
: type == typeof(ChangeModel) ? new List<object>(changes)
: new List<object>();
await JS.InvokeVoidAsync("download", fileName, Generate(type, objectData));
}
void GenerateEntityModels() {
var properties = typeof(EntityInfoModel).GetProperties();
infoText += "Id,Name,Descriptive,Description,Notes\n";
var id = 1;
foreach (var entity in entities) {
infoText += $"{id++},{entity.Info().Name},{entity.Info().Descriptive},{entity.Info().Description},{entity.Info().Notes}\n";
}
}
string Generate(Type type, List<object> dataList) {
var properties = type.GetProperties();
var generatedText = "";
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
if (property.GetAccessors().First().IsVirtual) {
continue;
}
var attributes = property.GetCustomAttributes().OfType<ObsoleteAttribute>();
if (attributes.Count() > 0) {
continue;
}
generatedText += property.Name;
if (index != properties.Count() - 1) {
generatedText += ",";
}
}
generatedText = generatedText.Trim();
if (generatedText.EndsWith(",")) {
generatedText = generatedText.Remove(generatedText.Length - 1);
}
generatedText += "\n";
foreach (var data in dataList) {
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
if (property.GetAccessors().First().IsVirtual) {
continue;
}
var attributes = property.GetCustomAttributes().OfType<ObsoleteAttribute>();
if (attributes.Count() > 0) {
continue;
}
if (property.GetValue(data) != null) {
generatedText += "\"" + property.GetValue(data).ToString().Replace("\"", "\"\"") + "\"";
if (index != properties.Count() - 1) {
generatedText += ",";
}
}
else {
generatedText += "\"" + " " + "\"";
if (index != properties.Count() - 1) {
generatedText += ",";
}
}
}
generatedText = generatedText.Trim();
if (generatedText.EndsWith(",")) {
generatedText = generatedText.Remove(generatedText.Length - 1);
}
generatedText += "\n";
}
return generatedText;
}
void GenerateWeapons() {
var properties = typeof(EntityWeaponModel).GetProperties();
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
if (property.GetAccessors().First().IsVirtual) {
continue;
}
var attributes = property.GetCustomAttributes().OfType<ObsoleteAttribute>
();
if (attributes.Count() > 0) {
continue;
}
weaponText += property.Name;
if (index != properties.Count() - 1) {
weaponText += ",";
}
}
weaponText += "\n";
foreach (var entity in entities) {
foreach (var weapon in entity.Weapons()) {
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
if (property.GetAccessors().First().IsVirtual) {
continue;
}
var attributes = property.GetCustomAttributes().OfType<ObsoleteAttribute>
();
if (attributes.Count() > 0) {
continue;
}
weaponText += property.GetValue(weapon);
if (index != properties.Count() - 1) {
weaponText += ",";
}
}
weaponText += "\n";
}
}
}
void GenerateExample() {
var properties = typeof(EntityInfoModel).GetProperties();
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
infoText += property.Name;
if (index != properties.Count() - 1) {
infoText += ",";
}
}
infoText += "\n";
foreach (var entity in entities) {
if (entity.Info() != null) {
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
infoText += property.GetValue(entity.Info());
if (index != properties.Count() - 1) {
infoText += ",";
}
}
infoText += "\n";
}
}
}
}

9
IGP/Portals/EntityDialogPortal.razor

@ -9,12 +9,14 @@
@code { @code {
protected override void OnInitialized() protected override void OnInitialized()
{ {
entityDialogService.Subscribe(OnUpdate); entityDialogService.Subscribe(OnUpdate);
} }
public void Dispose() { public void Dispose()
{
entityDialogService.Unsubscribe(OnUpdate); entityDialogService.Unsubscribe(OnUpdate);
} }
@ -23,5 +25,4 @@
StateHasChanged(); StateHasChanged();
} }
} }

15
IGP/Program.cs

@ -1,20 +1,16 @@
using IGP; using IGP;
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using Services;
using Services.Development;
using Services.Immortal;
using Services.Website;
#if NO_SQL #if NO_SQL
#else #else
using Contexts; using Contexts;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
#endif #endif
using Services;
using Services.Immortal;
using Services.Website;
using Services.Development;
using IEntityDisplayService = Services.IEntityDisplayService;
var builder = WebAssemblyHostBuilder.CreateDefault(args); var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Logging.SetMinimumLevel(LogLevel.Warning); builder.Logging.SetMinimumLevel(LogLevel.Warning);
@ -37,7 +33,8 @@ builder.Services.AddSingleton<IEntityFilterService, EntityFilterService>();
builder.Services.AddSingleton<IEntityDisplayService, EntityDisplayService>(); builder.Services.AddSingleton<IEntityDisplayService, EntityDisplayService>();
builder.Services.AddSingleton(new HttpClient { builder.Services.AddSingleton(new HttpClient
{
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
}); });

44
IGP/_Imports.razor

@ -1,6 +1,4 @@
 @using Components.Display
@using Components.Display
@using Components.Feedback @using Components.Feedback
@using Components.Form @using Components.Form
@using Components.Info @using Components.Info
@ -9,17 +7,26 @@
@using Components.Navigation @using Components.Navigation
@using Components.Shared @using Components.Shared
@using Components.Utils @using Components.Utils
@using IGP.Portals
@using IGP.Pages
@using IGP.Dialog @using IGP.Dialog
@using IGP.Pages
@using IGP.Pages.Agile.Parts @using IGP.Pages.Agile.Parts
@using IGP.Pages.BuildCalculator.Parts @using IGP.Pages.BuildCalculator.Parts
@using IGP.Pages.Comparision
@using IGP.Pages.Comparision.Parts
@using IGP.Pages.Database.Entity @using IGP.Pages.Database.Entity
@using IGP.Pages.Database.Entity.Parts @using IGP.Pages.Database.Entity.Parts
@using IGP.Pages.Database.Parts @using IGP.Pages.Database.Parts
@using IGP.Pages.Documentation
@using IGP.Pages.Documentation.Parts
@using IGP.Pages.Home
@using IGP.Pages.Home.Parts
@using IGP.Pages.MakingOf.Parts @using IGP.Pages.MakingOf.Parts
@using IGP.Pages.MemoryTester.Parts @using IGP.Pages.MemoryTester.Parts
@using IGP.Pages.RoadMap.Parts @using IGP.Pages.RoadMap.Parts
@using IGP.Pages.Notes
@using IGP.Pages.Notes.Parts
@using IGP.Portals
@using Markdig
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web
@ -27,21 +34,20 @@
@using Microsoft.AspNetCore.Components.WebAssembly.Http @using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.EntityFrameworkCore @using Microsoft.EntityFrameworkCore
@using Microsoft.JSInterop @using Microsoft.JSInterop
@using Model.Immortal.Chart @using Model.Chart
@using Model.Immortal.Economy @using Model.Development.Git
@using Model.Immortal.Entity @using Model.Doc
@using Model.Immortal.Entity.Data @using Model.Economy
@using Model.Immortal.Entity.Parts @using Model.Entity
@using Model.Immortal.Hotkeys @using Model.Entity.Data
@using Model.Immortal.MemoryTester @using Model.Entity.Parts
@using Model.Immortal.MemoryTester @using Model.Hotkeys
@using Model.Immortal.Notes @using Model.MemoryTester
@using Model.Immortal.RoadMap @using Model.Notes
@using Model.Immortal.RoadMap @using Model.RoadMap
@using Model.Immortal.RoadMap.Enums @using Model.RoadMap.Enums
@using Model.Immortal.Types @using Model.Types
@using Model.Website @using Model.Website
@using Model.Work.Git
@using Model.Work.Tasks @using Model.Work.Tasks
@using Model.Work.Tasks.Enums @using Model.Work.Tasks.Enums
@using Services @using Services

6
IGP/wwwroot/css/app.css

@ -15,9 +15,13 @@
--secondary-border-hover: #a168ff; --secondary-border-hover: #a168ff;
--paper: #252526; --paper: #252526;
--paper-border: #151516; --paper-border: #151516;
--paper-hover: #52366f;
--paper-border-hover: #653497;
--info: #451376; --info: #451376;
--info-border: #210b36; --info-border: #210b36;
--dialog-border-color: black; --dialog-border-color: black;
--dialog-border-width: 2px; --dialog-border-width: 2px;
--dialog-radius: 6px; --dialog-radius: 6px;

1
IGP/wwwroot/generated/AgileSprintModels.json

@ -0,0 +1 @@
[{"Id":1,"Name":"Agile Sprint","Description":"Changelogs and sprint views were going to be pushed till later, but I am feeling inspired by the IGP Content Creators\u0027 minimum weekly lifecycle requirement. So I am going to focus on agile-related tasks, and handle roadmap tasks after this initial sprint. All weekly sprints will release on Sunday, starting next Sunday.","StartDate":"2022-02-14T00:00:00","EndDate":"2022-02-20T00:00:00","Notes":null,"AgileTaskModels":[]},{"Id":2,"Name":"SQL Update","Description":"The SQL update is big enough to be a full sprint in of itself, and I spent less time this week for development. Will just extend sprint by 2 week, and remove all non SQL tasks from the sprint.","StartDate":"2022-02-20T00:00:00","EndDate":"2022-03-27T00:00:00","Notes":null,"AgileTaskModels":[]},{"Id":3,"Name":"Database Page","Description":"Improvements to the Database page","StartDate":"2022-03-27T00:00:00","EndDate":"2022-04-03T00:00:00","Notes":null,"AgileTaskModels":[]},{"Id":4,"Name":"Branding","Description":"Improve streaming branding around the website","StartDate":"2022-04-03T00:00:00","EndDate":"2022-04-10T00:00:00","Notes":null,"AgileTaskModels":[]},{"Id":5,"Name":"Calculators","Description":"Improve Calculators","StartDate":"2022-04-10T00:00:00","EndDate":"2022-04-24T00:00:00","Notes":null,"AgileTaskModels":[]},{"Id":6,"Name":"Infrastructure","Description":"Localization, Analytics, and Test Automation","StartDate":"2022-04-24T00:00:00","EndDate":"2022-05-08T00:00:00","Notes":null,"AgileTaskModels":[]}]

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save