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"
|
||||
}
|
||||
]
|
||||
}
|
@ -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 "/"
|
||||
@using System.Globalization
|
||||
@using TP_Blazor.Components
|
||||
|
||||
<PageTitle>Index</PageTitle>
|
||||
|
||||
<h1>Hello, world!</h1>
|
||||
<p>
|
||||
<b>CurrentCulture</b>: @CultureInfo.CurrentCulture
|
||||
</p>
|
||||
|
||||
Welcome to your new app.
|
||||
|
||||
<SurveyPrompt Title="How is Blazor working for you?" />
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<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