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. 14
      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. 31
      IGP/App.razor
  31. BIN
      IGP/Database.db
  32. 8
      IGP/Dialog/EntityDialogComponent.razor
  33. 5
      IGP/IGP.csproj
  34. 4
      IGP/Index.razor
  35. 53
      IGP/PageLayout.razor
  36. 47
      IGP/Pages/Agile/AgilePage.razor
  37. 29
      IGP/Pages/Agile/Parts/BacklogComponent.razor
  38. 46
      IGP/Pages/Agile/Parts/SprintComponent.razor
  39. 106
      IGP/Pages/BuildCalculator/BuildCalculatorPage.razor
  40. 37
      IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor
  41. 16
      IGP/Pages/BuildCalculator/Parts/BankComponent.razor
  42. 19
      IGP/Pages/BuildCalculator/Parts/BuildOrderComponent.razor
  43. 61
      IGP/Pages/BuildCalculator/Parts/ChartComponent.razor
  44. 28
      IGP/Pages/BuildCalculator/Parts/EntityClickViewComponent.razor
  45. 18
      IGP/Pages/BuildCalculator/Parts/FilterComponent.razor
  46. 30
      IGP/Pages/BuildCalculator/Parts/HighlightsComponent.razor
  47. 131
      IGP/Pages/BuildCalculator/Parts/HotkeyViewerComponent.razor
  48. 10
      IGP/Pages/BuildCalculator/Parts/InputPanelComponent.razor
  49. 16
      IGP/Pages/BuildCalculator/Parts/TimelineComponent.razor
  50. 27
      IGP/Pages/BuildCalculator/Parts/TimingComponent.razor
  51. 54
      IGP/Pages/ChangeLogPage.razor
  52. 31
      IGP/Pages/Comparision/ComparisionPage.razor
  53. 11
      IGP/Pages/Comparision/Parts/BuildLoaderComponent.razor
  54. 8
      IGP/Pages/Comparision/Parts/SandComponent.razor
  55. 2
      IGP/Pages/ContactPage.razor
  56. 90
      IGP/Pages/Database/DatabasePage.razor
  57. 15
      IGP/Pages/Database/DatabaseSinglePage.razor
  58. 5
      IGP/Pages/Database/Entity/EntityViewComponent.razor
  59. 44
      IGP/Pages/Database/Entity/Parts/EntityAbilitiesComponent.razor
  60. 7
      IGP/Pages/Database/Entity/Parts/EntityHeaderComponent.razor
  61. 35
      IGP/Pages/Database/Entity/Parts/EntityInfoComponent.razor
  62. 8
      IGP/Pages/Database/Entity/Parts/EntityMechanicsComponent.razor
  63. 40
      IGP/Pages/Database/Entity/Parts/EntityPassivesComponent.razor
  64. 81
      IGP/Pages/Database/Entity/Parts/EntityProductionComponent.razor
  65. 36
      IGP/Pages/Database/Entity/Parts/EntityPyreSpellsComponent.razor
  66. 75
      IGP/Pages/Database/Entity/Parts/EntityStatsComponent.razor
  67. 13
      IGP/Pages/Database/Entity/Parts/EntityUpgradesComponent.razor
  68. 12
      IGP/Pages/Database/Entity/Parts/EntityVanguardAddedComponent.razor
  69. 13
      IGP/Pages/Database/Entity/Parts/EntityVanguardsComponent.razor
  70. 8
      IGP/Pages/Database/Entity/Parts/EntityWeaponsComponent.razor
  71. 55
      IGP/Pages/Database/Parts/EntityFilterComponent.razor
  72. 115
      IGP/Pages/Documentation/DocumentationIndexPage.razor
  73. 98
      IGP/Pages/Documentation/DocumentationPage.razor
  74. 35
      IGP/Pages/Documentation/Parts/DocumentComponent.razor
  75. 70
      IGP/Pages/Documentation/Parts/DocumentInnerNavComponent.razor
  76. 46
      IGP/Pages/Documentation/Parts/DocumentNavComponent.razor
  77. 33
      IGP/Pages/HarassCalculatorPage.razor
  78. 82
      IGP/Pages/Home/HomePage.razor
  79. 76
      IGP/Pages/Home/Parts/ContentHighlightComponent.razor
  80. 149
      IGP/Pages/HomePage.razor
  81. 24
      IGP/Pages/MakingOf/Parts/MakingOfColours.razor
  82. 2
      IGP/Pages/MakingOf/Parts/MakingOfDialogs.razor
  83. 9
      IGP/Pages/MakingOf/Parts/MakingOfDisplays.razor
  84. 2
      IGP/Pages/MakingOf/Parts/MakingOfFeedback.razor
  85. 40
      IGP/Pages/MemoryTester/Parts/UnitMemory.razor
  86. 31
      IGP/Pages/MemoryTester/Parts/UnitMemoryManager.razor
  87. 140
      IGP/Pages/Notes/NotesIndexPage.razor
  88. 114
      IGP/Pages/Notes/NotesPage.razor
  89. 35
      IGP/Pages/Notes/Parts/NoteComponent.razor
  90. 75
      IGP/Pages/Notes/Parts/NoteInnerNavComponent.razor
  91. 43
      IGP/Pages/Notes/Parts/NoteNavComponent.razor
  92. 3
      IGP/Pages/RoadMap/Parts/RoadMapComponent.razor
  93. 3
      IGP/Pages/RoadMap/RoadMapPage.razor
  94. 229
      IGP/Pages/SandboxPage.razor
  95. 5
      IGP/Portals/EntityDialogPortal.razor
  96. 15
      IGP/Program.cs
  97. 44
      IGP/_Imports.razor
  98. 4
      IGP/wwwroot/css/app.css
  99. 1
      IGP/wwwroot/generated/AgileSprintModels.json
  100. 1
      IGP/wwwroot/generated/AgileTaskModels.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 {
[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="devOnlyTitleContainer">
<div class="devOnlyTitle">
@ -58,15 +58,15 @@
@code {
[Inject]
NavigationManager NavigationManager { get; set; }
NavigationManager NavigationManager { get; set; } = default!;
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
bool IsOnDev;
bool isOnDev;
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 {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public string Title { get; set; }
public string Title { get; set; } = default!;
}

5
Components/Display/InfoTooltipComponent.razor

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

10
Components/Display/MakingOfComponent.razor

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

4
Components/Display/MakingOfSectionComponent.razor

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

4
Components/Form/FormDisplayComponent.razor

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

4
Components/Form/FormEscapeCodeComponent.razor

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

12
Components/Form/FormGuessComponent.razor

@ -1,6 +1,6 @@
@using Services
@using Services.Immortal
@using Model.Immortal.MemoryTester
@using Model.MemoryTester
@implements IDisposable
@inject IMemoryTesterService MemoryTesterService
@ -13,7 +13,7 @@
}
<div>
<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..."
type="number"
value="@guess"
@ -80,16 +80,16 @@
public string Info { get; set; } = "";
[Parameter]
public EventCallback<AnswerEventArgs> OnChange { get; set; }
public EventCallback<AnswerEventArgs> OnChange { get; set; } = default!;
[Parameter]
public MemoryQuestionModel MemoryQuestion { get; set; }
public MemoryQuestionModel MemoryQuestion { get; set; } = default!;
[Parameter]
public bool IsSubmitted { get; set; }
private string guess { get; set; } = "";
private string? guess = "";
private string labelId = "";
@ -142,7 +142,7 @@
}
void OnGuessChanged(ChangeEventArgs changeEventArgs) {
guess = changeEventArgs.Value.ToString();
guess = changeEventArgs.Value!.ToString()!;
OnChange.InvokeAsync(new AnswerEventArgs {
Name = MemoryQuestion.Name,

6
Components/Inputs/ButtonComponent.razor

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

4
Components/Inputs/ButtonGroupComponent.razor

@ -68,10 +68,10 @@
@code {
[Parameter]
public string Choice { get; set; }
public string Choice { get; set; } = default!;
[Parameter]
public List<string> Choices { get; set; }
public List<string> Choices { get; set; } = default!;
[Parameter]
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 System.ComponentModel.DataAnnotations
@using Model.Immortal.Entity.Data
@using Model.Entity.Data
@using Services
@inject IEntityDialogService entityDialogService
@ -18,7 +18,7 @@ else
@code {
[Parameter] public string EntityId { get; set; }
[Parameter] public string EntityId { get; set; } = default!;
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 {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
}

17
Components/MarkdownContent/MarkdownContent.razor

@ -1,22 +1,15 @@
@if (Markdown == null) {
<div>Loading...</div>
}
else {
@((MarkupString)Markdown)
}
@((MarkupString)MarkdownText)
@code {
[Inject]
protected HttpClient Http { get; set; }
protected HttpClient Http { get; set; } = default!;
[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() {
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
[Parameter]
public List<WebSectionModel> WebSections { get; set; }
public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter]
public List<WebPageModel> WebPages { get; set; }
public List<WebPageModel> WebPages { get; set; } = default!;
#else
[Parameter]
public DbSet<WebSectionModel> WebSections { get; set; }
public DbSet<WebSectionModel> WebSections { get; set; } = default!;
[Parameter]
public DbSet<WebPageModel> WebPages { get; set; }
public DbSet<WebPageModel> WebPages { get; set; } = default!;
#endif
protected override void OnInitialized() {

36
Components/Navigation/MobileNavComponent.razor

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

11
Components/Navigation/NavLinkComponent.razor

@ -5,7 +5,7 @@
@inject NavigationManager NavigationManager;
@if (IsOnPage) {
@if (isOnPage) {
<NavLink href="@Page.Href" class="navContainer navLink navSelected">
<div class="navName">
@Page.Name
@ -62,14 +62,15 @@ else {
@code {
[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();
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 {
[Parameter]
public WebSectionModel? Section { get; set; }
public WebSectionModel Section { get; set; } = default!;
[Parameter]
public List<WebPageModel>? Children { get; set; }
public List<WebPageModel> Children { get; set; } = default!;
}

14
Components/Navigation/TabletNavComponent.razor

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

6
Components/Shared/DisplayableContent.razor

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

4
Components/Shared/DisplayableRoute.razor

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

4
Components/Shared/MathDivisionComponent.razor

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

6
Components/Shared/MathLoopSumComponent.razor

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

2
Components/Shared/SpoilerTextComponent.razor

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

34
Contexts/DatabaseContext.cs

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

31
IGP/App.razor

@ -17,16 +17,43 @@
<style>
a {
color: #8fc5ff;
color: white;
font-weight: 700;
}
a:hover {
color: #d2f0ff;
color: white;
text-decoration: underline;
text-decoration-color: #8fc5ff;
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>
@code {

BIN
IGP/Database.db

Binary file not shown.

8
IGP/Dialog/EntityDialogComponent.razor

@ -134,18 +134,19 @@
@code {
EntityModel entity = null;
EntityModel entity = default!;
private int refresh = 0;
protected override void OnInitialized()
{
entity = DATA.Get()[entityDialogService.GetEntityId()];
entity = DATA.Get()[entityDialogService.GetEntityId() ?? string.Empty];
entityDialogService.Subscribe(OnUpdate);
}
public void Dispose() {
public void Dispose()
{
entityDialogService.Unsubscribe(OnUpdate);
}
@ -164,4 +165,3 @@
}
}

5
IGP/IGP.csproj

@ -36,4 +36,9 @@
<ProjectReference Include="..\Model\Model.csproj"/>
<ProjectReference Include="..\Services\Services.csproj"/>
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\generated"/>
</ItemGroup>
</Project>

4
IGP/Index.razor

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

53
IGP/PageLayout.razor

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

47
IGP/Pages/Agile/AgilePage.razor

@ -5,13 +5,15 @@
@page "/agile"
@if (AgileService.IsLoaded()) {
@if (AgileService.IsLoaded())
{
<LayoutMediumContentComponent>
<WebsiteTitleComponent>Agile</WebsiteTitleComponent>
<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)">
<summary class="sprintSummary">
<div class="sprintTitle">@sprint.Name</div>
@ -20,19 +22,22 @@
<div class="sprintStartDate">
@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 class="sprintEndDate">
@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>
</summary>
<SprintComponent Sprint=sprint Tasks=AgileService.TaskModels></SprintComponent>
<SprintComponent AgileSprint="sprint"></SprintComponent>
</details>
}
@ -49,6 +54,8 @@
<ContentDividerComponent></ContentDividerComponent>
<PaperComponent>
<InfoBodyComponent>
<InfoQuestionComponent>What is Agile?</InfoQuestionComponent>
<InfoAnswerComponent>
@ -59,19 +66,19 @@
Any unfinished tasks are moved into the next sprint, or the sprint will be extended by a week.
</InfoAnswerComponent>
</InfoBodyComponent>
</PaperComponent>
</LayoutMediumContentComponent>
}
else {
<LoadingComponent></LoadingComponent>
else
{
<LoadingComponent/>
}
@code {
#if NO_SQL
public List<TaskModel> Tasks => AgileService.TaskModels;
public List<SprintModel> Sprints => AgileService.SprintModels;
#else
[Inject]
DatabaseContext Database { get; set; }
@ -83,21 +90,26 @@ else {
public DbSet<SprintModel> Sprints { get; set; }
#endif
private readonly List<TaskModel> backlog = new();
private readonly List<AgileTaskModel> backlog = new();
protected override void OnInitialized() {
protected override void OnInitialized()
{
AgileService.Subscribe(HasChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
AgileService.Unsubscribe(HasChanged);
}
void HasChanged() {
void HasChanged()
{
backlog.Clear();
foreach (var task in Tasks) {
if (task.SprintModelId == null) {
foreach (var task in AgileService.AgileTaskModels!)
{
if (task.AgileSprintModelId == null)
{
backlog.Add(task);
}
}
@ -105,7 +117,8 @@ else {
StateHasChanged();
}
protected override async Task OnInitializedAsync() {
protected override async Task OnInitializedAsync()
{
#if NO_SQL
await AgileService.Load();
#else

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

@ -1,6 +1,7 @@
<div class="sprintContainer">
<div class="tasksContainer">
@foreach (var task in Backlog) {
@foreach (var task in Backlog)
{
<div class="taskContainer @task.Status.ToLower()">
<div class="taskName">@task.Name</div>
<div class="taskDetails">
@ -17,7 +18,8 @@
</div>
</LayoutColumnComponent>
<LayoutColumnComponent>
@if (task.Finished != null) {
@if (task.Finished != null)
{
<div class="taskFinished">
<b>Finished: </b>@task.Finished
</div>
@ -49,19 +51,6 @@
padding-top: 16px;
}
.sprintDescription {
grid-area: description;
}
.sprintStartDate {
}
.sprintEndDate {
}
.sprintNotes {
}
@@media only screen and (max-width: 1025px) {
.sprintContainer {
@ -73,14 +62,6 @@
box-shadow: none;
padding: 8px;
}
.sprintStartDate {
text-align: left;
}
.sprintEndDate {
text-align: left;
}
}
.tasksContainer {
@ -197,6 +178,6 @@
@code {
[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="sprintStatus">
<b>Status: </b>@Sprint.GetSprintType()
<b>Status: </b>@AgileSprint.GetSprintType()
</div>
<div class="sprintDescription">
<b>Description: </b>@Sprint.Description
<b>Description: </b>@AgileSprint.Description
</div>
<div class="sprintNotes">
<b>Notes: </b>@Sprint.Notes
<b>Notes: </b>@AgileSprint.Notes
</div>
<div class="tasksContainer">
@if (selectedTasks.Count > 0) {
@foreach (var task in selectedTasks) {
@if (AgileSprint.AgileTaskModels.Count > 0)
{
@foreach (var task in AgileSprint.AgileTaskModels)
{
<div class="taskContainer @task.Status.ToLower() @task.Task.ToLower()">
<div class="taskName">@task.Name</div>
<div class="taskDetails">
@ -28,13 +30,14 @@
</LayoutColumnComponent>
<LayoutColumnComponent>
@if (task.Finished != null) {
@if (task.Finished != null)
{
<div class="taskFinished">
<b>Finished: </b>@task.Finished.Value.ToString("dd/MM/yyyy")
</div>
}
<div class="taskCreated">
<b>Created: </b>@task.Created.Value.ToString("dd/MM/yyyy")
<b>Created: </b>@task.Created!.Value.ToString("dd/MM/yyyy")
</div>
</LayoutColumnComponent>
</LayoutRowComponent>
@ -48,7 +51,8 @@
</div>
}
}
else {
else
{
<div>Add Tasks...</div>
}
</div>
@ -66,14 +70,6 @@
grid-area: description;
}
.sprintStartDate {
}
.sprintEndDate {
}
.sprintNotes {
}
@@media only screen and (max-width: 1025px) {
@ -221,23 +217,7 @@
@code {
#if NO_SQL
[Parameter]
public List<TaskModel> Tasks { get; set; }
#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();
}
public AgileSprintModel AgileSprint { get; set; } = default!;
}

106
IGP/Pages/BuildCalculator/BuildCalculatorPage.razor

@ -2,6 +2,12 @@
@layout PageLayout
@inject IKeyService keyService
@inject IImmortalSelectionService filterService
@inject IBuildOrderService buildOrderService
@inject IEconomyService economyService
@inject ITimingService timingService
@page "/build-calculator"
<LayoutLargeContentComponent>
@ -20,19 +26,15 @@
<div class="calculatorGrid">
<div style="grid-area: timing;" class="gridItem">
<InfoTooltipComponent InfoText="Enter build details.
<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.">
<InfoTooltipComponent InfoText="">
<TimingComponent></TimingComponent>
</InfoTooltipComponent>
</div>
@if (true) {
@if (true)
{
<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.">
<ChartComponent></ChartComponent>
@ -70,18 +72,15 @@
<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>
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>">
<InfoTooltipComponent InfoText="">
<HotkeyViewerComponent Size="80"></HotkeyViewerComponent>
</InfoTooltipComponent>
</div>
@if (false) {
@if (false)
{
<div style="grid-area: timeline;" class="gridItem">
<TimelineComponent></TimelineComponent>
</div>
@ -216,72 +215,59 @@ Additionally, more entities will appear as you build the required technology. Yo
@code {
[Inject]
IKeyService KeyService { get; set; }
[Inject]
IImmortalSelectionService FilterService { get; set; }
[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);
protected override void OnInitialized()
{
keyService.Subscribe(HandleClick);
filterService.Subscribe(StateHasChanged);
economyService.Subscribe(StateHasChanged);
timingService.Subscribe(HandleTimingChanged);
economyService.Calculate(buildOrderService, timingService, 0);
}
void IDisposable.Dispose() {
KeyService.Unsubscribe(HandleClick);
FilterService.Unsubscribe(StateHasChanged);
TimingService.Unsubscribe(StateHasChanged);
EconomyService.Unsubscribe(StateHasChanged);
void IDisposable.Dispose()
{
keyService.Unsubscribe(HandleClick);
filterService.Unsubscribe(StateHasChanged);
timingService.Unsubscribe(StateHasChanged);
economyService.Unsubscribe(StateHasChanged);
}
protected void HandleTimingChanged() {
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
private void HandleTimingChanged()
{
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
}
protected void HandleClick() {
var hotkey = KeyService.GetHotkey();
private void HandleClick()
{
var hotkey = keyService.GetHotkey();
if (hotkey == "") {
if (hotkey == "")
{
return;
}
if (hotkey == "`") {
BuildOrderService.RemoveLast();
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
if (hotkey == "`")
{
buildOrderService.RemoveLast();
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
StateHasChanged();
return;
}
var hotkeyGroup = KeyService.GetHotkeyGroup();
var isHoldSpace = KeyService.IsHoldingSpace();
var faction = FilterService.GetFactionType();
var immortal = FilterService.GetImmortalType();
var hotkeyGroup = keyService.GetHotkeyGroup();
var isHoldSpace = keyService.IsHoldingSpace();
var faction = filterService.GetFactionType();
var immortal = filterService.GetImmortalType();
var entity = EntityModel.GetFrom(hotkey, hotkeyGroup, isHoldSpace, faction, immortal);
if (entity == null) {
if (entity == null)
{
return;
}
if (BuildOrderService.Add(entity, EconomyService)) {
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
if (buildOrderService.Add(entity, economyService))
{
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
}
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -10,16 +10,18 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
[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);
}
private void HandleKeyUp(KeyboardEventArgs e) {
private void HandleKeyUp(KeyboardEventArgs e)
{
KeyService.RemovePressedKey(e.Key);
}

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

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

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

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

54
IGP/Pages/ChangeLogPage.razor

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

31
IGP/Pages/Comparision/ComparisionPage.razor

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

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

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

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

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

2
IGP/Pages/ContactPage.razor

@ -11,7 +11,7 @@
How do I contact you for feature requests and bug reports?
</InfoQuestionComponent>
<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>
</InfoBodyComponent>
</PaperComponent>

90
IGP/Pages/Database/DatabasePage.razor

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

15
IGP/Pages/Database/DatabaseSinglePage.razor

@ -17,14 +17,15 @@
</PaperComponent>
<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>
@if(Text.Trim().ToLower().Equals("walter"))
@if (Text!.Trim().ToLower().Equals("walter"))
{
<PaperComponent>
<CodeComponent>Unhandled Exception: EXCEPTION_MEMORY_SIZE_VIOLATION
<CodeComponent>
Unhandled Exception: EXCEPTION_MEMORY_SIZE_VIOLATION
UNIT_WALTER too powerful to be displayed.
This SHOULD NEVER HAPPEN!
@ -55,16 +56,15 @@
</LayoutLargeContentComponent>
@code {
[Parameter]
public string? Text { get; set; }
private EntityModel? entity = null;
private EntityModel? entity;
protected override void OnInitialized()
{
entityDisplayService.Subscribe(StateHasChanged);
foreach (var e in DATA.Get().Values)
@ -77,7 +77,8 @@
}
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
entityDisplayService.Unsubscribe(StateHasChanged);
}

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

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

44
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"))
{
@foreach (var idAbility in Entity.IdAbilities()) {
@foreach (var idAbility in Entity.IdAbilities())
{
var spell = EntityModel.Get(idAbility.Id);
var info = spell.Info();
@ -15,25 +17,30 @@
<b>- Description:</b> @((MarkupString)info.Description)
</div>
@if (!info.Notes.Trim().Equals("")) {
@if (!info.Notes.Trim().Equals(""))
{
<div>
<b>- Notes:</b> @((MarkupString)info.Notes)
</div>
}
<div>
@if (production != null) {
if (production.Energy != 0) {
@if (production != null)
{
if (production.Energy != 0)
{
<div>
<b>- Energy: </b> @production.Energy
</div>
}
if (production.BuildTime != 0) {
if (production.BuildTime != 0)
{
<div>
<b>- BuildTime: </b> @production.BuildTime
</div>
}
if (production.Cooldown != 0) {
if (production.Cooldown != 0)
{
<div>
<b>- Cooldown: </b> @production.Cooldown
</div>
@ -42,13 +49,12 @@
</div>
</div>
}
}
else
{
<EntityDisplayComponent Title="Abilities">
@foreach (var idAbility in Entity.IdAbilities()) {
@foreach (var idAbility in Entity.IdAbilities())
{
var spell = EntityModel.Get(idAbility.Id);
var info = spell.Info();
@ -62,25 +68,30 @@
<b>Description:</b> @((MarkupString)info.Description)
</div>
@if (!info.Notes.Trim().Equals("")) {
@if (!info.Notes.Trim().Equals(""))
{
<div>
<b>Notes:</b> @((MarkupString)info.Notes)
</div>
}
<div>
@if (production != null) {
if (production.Energy != 0) {
@if (production != null)
{
if (production.Energy != 0)
{
<div>
<b> Energy: </b> @production.Energy
</div>
}
if (production.BuildTime != 0) {
if (production.BuildTime != 0)
{
<div>
<b> BuildTime: </b> @production.BuildTime
</div>
}
if (production.Cooldown != 0) {
if (production.Cooldown != 0)
{
<div>
<b> Cooldown: </b> @production.Cooldown
</div>
@ -91,14 +102,13 @@
}
</EntityDisplayComponent>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";

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

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

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

@ -1,13 +1,14 @@

@if (StyleType.Equals("Plain"))
@if (StyleType.Equals("Plain"))
{
@if (Entity!.Info().Description != "")
{
@if (Entity.Info().Description != "") {
<div>
<b>Description:</b> @((MarkupString)Entity.Info().Description)
</div>
}
@if (Entity.Info().Notes != "") {
@if (Entity.Info().Notes != "")
{
<div>
<b>Notes:</b> @((MarkupString)Entity.Info().Notes)
</div>
@ -16,19 +17,22 @@
<div class="infoDisplayContainer">
<div>
@if (Entity.Faction() != null) {
@if (Entity.Faction() != null)
{
<div>
<b>Faction:</b> @Entity.Faction().Faction
</div>
}
@if (Entity.Tier() != null) {
@if (Entity.Tier() != null)
{
<div>
<b>Tier:</b> @Entity.Tier().Tier
</div>
}
</div>
@if (Entity.Hotkey() != null) {
@if (Entity.Hotkey() != null)
{
<div>
<div>
<b>Hotkey Group:</b> @Entity.Hotkey().HotkeyGroup
@ -46,13 +50,15 @@
else
{
<EntityDisplayComponent Title="Info">
@if (Entity.Info().Description != "") {
@if (Entity!.Info().Description != "")
{
<div>
<b>Description:</b> @((MarkupString)Entity.Info().Description)
</div>
}
@if (Entity.Info().Notes != "") {
@if (Entity.Info().Notes != "")
{
<div>
<b>Notes:</b> @((MarkupString)Entity.Info().Notes)
</div>
@ -61,19 +67,22 @@ else
<div class="infoDisplayContainer">
<div>
@if (Entity.Faction() != null) {
@if (Entity.Faction() != null)
{
<div>
<b>Faction:</b> @Entity.Faction().Faction
</div>
}
@if (Entity.Tier() != null) {
@if (Entity.Tier() != null)
{
<div>
<b>Tier:</b> @Entity.Tier().Tier
</div>
}
</div>
@if (Entity.Hotkey() != null) {
@if (Entity.Hotkey() != null)
{
<div>
<div>
<b>Hotkey Group:</b> @Entity.Hotkey().HotkeyGroup
@ -109,7 +118,7 @@ else
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";

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

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

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

@ -1,7 +1,9 @@
@if (Entity.IdPassives().Count > 0) {
@if (Entity!.IdPassives().Count > 0)
{
@if (StyleType.Equals("Plain"))
{
@foreach (var idPassive in Entity.IdPassives()) {
@foreach (var idPassive in Entity.IdPassives())
{
var passive = EntityModel.Get(idPassive.Id);
var info = passive.Info();
@ -16,22 +18,25 @@
<b>- Description:</b> @((MarkupString)info.Description)
</div>
@if (!info.Notes.Trim().Equals("")) {
@if (!info.Notes.Trim().Equals(""))
{
<div>
<b>- Description:</b> @((MarkupString)info.Notes)
</div>
}
</div>
@if (production != null) {
@if (production != null)
{
<div>
@if (production.Pyre != 0) {
@if (production.Pyre != 0)
{
<div>
<b>- Pyre:</b> @production.Pyre
</div>
}
@if (production.Cooldown != 0) {
@if (production.Cooldown != 0)
{
<div>
<b>- Cooldown:</b> @production.Cooldown.ToString()s
</div>
@ -39,13 +44,12 @@
</div>
}
}
}
else
{
<EntityDisplayComponent Title="Passives">
@foreach (var idPassive in Entity.IdPassives()) {
@foreach (var idPassive in Entity.IdPassives())
{
var passive = EntityModel.Get(idPassive.Id);
var info = passive.Info();
@ -60,22 +64,25 @@
<b>Description:</b> @((MarkupString)info.Description)
</div>
@if (!info.Notes.Trim().Equals("")) {
@if (!info.Notes.Trim().Equals(""))
{
<div>
<b>Description:</b> @((MarkupString)info.Notes)
</div>
}
</div>
@if (production != null) {
@if (production != null)
{
<div>
@if (production.Pyre != 0) {
@if (production.Pyre != 0)
{
<div>
<b>Pyre:</b> @production.Pyre
</div>
}
@if (production.Cooldown != 0) {
@if (production.Cooldown != 0)
{
<div>
<b>Cooldown:</b> @production.Cooldown.ToString()s
</div>
@ -85,14 +92,13 @@
}
</EntityDisplayComponent>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]

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

@ -1,8 +1,9 @@
@if (Production != null || Supply != null || Requirements.Count > 0) {
@if (Production != null || Supply != null || Requirements.Count > 0)
{
@if (StyleType.Equals("Plain"))
{
@if (Requirements.Count() > 0) {
@if (Requirements.Count() > 0)
{
<div>
@foreach (var requirement in Requirements)
{
@ -20,52 +21,62 @@
@if (Production != null && (!Production.Alloy.Equals(0)
|| !Production.Ether.Equals(0)
|| !Production.BuildTime.Equals(0)
|| !Production.Cooldown.Equals(0))) {
|| !Production.Cooldown.Equals(0)))
{
<div>
@if (!Production.Alloy.Equals(0)) {
@if (!Production.Alloy.Equals(0))
{
<div>
<b>Alloy:</b> @Production.Alloy
</div>
}
@if (!Production.Ether.Equals(0)) {
@if (!Production.Ether.Equals(0))
{
<div>
<b>Ether:</b> @Production.Ether
</div>
}
@if (!Production.Pyre.Equals(0)) {
@if (!Production.Pyre.Equals(0))
{
<div>
<b>Pyre:</b> @Production.Pyre
</div>
}
@if (!Production.BuildTime.Equals(0)) {
@if (!Production.BuildTime.Equals(0))
{
<div>
<b>Build Time:</b> @Production.BuildTime.ToString()s
</div>
}
@if (!Production.Energy.Equals(0)) {
@if (!Production.Energy.Equals(0))
{
<div>
<b>Energy:</b> @Production.Energy
</div>
}
@if (!Production.Cooldown.Equals(0)) {
@if (!Production.Cooldown.Equals(0))
{
<div>
<b>Cooldown:</b> @Production.Cooldown.ToString()s
</div>
}
</div>
}
@if (Supply != null) {
@if (Supply != null)
{
<div>
@if (!Supply.Grants.Equals(0)) {
@if (!Supply.Grants.Equals(0))
{
<div>
<b>Grants:</b> @Supply.Grants
</div>
}
@if (!Supply.Takes.Equals(0)) {
@if (!Supply.Takes.Equals(0))
{
<div>
<b>Takes:</b> @Supply.Takes Supply
</div>
@ -76,12 +87,13 @@
else
{
<EntityDisplayComponent Title="Production">
<div class="ProductionContainer">
@if (Requirements.Count() > 0) {
@if (Requirements.Count() > 0)
{
<div>
@foreach (var requirement in Requirements) {
@foreach (var requirement in Requirements)
{
<div>
<span>
@ -95,52 +107,62 @@
@if (Production != null && (!Production.Alloy.Equals(0)
|| !Production.Ether.Equals(0)
|| !Production.BuildTime.Equals(0)
|| !Production.Cooldown.Equals(0))) {
|| !Production.Cooldown.Equals(0)))
{
<div>
@if (!Production.Alloy.Equals(0)) {
@if (!Production.Alloy.Equals(0))
{
<div>
<b>Alloy:</b> @Production.Alloy
</div>
}
@if (!Production.Ether.Equals(0)) {
@if (!Production.Ether.Equals(0))
{
<div>
<b>Ether:</b> @Production.Ether
</div>
}
@if (!Production.Pyre.Equals(0)) {
@if (!Production.Pyre.Equals(0))
{
<div>
<b>Pyre:</b> @Production.Pyre
</div>
}
@if (!Production.BuildTime.Equals(0)) {
@if (!Production.BuildTime.Equals(0))
{
<div>
<b>Build Time:</b> @Production.BuildTime.ToString()s
</div>
}
@if (!Production.Energy.Equals(0)) {
@if (!Production.Energy.Equals(0))
{
<div>
<b>Energy:</b> @Production.Energy
</div>
}
@if (!Production.Cooldown.Equals(0)) {
@if (!Production.Cooldown.Equals(0))
{
<div>
<b>Cooldown:</b> @Production.Cooldown.ToString()s
</div>
}
</div>
}
@if (Supply != null) {
@if (Supply != null)
{
<div>
@if (!Supply.Grants.Equals(0)) {
@if (!Supply.Grants.Equals(0))
{
<div>
<b>Grants:</b> @Supply.Grants
</div>
}
@if (!Supply.Takes.Equals(0)) {
@if (!Supply.Takes.Equals(0))
{
<div>
<b>Takes:</b> @Supply.Takes Supply
</div>
@ -164,7 +186,6 @@
}
}
</style>
}
}
@ -178,9 +199,9 @@
public string StyleType { get; set; } = "Detailed";
private EntityProductionModel Production => Entity.Production();
private List<EntityRequirementModel> Requirements => Entity.Requirements();
private EntitySupplyModel Supply => Entity.Supply();
private EntityProductionModel Production => Entity!.Production();
private List<EntityRequirementModel> Requirements => Entity!.Requirements();
private EntitySupplyModel Supply => Entity!.Supply();
protected override void OnParametersSet()

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

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

@ -1,36 +1,43 @@

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

13
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"))
{
@foreach (var upgradeId in Entity.IdUpgrades()) {
@foreach (var upgradeId in Entity.IdUpgrades())
{
var entity = EntityModel.Get(upgradeId.Id);
<div>
<div>
@ -12,13 +14,13 @@
</div>
</div>
}
}
else
{
<EntityDisplayComponent Title="Upgrades">
<div class="upgradesContainer">
@foreach (var upgradeId in Entity.IdUpgrades()) {
@foreach (var upgradeId in Entity.IdUpgrades())
{
var entity = EntityModel.Get(upgradeId.Id);
<div>
<div>
@ -47,14 +49,13 @@
}
</style>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]

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

@ -1,4 +1,5 @@
@if (Vanguard != null) {
@if (Vanguard != null)
{
var immortalId = Vanguard.ImmortalId;
var immortal = DATA.Get()[immortalId];
@ -9,7 +10,8 @@
<div>
<b>Immortal:</b> @immortal.Info().Name
</div>
@if (!Vanguard.ReplaceId.Equals("")) {
@if (!Vanguard.ReplaceId.Equals(""))
{
<div>
<b>Replaces:</b> @replaced.Info().Name
</div>
@ -22,7 +24,8 @@
<div>
<b>Immortal:</b> <EntityLabelComponent EntityId="@immortal.DataType"/>
</div>
@if (!Vanguard.ReplaceId.Equals("")) {
@if (!Vanguard.ReplaceId.Equals(""))
{
<div>
<b>Replaces:</b> <EntityLabelComponent EntityId="@Vanguard.ReplaceId"></EntityLabelComponent>
</div>
@ -33,8 +36,9 @@
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
private EntityVanguardAddedModel? Vanguard => Entity?.VanguardAdded();

13
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"))
{
@foreach (var data in Entity.IdVanguards()) {
@foreach (var data in Entity.IdVanguards())
{
var entity = EntityModel.Get(data.Id);
var requirements = entity.Requirements();
@ -30,7 +32,8 @@
else
{
<EntityDisplayComponent Title="Vanguards">
@foreach (var data in Entity.IdVanguards()) {
@foreach (var data in Entity.IdVanguards())
{
var entity = EntityModel.Get(data.Id);
var requirements = entity.Requirements();
@ -52,15 +55,13 @@
</div>
}
</EntityDisplayComponent>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]

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

@ -1,8 +1,8 @@
@if (Entity.Weapons().Count > 0)
@if (Entity!.Weapons().Count > 0)
{
@if (StyleType.Equals("Plain"))
{
int index = 0;
var index = 0;
foreach (var data in Entity.Weapons())
{
@ -104,7 +104,6 @@
}
else
{
<EntityDisplayComponent Title="Weapons">
<div class="weaponsContainer">
@foreach (var data in Entity.Weapons())
@ -222,14 +221,13 @@
margin-bottom: 6px;
}
</style>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]

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

@ -2,23 +2,27 @@
<div class="desktopFiltersContainer">
<div class="filtersContainer">
<div class="filterContainer">
@foreach (var choice in EntityFilterService.GetFactionChoices()) {
@foreach (var choice in EntityFilterService.GetFactionChoices())
{
var styleClass = "";
if (choice.Equals(EntityFilterService.GetFactionType())) {
if (choice.Equals(EntityFilterService.GetFactionType()))
{
styleClass = "selected";
}
<button @onclick="@(e => OnChangeFaction(choice))" class="choiceButton @styleClass">@choice</button>
}
</div>
@if (EntityFilterService.GetFactionType() != "Any" && EntityFilterService.GetFactionType() != "None") {
@if (EntityFilterService.GetFactionType() != "Any" && EntityFilterService.GetFactionType() != "None")
{
<div class="filterContainer">
@foreach (var choice in EntityFilterService.GetImmortalChoices())
{
var name = DATA.Get()[choice].Info().Name;
var styleClass = "";
if (choice.Equals(EntityFilterService.GetImmortalType())) {
if (choice.Equals(EntityFilterService.GetImmortalType()))
{
styleClass = "selected";
}
<button class="choiceButton @styleClass" @onclick="@(e => OnChangeImmortal(choice))">@name</button>
@ -27,16 +31,18 @@
}
</div>
<div class="filterContainer">
@foreach (var choice in EntityFilterService.GetEntityChoices()) {
@foreach (var choice in EntityFilterService.GetEntityChoices())
{
var styleClass = "";
if (choice.Equals(EntityFilterService.GetEntityType())) {
if (choice.Equals(EntityFilterService.GetEntityType()))
{
styleClass = "selected";
}
<button class="choiceButton @styleClass" @onclick="@(e => OnChangeEntity(choice))">@choice.Replace("_", " ")</button>
}
</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>
@ -199,40 +205,49 @@
@code {
[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);
StateHasChanged();
}
void OnChangeImmortal(string clickedImmortal) {
void OnChangeImmortal(string clickedImmortal)
{
EntityFilterService.SelectImmortalType(clickedImmortal);
}
void OnChangeEntity(string clickedEntity) {
void OnChangeEntity(string clickedEntity)
{
EntityFilterService.SelectEntityType(clickedEntity);
}
void OnFactionChanged(ChangeEventArgs e) {
EntityFilterService.SelectFactionType(e.Value.ToString());
void OnFactionChanged(ChangeEventArgs e)
{
EntityFilterService.SelectFactionType(e.Value!.ToString()!);
}
void OnImmortalChanged(ChangeEventArgs e) {
EntityFilterService.SelectImmortalType(e.Value.ToString());
void OnImmortalChanged(ChangeEventArgs e)
{
EntityFilterService.SelectImmortalType(e.Value!.ToString()!);
}
void OnEntityChanged(ChangeEventArgs e) {
EntityFilterService.SelectEntityType(e.Value.ToString());
void OnEntityChanged(ChangeEventArgs e)
{
EntityFilterService.SelectEntityType(e.Value!.ToString()!);
}
void OnSearchTextChanged(ChangeEventArgs e) {
EntityFilterService.EnterSearchText(e.Value.ToString());
void OnSearchTextChanged(ChangeEventArgs e)
{
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);
}
}

98
IGP/Pages/Documentation/DocumentationPage.razor

@ -1,68 +1,39 @@
@layout PageLayout
@inject IDocumentationService DocumentationService
@using Markdig
@implements IDisposable
@inject IDocumentationService documentationService
@page "/docs/{text?}"
@implements IDisposable
@page "/docs/{href1}/{href2?}/{href3?}/{href4?}/{href5?}"
@if (!DocumentationService.IsLoaded())
@if (!documentationService.IsLoaded())
{
<LoadingComponent></LoadingComponent>
<LoadingComponent/>
}
else
{
<LayoutMediumContentComponent>
<WebsiteTitleComponent>Documentation</WebsiteTitleComponent>
<div class="section">
<div for="docSection">Section: </div>
<div style="flex: 1"></div>
<select @oninput="OnSectionChanged" style="background-color: #36393F; width: 250px; margin-right: 16px;" name="docSection">
<option value="All">All</option>
</select>
</div>
<div class="docsContainer">
@foreach (var doc in DocumentationService.DocumentationModels) {
if (selectedSection != "All" && doc.Section != selectedSection) {
<LayoutWithSidebarComponent>
<Sidebar>
<DocumentNavComponent
Connections="documentationService.DocConnectionModels"
Documents="documentationService.DocContentModels"/>
</Sidebar>
<Content>
<PaperComponent>
@foreach (var doc in documentationService.DocContentModels)
{
if (!doc.Href.Equals(Href))
{
continue;
}
<PaperComponent>
<div style="display: flex; flex-direction: row;">
<span style="font-weight: bold; font-style:italic;">@doc.Section</span>
<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>
<DocumentComponent DocContentModel="doc"/>
}
</PaperComponent>
</Content>
</LayoutWithSidebarComponent>
}
</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);
}
.docsContainer {
display: flex;
flex-direction: column;
gap: 16px;
}
pre code {
@ -121,25 +92,32 @@ else
@code {
[Parameter]
public string? Text { get; set; }
public string? Href1 { get; set; }
[Parameter]
public string? Href2 { get; set; }
[Parameter]
public string? Href3 { get; set; }
string selectedSection = "All";
[Parameter]
public string? Href4 { get; set; }
[Parameter]
public string? Href5 { get; set; }
private string Href => Href5 ?? Href4 ?? Href3 ?? Href2 ?? Href1 ?? "";
protected override void OnInitialized()
{
DocumentationService.Subscribe(StateHasChanged);
documentationService.Subscribe(StateHasChanged);
DocumentationService.Load();
documentationService.Load();
}
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>
<FormNumberComponent Min="0"
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>
</FormNumberComponent>
<FormNumberComponent Min="0"
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>
</FormNumberComponent>
<FormNumberComponent Min="0"
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>
</FormNumberComponent>
@ -230,42 +230,51 @@
float NumberOfWorkersLostToHarass = 1;
float NumberOfTownHallsExisting = 1;
float SimultaneousProductionFloor() {
if (NumberOfTownHallsExisting <= 0 || NumberOfWorkersLostToHarass <= 0) {
float SimultaneousProductionFloor()
{
if (NumberOfTownHallsExisting <= 0 || NumberOfWorkersLostToHarass <= 0)
{
return 0;
}
return (float)Math.Floor(NumberOfWorkersLostToHarass / Math.Min(NumberOfTownHallsExisting, NumberOfWorkersLostToHarass));
}
float LeftOverWorkersToProduceCount() {
float LeftOverWorkersToProduceCount()
{
return NumberOfWorkersLostToHarass % Math.Min(NumberOfTownHallsExisting, NumberOfWorkersLostToHarass);
}
float WorkerReplacementCost() {
float WorkerReplacementCost()
{
return CostOfWorker * NumberOfWorkersLostToHarass;
}
float DelayedMiningCost() {
float DelayedMiningCost()
{
return TotalAlloyHarassment - WorkerReplacementCost();
}
void Calculate() {
void Calculate()
{
TotalAlloyHarassment = WorkerReplacementCost();
for (var workerProductionIndex = 0; workerProductionIndex < SimultaneousProductionFloor(); workerProductionIndex++) {
for (var workerProductionIndex = 0; workerProductionIndex < SimultaneousProductionFloor(); workerProductionIndex++)
{
TotalAlloyHarassment += AlloyMinedPerSecondByWorker * (TimeToProduceWorker + TravelTime) * (workerProductionIndex + 1);
}
TotalAlloyHarassment += LeftOverWorkersToProduceCount() * (TimeToProduceWorker + TravelTime) * AlloyMinedPerSecondByWorker;
}
protected override void OnInitialized() {
protected override void OnInitialized()
{
Calculate();
}
void ValueChanged(float test) {
void ValueChanged(float test)
{
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>

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

@ -20,56 +20,56 @@
<div class="color accent">
<div>Accent</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 class="color primary">
<div>Primary</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>
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>
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>
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 class="color secondary">
<div>Secondary</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>
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>
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 class="color paper">
<div>Paper</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>
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 class="color background">
<div>Background</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 class="color info">
<div>Info</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>

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

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

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

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

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

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

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

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

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

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

114
IGP/Pages/Notes/NotesPage.razor

@ -1,109 +1,71 @@
@layout PageLayout
@inject INoteService NoteService
@inject INoteService noteService
@implements IDisposable
@page "/notes"
@page "/notes/{href1}/{href2?}/{href3?}/{href4?}/{href5?}"
@if (!NoteService.IsLoaded())
@if (!noteService.IsLoaded())
{
<LoadingComponent></LoadingComponent>
<LoadingComponent/>
}
else
{
<LayoutMediumContentComponent>
<WebsiteTitleComponent>Notes</WebsiteTitleComponent>
<div class="section">
<div for="noteSection">Section: </div>
<div style="flex: 1"></div>
<select @oninput="OnSectionChanged" style="background-color: #36393F; width: 250px; margin-right: 16px;" name="noteSection">
<option value="All">All</option>
</select>
</div>
<div class="notesContainer">
@foreach (var note in NoteService.NoteModels) {
if (note.IsHidden) {
continue;
}
if (selectedSection != "All" && note.Section != selectedSection) {
<LayoutWithSidebarComponent>
<Sidebar>
<NoteNavComponent
Connections="noteService.NoteConnectionModels"
Notes="noteService.NoteContentModels"/>
</Sidebar>
<Content>
<PaperComponent>
@foreach (var note in noteService.NoteContentModels)
{
if (!note.Href.Equals(Href))
{
continue;
}
@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>
<NoteComponent NoteContentModel="note"/>
}
<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>
</Content>
</LayoutWithSidebarComponent>
}
</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 {
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>
@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()
{
NoteService.Subscribe(StateHasChanged);
noteService.Subscribe(StateHasChanged);
NoteService.Load();
noteService.Load();
}
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>
<b>Priority:</b> @RoadMap.Priority.Replace("_", " ")
@ -53,6 +53,7 @@
</style>
@code {
[Parameter]
public ImmortalRoadMapModel? RoadMap { get; set; }

3
IGP/Pages/RoadMap/RoadMapPage.razor

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

5
IGP/Portals/EntityDialogPortal.razor

@ -9,12 +9,14 @@
@code {
protected override void OnInitialized()
{
entityDialogService.Subscribe(OnUpdate);
}
public void Dispose() {
public void Dispose()
{
entityDialogService.Unsubscribe(OnUpdate);
}
@ -24,4 +26,3 @@
}
}

15
IGP/Program.cs

@ -1,20 +1,16 @@
using IGP;
using Microsoft.AspNetCore.Components.Web;
using Services;
using Services.Development;
using Services.Immortal;
using Services.Website;
#if NO_SQL
#else
using Contexts;
using Microsoft.EntityFrameworkCore;
#endif
using Services;
using Services.Immortal;
using Services.Website;
using Services.Development;
using IEntityDisplayService = Services.IEntityDisplayService;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Logging.SetMinimumLevel(LogLevel.Warning);
@ -37,7 +33,8 @@ builder.Services.AddSingleton<IEntityFilterService, EntityFilterService>();
builder.Services.AddSingleton<IEntityDisplayService, EntityDisplayService>();
builder.Services.AddSingleton(new HttpClient {
builder.Services.AddSingleton(new HttpClient
{
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.Form
@using Components.Info
@ -9,17 +7,26 @@
@using Components.Navigation
@using Components.Shared
@using Components.Utils
@using IGP.Portals
@using IGP.Pages
@using IGP.Dialog
@using IGP.Pages
@using IGP.Pages.Agile.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.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.MemoryTester.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.Routing
@using Microsoft.AspNetCore.Components.Web
@ -27,21 +34,20 @@
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.EntityFrameworkCore
@using Microsoft.JSInterop
@using Model.Immortal.Chart
@using Model.Immortal.Economy
@using Model.Immortal.Entity
@using Model.Immortal.Entity.Data
@using Model.Immortal.Entity.Parts
@using Model.Immortal.Hotkeys
@using Model.Immortal.MemoryTester
@using Model.Immortal.MemoryTester
@using Model.Immortal.Notes
@using Model.Immortal.RoadMap
@using Model.Immortal.RoadMap
@using Model.Immortal.RoadMap.Enums
@using Model.Immortal.Types
@using Model.Chart
@using Model.Development.Git
@using Model.Doc
@using Model.Economy
@using Model.Entity
@using Model.Entity.Data
@using Model.Entity.Parts
@using Model.Hotkeys
@using Model.MemoryTester
@using Model.Notes
@using Model.RoadMap
@using Model.RoadMap.Enums
@using Model.Types
@using Model.Website
@using Model.Work.Git
@using Model.Work.Tasks
@using Model.Work.Tasks.Enums
@using Services

4
IGP/wwwroot/css/app.css

@ -15,6 +15,10 @@
--secondary-border-hover: #a168ff;
--paper: #252526;
--paper-border: #151516;
--paper-hover: #52366f;
--paper-border-hover: #653497;
--info: #451376;
--info-border: #210b36;

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":[]}]

1
IGP/wwwroot/generated/AgileTaskModels.json

File diff suppressed because one or more lines are too long

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

Loading…
Cancel
Save