commit
8390584e7c
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="UserContentModel">
|
||||||
|
<attachedFolders />
|
||||||
|
<explicitIncludes />
|
||||||
|
<explicitExcludes />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${workspaceFolder}/TP Blazor/TP Blazor.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "publish",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"publish",
|
||||||
|
"${workspaceFolder}/TP Blazor/TP Blazor.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "watch",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"watch",
|
||||||
|
"run",
|
||||||
|
"--project",
|
||||||
|
"${workspaceFolder}/TP Blazor/TP Blazor.csproj"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -1,12 +1,14 @@
|
|||||||
<Router AppAssembly="@typeof(App).Assembly">
|
<CascadingBlazoredModal>
|
||||||
<Found Context="routeData">
|
<Router AppAssembly="@typeof(App).Assembly">
|
||||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
<Found Context="routeData">
|
||||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||||
</Found>
|
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||||
<NotFound>
|
</Found>
|
||||||
<PageTitle>Not found</PageTitle>
|
<NotFound>
|
||||||
<LayoutView Layout="@typeof(MainLayout)">
|
<PageTitle>Not found</PageTitle>
|
||||||
<p role="alert">Sorry, there's nothing at this address.</p>
|
<LayoutView Layout="@typeof(MainLayout)">
|
||||||
</LayoutView>
|
<p role="alert">Sorry, there's nothing at this address.</p>
|
||||||
</NotFound>
|
</LayoutView>
|
||||||
</Router>
|
</NotFound>
|
||||||
|
</Router>
|
||||||
|
</CascadingBlazoredModal>
|
@ -0,0 +1,10 @@
|
|||||||
|
@using TP_Blazor.Models
|
||||||
|
|
||||||
|
<h3>Card</h3>
|
||||||
|
|
||||||
|
@typeparam TItem
|
||||||
|
<div class="card text-center">
|
||||||
|
@CardHeader(Item)
|
||||||
|
@CardBody(Item)
|
||||||
|
@CardFooter
|
||||||
|
</div>
|
@ -0,0 +1,19 @@
|
|||||||
|
using Microsoft.AspNetCore.Localization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace TP_Blazor.Controllers;
|
||||||
|
|
||||||
|
[Route("[controller]/[action]")]
|
||||||
|
public class CultureController:Controller
|
||||||
|
{
|
||||||
|
public IActionResult SetCulture(string culture, string returnUrl)
|
||||||
|
{
|
||||||
|
if(culture != null)
|
||||||
|
{
|
||||||
|
this.HttpContext.Response.Cookies.Append(
|
||||||
|
CookieRequestCultureProvider.DefaultCookieName,
|
||||||
|
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)));
|
||||||
|
}
|
||||||
|
return this.LocalRedirect(returnUrl);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
using TP_Blazor.Models;
|
||||||
|
|
||||||
|
namespace TP_Blazor.Factories;
|
||||||
|
|
||||||
|
public static class ItemFactory
|
||||||
|
{
|
||||||
|
public static ItemModel ToModel(Item item, byte[] imageContent)
|
||||||
|
{
|
||||||
|
return new ItemModel
|
||||||
|
{
|
||||||
|
Id = item.Id,
|
||||||
|
DisplayName = item.DisplayName,
|
||||||
|
Name = item.Name,
|
||||||
|
RepairWith = item.RepairWith,
|
||||||
|
EnchantCategories = item.EnchantCategories,
|
||||||
|
MaxDurability = item.MaxDurability,
|
||||||
|
StackSize = item.StackSize,
|
||||||
|
ImageContent = imageContent
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Item Create(ItemModel model)
|
||||||
|
{
|
||||||
|
return new Item
|
||||||
|
{
|
||||||
|
Id = model.Id,
|
||||||
|
DisplayName = model.DisplayName,
|
||||||
|
Name = model.Name,
|
||||||
|
RepairWith = model.RepairWith,
|
||||||
|
EnchantCategories = model.EnchantCategories,
|
||||||
|
MaxDurability = model.MaxDurability,
|
||||||
|
StackSize = model.StackSize,
|
||||||
|
CreatedDate = DateTime.Now
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Update(Item item, ItemModel model)
|
||||||
|
{
|
||||||
|
item.DisplayName = model.DisplayName;
|
||||||
|
item.Name = model.Name;
|
||||||
|
item.RepairWith = model.RepairWith;
|
||||||
|
item.EnchantCategories = model.EnchantCategories;
|
||||||
|
item.MaxDurability = model.MaxDurability;
|
||||||
|
item.StackSize = model.StackSize;
|
||||||
|
item.UpdatedDate = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
<div class="simple-form">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Are you sure you want to delete @item.DisplayName ?
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button @onclick="ConfirmDelete" class="btn btn-primary">Delete</button>
|
||||||
|
|
||||||
|
<button @onclick="Cancel" class="btn btn-secondary">Cancel</button>
|
||||||
|
</div>
|
@ -0,0 +1,37 @@
|
|||||||
|
using Blazored.Modal;
|
||||||
|
using Blazored.Modal.Services;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using TP_Blazor.Models;
|
||||||
|
using TP_Blazor.Services;
|
||||||
|
|
||||||
|
namespace TP_Blazor.Modals;
|
||||||
|
|
||||||
|
public partial class DeleteConfirmation
|
||||||
|
{
|
||||||
|
[CascadingParameter]
|
||||||
|
public BlazoredModalInstance ModalInstance { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
public IDataService DataService { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
private Item item = new Item();
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
// Get the item
|
||||||
|
item = await DataService.GetById(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfirmDelete()
|
||||||
|
{
|
||||||
|
ModalInstance.CloseAsync(ModalResult.Ok(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cancel()
|
||||||
|
{
|
||||||
|
ModalInstance.CancelAsync();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
@page "/add"
|
||||||
|
|
||||||
|
<h3>Add</h3>
|
||||||
|
|
||||||
|
<EditForm Model="@itemModel" OnValidSubmit="@OnHandleValidSubmit">
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
<p>
|
||||||
|
<label for="display-name">
|
||||||
|
Display name:
|
||||||
|
<InputText id="display-name" @bind-Value="itemModel.DisplayName" />
|
||||||
|
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="name">
|
||||||
|
Name:
|
||||||
|
<InputText id="name" @bind-Value="itemModel.Name" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="stack-size">
|
||||||
|
Stack size:
|
||||||
|
<InputNumber id="stack-size" @bind-Value="itemModel.StackSize" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="max-durability">
|
||||||
|
Max durability:
|
||||||
|
<InputNumber id="max-durability" @bind-Value="itemModel.MaxDurability" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Enchant categories:
|
||||||
|
<div>
|
||||||
|
@foreach (var item in enchantCategories)
|
||||||
|
{
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" @onchange="@(e => OnEnchantCategoriesChange(item, e.Value))" />@item
|
||||||
|
</label>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Repair with:
|
||||||
|
<div>
|
||||||
|
@foreach (var item in repairWith)
|
||||||
|
{
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" @onchange="@(e => OnRepairWithChange(item, e.Value))" />@item
|
||||||
|
</label>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Item image:
|
||||||
|
<InputFile OnChange="@LoadImage" accept=".png" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Accept Condition:
|
||||||
|
<InputCheckbox @bind-Value="itemModel.AcceptCondition" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
<ValidationSummary />
|
||||||
|
</EditForm>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
|||||||
|
@page "/edit/{Id:int}"
|
||||||
|
|
||||||
|
<h3>Edit</h3>
|
||||||
|
<EditForm Model="@itemModel" OnValidSubmit="@HandleValidSubmit">
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
<ValidationSummary />
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<label for="display-name">
|
||||||
|
Display name:
|
||||||
|
<InputText id="display-name" @bind-Value="itemModel.DisplayName" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="name">
|
||||||
|
Name:
|
||||||
|
<InputText id="name" @bind-Value="itemModel.Name" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="stack-size">
|
||||||
|
Stack size:
|
||||||
|
<InputNumber id="stack-size" @bind-Value="itemModel.StackSize" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="max-durability">
|
||||||
|
Max durability:
|
||||||
|
<InputNumber id="max-durability" @bind-Value="itemModel.MaxDurability" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Enchant categories:
|
||||||
|
<div>
|
||||||
|
@foreach (var item in enchantCategories)
|
||||||
|
{
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" @onchange="@(e => OnEnchantCategoriesChange(item, e.Value))" checked="@(itemModel.EnchantCategories.Contains(item) ? "checked" : null)" />@item
|
||||||
|
</label>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Repair with:
|
||||||
|
<div>
|
||||||
|
@foreach (var item in repairWith)
|
||||||
|
{
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" @onchange="@(e => OnRepairWithChange(item, e.Value))" checked="@(itemModel.RepairWith.Contains(item) ? "checked" : null)" />@item
|
||||||
|
</label>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Current Item image:
|
||||||
|
@if (File.Exists($"{WebHostEnvironment.WebRootPath}/images/{itemModel.Name}.png"))
|
||||||
|
{
|
||||||
|
<img src="images/@(itemModel.Name).png" class="img-thumbnail" title="@itemModel.DisplayName" alt="@itemModel.DisplayName" style="max-width: 150px"/>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<img src="images/default.png" class="img-thumbnail" title="@itemModel.DisplayName" alt="@itemModel.DisplayName" style="max-width: 150px"/>
|
||||||
|
}
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Item image:
|
||||||
|
<InputFile OnChange="@LoadImage" accept=".png" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Accept Condition:
|
||||||
|
<InputCheckbox @bind-Value="itemModel.AcceptCondition" />
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</EditForm>
|
@ -0,0 +1,106 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
|
using TP_Blazor.Factories;
|
||||||
|
using TP_Blazor.Models;
|
||||||
|
using TP_Blazor.Services;
|
||||||
|
|
||||||
|
namespace TP_Blazor.Pages;
|
||||||
|
|
||||||
|
public partial class Edit
|
||||||
|
{
|
||||||
|
[Parameter]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
private List<string> enchantCategories = new List<string>() { "armor", "armor_head", "armor_chest", "weapon", "digger", "breakable", "vanishable" };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The current item model
|
||||||
|
/// </summary>
|
||||||
|
private ItemModel itemModel = new()
|
||||||
|
{
|
||||||
|
EnchantCategories = new List<string>(),
|
||||||
|
RepairWith = new List<string>()
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The default repair with.
|
||||||
|
/// </summary>
|
||||||
|
private List<string> repairWith = new List<string>() { "oak_planks", "spruce_planks", "birch_planks", "jungle_planks", "acacia_planks", "dark_oak_planks", "crimson_planks", "warped_planks" };
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
public IDataService DataService { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
public NavigationManager NavigationManager { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
public IWebHostEnvironment WebHostEnvironment { get; set; }
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
var item = await DataService.GetById(Id);
|
||||||
|
|
||||||
|
var fileContent = await File.ReadAllBytesAsync($"{WebHostEnvironment.WebRootPath}/images/default.png");
|
||||||
|
|
||||||
|
if (File.Exists($"{WebHostEnvironment.WebRootPath}/images/{itemModel.Name}.png"))
|
||||||
|
{
|
||||||
|
fileContent = await File.ReadAllBytesAsync($"{WebHostEnvironment.WebRootPath}/images/{item.Name}.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the model with the item
|
||||||
|
itemModel =ItemFactory.ToModel(item, fileContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void HandleValidSubmit()
|
||||||
|
{
|
||||||
|
await DataService.Update(Id, itemModel);
|
||||||
|
|
||||||
|
NavigationManager.NavigateTo("list");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadImage(InputFileChangeEventArgs e)
|
||||||
|
{
|
||||||
|
// Set the content of the image to the model
|
||||||
|
using (var memoryStream = new MemoryStream())
|
||||||
|
{
|
||||||
|
await e.File.OpenReadStream().CopyToAsync(memoryStream);
|
||||||
|
itemModel.ImageContent = memoryStream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnEnchantCategoriesChange(string item, object checkedValue)
|
||||||
|
{
|
||||||
|
if ((bool)checkedValue)
|
||||||
|
{
|
||||||
|
if (!itemModel.EnchantCategories.Contains(item))
|
||||||
|
{
|
||||||
|
itemModel.EnchantCategories.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemModel.EnchantCategories.Contains(item))
|
||||||
|
{
|
||||||
|
itemModel.EnchantCategories.Remove(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnRepairWithChange(string item, object checkedValue)
|
||||||
|
{
|
||||||
|
if ((bool)checkedValue)
|
||||||
|
{
|
||||||
|
if (!itemModel.RepairWith.Contains(item))
|
||||||
|
{
|
||||||
|
itemModel.RepairWith.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemModel.RepairWith.Contains(item))
|
||||||
|
{
|
||||||
|
itemModel.RepairWith.Remove(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,28 @@
|
|||||||
@page "/"
|
@page "/"
|
||||||
|
@using System.Globalization
|
||||||
|
@using TP_Blazor.Components
|
||||||
|
|
||||||
<PageTitle>Index</PageTitle>
|
<PageTitle>Index</PageTitle>
|
||||||
|
|
||||||
<h1>Hello, world!</h1>
|
<h1>Hello, world!</h1>
|
||||||
|
<p>
|
||||||
|
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
|
||||||
|
</p>
|
||||||
|
|
||||||
Welcome to your new app.
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
<SurveyPrompt Title="How is Blazor working for you?" />
|
<div class="card-header">
|
||||||
|
My templated Component Header
|
||||||
|
</div>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<div class="card-body">
|
||||||
|
<h4>Template Component Body</h4>
|
||||||
|
</div>
|
||||||
|
</CardBody>
|
||||||
|
<CardFooter>
|
||||||
|
<div class="card-footer">
|
||||||
|
template component Footer
|
||||||
|
</div>
|
||||||
|
</CardFooter>
|
||||||
|
</Card>
|
||||||
|
@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="btnTitle" xml:space="preserve">
|
||||||
|
<value>My Title</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
@ -0,0 +1,147 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="About" xml:space="preserve">
|
||||||
|
<value>à propos</value>
|
||||||
|
</data>
|
||||||
|
<data name="btnTitle" xml:space="preserve">
|
||||||
|
<value>Ajouter</value>
|
||||||
|
</data>
|
||||||
|
<data name="Header1" xml:space="preserve">
|
||||||
|
<value>Image</value>
|
||||||
|
</data>
|
||||||
|
<data name="Header2" xml:space="preserve">
|
||||||
|
<value>Nom</value>
|
||||||
|
</data>
|
||||||
|
<data name="Header3" xml:space="preserve">
|
||||||
|
<value>Taille</value>
|
||||||
|
</data>
|
||||||
|
<data name="MenueItem1" xml:space="preserve">
|
||||||
|
<value>Acceuil</value>
|
||||||
|
</data>
|
||||||
|
<data name="MenueItem2" xml:space="preserve">
|
||||||
|
<value>List</value>
|
||||||
|
</data>
|
||||||
|
<data name="MenueItem3" xml:space="preserve">
|
||||||
|
<value>Compteur</value>
|
||||||
|
</data>
|
||||||
|
<data name="Title" xml:space="preserve">
|
||||||
|
<value>Liste d'utilisateur</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
@ -0,0 +1,134 @@
|
|||||||
|
using Blazored.LocalStorage;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using TP_Blazor.Factories;
|
||||||
|
using TP_Blazor.Models;
|
||||||
|
|
||||||
|
namespace TP_Blazor.Services;
|
||||||
|
|
||||||
|
public class DataLocalService:IDataService
|
||||||
|
{
|
||||||
|
private readonly HttpClient _httpClient;
|
||||||
|
private readonly ILocalStorageService _localStorageService;
|
||||||
|
private readonly NavigationManager _navigationManager;
|
||||||
|
private readonly IWebHostEnvironment _webHostEnvironment;
|
||||||
|
|
||||||
|
public DataLocalService(HttpClient httpClient, ILocalStorageService localStorageService, NavigationManager navigationManager, IWebHostEnvironment webHostEnvironment)
|
||||||
|
{
|
||||||
|
_httpClient = httpClient;
|
||||||
|
_localStorageService = localStorageService;
|
||||||
|
_navigationManager = navigationManager;
|
||||||
|
_webHostEnvironment = webHostEnvironment;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Add(ItemModel item)
|
||||||
|
{
|
||||||
|
var currentItems = await _localStorageService.GetItemAsync<List<Item>>("data");
|
||||||
|
item.Id = currentItems.Max(s=>s.Id)+1;
|
||||||
|
// currentItems.Add(new Item
|
||||||
|
// {
|
||||||
|
// Id = item.Id,
|
||||||
|
// Name = item.Name,
|
||||||
|
// DisplayName = item.DisplayName,
|
||||||
|
// RepairWith = item.RepairWith,
|
||||||
|
// EnchantCategories = item.EnchantCategories,
|
||||||
|
// MaxDurability = item.MaxDurability,
|
||||||
|
// StackSize = item.StackSize,
|
||||||
|
// CreatedDate = DateTime.Now
|
||||||
|
// });
|
||||||
|
currentItems.Add(ItemFactory.Create(item));
|
||||||
|
|
||||||
|
var imagePathsInfo = new DirectoryInfo(Path.Combine($"{_webHostEnvironment.ContentRootPath}/images"));
|
||||||
|
if (!imagePathsInfo.Exists)
|
||||||
|
{
|
||||||
|
imagePathsInfo.Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileName = new FileInfo($"{imagePathsInfo}/{item.Name}.png");
|
||||||
|
await File.WriteAllBytesAsync(fileName.FullName, item.ImageContent);
|
||||||
|
await _localStorageService.SetItemAsync("data", currentItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Count()
|
||||||
|
{
|
||||||
|
var currentItems = _localStorageService.GetItemAsync<Item[]>("data");
|
||||||
|
if (currentItems== null)
|
||||||
|
{
|
||||||
|
var originalItems = _httpClient.GetFromJsonAsync<Item[]>($"f{_navigationManager.BaseUri}ake-data.json");
|
||||||
|
await _localStorageService.SetItemAsync("data", originalItems);
|
||||||
|
}
|
||||||
|
return (await _localStorageService.GetItemAsync<Item[]>("data")).Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Item>> List(int page, int pageSize)
|
||||||
|
{
|
||||||
|
var currentItems = _localStorageService.GetItemAsync<Item[]>("data");
|
||||||
|
if (currentItems == null)
|
||||||
|
{
|
||||||
|
var originalItems = _httpClient.GetFromJsonAsync<Item[]>($"f{_navigationManager.BaseUri}ake-data.json");
|
||||||
|
_localStorageService.SetItemAsync("data", originalItems);
|
||||||
|
}
|
||||||
|
return (await _localStorageService.GetItemAsync<Item[]>("data")).Skip((page-1)*pageSize).Take(pageSize).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Item> GetById(int id)
|
||||||
|
{
|
||||||
|
var currentItems =await _localStorageService.GetItemAsync<List<Item>>("data");
|
||||||
|
var item = currentItems.FirstOrDefault(s => s.Id == id);
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Item with id {id} not found");
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Update(int id, ItemModel item)
|
||||||
|
{
|
||||||
|
var currentItems = await _localStorageService.GetItemAsync<List<Item>>("data");
|
||||||
|
var itemToUpdate = currentItems.FirstOrDefault(s => s.Id == id);
|
||||||
|
|
||||||
|
if (itemToUpdate == null)
|
||||||
|
{
|
||||||
|
throw new Exception($"Item with id {id} not found");
|
||||||
|
}
|
||||||
|
var imagePathsInfo = new DirectoryInfo($"{_webHostEnvironment.ContentRootPath}/images");
|
||||||
|
if (!imagePathsInfo.Exists)
|
||||||
|
{
|
||||||
|
imagePathsInfo.Create();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemToUpdate.Name != item.Name)
|
||||||
|
{
|
||||||
|
var oldFileName = new FileInfo($"{imagePathsInfo}/{itemToUpdate.Name}.png");
|
||||||
|
if (oldFileName.Exists)
|
||||||
|
{
|
||||||
|
oldFileName.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileName = new FileInfo($"{imagePathsInfo}/{item.Name}.png");
|
||||||
|
await File.WriteAllBytesAsync(fileName.FullName, item.ImageContent);
|
||||||
|
// itemToUpdate.Name = item.Name;
|
||||||
|
// itemToUpdate.DisplayName = item.DisplayName;
|
||||||
|
// itemToUpdate.RepairWith = item.RepairWith;
|
||||||
|
// itemToUpdate.EnchantCategories = item.EnchantCategories;
|
||||||
|
// itemToUpdate.MaxDurability = item.MaxDurability;
|
||||||
|
// itemToUpdate.StackSize = item.StackSize;
|
||||||
|
// itemToUpdate.UpdatedDate = DateTime.Now;
|
||||||
|
ItemFactory.Update(itemToUpdate, item);
|
||||||
|
await _localStorageService.SetItemAsync("data", currentItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(int id)
|
||||||
|
{
|
||||||
|
var currentItems =await _localStorageService.GetItemAsync<List<Item>>("data");
|
||||||
|
var itemToDelete = currentItems.FirstOrDefault(s => s.Id == id);
|
||||||
|
currentItems.Remove(itemToDelete);
|
||||||
|
var imagePathsInfo = new DirectoryInfo($"{_webHostEnvironment.ContentRootPath}/images");
|
||||||
|
var fileName = new FileInfo($"{imagePathsInfo}/{itemToDelete.Name}.png");
|
||||||
|
if (fileName.Exists)
|
||||||
|
{
|
||||||
|
File.Delete(fileName.FullName);
|
||||||
|
}
|
||||||
|
await _localStorageService.SetItemAsync("data", currentItems);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
using TP_Blazor.Models;
|
||||||
|
|
||||||
|
namespace TP_Blazor.Services;
|
||||||
|
|
||||||
|
public interface IDataService
|
||||||
|
{
|
||||||
|
public Task Add(ItemModel item);
|
||||||
|
Task<int> Count();
|
||||||
|
Task<List<Item>> List(int page, int pageSize);
|
||||||
|
Task<Item> GetById(int id);
|
||||||
|
Task Update(int id,ItemModel item);
|
||||||
|
Task Delete(int id);
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
@using System.Globalization
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<label>
|
||||||
|
Select your locale:
|
||||||
|
<select @bind="Culture">
|
||||||
|
@foreach (var culture in supportedCultures)
|
||||||
|
{
|
||||||
|
<option value="@culture">@culture.DisplayName</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</p>
|
@ -0,0 +1,32 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace TP_Blazor.Shared;
|
||||||
|
|
||||||
|
public partial class CultureSelector
|
||||||
|
{
|
||||||
|
private CultureInfo[] supportedCultures = new[]
|
||||||
|
{
|
||||||
|
new CultureInfo("en-US"),
|
||||||
|
new CultureInfo("fr-FR")
|
||||||
|
};
|
||||||
|
|
||||||
|
private CultureInfo Culture
|
||||||
|
{
|
||||||
|
get => CultureInfo.CurrentCulture;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (CultureInfo.CurrentUICulture == value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var culture = value.Name.ToLower(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
var uri = new Uri(this.NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
|
||||||
|
var query = $"?culture={Uri.EscapeDataString(culture)}&" + $"redirectUri={Uri.EscapeDataString(uri)}";
|
||||||
|
|
||||||
|
// Redirect the user to the culture controller to set the cookie
|
||||||
|
this.NavigationManager.NavigateTo("/Culture/SetCulture" + query, forceLoad: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
Loading…
Reference in new issue