Add code to upload machine photos as well as edit or view details about them.

This commit is contained in:
2020-05-31 03:43:56 +01:00
parent 556c5b2062
commit 0310fe1b31
32 changed files with 4388 additions and 1567 deletions

View File

@@ -0,0 +1,856 @@
@{
/******************************************************************************
// MARECHAI: Master repository of computing history artifacts information
// ----------------------------------------------------------------------------
//
// Filename : Details.cshtml
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// --[ Description ] ----------------------------------------------------------
//
// Admin view details
//
// --[ License ] --------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2003-2020 Natalia Portillo
*******************************************************************************/
}
@page "/admin/machines/photo/create/{MachineId:int}"
@using Marechai.Database
@using Marechai.Database.Models
@inherits OwningComponentBase<MachinePhotosService>
@inject IStringLocalizer<MachinePhotosService> L
@inject NavigationManager NavigationManager
@inject LicensesService LicensesService
@inject IFileReaderService FileReaderService;
@inject MachinesService MachinesService;
@inject Microsoft.AspNetCore.Identity.UserManager<ApplicationUser> UserManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IWebHostEnvironment Host
@attribute [Authorize(Roles = "UberAdmin, Admin")]
@if (!_loaded)
{
<p align="center">@L["Loading..."]</p>
return;
}
<h3>@string.Format(L["Upload photo for machine {0} manufactured by {1}"], _machine.Name, _machine.Company)</h3>
<hr />
@if(!_uploaded)
{
@if(!_uploading)
{
<FieldLabel>@L["Choose photo file"]</FieldLabel>
<input type="file" @ref=_inputUpload /><br/>
<Field>
<FieldLabel>@L["License"]</FieldLabel>
<Select TValue="int" @bind-SelectedValue="@_licenseId">
@foreach (var license in _licenses)
{
<SelectItem TValue="int" Value="@license.Id">@license.Name</SelectItem>
}
</Select>
</Field>
<Field>
<FieldLabel>@L["Source URL"]</FieldLabel>
<Check TValue="bool" @bind-Checked="@_unknownSource">@L["Unknown (source url)"]</Check>
@if (!_unknownSource)
{
<Validation Validator="@ValidateSource">
<TextEdit @bind-Text="@_sourceUrl">
<Feedback>
<ValidationError>@L["Please enter a valid source URL."]</ValidationError>
</Feedback>
</TextEdit>
</Validation>
}
</Field>
<div>TODO: Put legal disclaimer here</div>
<Button Color="Color.Success" Clicked="@UploadFile" Disabled="@_uploading">@L["Upload"]</Button><br/>
}
else
{
@L["Uploading..."]
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: @(_progressValue)%;" aria-valuenow="@_progressValue" aria-valuemin="0" aria-valuemax="100">@($"{_progressValue:F2}")%</div>
</div>
}
@if(_uploadError)
{
<span class="text-danger">@_uploadErrorMessage</span>
}
}
else
{
<h5>@string.Format(L["Image format recognized as {0}"], _imageFormat)</h5>
@if (_allFinished)
{
<span class="text-success">@L["All finished!"]</span>
<a class="btn btn-success" href="/admin/machines/photo/details/@_model.Id">@L["Go to photo details"]</a>
}
<table>
<tr>
<td>
@L["Extracting Exif information..."]
</td>
<td>
@if(_extractExif == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_extractExif == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
</tr>
<tr>
<td>
@L["Moving file to proper place..."]
</td>
<td>
@if(_moveFile == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_moveFile == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_moveFile == true)
{
<a href="/assets/photos/machines/originals/@($"{_model.Id}{_model.OriginalExtension}")" target="_blank">
<img src="/assets/photos/machines/originals/@($"{_model.Id}{_model.OriginalExtension}")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG with an HD resolution (thumbnail)..."]
</td>
<td>
@if(_convertJpegHdTh == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJpegHdTh == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJpegHdTh == true)
{
<a href="@($"/assets/photos/machines/thumbs/jpeg/hd/{_model.Id}.jpg")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/jpeg/hd/{_model.Id}.jpg")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG with a 1440p resolution (thumbnail)..."]
</td>
<td>
@if(_convertJpeg1440Th == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJpeg1440Th == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJpeg1440Th == true)
{
<a href="@($"/assets/photos/machines/thumbs/jpeg/1440p/{_model.Id}.jpg")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/jpeg/1440p/{_model.Id}.jpg")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG with a 4K resolution (thumbnail)..."]
</td>
<td>
@if(_convertJpeg4kTh == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJpeg4kTh == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJpeg4kTh == true)
{
<a href="@($"/assets/photos/machines/thumbs/jpeg/4k/{_model.Id}.jpg")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/jpeg/4k/{_model.Id}.jpg")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG with an HD resolution..."]
</td>
<td>
@if(_convertJpegHd == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJpegHd == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJpegHd == true)
{
<a href="@($"/assets/photos/machines/jpeg/hd/{_model.Id}.jpg")" target="_blank">
<img src="@($"/assets/photos/machines/jpeg/hd/{_model.Id}.jpg")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG with a 1440p resolution..."]
</td>
<td>
@if(_convertJpeg1440 == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJpeg1440 == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJpeg1440 == true)
{
<a href="@($"/assets/photos/machines/jpeg/1440p/{_model.Id}.jpg")" target="_blank">
<img src="@($"/assets/photos/machines/jpeg/1440p/{_model.Id}.jpg")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG with a 4K resolution..."]
</td>
<td>
@if(_convertJpeg4k == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJpeg4k == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJpeg4k == true)
{
<a href="@($"/assets/photos/machines/jpeg/4k/{_model.Id}.jpg")" target="_blank">
<img src="@($"/assets/photos/machines/jpeg/4k/{_model.Id}.jpg")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG2000 with an HD resolution (thumbnail)..."]
</td>
<td>
@if(_convertJp2kHdTh == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJp2kHdTh == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJp2kHdTh == true)
{
<a href="@($"/assets/photos/machines/thumbs/jp2k/hd/{_model.Id}.jp2")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/jp2k/hd/{_model.Id}.jp2")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG2000 with a 1440p resolution (thumbnail)..."]
</td>
<td>
@if(_convertJp2k1440Th == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJp2k1440Th == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJp2k1440Th == true)
{
<a href="@($"/assets/photos/machines/thumbs/jp2k/1440p/{_model.Id}.jp2")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/jp2k/1440p/{_model.Id}.jp2")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG2000 with a 4K resolution (thumbnail)..."]
</td>
<td>
@if(_convertJp2k4kTh == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJp2k4kTh == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJp2k4kTh == true)
{
<a href="@($"/assets/photos/machines/thumbs/jp2k/4k/{_model.Id}.jp2")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/jp2k/4k/{_model.Id}.jp2")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG2000 with an HD resolution..."]
</td>
<td>
@if(_convertJp2kHd == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJp2kHd == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJp2kHd == true)
{
<a href="@($"/assets/photos/machines/jp2k/hd/{_model.Id}.jp2")" target="_blank">
<img src="@($"/assets/photos/machines/jp2k/hd/{_model.Id}.jp2")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG2000 with a 1440p resolution..."]
</td>
<td>
@if(_convertJp2k1440 == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJp2k1440 == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJp2k1440 == true)
{
<a href="@($"/assets/photos/machines/jp2k/1440p/{_model.Id}.jp2")" target="_blank">
<img src="@($"/assets/photos/machines/jp2k/1440p/{_model.Id}.jp2")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to JPEG2000 with a 4K resolution..."]
</td>
<td>
@if(_convertJp2k4k == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertJp2k4k == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertJp2k4k == true)
{
<a href="@($"/assets/photos/machines/jp2k/4k/{_model.Id}.jp2")" target="_blank">
<img src="@($"/assets/photos/machines/jp2k/4k/{_model.Id}.jp2")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to WebP with an HD resolution (thumbnail)..."]
</td>
<td>
@if(_convertWebpHdTh == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertWebpHdTh == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertWebpHdTh == true)
{
<a href="@($"/assets/photos/machines/thumbs/webp/hd/{_model.Id}.webp")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/webp/hd/{_model.Id}.webp")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to WebP with a 1440p resolution (thumbnail)..."]
</td>
<td>
@if(_convertWebp1440Th == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertWebp1440Th == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertWebp1440Th == true)
{
<a href="@($"/assets/photos/machines/thumbs/webp/1440p/{_model.Id}.webp")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/webp/1440p/{_model.Id}.webp")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to WebP with a 4K resolution (thumbnail)..."]
</td>
<td>
@if(_convertWebp4kTh == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertWebp4kTh == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertWebp4kTh == true)
{
<a href="@($"/assets/photos/machines/thumbs/webp/4k/{_model.Id}.webp")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/webp/4k/{_model.Id}.webp")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to WebP with an HD resolution..."]
</td>
<td>
@if(_convertWebpHd == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertWebpHd == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertWebpHd == true)
{
<a href="@($"/assets/photos/machines/webp/hd/{_model.Id}.webp")" target="_blank">
<img src="@($"/assets/photos/machines/webp/hd/{_model.Id}.webp")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to WebP with a 1440p resolution..."]
</td>
<td>
@if(_convertWebp1440 == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertWebp1440 == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertWebp1440 == true)
{
<a href="@($"/assets/photos/machines/webp/1440p/{_model.Id}.webp")" target="_blank">
<img src="@($"/assets/photos/machines/webp/1440p/{_model.Id}.webp")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to WebP with a 4K resolution..."]
</td>
<td>
@if(_convertWebp4k == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertWebp4k == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertWebp4k == true)
{
<a href="@($"/assets/photos/machines/webp/4k/{_model.Id}.webp")" target="_blank">
<img src="@($"/assets/photos/machines/webp/4k/{_model.Id}.webp")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to HEIF with an HD resolution (thumbnail)..."]
</td>
<td>
@if(_convertHeifHdTh == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertHeifHdTh == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertHeifHdTh == true)
{
<a href="@($"/assets/photos/machines/thumbs/heif/hd/{_model.Id}.heic")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/heif/hd/{_model.Id}.heic")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to HEIF with a 1440p resolution (thumbnail)..."]
</td>
<td>
@if(_convertHeif1440Th == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertHeif1440Th == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertHeif1440Th == true)
{
<a href="@($"/assets/photos/machines/thumbs/heif/1440p/{_model.Id}.heic")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/heif/1440p/{_model.Id}.heic")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to HEIF with a 4K resolution (thumbnail)..."]
</td>
<td>
@if(_convertHeif4kTh == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertHeif4kTh == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertHeif4kTh == true)
{
<a href="@($"/assets/photos/machines/thumbs/heif/4k/{_model.Id}.heic")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/heif/4k/{_model.Id}.heic")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to HEIF with an HD resolution..."]
</td>
<td>
@if(_convertHeifHd == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertHeifHd == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertHeifHd == true)
{
<a href="@($"/assets/photos/machines/heif/hd/{_model.Id}.heic")" target="_blank">
<img src="@($"/assets/photos/machines/heif/hd/{_model.Id}.heic")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to HEIF with a 1440p resolution..."]
</td>
<td>
@if(_convertHeif1440 == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertHeif1440 == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertHeif1440 == true)
{
<a href="@($"/assets/photos/machines/heif/1440p/{_model.Id}.heic")" target="_blank">
<img src="@($"/assets/photos/machines/heif/1440p/{_model.Id}.heic")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to HEIF with a 4K resolution..."]
</td>
<td>
@if(_convertHeif4k == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertHeif4k == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertHeif4k == true)
{
<a href="@($"/assets/photos/machines/heif/4k/{_model.Id}.heic")" target="_blank">
<img src="@($"/assets/photos/machines/heif/4k/{_model.Id}.heic")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to AV1F with an HD resolution (thumbnail)..."]
</td>
<td>
@if(_convertAvifHdTh == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertAvifHdTh == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertAvifHdTh == true)
{
<a href="@($"/assets/photos/machines/thumbs/avif/hd/{_model.Id}.avif")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/avif/hd/{_model.Id}.avif")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to AV1F with a 1440p resolution (thumbnail)..."]
</td>
<td>
@if(_convertAvif1440Th == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertAvif1440Th == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertAvif1440Th == true)
{
<a href="@($"/assets/photos/machines/thumbs/avif/1440p/{_model.Id}.avif")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/avif/1440p/{_model.Id}.avif")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to AV1F with a 4K resolution (thumbnail)..."]
</td>
<td>
@if(_convertAvif4kTh == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertAvif4kTh == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertAvif4kTh == true)
{
<a href="@($"/assets/photos/machines/thumbs/avif/4k/{_model.Id}.avif")" target="_blank">
<img src="@($"/assets/photos/machines/thumbs/avif/4k/{_model.Id}.avif")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to AV1F with an HD resolution..."]
</td>
<td>
@if(_convertAvifHd == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertAvifHd == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertAvifHd == true)
{
<a href="@($"/assets/photos/machines/avif/hd/{_model.Id}.avif")" target="_blank">
<img src="@($"/assets/photos/machines/avif/hd/{_model.Id}.avif")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to AV1F with a 1440p resolution..."]
</td>
<td>
@if(_convertAvif1440 == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertAvif1440 == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertAvif1440 == true)
{
<a href="@($"/assets/photos/machines/avif/1440p/{_model.Id}.avif")" target="_blank">
<img src="@($"/assets/photos/machines/avif/1440p/{_model.Id}.avif")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Converting photo to AV1F with a 4K resolution..."]
</td>
<td>
@if(_convertAvif4k == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_convertAvif4k == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
@if(_convertAvif4k == true)
{
<a href="@($"/assets/photos/machines/avif/4k/{_model.Id}.avif")" target="_blank">
<img src="@($"/assets/photos/machines/avif/4k/{_model.Id}.avif")" alt="" height="auto" width="auto" style="max-height: 256px; max-width: 256px" />
</a>
}
</td>
</tr>
<tr>
<td>
@L["Adding photo to database..."]
</td>
<td>
@if(_addToDatabase == true)
{
<span class="text-success">@L["OK!"]</span>
}
else if(_addToDatabase == false)
{
<span class="text-danger">@L["Error!"]</span>
}
</td>
<td>
</td>
</tr>
</table>
}

View File

@@ -0,0 +1,614 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Blazor.FileReader;
using Blazorise;
using Marechai.Helpers;
using Marechai.Shared;
using Marechai.ViewModels;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
namespace Marechai.Pages.Admin.Details
{
public partial class CreateMachinePhoto
{
const int _maxUploadSize = 25 * 1048576;
bool? _addToDatabase;
bool _allFinished;
AuthenticationState _authState;
bool? _convertAvif1440;
bool? _convertAvif1440Th;
bool? _convertAvif4k;
bool? _convertAvif4kTh;
bool? _convertAvifHd;
bool? _convertAvifHdTh;
bool? _convertHeif1440;
bool? _convertHeif1440Th;
bool? _convertHeif4k;
bool? _convertHeif4kTh;
bool? _convertHeifHd;
bool? _convertHeifHdTh;
bool? _convertJp2k1440;
bool? _convertJp2k1440Th;
bool? _convertJp2k4k;
bool? _convertJp2k4kTh;
bool? _convertJp2kHd;
bool? _convertJp2kHdTh;
bool? _convertJpeg1440;
bool? _convertJpeg1440Th;
bool? _convertJpeg4k;
bool? _convertJpeg4kTh;
bool? _convertJpegHd;
bool? _convertJpegHdTh;
bool? _convertWebp1440;
bool? _convertWebp1440Th;
bool? _convertWebp4k;
bool? _convertWebp4kTh;
bool? _convertWebpHd;
bool? _convertWebpHdTh;
bool? _extractExif;
string _imageFormat;
ElementReference _inputUpload;
int _licenseId;
List<Database.Models.License> _licenses;
bool _loaded;
MachineViewModel _machine;
MachinePhotoViewModel _model;
bool? _moveFile;
double _progressValue;
string _sourceUrl;
bool _unknownSource;
bool _uploaded;
bool _uploadError;
string _uploadErrorMessage;
bool _uploading;
[Parameter]
public Guid Id { get; set; }
[Parameter]
public int MachineId { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if(_loaded)
return;
_licenses = await LicensesService.GetAsync();
_machine = await MachinesService.GetAsync(MachineId);
_authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
if(_machine is null)
NavigationManager.ToBaseRelativePath("admin/machines");
_loaded = true;
StateHasChanged();
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
async Task UploadFile()
{
if(!_unknownSource &&
string.IsNullOrWhiteSpace(_sourceUrl))
return;
if(_licenseId == 0)
{
_uploadError = true;
_uploadErrorMessage = L["Please choose a valid license."];
return;
}
var processExiftool = new Process
{
StartInfo =
{
FileName = "exiftool", CreateNoWindow = true, RedirectStandardError = true,
RedirectStandardOutput = true
}
};
var processIdentify = new Process
{
StartInfo =
{
FileName = "identify", CreateNoWindow = true, RedirectStandardError = true,
RedirectStandardOutput = true
}
};
var processConvert = new Process
{
StartInfo =
{
FileName = "convert", CreateNoWindow = true, RedirectStandardError = true,
RedirectStandardOutput = true
}
};
string identifyOutput;
string convertOutput;
string exiftoolOutput;
try
{
processIdentify.Start();
identifyOutput = await processIdentify.StandardOutput.ReadToEndAsync();
processIdentify.WaitForExit();
processConvert.Start();
convertOutput = await processConvert.StandardOutput.ReadToEndAsync();
processConvert.WaitForExit();
processExiftool.Start();
exiftoolOutput = await processExiftool.StandardOutput.ReadToEndAsync();
processExiftool.WaitForExit();
}
catch(Exception)
{
_uploadError = true;
_uploadErrorMessage = L["Cannot run ImageMagick please contact the administrator."];
return;
}
IFileReference file = (await FileReaderService.CreateReference(_inputUpload).EnumerateFilesAsync()).
FirstOrDefault();
if(file is null)
return;
IFileInfo fileInfo = await file.ReadFileInfoAsync();
if(fileInfo.Size > _maxUploadSize)
{
_uploadError = true;
_uploadErrorMessage = L["The selected file is too big."];
return;
}
string tmpPath = Path.GetTempFileName();
FileStream outFs;
try
{
outFs = new FileStream(tmpPath, FileMode.Open, FileAccess.ReadWrite);
}
catch(Exception)
{
_uploadError = true;
_uploadErrorMessage = L["There was an error uploading the file."];
return;
}
_uploading = true;
await using AsyncDisposableStream fs = await file.OpenReadAsync();
byte[] buffer = new byte[20480];
try
{
double lastProgress = 0;
int count;
while((count = await fs.ReadAsync(buffer, 0, buffer.Length)) != 0)
{
await outFs.WriteAsync(buffer, 0, count);
double progress = ((double)fs.Position * 100) / fs.Length;
if(!(progress > lastProgress + 0.01))
continue;
_progressValue = progress;
await InvokeAsync(StateHasChanged);
await Task.Yield();
lastProgress = progress;
}
}
catch(Exception)
{
_uploading = false;
_uploadError = true;
_uploadErrorMessage = L["There was an error uploading the file."];
return;
}
outFs.Close();
_uploading = false;
await InvokeAsync(StateHasChanged);
await Task.Yield();
processIdentify = new Process
{
StartInfo =
{
FileName = "identify", CreateNoWindow = true, RedirectStandardError = true,
RedirectStandardOutput = true, ArgumentList =
{
tmpPath
}
}
};
processIdentify.Start();
identifyOutput = await processIdentify.StandardOutput.ReadToEndAsync();
processIdentify.WaitForExit();
if(processIdentify.ExitCode != 0 ||
string.IsNullOrWhiteSpace(identifyOutput))
{
_uploading = false;
_uploadError = true;
_uploadErrorMessage = L["The uploaded file was not recognized as an image."];
File.Delete(tmpPath);
return;
}
string[] pieces = identifyOutput.Substring(tmpPath.Length).
Split(" ", StringSplitOptions.RemoveEmptyEntries);
if(pieces.Length < 2)
{
_uploading = false;
_uploadError = true;
_uploadErrorMessage = L["The uploaded file was not recognized as an image."];
File.Delete(tmpPath);
return;
}
// TODO: Move this to Helpers, keep progress
string extension = ImageMagick.GetExtension(pieces[0]);
if(string.IsNullOrWhiteSpace(extension))
{
_uploading = false;
_uploadError = true;
_uploadErrorMessage = L["The uploaded file was not recognized as an image."];
File.Delete(tmpPath);
return;
}
_imageFormat = pieces[0];
_uploaded = true;
_model = new MachinePhotoViewModel
{
UserId = (await UserManager.GetUserAsync(_authState.User)).Id, MachineId = MachineId,
Id = Guid.NewGuid(), OriginalExtension = extension, UploadDate = DateTime.UtcNow,
Source = _unknownSource ? null : _sourceUrl, LicenseId = _licenseId
};
try
{
processExiftool = new Process
{
StartInfo =
{
FileName = "exiftool", CreateNoWindow = true, RedirectStandardError = true,
RedirectStandardOutput = true, ArgumentList =
{
"-n", "-json", tmpPath
}
}
};
processExiftool.Start();
exiftoolOutput = await processExiftool.StandardOutput.ReadToEndAsync();
processExiftool.WaitForExit();
Exif[] exif = JsonSerializer.Deserialize<Exif[]>(exiftoolOutput);
if(exif?.Length >= 1)
exif[0].ToViewModel(_model);
_extractExif = true;
}
catch(Exception)
{
_extractExif = false;
}
string originalFilePath = Path.Combine(Host.WebRootPath, "assets", "photos", "machines", "originals",
$"{_model.Id}{_model.OriginalExtension}");
try
{
File.Move(tmpPath, originalFilePath);
_moveFile = true;
}
catch(Exception)
{
_moveFile = false;
File.Delete(tmpPath);
return;
}
await Task.Yield();
await InvokeAsync(StateHasChanged);
var photos = new Photos();
photos.FinishedAll += OnFinishedAll;
photos.FinishedRenderingJpeg4k += OnFinishedRenderingJpeg4k;
photos.FinishedRenderingJpeg1440 += OnFinishedRenderingJpeg1440;
photos.FinishedRenderingJpegHd += OnFinishedRenderingJpegHd;
photos.FinishedRenderingJpeg4kThumbnail += OnFinishedRenderingJpeg4kThumbnail;
photos.FinishedRenderingJpeg1440Thumbnail += OnFinishedRenderingJpeg1440Thumbnail;
photos.FinishedRenderingJpegHdThumbnail += OnFinishedRenderingJpegHdThumbnail;
photos.FinishedRenderingJp2k4k += OnFinishedRenderingJp2k4k;
photos.FinishedRenderingJp2k1440 += OnFinishedRenderingJp2k1440;
photos.FinishedRenderingJp2kHd += OnFinishedRenderingJp2kHd;
photos.FinishedRenderingJp2k4kThumbnail += OnFinishedRenderingJp2k4kThumbnail;
photos.FinishedRenderingJp2k1440Thumbnail += OnFinishedRenderingJp2k1440Thumbnail;
photos.FinishedRenderingJp2kHdThumbnail += OnFinishedRenderingJp2kHdThumbnail;
photos.FinishedRenderingWebp4k += OnFinishedRenderingWebp4k;
photos.FinishedRenderingWebp1440 += OnFinishedRenderingWebp1440;
photos.FinishedRenderingWebpHd += OnFinishedRenderingWebpHd;
photos.FinishedRenderingWebp4kThumbnail += OnFinishedRenderingWebp4kThumbnail;
photos.FinishedRenderingWebp1440Thumbnail += OnFinishedRenderingWebp1440Thumbnail;
photos.FinishedRenderingWebpHdThumbnail += OnFinishedRenderingWebpHdThumbnail;
photos.FinishedRenderingHeif4k += OnFinishedRenderingHeif4k;
photos.FinishedRenderingHeif1440 += OnFinishedRenderingHeif1440;
photos.FinishedRenderingHeifHd += OnFinishedRenderingHeifHd;
photos.FinishedRenderingHeif4kThumbnail += OnFinishedRenderingHeif4kThumbnail;
photos.FinishedRenderingHeif1440Thumbnail += OnFinishedRenderingHeif1440Thumbnail;
photos.FinishedRenderingHeifHdThumbnail += OnFinishedRenderingHeifHdThumbnail;
photos.FinishedRenderingAvif4k += OnFinishedRenderingAvif4k;
photos.FinishedRenderingAvif1440 += OnFinishedRenderingAvif1440;
photos.FinishedRenderingAvifHd += OnFinishedRenderingAvifHd;
photos.FinishedRenderingAvif4kThumbnail += OnFinishedRenderingAvif4kThumbnail;
photos.FinishedRenderingAvif1440Thumbnail += OnFinishedRenderingAvif1440Thumbnail;
photos.FinishedRenderingAvifHdThumbnail += OnFinishedRenderingAvifHdThumbnail;
#pragma warning disable 4014
Task.Run(() => photos.ConversionWorker(Host.WebRootPath, _model.Id, originalFilePath, _imageFormat));
#pragma warning restore 4014
}
async Task OnFinishedRenderingJpeg4k(bool result)
{
_convertJpeg4k = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJpeg1440(bool result)
{
_convertJpeg1440 = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJpegHd(bool result)
{
_convertJpegHd = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJpeg4kThumbnail(bool result)
{
_convertJpeg4kTh = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJpeg1440Thumbnail(bool result)
{
_convertJpeg1440Th = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJpegHdThumbnail(bool result)
{
_convertJpegHdTh = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJp2k4k(bool result)
{
_convertJp2k4k = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJp2k1440(bool result)
{
_convertJp2k1440 = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJp2kHd(bool result)
{
_convertJp2kHd = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJp2k4kThumbnail(bool result)
{
_convertJp2k4kTh = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJp2k1440Thumbnail(bool result)
{
_convertJp2k1440Th = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingJp2kHdThumbnail(bool result)
{
_convertJp2kHdTh = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingWebp4k(bool result)
{
_convertWebp4k = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingWebp1440(bool result)
{
_convertWebp1440 = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingWebpHd(bool result)
{
_convertWebpHd = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingWebp4kThumbnail(bool result)
{
_convertWebp4kTh = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingWebp1440Thumbnail(bool result)
{
_convertWebp1440Th = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingWebpHdThumbnail(bool result)
{
_convertWebpHdTh = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingHeif4k(bool result)
{
_convertHeif4k = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingHeif1440(bool result)
{
_convertHeif1440 = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingHeifHd(bool result)
{
_convertHeifHd = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingHeif4kThumbnail(bool result)
{
_convertHeif4kTh = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingHeif1440Thumbnail(bool result)
{
_convertHeif1440Th = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingHeifHdThumbnail(bool result)
{
_convertHeifHdTh = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingAvif4k(bool result)
{
_convertAvif4k = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingAvif1440(bool result)
{
_convertAvif1440 = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingAvifHd(bool result)
{
_convertAvifHd = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingAvif4kThumbnail(bool result)
{
_convertAvif4kTh = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingAvif1440Thumbnail(bool result)
{
_convertAvif1440Th = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedRenderingAvifHdThumbnail(bool result)
{
_convertAvifHdTh = result;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
async Task OnFinishedAll(bool result)
{
try
{
await Service.CreateAsync(_model);
_addToDatabase = true;
}
catch(Exception e)
{
_addToDatabase = false;
Console.WriteLine(e);
throw;
}
_allFinished = true;
await Task.Yield();
await InvokeAsync(StateHasChanged);
}
void ValidateSource(ValidatorEventArgs e) =>
Validators.ValidateUrl(e, L["Source URL must be smaller than 255 characters."], 255);
}
}

View File

@@ -49,6 +49,7 @@
@inject StorageByMachineService StorageByMachineService
@inject ScreensByMachineService ScreensByMachineService
@inject ScreensService ScreensService
@inject MachinePhotosService MachinePhotosService
@attribute [Authorize(Roles = "UberAdmin, Admin")]
<h3>@L["Machine details"]</h3>
<hr />

View File

@@ -61,6 +61,7 @@ namespace Marechai.Pages.Admin.Details
List<StorageByMachineViewModel> _machineStorage;
MachineViewModel _model;
bool _noFamily;
List<Guid> _photos;
bool _prototype;
bool _savingCpu;
bool _savingGpu;
@@ -111,6 +112,7 @@ namespace Marechai.Pages.Admin.Details
_machineMemories = await MemoriesByMachineService.GetByMachine(Id);
_machineStorage = await StorageByMachineService.GetByMachine(Id);
_machineScreens = await ScreensByMachineService.GetByMachine(Id);
_photos = await MachinePhotosService.GetGuidsByMachineAsync(Id);
_editing = _creating || NavigationManager.ToBaseRelativePath(NavigationManager.Uri).ToLowerInvariant().
StartsWith("admin/machines/edit/",

View File

@@ -0,0 +1,769 @@
@{
/******************************************************************************
// MARECHAI: Master repository of computing history artifacts information
// ----------------------------------------------------------------------------
//
// Filename : Details.cshtml
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// --[ Description ] ----------------------------------------------------------
//
// Admin view details
//
// --[ License ] --------------------------------------------------------------
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
// Copyright © 2003-2020 Natalia Portillo
*******************************************************************************/
}
@page "/admin/machines/photo/details/{Id:guid}"
@page "/admin/machines/photo/edit/{Id:guid}"
@using Marechai.Database
@using Marechai.Database.Models
@inherits OwningComponentBase<MachinePhotosService>
@inject IStringLocalizer<MachinePhotosService> L
@inject NavigationManager NavigationManager
@inject LicensesService LicensesService
@inject Microsoft.AspNetCore.Identity.UserManager<ApplicationUser> UserManager
@attribute [Authorize(Roles = "UberAdmin, Admin")]
<h3>@L["Machine photo details"]</h3>
<hr />
@if (!_loaded)
{
<p align="center">@L["Loading..."]</p>
return;
}
<div>
<Field>
<FieldLabel>@L["Machine"]</FieldLabel>
<TextEdit Disabled="true" Text="@($"{_model.MachineCompanyName} - {_model.MachineName}")"/>
</Field>
<Field>
<FieldLabel>@L["Uploaded by"]</FieldLabel>
<TextEdit Disabled="true" Text="@($"{_user.UserName} <{_user.Email}>")"/>
</Field>
<Field>
<FieldLabel>@L["Uploaded date"]</FieldLabel>
<TextEdit Disabled="true" Text="@($"{_model.UploadDate}")"/>
</Field>
<Field>
<FieldLabel>@L["License"]</FieldLabel>
<Select Disabled="!_editing" TValue="int" @bind-SelectedValue="@_model.LicenseId">
@foreach (var license in _licenses)
{
<SelectItem TValue="int" Value="@license.Id">@license.Name</SelectItem>
}
</Select>
</Field>
@if (_editing || _model.Author != null)
{
<Field>
<FieldLabel>@L["Author"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownAuthor">@L["Unknown (author)"]</Check>
}
@if (!_editing ||
!_unknownSource)
{
<Validation Validator="@ValidateAuthor">
<TextEdit Disabled="!_editing" @bind-Text="@_model.Author">
<Feedback>
<ValidationError>@L["Please enter a valid author."]</ValidationError>
</Feedback>
</TextEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.Source != null)
{
<Field>
<FieldLabel>@L["Source URL"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownSource">@L["Unknown (source url)"]</Check>
}
@if (!_editing ||
!_unknownSource)
{
<Validation Validator="@ValidateSource">
<TextEdit Disabled="!_editing" @bind-Text="@_model.Source">
<Feedback>
<ValidationError>@L["Please enter a valid source URL."]</ValidationError>
</Feedback>
</TextEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.Aperture != null)
{
<Field>
<FieldLabel>@L["Aperture"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownAperture">@L["Unknown (aperture)"]</Check>
}
@if (!_editing ||
!_unknownAperture)
{
<Validation Validator="@ValidateDoubleBiggerThanZero">
<NumericEdit Disabled="!_editing" TValue="double?" Decimals="3" @bind-Value="@_model.Aperture">
<Feedback>
<ValidationError>@L["Please enter a valid aperture."]</ValidationError>
</Feedback>
</NumericEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.CameraManufacturer != null)
{
<Field>
<FieldLabel>@L["Camera manufacturer"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownCameraManufacturer">@L["Unknown (camera manufacturer)"]</Check>
}
@if (!_editing ||
!_unknownCameraManufacturer)
{
<Validation Validator="@ValidateCameraManufacturer">
<TextEdit Disabled="!_editing" @bind-Text="@_model.CameraManufacturer">
<Feedback>
<ValidationError>@L["Please enter a valid camera manufacturer."]</ValidationError>
</Feedback>
</TextEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.CameraModel != null)
{
<Field>
<FieldLabel>@L["Camera model"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownCameraModel">@L["Unknown (camera model)"]</Check>
}
@if (!_editing ||
!_unknownCameraModel)
{
<Validation Validator="@ValidateCameraModel">
<TextEdit Disabled="!_editing" @bind-Text="@_model.CameraModel">
<Feedback>
<ValidationError>@L["Please enter a valid camera model."]</ValidationError>
</Feedback>
</TextEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.ColorSpace != null)
{
<Field>
<FieldLabel>@L["Color space"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownColorSpace">@L["Unknown (color space)"]</Check>
}
@if (!_editing ||
!_unknownColorSpace)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@ColorSpace">
@foreach (ushort value in Enum.GetValues(typeof(ColorSpace)))
{
<SelectItem TValue="ushort" Value="@value">@(((ColorSpace)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.Contrast != null)
{
<Field>
<FieldLabel>@L["Contrast"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownContrast">@L["Unknown (contrast)"]</Check>
}
@if (!_editing ||
!_unknownContrast)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@Contrast">
@foreach (ushort value in Enum.GetValues(typeof(Contrast)))
{
<SelectItem TValue="ushort" Value="@value">@(((Contrast)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.CreationDate != null)
{
<Field>
<FieldLabel>@L["Creation date"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownCreationDate">@L["Unknown (creation date)"]</Check>
}
@if (!_editing ||
!_unknownCreationDate)
{
<Validation Validator="@ValidateDate">
<DateEdit Disabled="!_editing" TValue="DateTime?" @bind-Date="@_model.CreationDate">
<Feedback>
<ValidationError>@L["Please enter a correct creation date."]</ValidationError>
</Feedback>
</DateEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.DigitalZoomRatio != null)
{
<Field>
<FieldLabel>@L["Digital zoom ratio"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownDigitalZoomRatio">@L["Unknown (digital zoom ratio)"]</Check>
}
@if (!_editing ||
!_unknownDigitalZoomRatio)
{
<Validation Validator="@ValidateDoubleBiggerOrEqualThanZero">
<NumericEdit Disabled="!_editing" TValue="double?" Decimals="3" @bind-Value="@_model.DigitalZoomRatio">
<Feedback>
<ValidationError>@L["Please enter a valid digital zoom ratio."]</ValidationError>
</Feedback>
</NumericEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.ExifVersion != null)
{
<Field>
<FieldLabel>@L["Exif version"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownExifVersion">@L["Unknown (exif version)"]</Check>
}
@if (!_editing ||
!_unknownExifVersion)
{
<Validation Validator="@ValidateExifVersion">
<TextEdit Disabled="!_editing" @bind-Text="@_model.ExifVersion">
<Feedback>
<ValidationError>@L["Please enter a valid Exif version."]</ValidationError>
</Feedback>
</TextEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.ExposureTime != null)
{
<Field>
<FieldLabel>@L["Exposure time"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownExposure">@L["Unknown (exposure time)"]</Check>
}
@if (!_editing ||
!_unknownExposure)
{
<Validation Validator="@ValidateDoubleBiggerThanZero">
<NumericEdit Disabled="!_editing" TValue="double?" Decimals="3" @bind-Value="@_model.ExposureTime">
<Feedback>
<ValidationError>@L["Please enter a valid exposure time."]</ValidationError>
</Feedback>
</NumericEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.ExposureMethod != null)
{
<Field>
<FieldLabel>@L["Exposure mode"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownExposureMethod">@L["Unknown (exposure mode)"]</Check>
}
@if (!_editing ||
!_unknownExposureMethod)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@ExposureMode">
@foreach (ushort value in Enum.GetValues(typeof(ExposureMode)))
{
<SelectItem TValue="ushort" Value="@value">@(((ExposureMode)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.ExposureProgram != null)
{
<Field>
<FieldLabel>@L["Exposure program"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownExposureProgram">@L["Unknown (exposure program)"]</Check>
}
@if (!_editing ||
!_unknownExposureProgram)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@ExposureProgram">
@foreach (ushort value in Enum.GetValues(typeof(ExposureProgram)))
{
<SelectItem TValue="ushort" Value="@value">@(((ExposureProgram)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.Flash != null)
{
<Field>
<FieldLabel>@L["Flash"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownFlash">@L["Unknown (flash)"]</Check>
}
@if (!_editing ||
!_unknownFlash)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@Flash">
@foreach (ushort value in Enum.GetValues(typeof(Flash)))
{
<SelectItem TValue="ushort" Value="@value">@(((Flash)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.Focal != null)
{
<Field>
<FieldLabel>@L["F-number"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownFocal">@L["Unknown (f-number)"]</Check>
}
@if (!_editing ||
!_unknownFocal)
{
<Validation Validator="@ValidateDoubleBiggerThanZero">
<NumericEdit Disabled="!_editing" TValue="double?" Decimals="3" @bind-Value="@_model.Focal">
<Feedback>
<ValidationError>@L["Please enter a valid focal number."]</ValidationError>
</Feedback>
</NumericEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.FocalLength != null)
{
<Field>
<FieldLabel>@L["Focal length"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownFocalLength">@L["Unknown (focal length)"]</Check>
}
@if (!_editing ||
!_unknownFocalLength)
{
<Validation Validator="@ValidateDoubleBiggerThanZero">
<NumericEdit Disabled="!_editing" TValue="double?" Decimals="3" @bind-Value="@_model.FocalLength">
<Feedback>
<ValidationError>@L["Please enter a valid focal length."]</ValidationError>
</Feedback>
</NumericEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.FocalLengthEquivalent != null)
{
<Field>
<FieldLabel>@L["Focal length in 35mm film"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownFocalLengthEquivalent">@L["Unknown (focal length in 35mm film)"]</Check>
}
@if (!_editing ||
!_unknownFocalLengthEquivalent)
{
<Validation Validator="@ValidateDoubleBiggerThanZero">
<NumericEdit Disabled="!_editing" TValue="double?" Decimals="3" @bind-Value="@_model.FocalLengthEquivalent">
<Feedback>
<ValidationError>@L["Please enter a valid focal length in 35mm film."]</ValidationError>
</Feedback>
</NumericEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.HorizontalResolution != null)
{
<Field>
<FieldLabel>@L["Horizontal resolution"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownHorizontalResolution">@L["Unknown (horizontal resolution)"]</Check>
}
@if (!_editing ||
!_unknownHorizontalResolution)
{
<Validation Validator="@ValidateDoubleBiggerThanZero">
<NumericEdit Disabled="!_editing" TValue="double?" Decimals="3" @bind-Value="@_model.HorizontalResolution">
<Feedback>
<ValidationError>@L["Please enter a valid horizontal resolution."]</ValidationError>
</Feedback>
</NumericEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.IsoRating != null)
{
<Field>
<FieldLabel>@L["ISO rating"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownIsoRating">@L["Unknown (ISO rating)"]</Check>
}
@if (!_editing ||
!_unknownIsoRating)
{
<Validation Validator="@ValidateUnsignedShortBiggerThanZero">
<NumericEdit Disabled="!_editing" TValue="ushort?" @bind-Value="@_model.IsoRating">
<Feedback>
<ValidationError>@L["Please enter a valid ISO rating."]</ValidationError>
</Feedback>
</NumericEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.Lens != null)
{
<Field>
<FieldLabel>@L["Lens"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownLens">@L["Unknown (lens)"]</Check>
}
@if (!_editing ||
!_unknownLens)
{
<Validation Validator="@ValidateLens">
<TextEdit Disabled="!_editing" @bind-Text="@_model.Lens">
<Feedback>
<ValidationError>@L["Please enter a valid lens."]</ValidationError>
</Feedback>
</TextEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.LightSource != null)
{
<Field>
<FieldLabel>@L["Light source"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownLightSource">@L["Unknown (light source)"]</Check>
}
@if (!_editing ||
!_unknownLightSource)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@LightSource">
@foreach (ushort value in Enum.GetValues(typeof(LightSource)))
{
<SelectItem TValue="ushort" Value="@value">@(((LightSource)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.MeteringMode != null)
{
<Field>
<FieldLabel>@L["Metering mode"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownMeteringMode">@L["Unknown (metering mode)"]</Check>
}
@if (!_editing ||
!_unknownMeteringMode)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@MeteringMode">
@foreach (ushort value in Enum.GetValues(typeof(MeteringMode)))
{
<SelectItem TValue="ushort" Value="@value">@(((MeteringMode)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.ResolutionUnit != null)
{
<Field>
<FieldLabel>@L["Resolution unit"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownResolutionUnit">@L["Unknown (resolution unit)"]</Check>
}
@if (!_editing ||
!_unknownResolutionUnit)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@ResolutionUnit">
@foreach (ushort value in Enum.GetValues(typeof(ResolutionUnit)))
{
<SelectItem TValue="ushort" Value="@value">@(((ResolutionUnit)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.Orientation != null)
{
<Field>
<FieldLabel>@L["Orientation"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownOrientation">@L["Unknown (orientation)"]</Check>
}
@if (!_editing ||
!_unknownOrientation)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@Orientation">
@foreach (ushort value in Enum.GetValues(typeof(Marechai.Database.Orientation)))
{
<SelectItem TValue="ushort" Value="@value">@(((Marechai.Database.Orientation)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.Saturation != null)
{
<Field>
<FieldLabel>@L["Saturation"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownSaturation">@L["Unknown (saturation)"]</Check>
}
@if (!_editing ||
!_unknownSaturation)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@Saturation">
@foreach (ushort value in Enum.GetValues(typeof(Saturation)))
{
<SelectItem TValue="ushort" Value="@value">@(((Saturation)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.SceneCaptureType != null)
{
<Field>
<FieldLabel>@L["Scene capture type"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownSceneCaptureType">@L["Unknown (scene capture type)"]</Check>
}
@if (!_editing ||
!_unknownSceneCaptureType)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@SceneCaptureType">
@foreach (ushort value in Enum.GetValues(typeof(SceneCaptureType)))
{
<SelectItem TValue="ushort" Value="@value">@(((SceneCaptureType)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.SensingMethod != null)
{
<Field>
<FieldLabel>@L["Sensing method"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownSensingMethod">@L["Unknown (sensing method)"]</Check>
}
@if (!_editing ||
!_unknownSensingMethod)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@SensingMethod">
@foreach (ushort value in Enum.GetValues(typeof(SensingMethod)))
{
<SelectItem TValue="ushort" Value="@value">@(((SensingMethod)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.Sharpness != null)
{
<Field>
<FieldLabel>@L["Sharpness"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownSharpness">@L["Unknown (sharpness)"]</Check>
}
@if (!_editing ||
!_unknownSharpness)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@Sharpness">
@foreach (ushort value in Enum.GetValues(typeof(Sharpness)))
{
<SelectItem TValue="ushort" Value="@value">@(((Sharpness)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.SoftwareUsed != null)
{
<Field>
<FieldLabel>@L["Software used"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownSoftwareUsed">@L["Unknown (software used)"]</Check>
}
@if (!_editing ||
!_unknownSoftwareUsed)
{
<Validation Validator="@ValidateSoftwareUsed">
<TextEdit Disabled="!_editing" @bind-Text="@_model.SoftwareUsed">
<Feedback>
<ValidationError>@L["Please enter a valid software used."]</ValidationError>
</Feedback>
</TextEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.SubjectDistanceRange != null)
{
<Field>
<FieldLabel>@L["Subject distance range"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownSubjectDistanceRange">@L["Unknown (subject distance range)"]</Check>
}
@if (!_editing ||
!_unknownSubjectDistanceRange)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@SubjectDistanceRange">
@foreach (ushort value in Enum.GetValues(typeof(SubjectDistanceRange)))
{
<SelectItem TValue="ushort" Value="@value">@(((SubjectDistanceRange)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.VerticalResolution != null)
{
<Field>
<FieldLabel>@L["Vertical resolution"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownVerticalResolution">@L["Unknown (vertical resolution)"]</Check>
}
@if (!_editing ||
!_unknownVerticalResolution)
{
<Validation Validator="@ValidateDoubleBiggerThanZero">
<NumericEdit Disabled="!_editing" TValue="double?" Decimals="3" @bind-Value="@_model.VerticalResolution">
<Feedback>
<ValidationError>@L["Please enter a valid vertical resolution."]</ValidationError>
</Feedback>
</NumericEdit>
</Validation>
}
</Field>
}
@if (_editing || _model.WhiteBalance != null)
{
<Field>
<FieldLabel>@L["White balance"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownWhiteBalance">@L["Unknown (white balance)"]</Check>
}
@if (!_editing ||
!_unknownWhiteBalance)
{
<Select Disabled="!_editing" TValue="ushort" @bind-SelectedValue="@WhiteBalance">
@foreach (ushort value in Enum.GetValues(typeof(WhiteBalance)))
{
<SelectItem TValue="ushort" Value="@value">@(((WhiteBalance)value).ToString())</SelectItem>
}
</Select>
}
</Field>
}
@if (_editing || _model.Comments != null)
{
<Field>
<FieldLabel>@L["User comments"]</FieldLabel>
@if (_editing)
{
<Check TValue="bool" @bind-Checked="@_unknownComments">@L["Unknown or empty (user comments)"]</Check>
}
@if (!_editing ||
!_unknownComments)
{
<Validation Validator="@ValidateComments">
<TextEdit Disabled="!_editing" @bind-Text="@_model.Comments">
<Feedback>
<ValidationError>@L["Please enter valid comments."]</ValidationError>
</Feedback>
</TextEdit>
</Validation>
}
</Field>
}
</div>
<a href="/assets/photos/machines/originals/@($"{_model.Id}{_model.OriginalExtension}")" target="_blank">
<img src="/assets/photos/machines/originals/@($"{_model.Id}{_model.OriginalExtension}")" alt="" height="auto" width="auto" style="max-height: 512px; max-width: 512px" />
</a>
<div>
@if (!_editing)
{
<Button Color="Color.Primary" Clicked="@OnEditClicked">@L["Edit"]</Button>
}
else
{
<Button Color="Color.Success" Clicked="@OnSaveClicked">@L["Save"]</Button>
<Button Color="Color.Danger" Clicked="@OnCancelClicked">@L["Cancel"]</Button>
}
<a href="/admin/machines/details/@_model.MachineId" class="btn btn-secondary">@L["Back to machine"]</a>
</div>

View File

@@ -0,0 +1,387 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Blazorise;
using Marechai.Database;
using Marechai.Database.Models;
using Marechai.Shared;
using Marechai.ViewModels;
using Microsoft.AspNetCore.Components;
using Orientation = Marechai.Database.Orientation;
namespace Marechai.Pages.Admin.Details
{
public partial class MachinePhoto
{
const int _maxUploadSize = 25 * 1048576;
bool _editing;
List<Database.Models.License> _licenses;
bool _loaded;
MachinePhotoViewModel _model;
bool _unknownAperture;
bool _unknownAuthor;
bool _unknownCameraManufacturer;
bool _unknownCameraModel;
bool _unknownColorSpace;
bool _unknownComments;
bool _unknownContrast;
bool _unknownCreationDate;
bool _unknownDigitalZoomRatio;
bool _unknownExifVersion;
bool _unknownExposure;
bool _unknownExposureMethod;
bool _unknownExposureProgram;
bool _unknownFlash;
bool _unknownFocal;
bool _unknownFocalLength;
bool _unknownFocalLengthEquivalent;
bool _unknownHorizontalResolution;
bool _unknownIsoRating;
bool _unknownLens;
bool _unknownLightSource;
bool _unknownMeteringMode;
bool _unknownOrientation;
bool _unknownResolutionUnit;
bool _unknownSaturation;
bool _unknownSceneCaptureType;
bool _unknownSensingMethod;
bool _unknownSharpness;
bool _unknownSoftwareUsed;
bool _unknownSource;
bool _unknownSubjectDistanceRange;
bool _unknownVerticalResolution;
bool _unknownWhiteBalance;
ApplicationUser _user;
[Parameter]
public Guid Id { get; set; }
[Parameter]
public int MachineId { get; set; }
ushort ColorSpace
{
get
{
if(_model.ColorSpace is null)
return 0;
return(ushort)_model.ColorSpace;
}
set => _model.ColorSpace = (ColorSpace)value;
}
ushort Contrast
{
get
{
if(_model.Contrast is null)
return 0;
return(ushort)_model.Contrast;
}
set => _model.Contrast = (Contrast)value;
}
ushort ExposureMode
{
get
{
if(_model.ExposureMethod is null)
return 0;
return(ushort)_model.ExposureMethod;
}
set => _model.ExposureMethod = (ExposureMode)value;
}
ushort ExposureProgram
{
get
{
if(_model.ExposureProgram is null)
return 0;
return(ushort)_model.ExposureProgram;
}
set => _model.ExposureProgram = (ExposureProgram)value;
}
ushort Flash
{
get
{
if(_model.Flash is null)
return 0;
return(ushort)_model.Flash;
}
set => _model.Flash = (Flash)value;
}
ushort LightSource
{
get
{
if(_model.LightSource is null)
return 0;
return(ushort)_model.LightSource;
}
set => _model.LightSource = (LightSource)value;
}
ushort MeteringMode
{
get
{
if(_model.MeteringMode is null)
return 0;
return(ushort)_model.MeteringMode;
}
set => _model.MeteringMode = (MeteringMode)value;
}
ushort ResolutionUnit
{
get
{
if(_model.ResolutionUnit is null)
return 0;
return(ushort)_model.ResolutionUnit;
}
set => _model.ResolutionUnit = (ResolutionUnit)value;
}
ushort Orientation
{
get
{
if(_model.Orientation is null)
return 0;
return(ushort)_model.Orientation;
}
set => _model.Orientation = (Orientation)value;
}
ushort Saturation
{
get
{
if(_model.Saturation is null)
return 0;
return(ushort)_model.Saturation;
}
set => _model.Saturation = (Saturation)value;
}
ushort SceneCaptureType
{
get
{
if(_model.SceneCaptureType is null)
return 0;
return(ushort)_model.SceneCaptureType;
}
set => _model.SceneCaptureType = (SceneCaptureType)value;
}
ushort SensingMethod
{
get
{
if(_model.SensingMethod is null)
return 0;
return(ushort)_model.SensingMethod;
}
set => _model.SensingMethod = (SensingMethod)value;
}
ushort Sharpness
{
get
{
if(_model.Sharpness is null)
return 0;
return(ushort)_model.Sharpness;
}
set => _model.Sharpness = (Sharpness)value;
}
ushort SubjectDistanceRange
{
get
{
if(_model.SubjectDistanceRange is null)
return 0;
return(ushort)_model.SubjectDistanceRange;
}
set => _model.SubjectDistanceRange = (SubjectDistanceRange)value;
}
ushort WhiteBalance
{
get
{
if(_model.WhiteBalance is null)
return 0;
return(ushort)_model.WhiteBalance;
}
set => _model.WhiteBalance = (WhiteBalance)value;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if(_loaded)
return;
_loaded = true;
if(Id == Guid.Empty)
return;
_model = await Service.GetAsync(Id);
_licenses = await LicensesService.GetAsync();
_editing = NavigationManager.ToBaseRelativePath(NavigationManager.Uri).ToLowerInvariant().
StartsWith("admin/machines/photo/edit/", StringComparison.InvariantCulture);
if(_editing)
SetCheckboxes();
_user = await UserManager.FindByIdAsync(_model.UserId);
StateHasChanged();
}
void SetCheckboxes()
{
_unknownAperture = _model.Aperture is null;
_unknownAuthor = _model.Author is null;
_unknownSource = _model.Source is null;
_unknownCameraManufacturer = _model.CameraManufacturer is null;
_unknownCameraModel = _model.CameraModel is null;
_unknownColorSpace = _model.ColorSpace is null;
_unknownContrast = _model.Contrast is null;
_unknownCreationDate = _model.CreationDate is null;
_unknownDigitalZoomRatio = _model.DigitalZoomRatio is null;
_unknownExifVersion = _model.ExifVersion is null;
_unknownExposure = _model.ExposureTime is null;
_unknownExposureMethod = _model.ExposureMethod is null;
_unknownExposureProgram = _model.ExposureProgram is null;
_unknownFlash = _model.Flash is null;
_unknownFocal = _model.Focal is null;
_unknownFocalLength = _model.FocalLength is null;
_unknownFocalLengthEquivalent = _model.FocalLengthEquivalent is null;
_unknownIsoRating = _model.IsoRating is null;
_unknownLens = _model.Lens is null;
_unknownLightSource = _model.LightSource is null;
_unknownMeteringMode = _model.MeteringMode is null;
_unknownResolutionUnit = _model.ResolutionUnit is null;
_unknownOrientation = _model.Orientation is null;
_unknownSaturation = _model.Saturation is null;
_unknownSceneCaptureType = _model.SceneCaptureType is null;
_unknownSensingMethod = _model.SensingMethod is null;
_unknownSharpness = _model.Sharpness is null;
_unknownSoftwareUsed = _model.SoftwareUsed is null;
_unknownSubjectDistanceRange = _model.SoftwareUsed is null;
_unknownHorizontalResolution = _model.HorizontalResolution is null;
_unknownVerticalResolution = _model.VerticalResolution is null;
_unknownWhiteBalance = _model.WhiteBalance is null;
_unknownComments = _model.Comments is null;
}
void OnEditClicked()
{
_editing = true;
SetCheckboxes();
StateHasChanged();
}
async void OnCancelClicked()
{
_editing = false;
_model = await Service.GetAsync(Id);
SetCheckboxes();
StateHasChanged();
}
async void OnSaveClicked()
{
await Service.UpdateAsync(_model);
_editing = false;
_model = await Service.GetAsync(Id);
SetCheckboxes();
StateHasChanged();
}
void ValidateDoubleBiggerThanZero(ValidatorEventArgs e)
{
if(e.Value is double item &&
item > 0)
e.Status = ValidationStatus.Success;
else
e.Status = ValidationStatus.Error;
}
void ValidateDoubleBiggerOrEqualThanZero(ValidatorEventArgs e)
{
if(e.Value is double item &&
item >= 0)
e.Status = ValidationStatus.Success;
else
e.Status = ValidationStatus.Error;
}
void ValidateUnsignedShortBiggerThanZero(ValidatorEventArgs e)
{
if(e.Value is ushort item &&
item > 0)
e.Status = ValidationStatus.Success;
else
e.Status = ValidationStatus.Error;
}
void ValidateAuthor(ValidatorEventArgs e) =>
Validators.ValidateString(e, L["Author must be 255 characters or less."], 255);
void ValidateSource(ValidatorEventArgs e) =>
Validators.ValidateUrl(e, L["Source URL must be smaller than 255 characters."], 255);
void ValidateCameraManufacturer(ValidatorEventArgs e) =>
Validators.ValidateString(e, L["Camera manufacturer must be 255 characters or less."], 255);
void ValidateCameraModel(ValidatorEventArgs e) =>
Validators.ValidateString(e, L["Camera model must be 255 characters or less."], 255);
void ValidateDate(ValidatorEventArgs e)
{
if(!(e.Value is DateTime item) ||
item.Year <= 1816 ||
item >= DateTime.UtcNow)
e.Status = ValidationStatus.Error;
else
e.Status = ValidationStatus.Success;
}
void ValidateExifVersion(ValidatorEventArgs e) =>
Validators.ValidateString(e, L["Exif version must be 255 characters or less."], 255);
void ValidateLens(ValidatorEventArgs e) =>
Validators.ValidateString(e, L["Lens name must be 255 characters or less."], 255);
void ValidateSoftwareUsed(ValidatorEventArgs e) =>
Validators.ValidateString(e, L["Software used must be 255 characters or less."], 255);
void ValidateComments(ValidatorEventArgs e) =>
Validators.ValidateString(e, L["User comments must be 255 characters or less."], 255);
}
}