Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e3284ca91e | |||
| 39e3dd6528 | |||
| e9d60e3983 | |||
| 7310e4ed71 | |||
| 0feac0f0a0 | |||
| 46150d3a69 |
@@ -25,7 +25,7 @@ jobs:
|
||||
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_CALM_MUD_04916B210 }}
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
action: "upload"
|
||||
app_location: "IGP"
|
||||
app_location: "Web"
|
||||
api_location: ""
|
||||
output_location: "./wwwroot"
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_NICE_COAST_0F8B08010 }}
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
action: "upload"
|
||||
app_location: "IGP"
|
||||
app_location: "Web"
|
||||
api_location: ""
|
||||
output_location: "./wwwroot"
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
3.0
|
||||
@@ -7,7 +7,7 @@
|
||||
"type": "process",
|
||||
"args": [
|
||||
"build",
|
||||
"${workspaceFolder}/IGP/IGP.csproj",
|
||||
"${workspaceFolder}/Web/Web.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
@@ -19,7 +19,7 @@
|
||||
"type": "process",
|
||||
"args": [
|
||||
"publish",
|
||||
"${workspaceFolder}/IGP/IGP.csproj",
|
||||
"${workspaceFolder}/Web/Web.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
@@ -33,7 +33,7 @@
|
||||
"watch",
|
||||
"run",
|
||||
"--project",
|
||||
"${workspaceFolder}/IGP/IGP.csproj"
|
||||
"${workspaceFolder}/Web/Web.csproj"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<RootNamespace>API</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="HotChocolate.AspNetCore" Version="16.1.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Model\Model.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,254 @@
|
||||
using Model.Entity;
|
||||
using Model.Entity.Parts;
|
||||
|
||||
namespace API.GraphQL.Types;
|
||||
|
||||
public class EntityGraphType : ObjectType<EntityModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityModel> descriptor)
|
||||
{
|
||||
descriptor.Name("Entity");
|
||||
|
||||
descriptor.Field(e => e.DataType).Name("id");
|
||||
descriptor.Field(e => e.EntityType).Name("type");
|
||||
descriptor.Field(e => e.IsSpeculative);
|
||||
descriptor.Field(e => e.Descriptive).Name("descriptiveType");
|
||||
|
||||
descriptor.Ignore(e => e.EntityParts);
|
||||
|
||||
descriptor.Field("name")
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().GetName());
|
||||
|
||||
descriptor.Field("factionName")
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().GetFaction());
|
||||
|
||||
descriptor.Field("info")
|
||||
.Type<EntityInfoGraphType>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Info());
|
||||
|
||||
descriptor.Field("production")
|
||||
.Type<EntityProductionGraphType>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Production());
|
||||
|
||||
descriptor.Field("supply")
|
||||
.Type<EntitySupplyGraphType>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Supply());
|
||||
|
||||
descriptor.Field("tier")
|
||||
.Type<EntityTierGraphType>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Tier());
|
||||
|
||||
descriptor.Field("movement")
|
||||
.Type<EntityMovementGraphType>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Movement());
|
||||
|
||||
descriptor.Field("vitality")
|
||||
.Type<EntityVitalityGraphType>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Vitality());
|
||||
|
||||
descriptor.Field("requirements")
|
||||
.Type<ListType<EntityRequirementGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Requirements());
|
||||
|
||||
descriptor.Field("weapons")
|
||||
.Type<ListType<EntityWeaponGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Weapons());
|
||||
|
||||
descriptor.Field("hotkey")
|
||||
.Type<EntityHotkeyGraphType>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Hotkey());
|
||||
|
||||
descriptor.Field("faction")
|
||||
.Type<EntityFactionGraphType>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Faction());
|
||||
|
||||
descriptor.Field("harvest")
|
||||
.Type<EntityHarvestGraphType>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Harvest());
|
||||
|
||||
descriptor.Field("idAbilities")
|
||||
.Type<ListType<EntityIdReferenceGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().IdAbilities());
|
||||
|
||||
descriptor.Field("idArmies")
|
||||
.Type<ListType<EntityIdReferenceGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().IdArmies());
|
||||
|
||||
descriptor.Field("idPassives")
|
||||
.Type<ListType<EntityIdReferenceGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().IdPassives());
|
||||
|
||||
descriptor.Field("idUpgrades")
|
||||
.Type<ListType<EntityIdReferenceGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().IdUpgrades());
|
||||
|
||||
descriptor.Field("idVanguards")
|
||||
.Type<ListType<EntityIdReferenceGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().IdVanguards());
|
||||
|
||||
descriptor.Field("idPyreSpells")
|
||||
.Type<ListType<EntityIdReferenceGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().IdPyreSpells());
|
||||
|
||||
descriptor.Field("mechanics")
|
||||
.Type<ListType<EntityMechanicGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Mechanics());
|
||||
|
||||
descriptor.Field("passives")
|
||||
.Type<ListType<EntityNamedDescGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Passives());
|
||||
|
||||
descriptor.Field("strategies")
|
||||
.Type<ListType<EntityStrategyGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Strategies());
|
||||
|
||||
descriptor.Field("replaceds")
|
||||
.Type<ListType<EntityVanguardReplacedGraphType>>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().Replaceds());
|
||||
|
||||
descriptor.Field("vanguardAdded")
|
||||
.Type<EntityVanguardAddedGraphType>()
|
||||
.Resolve(ctx => ctx.Parent<EntityModel>().VanguardAdded());
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityInfoGraphType : ObjectType<EntityInfoModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityInfoModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
descriptor.Field(e => e.Name);
|
||||
descriptor.Field(e => e.Descriptive).Name("descriptiveType");
|
||||
descriptor.Field(e => e.Description);
|
||||
descriptor.Field(e => e.Notes);
|
||||
descriptor.Field(e => e.FlavorText);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityProductionGraphType : ObjectType<EntityProductionModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityProductionModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntitySupplyGraphType : ObjectType<EntitySupplyModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntitySupplyModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityTierGraphType : ObjectType<EntityTierModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityTierModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityMovementGraphType : ObjectType<EntityMovementModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityMovementModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityVitalityGraphType : ObjectType<EntityVitalityModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityVitalityModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityRequirementGraphType : ObjectType<EntityRequirementModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityRequirementModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityWeaponGraphType : ObjectType<EntityWeaponModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityWeaponModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityHotkeyGraphType : ObjectType<EntityHotkeyModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityHotkeyModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityFactionGraphType : ObjectType<EntityFactionModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityFactionModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityHarvestGraphType : ObjectType<EntityHarvestModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityHarvestModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityIdReferenceGraphType : ObjectType<EntityIdAbilityModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityIdAbilityModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityMechanicGraphType : ObjectType<EntityMechanicModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityMechanicModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityNamedDescGraphType : ObjectType<EntityPassiveModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityPassiveModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityStrategyGraphType : ObjectType<EntityStrategyModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityStrategyModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityVanguardReplacedGraphType : ObjectType<EntityVanguardReplacedModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityVanguardReplacedModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
|
||||
public class EntityVanguardAddedGraphType : ObjectType<EntityVanguardAddedModel>
|
||||
{
|
||||
protected override void Configure(IObjectTypeDescriptor<EntityVanguardAddedModel> descriptor)
|
||||
{
|
||||
descriptor.Ignore(e => e.Parent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using API.GraphQL.Types;
|
||||
using Model.Entity.Data;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.Services
|
||||
.AddGraphQLServer()
|
||||
.AddQueryType(d =>
|
||||
{
|
||||
d.Name("Query");
|
||||
|
||||
d.Field("entities")
|
||||
.Type<NonNullType<ListType<NonNullType<EntityGraphType>>>>()
|
||||
.Resolve(ctx => EntityData.Get().Values.ToList());
|
||||
|
||||
d.Field("entity")
|
||||
.Type<EntityGraphType>()
|
||||
.Argument("id", a => a.Type<NonNullType<StringType>>())
|
||||
.Resolve(ctx =>
|
||||
{
|
||||
var id = ctx.ArgumentValue<string>("id");
|
||||
EntityData.Get().TryGetValue(id, out var entity);
|
||||
return entity;
|
||||
});
|
||||
})
|
||||
.AddType<EntityGraphType>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.MapGraphQL();
|
||||
|
||||
app.Run();
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"profiles": {
|
||||
"API": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:63192;http://localhost:63193"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>IGP.Calculator.Cli</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Services\Services.csproj"/>
|
||||
<ProjectReference Include="..\Model\Model.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,9 +1,8 @@
|
||||
using IGP.Calculator.Cli.Services;
|
||||
using Model.Entity;
|
||||
using Model.Entity.Data;
|
||||
using Services;
|
||||
using Services.Immortal;
|
||||
using Services.Website;
|
||||
using IGP.Calculator.Cli.Services;
|
||||
|
||||
var faction = DataType.FACTION_QRath;
|
||||
var immortal = DataType.IMMORTAL_Orzum;
|
||||
@@ -11,7 +10,6 @@ var attackTime = 1500;
|
||||
var entityNames = new List<string>();
|
||||
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
{
|
||||
switch (args[i].ToLower())
|
||||
{
|
||||
case "--faction" when i + 1 < args.Length:
|
||||
@@ -48,7 +46,6 @@ for (var i = 0; i < args.Length; i++)
|
||||
entityNames.Add(args[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var toastService = new ToastService();
|
||||
var storageService = new NullStorageService();
|
||||
@@ -124,12 +121,12 @@ var finalEconomy = economyService.GetEconomy(timingService.GetAttackTime());
|
||||
var lastEconomy = economyService.GetEconomy(lastInterval);
|
||||
|
||||
Console.WriteLine($"Army Attacking At: {timingService.GetAttackTime()}s");
|
||||
Console.WriteLine($"");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine($"At attack time ({timingService.GetAttackTime()}s):");
|
||||
Console.WriteLine($" Alloy: {finalEconomy.Alloy,10:F1}");
|
||||
Console.WriteLine($" Ether: {finalEconomy.Ether,10:F1}");
|
||||
Console.WriteLine($" Pyre: {finalEconomy.Pyre,10:F1}");
|
||||
Console.WriteLine($"");
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine($"At last build action ({lastInterval}s):");
|
||||
Console.WriteLine($" Alloy: {lastEconomy.Alloy,10:F1}");
|
||||
Console.WriteLine($" Ether: {lastEconomy.Ether,10:F1}");
|
||||
@@ -6,8 +6,13 @@ public class NullStorageService : IStorageService
|
||||
{
|
||||
private readonly Dictionary<string, object?> _store = new();
|
||||
|
||||
public void Subscribe(Action action) { }
|
||||
public void Unsubscribe(Action action) { }
|
||||
public void Subscribe(Action action)
|
||||
{
|
||||
}
|
||||
|
||||
public void Unsubscribe(Action action)
|
||||
{
|
||||
}
|
||||
|
||||
public T GetValue<T>(string forKey)
|
||||
{
|
||||
@@ -21,5 +26,8 @@ public class NullStorageService : IStorageService
|
||||
_store[key] = value;
|
||||
}
|
||||
|
||||
public Task Load() => Task.CompletedTask;
|
||||
public Task Load()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>Components</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
@inject IGlossaryService glossaryService
|
||||
|
||||
@if (TermId != null)
|
||||
{
|
||||
var term = glossaryService.GetTerm(TermId);
|
||||
if (term != null)
|
||||
{
|
||||
<div class="glossaryTooltipWrapper">
|
||||
<div class="glossaryTooltipContent">
|
||||
<div class="glossaryTooltipHeader">
|
||||
<span class="glossaryTooltipTerm">@term.Term</span>
|
||||
<span class="glossaryTooltipCategory">@term.Category</span>
|
||||
</div>
|
||||
<div class="glossaryTooltipBody">
|
||||
@term.ShortDefinition
|
||||
</div>
|
||||
</div>
|
||||
@ChildContent
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
<style>
|
||||
.glossaryTooltipWrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.glossaryTooltipContent {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
width: 400px;
|
||||
max-width: 93vw;
|
||||
bottom: 100%;
|
||||
margin-bottom: 8px;
|
||||
padding: 12px;
|
||||
z-index: 2147483647;
|
||||
background-color: var(--info-secondary);
|
||||
border: 1px solid var(--info-secondary-border);
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.5);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.glossaryTooltipWrapper:hover .glossaryTooltipContent {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.glossaryTooltipHeader {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.glossaryTooltipTerm {
|
||||
font-weight: 800;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.glossaryTooltipCategory {
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.glossaryTooltipBody {
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
@@media only screen and (max-width: 1025px) {
|
||||
.glossaryTooltipContent {
|
||||
margin: auto;
|
||||
margin-bottom: 20px;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
|
||||
|
||||
[Parameter] public string TermId { get; set; } = default!;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
@using Model.MemoryTester
|
||||
@using Services.Immortal
|
||||
@implements IDisposable
|
||||
|
||||
@inject IMemoryTesterService MemoryTesterService
|
||||
@@ -13,7 +12,7 @@
|
||||
}
|
||||
<div>
|
||||
<input readonly="@MemoryQuestion.IsRevealed"
|
||||
class="formTextInput @(MemoryQuestion.IsRevealed ? "revealed" : IsSubmitted == false ? "guess" : int.Parse(guess ?? string.Empty) == MemoryQuestion.Answer ? "correct" : "wrong")"
|
||||
class="formTextInput @(MemoryQuestion.IsRevealed ? "revealed" : !IsSubmitted ? "guess" : int.Parse(guess ?? string.Empty) == MemoryQuestion.Answer ? "correct" : "wrong")"
|
||||
placeholder="guess..."
|
||||
type="number"
|
||||
value="@guess"
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
@implements IDisposable
|
||||
|
||||
<div class="cooldown-wrap" style="--cooldown-size: @(Size)px">
|
||||
<button class="cooldown-btn"
|
||||
disabled="@_isCooldown"
|
||||
@onclick="HandleClick"
|
||||
@onclick:preventDefault="_isCooldown">
|
||||
<span class="cooldown-btn-text">@ChildContent</span>
|
||||
</button>
|
||||
@if (_isCooldown)
|
||||
{
|
||||
<div class="cooldown-overlay" style="--angle: @(_elapsedAngle)deg">
|
||||
<span class="cooldown-label">@_remainingSeconds</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.cooldown-wrap {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
width: var(--cooldown-size, 120px);
|
||||
height: var(--cooldown-size, 120px);
|
||||
}
|
||||
.cooldown-btn {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 2px solid var(--primary);
|
||||
border-radius: 12px;
|
||||
background: var(--paper);
|
||||
color: var(--text-primary, #eee);
|
||||
font-weight: 700;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: background 0.15s, border-color 0.15s;
|
||||
line-height: 1.3;
|
||||
font-family: inherit;
|
||||
}
|
||||
.cooldown-btn:hover:not(:disabled) {
|
||||
background: var(--paper-hover);
|
||||
border-color: var(--primary-hover);
|
||||
}
|
||||
.cooldown-btn:active:not(:disabled) {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
.cooldown-btn:disabled {
|
||||
cursor: default;
|
||||
}
|
||||
.cooldown-btn-text {
|
||||
pointer-events: none;
|
||||
}
|
||||
.cooldown-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
.cooldown-overlay::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: inherit;
|
||||
background: rgba(22, 22, 24, 0.45);
|
||||
mask-image: conic-gradient(transparent 0deg, transparent var(--angle), #000 var(--angle), #000 360deg);
|
||||
-webkit-mask-image: conic-gradient(transparent 0deg, transparent var(--angle), #000 var(--angle), #000 360deg);
|
||||
}
|
||||
.cooldown-label {
|
||||
font-size: 1.6rem;
|
||||
font-weight: 900;
|
||||
color: #999;
|
||||
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
|
||||
pointer-events: none;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@code {
|
||||
[Parameter] public RenderFragment? ChildContent { get; set; }
|
||||
[Parameter] public EventCallback OnClick { get; set; }
|
||||
[Parameter] public int CooldownSeconds { get; set; } = 12;
|
||||
[Parameter] public int Size { get; set; } = 120;
|
||||
|
||||
private bool _isCooldown;
|
||||
private int _elapsedAngle;
|
||||
private int _remainingSeconds;
|
||||
private DateTime _startTime;
|
||||
private System.Timers.Timer? _timer;
|
||||
|
||||
private async Task HandleClick()
|
||||
{
|
||||
if (_isCooldown) return;
|
||||
await OnClick.InvokeAsync(null);
|
||||
StartCooldown();
|
||||
}
|
||||
|
||||
private void StartCooldown()
|
||||
{
|
||||
_isCooldown = true;
|
||||
_startTime = DateTime.UtcNow;
|
||||
_elapsedAngle = 0;
|
||||
_remainingSeconds = CooldownSeconds;
|
||||
|
||||
_timer = new System.Timers.Timer(33);
|
||||
_timer.Elapsed += OnTick;
|
||||
_timer.AutoReset = true;
|
||||
_timer.Enabled = true;
|
||||
}
|
||||
|
||||
private void OnTick(object? sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
var elapsed = (DateTime.UtcNow - _startTime).TotalSeconds;
|
||||
if (elapsed >= CooldownSeconds)
|
||||
{
|
||||
_isCooldown = false;
|
||||
_timer?.Stop();
|
||||
_timer?.Dispose();
|
||||
_timer = null;
|
||||
InvokeAsync(StateHasChanged);
|
||||
return;
|
||||
}
|
||||
|
||||
_elapsedAngle = (int)(elapsed / CooldownSeconds * 360);
|
||||
_remainingSeconds = CooldownSeconds - (int)elapsed;
|
||||
InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_timer != null)
|
||||
{
|
||||
_timer.Stop();
|
||||
_timer.Dispose();
|
||||
_timer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
@inject IGlossaryService glossaryService
|
||||
@inject IGlossaryDialogService glossaryDialogService
|
||||
|
||||
@if (TermId == null)
|
||||
{
|
||||
<span>Missing term</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
var term = glossaryService.GetTerm(TermId);
|
||||
if (term != null)
|
||||
{
|
||||
<button class="glossaryLabel @term.Category.ToLowerInvariant()" @onclick="TermLabelClicked"
|
||||
title="@term.ShortDefinition">
|
||||
@term.Term
|
||||
</button>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter] public string TermId { get; set; } = default!;
|
||||
|
||||
void TermLabelClicked()
|
||||
{
|
||||
glossaryDialogService.AddDialog(TermId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
.glossaryLabel {
|
||||
font-weight: bolder;
|
||||
box-shadow: 1px 1px 0 0 rgba(0, 0, 0, 0.2);
|
||||
padding-right: 4px;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
text-decoration: underline;
|
||||
text-decoration-style: dotted;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
|
||||
.glossaryLabel:hover {
|
||||
background-color: var(--primary-hover);
|
||||
}
|
||||
|
||||
.resource {
|
||||
color: gold;
|
||||
}
|
||||
|
||||
.mechanic {
|
||||
color: #8fc5ff;
|
||||
}
|
||||
|
||||
.faction {
|
||||
color: #da4e4e;
|
||||
}
|
||||
|
||||
.role {
|
||||
color: #87aa87;
|
||||
}
|
||||
@@ -7,15 +7,7 @@
|
||||
<i class="fa-solid fa-magnifying-glass" style="margin-left: 3px; margin-right: 6px;"></i> Search...
|
||||
</div>
|
||||
<div class="searchHotkey">
|
||||
@if (IsMac)
|
||||
{
|
||||
<span><i class="fa-solid fa-command"></i>K</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>CTRL + K</span>
|
||||
}
|
||||
|
||||
<span>/</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -51,8 +43,6 @@
|
||||
|
||||
private string _userAgent = "";
|
||||
|
||||
bool IsMac => _userAgent.Contains("Mac OS");
|
||||
|
||||
private void ButtonClicked(EventArgs eventArgs)
|
||||
{
|
||||
SearchService.Show();
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
@inject IEntityDialogService entityDialogService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<div class="techTreeContainer" @ref="containerRef">
|
||||
<svg class="techTreeSvg" width="@svgWidth" height="@svgHeight">
|
||||
<!-- Edges -->
|
||||
@foreach (var edge in Graph.Edges)
|
||||
{
|
||||
var source = Graph.Nodes.FirstOrDefault(n => n.Id == edge.SourceId);
|
||||
var target = Graph.Nodes.FirstOrDefault(n => n.Id == edge.TargetId);
|
||||
if (source != null && target != null)
|
||||
{
|
||||
var color = EdgeColor(edge.EdgeType);
|
||||
var strokeWidth = edge.EdgeType == TechTreeEdgeType.Produces ? "2.5" : "1.5";
|
||||
var strokeDash = edge.EdgeType == TechTreeEdgeType.RequiresProduction || edge.EdgeType == TechTreeEdgeType.RequiresResearch ? "6,3" : "";
|
||||
strokeDash = edge.EdgeType == TechTreeEdgeType.Morph ? "2,2" : strokeDash;
|
||||
|
||||
<line x1="@(source.X + nodeWidth / 2)" y1="@(source.Y + nodeHeight / 2)"
|
||||
x2="@(target.X + nodeWidth / 2)" y2="@(target.Y + nodeHeight / 2)"
|
||||
stroke="@color" stroke-width="@strokeWidth"
|
||||
stroke-dasharray="@strokeDash"
|
||||
marker-end="url(#arrowhead-@(edge.EdgeType))"/>
|
||||
}
|
||||
}
|
||||
|
||||
<!-- Arrowhead markers -->
|
||||
<defs>
|
||||
@foreach (var edgeType in Graph.Edges.Select(e => e.EdgeType).Distinct())
|
||||
{
|
||||
<marker id="arrowhead-@edgeType" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
|
||||
<polygon points="0 0, 10 3.5, 0 7" fill="@EdgeColor(edgeType)"/>
|
||||
</marker>
|
||||
}
|
||||
</defs>
|
||||
|
||||
<!-- Nodes -->
|
||||
@foreach (var node in Graph.Nodes)
|
||||
{
|
||||
var color = NodeColor(node.Descriptive);
|
||||
var isHighlighted = HighlightEntityId == node.Id;
|
||||
|
||||
<g class="techTreeNode" @onclick="() => OnNodeClick(node.Id)">
|
||||
<rect x="@node.X" y="@node.Y" width="@nodeWidth" height="@nodeHeight" rx="6"
|
||||
fill="var(--paper)" stroke="@color" stroke-width="@(isHighlighted ? 3 : 1.5)"
|
||||
class="@(isHighlighted ? "highlighted" : "")"/>
|
||||
<text x="@(node.X + nodeWidth / 2)" y="@(node.Y + nodeHeight / 2)"
|
||||
text-anchor="middle" dominant-baseline="central"
|
||||
fill="white" font-size="12" font-weight="600">
|
||||
@TruncateText(node.Name, 20)
|
||||
</text>
|
||||
<title>@node.Name (@node.EntityType)</title>
|
||||
</g>
|
||||
}
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.techTreeContainer {
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
border: 2px solid var(--paper-border);
|
||||
border-radius: 8px;
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
.techTreeSvg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.techTreeNode {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.techTreeNode rect {
|
||||
transition: stroke-width 0.15s;
|
||||
}
|
||||
|
||||
.techTreeNode rect.highlighted {
|
||||
filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.5));
|
||||
}
|
||||
|
||||
.techTreeNode:hover rect {
|
||||
stroke-width: 3;
|
||||
}
|
||||
</style>
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter] public TechTreeGraphModel Graph { get; set; } = new();
|
||||
|
||||
[Parameter] public string? HighlightEntityId { get; set; }
|
||||
|
||||
[Parameter] public EventCallback<string> OnEntitySelected { get; set; }
|
||||
|
||||
private ElementReference containerRef;
|
||||
private const float nodeWidth = 140;
|
||||
private const float nodeHeight = 36;
|
||||
private const float horizontalSpacing = 60;
|
||||
private const float verticalSpacing = 30;
|
||||
private const float topPadding = 40;
|
||||
private const float leftPadding = 40;
|
||||
|
||||
private float svgWidth = 800;
|
||||
private float svgHeight = 600;
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
ComputeLayout();
|
||||
}
|
||||
|
||||
void ComputeLayout()
|
||||
{
|
||||
if (Graph.Nodes.Count == 0) return;
|
||||
|
||||
var layers = Graph.Nodes.GroupBy(n => n.Layer)
|
||||
.OrderBy(g => g.Key)
|
||||
.ToList();
|
||||
|
||||
// Simple layered layout: left to right (layers are columns)
|
||||
for (var layerIdx = 0; layerIdx < layers.Count; layerIdx++)
|
||||
{
|
||||
var layerNodes = layers.ElementAt(layerIdx).OrderBy(n => n.Name).ToList();
|
||||
var layerHeight = layerNodes.Count * (nodeHeight + verticalSpacing) - verticalSpacing;
|
||||
|
||||
for (var nodeIdx = 0; nodeIdx < layerNodes.Count; nodeIdx++)
|
||||
{
|
||||
var node = layerNodes[nodeIdx];
|
||||
node.X = leftPadding + layerIdx * (nodeWidth + horizontalSpacing);
|
||||
node.Y = topPadding + nodeIdx * (nodeHeight + verticalSpacing);
|
||||
}
|
||||
}
|
||||
|
||||
svgWidth = layers.Count * (nodeWidth + horizontalSpacing) + leftPadding + 100;
|
||||
svgHeight = layers.Max(g => g.Count()) * (nodeHeight + verticalSpacing) + topPadding + 80;
|
||||
|
||||
if (svgWidth < 800) svgWidth = 800;
|
||||
if (svgHeight < 400) svgHeight = 400;
|
||||
}
|
||||
|
||||
void OnNodeClick(string entityId)
|
||||
{
|
||||
entityDialogService.AddDialog(entityId);
|
||||
OnEntitySelected.InvokeAsync(entityId);
|
||||
}
|
||||
|
||||
string NodeColor(string descriptive)
|
||||
{
|
||||
return descriptive.ToLowerInvariant() switch
|
||||
{
|
||||
"frontliner" => "#ff6b6b",
|
||||
"skirmisher" => "#ffa502",
|
||||
"support" => "#2ed573",
|
||||
"generalist" => "#1e90ff",
|
||||
"worker" => "#ffd43b",
|
||||
"stronghold" => "#ff4757",
|
||||
"upgrade" => "#a55eea",
|
||||
"technology" => "#a55eea",
|
||||
_ => "#8fc5ff"
|
||||
};
|
||||
}
|
||||
|
||||
string EdgeColor(string edgeType)
|
||||
{
|
||||
return edgeType switch
|
||||
{
|
||||
"Produces" => "#2ed573",
|
||||
"RequiresProduction" => "#ffa502",
|
||||
"RequiresResearch" => "#a55eea",
|
||||
"Morph" => "#ff6b6b",
|
||||
"Upgrades" => "#1e90ff",
|
||||
_ => "#666"
|
||||
};
|
||||
}
|
||||
|
||||
string TruncateText(string text, int maxLength)
|
||||
{
|
||||
return text.Length <= maxLength ? text : text.Substring(0, maxLength - 3) + "...";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,9 +4,13 @@
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
@using Model.Feedback
|
||||
@using Model.Glossary
|
||||
@using Model.TechTree
|
||||
@using Model.Website
|
||||
@using Model.Website.Enums
|
||||
@using Services
|
||||
@using Services.Immortal
|
||||
@using Services.Website
|
||||
@using System.Net.Http
|
||||
@using System.Net.Http.Json
|
||||
@using System.Text
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Device.App">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
|
||||
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Device;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
public App()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override Window CreateWindow(IActivationState? activationState)
|
||||
{
|
||||
return new Window(new AppShell());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<Shell
|
||||
x:Class="Device.AppShell"
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:Device"
|
||||
Title="Device">
|
||||
|
||||
<ShellContent
|
||||
Title="Home"
|
||||
ContentTemplate="{DataTemplate local:MainPage}"
|
||||
Route="MainPage" />
|
||||
|
||||
</Shell>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Device;
|
||||
|
||||
public partial class AppShell : Shell
|
||||
{
|
||||
public AppShell()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net10.0-android</TargetFrameworks>
|
||||
<TargetFrameworks Condition="!$([MSBuild]::IsOSPlatform('linux'))">$(TargetFrameworks);net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
|
||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net10.0-windows10.0.19041.0</TargetFrameworks>
|
||||
<ProjectRuntimeIdentifier Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">win-x64</ProjectRuntimeIdentifier>
|
||||
|
||||
<!-- Note for MacCatalyst:
|
||||
The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
|
||||
When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.
|
||||
The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
|
||||
either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
|
||||
<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->
|
||||
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>Device</RootNamespace>
|
||||
<UseMaui>true</UseMaui>
|
||||
<SingleProject>true</SingleProject>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
|
||||
<!-- Enable XAML source generation for faster build times and improved performance.
|
||||
This generates C# code from XAML at compile time instead of runtime inflation.
|
||||
To disable, remove this line.
|
||||
For individual files, you can override by setting Inflator metadata:
|
||||
<MauiXaml Update="MyPage.xaml" Inflator="Default" /> (reverts to defaults: Runtime for Debug, XamlC for Release)
|
||||
<MauiXaml Update="MyPage.xaml" Inflator="Runtime" /> (force runtime inflation) -->
|
||||
<MauiXamlInflator>SourceGen</MauiXamlInflator>
|
||||
|
||||
<!-- Display name -->
|
||||
<ApplicationTitle>Device</ApplicationTitle>
|
||||
|
||||
<!-- App Identifier -->
|
||||
<ApplicationId>com.companyname.device</ApplicationId>
|
||||
|
||||
<!-- Versions -->
|
||||
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
|
||||
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
|
||||
<WindowsPackageType>None</WindowsPackageType>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
|
||||
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- App Icon -->
|
||||
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4"/>
|
||||
|
||||
<!-- Splash Screen -->
|
||||
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128"/>
|
||||
|
||||
<!-- Images -->
|
||||
<MauiImage Include="Resources\Images\*"/>
|
||||
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185"/>
|
||||
|
||||
<!-- Custom Fonts -->
|
||||
<MauiFont Include="Resources\Fonts\*"/>
|
||||
|
||||
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
|
||||
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="$(MauiVersion)"/>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.0"/>
|
||||
<PackageReference Include="MudBlazor" Version="9.2.0"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Components\Components.csproj"/>
|
||||
<ProjectReference Include="..\Model\Model.csproj"/>
|
||||
<ProjectReference Include="..\Pages\Pages.csproj"/>
|
||||
<ProjectReference Include="..\Services\Services.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:Device"
|
||||
x:Class="Device.MainPage">
|
||||
|
||||
<BlazorWebView x:Name="blazorWebView" HostPage="wwwroot/device.html">
|
||||
<BlazorWebView.RootComponents>
|
||||
<RootComponent Selector="#app" ComponentType="{x:Type local:MainRazor}" />
|
||||
</BlazorWebView.RootComponents>
|
||||
</BlazorWebView>
|
||||
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Device;
|
||||
|
||||
public partial class MainPage : ContentPage
|
||||
{
|
||||
public MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
@inject IGlossaryDialogService GlossaryDialogService
|
||||
@inject IJSRuntime JsRuntime
|
||||
|
||||
<MudThemeProvider IsDarkMode="true"/>
|
||||
<MudDialogProvider/>
|
||||
<MudSnackbarProvider/>
|
||||
|
||||
<Router AppAssembly="@typeof(HomePage).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
|
||||
</Found>
|
||||
<NotFound>
|
||||
<PageTitle>Not found</PageTitle>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p role="alert">Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
||||
|
||||
<EntityDialogPortal/>
|
||||
<GlossaryDialogPortal/>
|
||||
<ToastPortal/>
|
||||
<SearchPortal/>
|
||||
<ConfirmationDialogPortal/>
|
||||
|
||||
@code {
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("glossaryInterop.init", DotNetObjectReference.Create(this));
|
||||
}
|
||||
}
|
||||
|
||||
[JSInvokable]
|
||||
public void OpenGlossaryTerm(string termId)
|
||||
{
|
||||
GlossaryDialogService.AddDialog(termId);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Blazored.LocalStorage;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MudBlazor.Services;
|
||||
using Services;
|
||||
using Services.Development;
|
||||
using Services.Immortal;
|
||||
using Services.Website;
|
||||
|
||||
namespace Device;
|
||||
|
||||
public static class MauiProgram
|
||||
{
|
||||
public static MauiApp CreateMauiApp()
|
||||
{
|
||||
var builder = MauiApp.CreateBuilder();
|
||||
builder
|
||||
.UseMauiApp<App>()
|
||||
.ConfigureFonts(fonts =>
|
||||
{
|
||||
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
|
||||
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
|
||||
});
|
||||
|
||||
#pragma warning disable CA1416 // BlazorWebView requires Android 23+, project targets 21+
|
||||
builder.Services.AddMauiBlazorWebView();
|
||||
#pragma warning restore CA1416
|
||||
|
||||
#if DEBUG
|
||||
builder.Services.AddBlazorWebViewDeveloperTools();
|
||||
builder.Logging.AddDebug();
|
||||
#endif
|
||||
|
||||
builder.Services.AddLocalization();
|
||||
|
||||
builder.Services.AddBlazoredLocalStorage(config =>
|
||||
{
|
||||
config.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
|
||||
config.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
|
||||
config.JsonSerializerOptions.IgnoreReadOnlyProperties = true;
|
||||
config.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
|
||||
config.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
||||
config.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip;
|
||||
config.JsonSerializerOptions.WriteIndented = false;
|
||||
});
|
||||
|
||||
|
||||
builder.Services.AddScoped<INavigationService, NavigationService>();
|
||||
builder.Services.AddScoped<IKeyService, KeyService>();
|
||||
builder.Services.AddScoped<IImmortalSelectionService, ImmortalSelectionService>();
|
||||
builder.Services.AddScoped<IBuildComparisonService, DeprecatedBuildComparisionService>();
|
||||
builder.Services.AddScoped<IBuildOrderService, BuildOrderService>();
|
||||
builder.Services.AddScoped<IEconomyService, EconomyService>();
|
||||
builder.Services.AddScoped<ITimingService, TimingService>();
|
||||
builder.Services.AddScoped<IMemoryTesterService, MemoryTesterService>();
|
||||
builder.Services.AddScoped<IEntityFilterService, EntityFilterService>();
|
||||
builder.Services.AddScoped<IEntityDisplayService, EntityDisplayService>();
|
||||
builder.Services.AddScoped<IEntityDialogService, EntityDialogService>();
|
||||
builder.Services.AddScoped<IGlossaryService, GlossaryService>();
|
||||
builder.Services.AddScoped<IGlossaryDialogService, GlossaryDialogService>();
|
||||
builder.Services.AddScoped<IToastService, ToastService>();
|
||||
builder.Services.AddScoped<INoteService, NoteService>();
|
||||
builder.Services.AddScoped<ISearchService, SearchService>();
|
||||
builder.Services.AddScoped<IStorageService, StorageService>();
|
||||
builder.Services.AddScoped<IPermissionService, PermissionService>();
|
||||
builder.Services.AddScoped<IEconomyComparisonService, EconomyComparisionService>();
|
||||
builder.Services.AddScoped<IDataCollectionService, DataCollectionService>();
|
||||
|
||||
builder.Services.AddScoped<IMyDialogService, MyDialogService>();
|
||||
builder.Services.AddScoped<TechTreeService>();
|
||||
|
||||
builder.Services.AddMudServices();
|
||||
|
||||
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("https://0.0.0.0") });
|
||||
|
||||
return builder.Build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round"
|
||||
android:supportsRtl="true"></application>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
</manifest>
|
||||
@@ -0,0 +1,11 @@
|
||||
using Android.App;
|
||||
using Android.Content.PM;
|
||||
|
||||
namespace Device;
|
||||
|
||||
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop,
|
||||
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
|
||||
ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
|
||||
public class MainActivity : MauiAppCompatActivity
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using Android.App;
|
||||
using Android.Runtime;
|
||||
|
||||
namespace Device;
|
||||
|
||||
[Application]
|
||||
public class MainApplication : MauiApplication
|
||||
{
|
||||
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
|
||||
: base(handle, ownership)
|
||||
{
|
||||
}
|
||||
|
||||
protected override MauiApp CreateMauiApp()
|
||||
{
|
||||
return MauiProgram.CreateMauiApp();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#512BD4</color>
|
||||
<color name="colorPrimaryDark">#2B0B98</color>
|
||||
<color name="colorAccent">#2B0B98</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
using Foundation;
|
||||
|
||||
namespace Device;
|
||||
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : MauiUIApplicationDelegate
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<!-- See https://aka.ms/maui-publish-app-store#add-entitlements for more information about adding entitlements.-->
|
||||
<dict>
|
||||
<!-- App Sandbox must be enabled to distribute a MacCatalyst app through the Mac App Store. -->
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<!-- When App Sandbox is enabled, this value is required to open outgoing network connections. -->
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- The Mac App Store requires you specify if the app uses encryption. -->
|
||||
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption -->
|
||||
<!-- <key>ITSAppUsesNonExemptEncryption</key> -->
|
||||
<!-- Please indicate <true/> or <false/> here. -->
|
||||
|
||||
<!-- Specify the category for your app here. -->
|
||||
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype -->
|
||||
<!-- <key>LSApplicationCategoryType</key> -->
|
||||
<!-- <string>public.app-category.YOUR-CATEGORY-HERE</string> -->
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.lifestyle</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/appicon.appiconset</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,15 @@
|
||||
using ObjCRuntime;
|
||||
using UIKit;
|
||||
|
||||
namespace Device;
|
||||
|
||||
public class Program
|
||||
{
|
||||
// This is the main entry point of the application.
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||
// you can specify it here.
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<maui:MauiWinUIApplication
|
||||
x:Class="Device.WinUI.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:maui="using:Microsoft.Maui"
|
||||
xmlns:local="using:Device.WinUI">
|
||||
|
||||
</maui:MauiWinUIApplication>
|
||||
@@ -0,0 +1,23 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
|
||||
namespace Device.WinUI;
|
||||
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
public partial class App : MauiWinUIApplication
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
IgnorableNamespaces="uap rescap">
|
||||
|
||||
<Identity Name="maui-package-name-placeholder" Publisher="CN=User Name" Version="0.0.0.0"/>
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="034A3819-8402-48FB-850F-9B134D4D5787"
|
||||
PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>$placeholder$</DisplayName>
|
||||
<PublisherDisplayName>User Name</PublisherDisplayName>
|
||||
<Logo>$placeholder$.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0"/>
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0"/>
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate"/>
|
||||
</Resources>
|
||||
|
||||
<Applications>
|
||||
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
|
||||
<uap:VisualElements
|
||||
DisplayName="$placeholder$"
|
||||
Description="$placeholder$"
|
||||
Square150x150Logo="$placeholder$.png"
|
||||
Square44x44Logo="$placeholder$.png"
|
||||
BackgroundColor="transparent">
|
||||
<uap:DefaultTile Square71x71Logo="$placeholder$.png" Wide310x150Logo="$placeholder$.png"
|
||||
Square310x310Logo="$placeholder$.png"/>
|
||||
<uap:SplashScreen Image="$placeholder$.png"/>
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust"/>
|
||||
</Capabilities>
|
||||
|
||||
</Package>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="Device.WinUI.app"/>
|
||||
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<!-- The combination of below two tags have the following effect:
|
||||
1) Per-Monitor for >= Windows 10 Anniversary Update
|
||||
2) System < Windows 10 Anniversary Update
|
||||
-->
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor
|
||||
</dpiAwareness>
|
||||
|
||||
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
@@ -0,0 +1,9 @@
|
||||
using Foundation;
|
||||
|
||||
namespace Device;
|
||||
|
||||
[Register("AppDelegate")]
|
||||
public class AppDelegate : MauiUIApplicationDelegate
|
||||
{
|
||||
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIDeviceFamily</key>
|
||||
<array>
|
||||
<integer>1</integer>
|
||||
<integer>2</integer>
|
||||
</array>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>XSAppIconAssets</key>
|
||||
<string>Assets.xcassets/appicon.appiconset</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,15 @@
|
||||
using ObjCRuntime;
|
||||
using UIKit;
|
||||
|
||||
namespace Device;
|
||||
|
||||
public class Program
|
||||
{
|
||||
// This is the main entry point of the application.
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||
// you can specify it here.
|
||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
This is the minimum required version of the Apple Privacy Manifest for .NET MAUI apps.
|
||||
The contents below are needed because of APIs that are used in the .NET framework and .NET MAUI SDK.
|
||||
|
||||
You are responsible for adding extra entries as needed for your application.
|
||||
|
||||
More information: https://aka.ms/maui-privacy-manifest
|
||||
-->
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>C617.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>35F9.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>E174.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<!--
|
||||
The entry below is only needed when you're using the Preferences API in your app.
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
</dict> -->
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Windows Machine": {
|
||||
"commandName": "Project",
|
||||
"nativeDebugging": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="456" height="456" fill="#512BD4"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 227 B |
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xml:space="preserve"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z"
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376"/>
|
||||
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z"
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376"/>
|
||||
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z"
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376"/>
|
||||
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z"
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 90 KiB |
@@ -0,0 +1,15 @@
|
||||
Any raw assets you want to be deployed with your application can be placed in
|
||||
this directory (and child directories). Deployment of the asset to your application
|
||||
is automatically handled by the following `MauiAsset` Build Action within your `.csproj`.
|
||||
|
||||
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
|
||||
These files will be deployed with your package and will be accessible using Essentials:
|
||||
|
||||
async Task LoadMauiAsset()
|
||||
{
|
||||
using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
|
||||
using var reader = new StreamReader(stream);
|
||||
|
||||
var contents = reader.ReadToEnd();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="456" height="456" viewBox="0 0 456 456" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xml:space="preserve"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="m 105.50037,281.60863 c -2.70293,0 -5.00091,-0.90042 -6.893127,-2.70209 -1.892214,-1.84778 -2.837901,-4.04181 -2.837901,-6.58209 0,-2.58722 0.945687,-4.80389 2.837901,-6.65167 1.892217,-1.84778 4.190197,-2.77167 6.893127,-2.77167 2.74819,0 5.06798,0.92389 6.96019,2.77167 1.93749,1.84778 2.90581,4.06445 2.90581,6.65167 0,2.54028 -0.96832,4.73431 -2.90581,6.58209 -1.89221,1.80167 -4.212,2.70209 -6.96019,2.70209 z"
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376"/>
|
||||
<path d="M 213.56111,280.08446 H 195.99044 L 149.69953,207.0544 c -1.17121,-1.84778 -2.14037,-3.76515 -2.90581,-5.75126 h -0.40578 c 0.36051,2.12528 0.54076,6.67515 0.54076,13.6496 v 65.13172 h -15.54349 v -99.36009 h 18.71925 l 44.7374,71.29798 c 1.89222,2.95695 3.1087,4.98917 3.64945,6.09751 h 0.26996 c -0.45021,-2.6325 -0.67573,-7.09015 -0.67573,-13.37293 v -64.02256 h 15.47557 z"
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376"/>
|
||||
<path d="m 289.25134,280.08446 h -54.40052 v -99.36009 h 52.23835 v 13.99669 h -36.15411 v 28.13085 h 33.31621 v 13.9271 h -33.31621 v 29.37835 h 38.31628 z"
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376"/>
|
||||
<path d="M 366.56466,194.72106 H 338.7222 v 85.3634 h -16.08423 v -85.3634 h -27.77455 v -13.99669 h 71.70124 z"
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke-width:0.838376"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
|
||||
|
||||
<!-- Note: For Android please see also Platforms\Android\Resources\values\colors.xml -->
|
||||
|
||||
<Color x:Key="Primary">#512BD4</Color>
|
||||
<Color x:Key="PrimaryDark">#ac99ea</Color>
|
||||
<Color x:Key="PrimaryDarkText">#242424</Color>
|
||||
<Color x:Key="Secondary">#DFD8F7</Color>
|
||||
<Color x:Key="SecondaryDarkText">#9880e5</Color>
|
||||
<Color x:Key="Tertiary">#2B0B98</Color>
|
||||
|
||||
<Color x:Key="White">White</Color>
|
||||
<Color x:Key="Black">Black</Color>
|
||||
<Color x:Key="Magenta">#D600AA</Color>
|
||||
<Color x:Key="MidnightBlue">#190649</Color>
|
||||
<Color x:Key="OffBlack">#1f1f1f</Color>
|
||||
|
||||
<Color x:Key="Gray100">#E1E1E1</Color>
|
||||
<Color x:Key="Gray200">#C8C8C8</Color>
|
||||
<Color x:Key="Gray300">#ACACAC</Color>
|
||||
<Color x:Key="Gray400">#919191</Color>
|
||||
<Color x:Key="Gray500">#6E6E6E</Color>
|
||||
<Color x:Key="Gray600">#404040</Color>
|
||||
<Color x:Key="Gray900">#212121</Color>
|
||||
<Color x:Key="Gray950">#141414</Color>
|
||||
|
||||
<SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource Primary}" />
|
||||
<SolidColorBrush x:Key="SecondaryBrush" Color="{StaticResource Secondary}" />
|
||||
<SolidColorBrush x:Key="TertiaryBrush" Color="{StaticResource Tertiary}" />
|
||||
<SolidColorBrush x:Key="WhiteBrush" Color="{StaticResource White}" />
|
||||
<SolidColorBrush x:Key="BlackBrush" Color="{StaticResource Black}" />
|
||||
|
||||
<SolidColorBrush x:Key="Gray100Brush" Color="{StaticResource Gray100}" />
|
||||
<SolidColorBrush x:Key="Gray200Brush" Color="{StaticResource Gray200}" />
|
||||
<SolidColorBrush x:Key="Gray300Brush" Color="{StaticResource Gray300}" />
|
||||
<SolidColorBrush x:Key="Gray400Brush" Color="{StaticResource Gray400}" />
|
||||
<SolidColorBrush x:Key="Gray500Brush" Color="{StaticResource Gray500}" />
|
||||
<SolidColorBrush x:Key="Gray600Brush" Color="{StaticResource Gray600}" />
|
||||
<SolidColorBrush x:Key="Gray900Brush" Color="{StaticResource Gray900}" />
|
||||
<SolidColorBrush x:Key="Gray950Brush" Color="{StaticResource Gray950}" />
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,503 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
|
||||
|
||||
<Style TargetType="ActivityIndicator">
|
||||
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="IndicatorView">
|
||||
<Setter Property="IndicatorColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="SelectedIndicatorColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray100}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="Stroke"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="StrokeShape" Value="Rectangle" />
|
||||
<Setter Property="StrokeThickness" Value="1" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="BoxView">
|
||||
<Setter Property="BackgroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource PrimaryDarkText}}" />
|
||||
<Setter Property="BackgroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource PrimaryDark}}" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="BorderWidth" Value="0" />
|
||||
<Setter Property="CornerRadius" Value="8" />
|
||||
<Setter Property="Padding" Value="14,10" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44" />
|
||||
<Setter Property="MinimumWidthRequest" Value="44" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="BackgroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="CheckBox">
|
||||
<Setter Property="Color" Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44" />
|
||||
<Setter Property="MinimumWidthRequest" Value="44" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="Color"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="DatePicker">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44" />
|
||||
<Setter Property="MinimumWidthRequest" Value="44" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Editor">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="PlaceholderColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44" />
|
||||
<Setter Property="MinimumWidthRequest" Value="44" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Entry">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="PlaceholderColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray500}}" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44" />
|
||||
<Setter Property="MinimumWidthRequest" Value="44" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="ImageButton">
|
||||
<Setter Property="Opacity" Value="1" />
|
||||
<Setter Property="BorderColor" Value="Transparent" />
|
||||
<Setter Property="BorderWidth" Value="0" />
|
||||
<Setter Property="CornerRadius" Value="0" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44" />
|
||||
<Setter Property="MinimumWidthRequest" Value="44" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="Opacity" Value="0.5" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="PointerOver" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Label">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Label" x:Key="Headline">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}" />
|
||||
<Setter Property="FontSize" Value="32" />
|
||||
<Setter Property="HorizontalOptions" Value="Center" />
|
||||
<Setter Property="HorizontalTextAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Label" x:Key="SubHeadline">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource MidnightBlue}, Dark={StaticResource White}}" />
|
||||
<Setter Property="FontSize" Value="24" />
|
||||
<Setter Property="HorizontalOptions" Value="Center" />
|
||||
<Setter Property="HorizontalTextAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Picker">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="TitleColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44" />
|
||||
<Setter Property="MinimumWidthRequest" Value="44" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="TitleColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="ProgressBar">
|
||||
<Setter Property="ProgressColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="ProgressColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="RadioButton">
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44" />
|
||||
<Setter Property="MinimumWidthRequest" Value="44" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="RefreshView">
|
||||
<Setter Property="RefreshColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="SearchBar">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="PlaceholderColor" Value="{StaticResource Gray500}" />
|
||||
<Setter Property="CancelButtonColor" Value="{StaticResource Gray500}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44" />
|
||||
<Setter Property="MinimumWidthRequest" Value="44" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="PlaceholderColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="SearchHandler">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="PlaceholderColor" Value="{StaticResource Gray500}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="PlaceholderColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Shadow">
|
||||
<Setter Property="Radius" Value="15" />
|
||||
<Setter Property="Opacity" Value="0.5" />
|
||||
<Setter Property="Brush" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource White}}" />
|
||||
<Setter Property="Offset" Value="10,10" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Slider">
|
||||
<Setter Property="MinimumTrackColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="MaximumTrackColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="ThumbColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="MinimumTrackColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="MaximumTrackColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="ThumbColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="SwipeItem">
|
||||
<Setter Property="BackgroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Switch">
|
||||
<Setter Property="OnColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
<Setter Property="ThumbColor" Value="{StaticResource White}" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="OnColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
<Setter Property="ThumbColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="On">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="OnColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Secondary}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="ThumbColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Primary}, Dark={StaticResource White}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Off">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="ThumbColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="TimePicker">
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource White}}" />
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="FontFamily" Value="OpenSansRegular" />
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="MinimumHeightRequest" Value="44" />
|
||||
<Setter Property="MinimumWidthRequest" Value="44" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray300}, Dark={StaticResource Gray600}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
<Style TargetType="TitleBar">
|
||||
<Setter Property="MinimumHeightRequest" Value="32"/>
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
<VisualStateGroupList>
|
||||
<VisualStateGroup x:Name="TitleActiveStates">
|
||||
<VisualState x:Name="TitleBarTitleActive">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="BackgroundColor" Value="Transparent" />
|
||||
<Setter Property="ForegroundColor" Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource White}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="TitleBarTitleInactive">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="BackgroundColor" Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
|
||||
<Setter Property="ForegroundColor" Value="{AppThemeBinding Light={StaticResource Gray400}, Dark={StaticResource Gray500}}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
-->
|
||||
|
||||
<Style TargetType="Page" ApplyToDerivedTypes="True">
|
||||
<Setter Property="Padding" Value="0" />
|
||||
<Setter Property="BackgroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Shell" ApplyToDerivedTypes="True">
|
||||
<Setter Property="Shell.BackgroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
|
||||
<Setter Property="Shell.ForegroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}" />
|
||||
<Setter Property="Shell.TitleColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Black}, Dark={StaticResource SecondaryDarkText}}" />
|
||||
<Setter Property="Shell.DisabledColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
|
||||
<Setter Property="Shell.UnselectedColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray200}}" />
|
||||
<Setter Property="Shell.NavBarHasShadow" Value="False" />
|
||||
<Setter Property="Shell.TabBarBackgroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Black}}" />
|
||||
<Setter Property="Shell.TabBarForegroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
|
||||
<Setter Property="Shell.TabBarTitleColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
|
||||
<Setter Property="Shell.TabBarUnselectedColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray900}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="NavigationPage">
|
||||
<Setter Property="BarBackgroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource OffBlack}}" />
|
||||
<Setter Property="BarTextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}" />
|
||||
<Setter Property="IconColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource White}}" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="TabbedPage">
|
||||
<Setter Property="BarBackgroundColor"
|
||||
Value="{AppThemeBinding Light={StaticResource White}, Dark={StaticResource Gray950}}" />
|
||||
<Setter Property="BarTextColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Magenta}, Dark={StaticResource White}}" />
|
||||
<Setter Property="UnselectedTabColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray200}, Dark={StaticResource Gray950}}" />
|
||||
<Setter Property="SelectedTabColor"
|
||||
Value="{AppThemeBinding Light={StaticResource Gray950}, Dark={StaticResource Gray200}}" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,58 @@
|
||||
@using System.Net.Http
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
@using Device
|
||||
@using IGP.Pages
|
||||
@using IGP.Pages.Home
|
||||
@using IGP.Pages.Home.Parts
|
||||
@using IGP.Dialog
|
||||
@using IGP.Pages.BuildCalculator
|
||||
@using IGP.Pages.BuildCalculator.Parts
|
||||
@using IGP.Pages.Database.Entity
|
||||
@using IGP.Pages.Database.Entity.Parts
|
||||
@using IGP.Pages.Database.Parts
|
||||
@using IGP.Pages.EconomyComparison
|
||||
@using IGP.Pages.EconomyComparison.Parts
|
||||
@using IGP.Pages.MemoryTester.Parts
|
||||
@using IGP.Pages.Notes
|
||||
@using IGP.Pages.Notes.Parts
|
||||
@using IGP.Portals
|
||||
@using IGP.Utils
|
||||
|
||||
@using Components.Display
|
||||
@using Components.Feedback
|
||||
@using Components.TechTree
|
||||
@using Components.Form
|
||||
@using Components.Info
|
||||
@using Components.Inputs
|
||||
@using Components.Layout
|
||||
@using Components.Navigation
|
||||
@using Components.Shared
|
||||
|
||||
@using Markdig
|
||||
@using Microsoft.Extensions.Localization
|
||||
@using Model.Chart
|
||||
@using Model.Economy
|
||||
@using Model.Entity
|
||||
@using Model.Entity.Data
|
||||
@using Model.Entity.Parts
|
||||
@using Model.Feedback
|
||||
@using Model.Glossary
|
||||
@using Model.Hotkeys
|
||||
@using Model.MemoryTester
|
||||
@using Model.Notes
|
||||
@using Model.RoadMap
|
||||
@using Model.RoadMap.Enums
|
||||
@using Model.TechTree
|
||||
@using Model.Types
|
||||
@using Model.Website
|
||||
@using Services
|
||||
@using Services.Immortal
|
||||
@using System.Globalization
|
||||
@using System.Reflection
|
||||
@using System.Timers
|
||||
@using MudBlazor
|
||||
@using MudBlazor.Services
|
||||
@@ -37,9 +37,7 @@
|
||||
--info-hover: #451376;
|
||||
--info-border-hover: #210b36;
|
||||
|
||||
--dialog-border-color: black;
|
||||
--dialog-border-width: 2px;
|
||||
--dialog-radius: 6px;
|
||||
--dialog-radius: 12px;
|
||||
}
|
||||
|
||||
html {
|
||||
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="background-color: #2C2E33; color: white;">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"/>
|
||||
<title>IGP Fan Reference</title>
|
||||
<base href="/"/>
|
||||
<link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css"
|
||||
integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" rel="stylesheet">
|
||||
<link href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" rel="stylesheet">
|
||||
<link href="css/app.css" rel="stylesheet"/>
|
||||
<link href="Device.styles.css" rel="stylesheet"/>
|
||||
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet"/>
|
||||
</head>
|
||||
|
||||
<body style="background-color: #161618; color: white;">
|
||||
<div id="app">
|
||||
<div style="width: 100vw; height: 100vh; background-color: black;"></div>
|
||||
</div>
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
An unhandled error has occurred.
|
||||
<a class="reload" href="">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
|
||||
<script src="_framework/blazor.webview.js"></script>
|
||||
<script src="javascript/download.js"></script>
|
||||
<script>
|
||||
window.DotNetReference = null;
|
||||
window.SetDotnetReference = function (dotnetReference) {
|
||||
window.DotNetReference = dotnetReference;
|
||||
};
|
||||
|
||||
window.getUserAgent = () => {
|
||||
return navigator.userAgent;
|
||||
};
|
||||
window.SetFocusToElement = (elementId) => {
|
||||
document.getElementById(elementId).focus();
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", function (e) {
|
||||
DotNetReference?.invokeMethodAsync('OnKeyPress', e.key, e.ctrlKey, e.shiftKey, e.altKey, e.metaKey)
|
||||
});
|
||||
|
||||
</script>
|
||||
<script>
|
||||
window.glossaryInterop = {
|
||||
dotNetRef: null,
|
||||
init: function(dotNetRef) {
|
||||
this.dotNetRef = dotNetRef;
|
||||
document.addEventListener('click', function(e) {
|
||||
var target = e.target;
|
||||
while (target) {
|
||||
if (target.classList && target.classList.contains('glossary-link')) {
|
||||
var id = target.getAttribute('data-glossary-id');
|
||||
if (id && window.glossaryInterop.dotNetRef) {
|
||||
window.glossaryInterop.dotNetRef.invokeMethodAsync('OpenGlossaryTerm', id);
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
}
|
||||
target = target.parentElement;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script crossorigin="anonymous"
|
||||
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
|
||||
src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"></script>
|
||||
<script crossorigin="anonymous"
|
||||
integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2"
|
||||
src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js"></script>
|
||||
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
@@ -1,7 +1,7 @@
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||
WORKDIR /src
|
||||
COPY . .
|
||||
RUN dotnet publish IGP/IGP.csproj -c Release -o /app/publish
|
||||
RUN dotnet publish Web/Web.csproj -c Release -o /app/publish
|
||||
|
||||
FROM nginx:alpine AS final
|
||||
WORKDIR /usr/share/nginx/html
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:local="clr-namespace:Hybrid"
|
||||
x:Class="Hybrid.App">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
|
||||
<!--
|
||||
For information about styling .NET MAUI pages
|
||||
please refer to the documentation:
|
||||
https://go.microsoft.com/fwlink/?linkid=2282329
|
||||
-->
|
||||
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Hybrid;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
public App()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override Window CreateWindow(IActivationState? activationState)
|
||||
{
|
||||
return new Window(new MainPage()) { Title = "Hybrid" };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<div class="page">
|
||||
<div class="sidebar">
|
||||
<NavMenu/>
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<div class="top-row px-4">
|
||||
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
|
||||
</div>
|
||||
|
||||
<article class="content px-4">
|
||||
@Body
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
@@ -0,0 +1,83 @@
|
||||
.page {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
padding-bottom: env(safe-area-inset-bottom, 0px);
|
||||
padding-right: env(safe-area-inset-right, 0px);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
padding-right: env(safe-area-inset-right, 0px);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.top-row ::deep a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row.auth ::deep a:first-child {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.top-row, article {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<div class="top-row ps-3 navbar navbar-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="">Hybrid</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="checkbox" title="Navigation menu" class="navbar-toggler"/>
|
||||
|
||||
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
|
||||
<nav class="nav flex-column">
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||
<span class="bi bi-house-door-fill-nav-menu" aria-hidden="true"></span> Home
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="database">
|
||||
<span class="bi bi-database-fill-nav-menu" aria-hidden="true"></span> Database
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="counter">
|
||||
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Counter
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="weather">
|
||||
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Weather
|
||||
</NavLink>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
@@ -0,0 +1,106 @@
|
||||
.navbar-toggler {
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
width: 3.5rem;
|
||||
height: 2.5rem;
|
||||
color: white;
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 1rem;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.navbar-toggler:checked {
|
||||
background-color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
min-height: 3.5rem;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.1rem;
|
||||
padding-left: env(safe-area-inset-left, 0px);
|
||||
}
|
||||
|
||||
.bi {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
margin-right: 0.75rem;
|
||||
top: -1px;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bi-house-door-fill-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-plus-square-fill-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-list-nested-nav-menu {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep .nav-link {
|
||||
color: #d7d7d7;
|
||||
background: none;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 3rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active {
|
||||
background-color: rgba(255,255,255,0.37);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item ::deep .nav-link:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-scrollable {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar-toggler:checked ~ .nav-scrollable {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.navbar-toggler {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-scrollable {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
|
||||
/* Allow sidebar to scroll for tall menus */
|
||||
height: calc(100vh - 3.5rem);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
@page "/counter"
|
||||
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p role="status">Current count: @currentCount</p>
|
||||
|
||||
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
||||
|
||||
@code {
|
||||
private int currentCount = 0;
|
||||
|
||||
private void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
@page "/database"
|
||||
@using Model.Entity
|
||||
@using Model.Entity.Data
|
||||
@using Model.Entity.Parts
|
||||
|
||||
<PageTitle>Database</PageTitle>
|
||||
|
||||
<div class="container-fluid py-3">
|
||||
<h1 class="mb-3">Database</h1>
|
||||
|
||||
<div class="card mb-4 shadow-sm filters-card">
|
||||
<div class="card-body">
|
||||
<div class="row g-3 align-items-end">
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<label for="factionSelect" class="form-label fw-semibold">Faction</label>
|
||||
<select id="factionSelect" class="form-select" @bind="selectedFaction" @bind:after="OnFactionChanged">
|
||||
<option value="@DataType.Any">Any</option>
|
||||
<option value="@DataType.FACTION_QRath">Q'Rath</option>
|
||||
<option value="@DataType.FACTION_Aru">Aru</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-md-6 col-lg-4">
|
||||
<label for="immortalSelect" class="form-label fw-semibold">Immortal</label>
|
||||
<select id="immortalSelect" class="form-select" @bind="selectedImmortal" @bind:after="OnImmortalChanged">
|
||||
<option value="@DataType.Any">Any</option>
|
||||
@foreach (var choice in immortalChoices)
|
||||
{
|
||||
<option value="@choice.Key">@choice.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 text-muted small">
|
||||
Showing @filteredEntities.Count @(filteredEntities.Count == 1 ? "entity" : "entities")
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
@foreach (var entity in filteredEntities)
|
||||
{
|
||||
<div class="col-12 col-sm-6 col-lg-4 col-xl-3">
|
||||
<div class="card h-100 shadow-sm entity-card">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<div class="d-flex justify-content-between align-items-start mb-2 gap-2">
|
||||
<h5 class="card-title mb-0 text-break">@entity.Info().Name</h5>
|
||||
@{
|
||||
var vanguard = entity.VanguardAdded();
|
||||
if (vanguard != null)
|
||||
{
|
||||
<span class="immortal-badge">@(EntityData.Get().TryGetValue(vanguard!.ImmortalId, out var imm) ? imm.Info().Name : "")</span>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<h6 class="card-subtitle mb-2">
|
||||
<span class="badge bg-secondary me-1">@entity.EntityType.Replace("_", " ")</span>
|
||||
@if (entity.Faction() != null)
|
||||
{
|
||||
<span class="badge bg-dark-subtle text-dark-emphasis">@(EntityData.Get().TryGetValue(entity.Faction().Faction, out var fac) ? fac.Info().Name : "")</span>
|
||||
}
|
||||
</h6>
|
||||
@if (!string.IsNullOrEmpty(entity.Info().Description))
|
||||
{
|
||||
<p class="card-text flex-grow-1 small">
|
||||
@(entity.Info().Description.Length > 120
|
||||
? entity.Info().Description[..117] + "..."
|
||||
: entity.Info().Description)
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (filteredEntities.Count == 0)
|
||||
{
|
||||
<div class="alert alert-info mt-3" role="alert">No entities match the selected filters.</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.filters-card {
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
}
|
||||
|
||||
.entity-card {
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
transition: box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.entity-card:hover {
|
||||
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
|
||||
}
|
||||
|
||||
.immortal-badge {
|
||||
display: inline-block;
|
||||
padding: 0.25em 0.65em;
|
||||
font-size: 0.75em;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
color: #000;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
border-radius: 0.375rem;
|
||||
background-color: #cff4fc;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@code {
|
||||
private string selectedFaction = DataType.Any;
|
||||
private string selectedImmortal = DataType.Any;
|
||||
private List<ImmortalChoice> immortalChoices = new();
|
||||
|
||||
private List<EntityModel> allEntities = new();
|
||||
private List<EntityModel> filteredEntities = new();
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
allEntities = EntityModel.GetList()
|
||||
.Where(e => !e.IsSpeculative)
|
||||
.ToList();
|
||||
RefreshImmortalChoices();
|
||||
ApplyFilters();
|
||||
}
|
||||
|
||||
private void OnFactionChanged()
|
||||
{
|
||||
if (selectedFaction != DataType.FACTION_QRath && selectedFaction != DataType.FACTION_Aru)
|
||||
{
|
||||
selectedFaction = DataType.Any;
|
||||
}
|
||||
selectedImmortal = DataType.Any;
|
||||
RefreshImmortalChoices();
|
||||
ApplyFilters();
|
||||
}
|
||||
|
||||
private void OnImmortalChanged()
|
||||
{
|
||||
ApplyFilters();
|
||||
}
|
||||
|
||||
private void RefreshImmortalChoices()
|
||||
{
|
||||
immortalChoices.Clear();
|
||||
|
||||
if (selectedFaction == DataType.FACTION_QRath || selectedFaction == DataType.Any)
|
||||
{
|
||||
AddImmortalChoice(DataType.IMMORTAL_Orzum);
|
||||
AddImmortalChoice(DataType.IMMORTAL_Ajari);
|
||||
}
|
||||
|
||||
if (selectedFaction == DataType.FACTION_Aru || selectedFaction == DataType.Any)
|
||||
{
|
||||
AddImmortalChoice(DataType.IMMORTAL_Atzlan);
|
||||
AddImmortalChoice(DataType.IMMORTAL_Mala);
|
||||
AddImmortalChoice(DataType.IMMORTAL_Xol);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddImmortalChoice(string id)
|
||||
{
|
||||
var name = EntityData.Get().TryGetValue(id, out var model)
|
||||
? model.Info().Name
|
||||
: id.Replace("IMMORTAL_", "");
|
||||
immortalChoices.Add(new ImmortalChoice(id, name));
|
||||
}
|
||||
|
||||
private void ApplyFilters()
|
||||
{
|
||||
var query = allEntities.AsEnumerable();
|
||||
|
||||
if (selectedFaction != DataType.Any)
|
||||
{
|
||||
query = query.Where(e =>
|
||||
e.Faction() != null && e.Faction().Faction == selectedFaction);
|
||||
}
|
||||
|
||||
if (selectedImmortal != DataType.Any)
|
||||
{
|
||||
query = query.Where(e =>
|
||||
e.VanguardAdded() != null && e.VanguardAdded().ImmortalId == selectedImmortal);
|
||||
}
|
||||
|
||||
filteredEntities = query.OrderBy(e => e.Info().Name).ToList();
|
||||
}
|
||||
|
||||
private record ImmortalChoice(string Key, string Name);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
@page "/"
|
||||
|
||||
<h1>Hello, world!</h1>
|
||||
|
||||
Welcome to your new app.
|
||||
|
||||
<ButtonComponent>Test</ButtonComponent>
|
||||