RobotNet/RobotNet.WebApp/Maps/Components/Element/ElementImage.razor
2025-10-15 15:15:53 +07:00

188 lines
7.6 KiB
Plaintext

@using System.Net.Http.Headers
@inject IJSRuntime JSRuntime
@inject ISnackbar Snackbar
@inject IHttpClientFactory HttpClientFactory
<div class="d-flex w-100 h-100 flex-row justify-content-around">
<div class="d-flex flex-column w-50">
<div class="d-flex flex-row m-2 align-items-center justify-content-between">
<MudText Typo="Typo.h6">Open</MudText>
<div class="d-flex flex-row">
<MudIconButton Class="me-3" Size="Size.Small" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Download" Color="Color.Primary" Disabled="@Disable" OnClick="@(async () => await DownloadImage(true))" />
<MudIconButton Class="me-3" Size="Size.Small" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Upload" Color="Color.Primary" Disabled="@Disable" OnClick="(() => OpenUpdateElementImage(true))" />
</div>
</div>
<div class="element-item">
<img src="@imageOpenSrc" alt="element model image" onerror="this.onerror=null; this.src='/images/Image-not-found.png';" />
</div>
</div>
<div class="d-flex flex-column w-50">
<div class="d-flex flex-row m-2 align-items-center justify-content-between">
<MudText Typo="Typo.h6">Close</MudText>
<div class="d-flex flex-row">
<MudIconButton Class="me-3" Size="Size.Small" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Download" Color="Color.Primary" Disabled="@Disable" OnClick="@(async () => await DownloadImage(true))" />
<MudIconButton Class="me-3" Size="Size.Small" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Upload" Color="Color.Primary" Disabled="@Disable" OnClick="(() => OpenUpdateElementImage(false))" />
</div>
</div>
<div class="element-item">
<img src="@imageCloseSrc" alt="element model image" onerror="this.onerror=null; this.src='/images/Image-not-found.png';" />
</div>
</div>
</div>
<MudDialog @bind-Visible="@IsUpdateElementImageVisable">
<TitleContent>
<MudText Typo="Typo.h6">
Update ElementModel's Image
</MudText>
</TitleContent>
<DialogContent>
<div class="d-flex flex-column w-100 h-100 px-3">
<div class="d-flex flex-row mb-2">
<InputFile id="fileElementImageCreate" OnChange="ElementImageChanged" accept=".png" hidden />
<MudButton HtmlTag="label"
Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.CloudUpload"
for="fileElementImageCreate">
Element Model Image
</MudButton>
</div>
<div class="d-flex mb-2">
<div class="element-update-item">
<img alt="Element Model Image" src="@ImagePreview" style="image-rendering: pixelated;" />
</div>
</div>
</div>
</DialogContent>
<DialogActions>
<MudButton OnClick="@(() => IsUpdateElementImageVisable = false)" Variant="Variant.Filled">Cancel</MudButton>
<MudButton Color="Color.Primary" OnClick="UpdateElementModelImage" Variant="Variant.Filled">Update</MudButton>
</DialogActions>
</MudDialog>
@code {
private bool Disable = true;
private string imageOpenSrc = "/images/Image-not-found.png";
private string imageCloseSrc = "/images/Image-not-found.png";
private string ElementModelName = "Element Model preview";
private Guid ElementModelId = Guid.Empty;
private string ImagePreview = "";
private IBrowserFile? ElementImageChange;
private bool IsUpdateElementImageVisable;
private bool IsOpen;
private HttpClient Http = default!;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (!firstRender) return;
Http = HttpClientFactory.CreateClient("MapManagerAPI");
}
public void SetElementModel(ElementModelDto? model)
{
if (model is null)
{
Disable = true;
ElementModelName = "Element Model preview";
imageOpenSrc = "/images/Image-not-found.png";
imageCloseSrc = "/images/Image-not-found.png";
ElementModelId = Guid.Empty;
}
else
{
imageOpenSrc = $"{Http.BaseAddress}api/images/elementmodel/{model.Id}?IsOpen=true&t={DateTime.Now}";
imageCloseSrc = $"{Http.BaseAddress}api/images/elementmodel/{model.Id}?IsOpen=false&t={DateTime.Now}";
ElementModelName = model.Name;
ElementModelId = model.Id;
Disable = false;
}
StateHasChanged();
}
private async Task DownloadImage(bool isOpen)
{
try
{
var response = await Http.GetAsync(isOpen ? imageOpenSrc : imageCloseSrc);
if (response.IsSuccessStatusCode)
{
var fileBytes = await response.Content.ReadAsByteArrayAsync();
var base64Data = Convert.ToBase64String(fileBytes);
var mimeType = "image/png";
var url = $"data:{mimeType};base64,{base64Data}";
await JSRuntime.InvokeVoidAsync("DownloadImage", base64Data, $"{ElementModelName}-{(isOpen ? "O" : "C")}.png");
}
else Snackbar.Add("Không thể tải ảnh robot", Severity.Warning);
}
catch (Exception ex)
{
Snackbar.Add($"Không thể tải ảnh robot: {ex.Message}", Severity.Warning);
}
}
private void OpenUpdateElementImage(bool isOpen)
{
IsOpen = isOpen;
ImagePreview = isOpen ? imageOpenSrc : imageCloseSrc;
ElementImageChange = null;
IsUpdateElementImageVisable = true;
StateHasChanged();
}
public async Task<string> UploadMedia(IBrowserFile file)
{
var path = Path.Combine(Path.GetTempPath(), ElementModelName);
await using var fs = new FileStream(path, FileMode.Create);
await file.OpenReadStream(file.Size).CopyToAsync(fs);
var bytes = new byte[file.Size];
fs.Position = 0;
await fs.ReadAsync(bytes);
fs.Close();
File.Delete(path);
return $"data:{file.ContentType};base64,{Convert.ToBase64String(bytes)}";
}
private async Task ElementImageChanged(InputFileChangeEventArgs e)
{
ElementImageChange = e.File;
if (ElementImageChange is not null)
{
ImagePreview = await UploadMedia(ElementImageChange);
StateHasChanged();
}
}
private async Task UpdateElementModelImage()
{
if (ElementImageChange is null) return;
using var content = new MultipartFormDataContent();
var fileContent = new StreamContent(ElementImageChange.OpenReadStream());
fileContent.Headers.ContentType = new MediaTypeHeaderValue(ElementImageChange.ContentType);
content.Add(fileContent, "image", ElementImageChange.Name);
var result = await (await Http.PutAsync($"api/ElementModels/{(IsOpen ? "openimage" : "closeimage")}/{ElementModelId}", content)).Content.ReadFromJsonAsync<MessageResult>();
if (result is null) Snackbar.Add("Lỗi giao tiếp với hệ thống", Severity.Error);
else if (!result.IsSuccess) Snackbar.Add(result.Message ?? "Lỗi chưa xác định.", Severity.Error);
else
{
if (IsOpen) imageOpenSrc = ImagePreview;
else imageCloseSrc = ImagePreview;
IsUpdateElementImageVisable = false;
Snackbar.Add("Thay đổi thành công", Severity.Success);
}
StateHasChanged();
}
}