Implemented simple image upload in ArticleEditor
Some checks failed
Build, Tag, Push Docker Image / build (push) Has been cancelled
Create Release / Generate Release (push) Has been cancelled

This commit is contained in:
Mia Rose Winter 2024-02-21 15:18:40 +01:00
parent 06ce7e995c
commit 4dac73c564
Signed by: miawinter
GPG key ID: 4B6F6A83178F595E
5 changed files with 156 additions and 14 deletions

View file

@ -20,17 +20,6 @@
</ul> </ul>
</div> </div>
<div class="my-3 flex flex-wrap gap-4">
@foreach (var image in Article.Images) {
<figure>
<img src="/images/@(image.Id)?size=400" width="400" alt="@image.ImageDescription"/>
<figcaption>
@image.ImageDescription
</figcaption>
</figure>
}
</div>
<EditForm method="post" FormName="article-editor" Model="@Model" OnValidSubmit="OnValidSubmit"> <EditForm method="post" FormName="article-editor" Model="@Model" OnValidSubmit="OnValidSubmit">
<DataAnnotationsValidator/> <DataAnnotationsValidator/>
<input type="hidden" @bind-value="@Model.Id"/> <input type="hidden" @bind-value="@Model.Id"/>
@ -154,7 +143,23 @@
} }
</div> </div>
</EditForm> </EditForm>
<CategoryPicker/>
<ImageModal Id="@ImageModal" ImageAdded="ImageAdded" />
<div class="my-3 flex flex-wrap gap-4 min-h-24">
@foreach (var image in Article.Images) {
<figure class="p-2 bg-base-200">
<img class="w-40" src="/images/@(image.Id)?size=400" width="400"
title="@image.ImageDescription" alt="@image.ImageDescription"/>
<figcaption>
<button type="button" class="btn btn-info w-full mt-3"
onclick="navigator.clipboard.writeText('![@image.ImageDescription](@(Navigation.ToAbsoluteUri("/images/" + image.Id))?size=400)')">
@Localizer["Image_CopyLink"]
</button>
</figcaption>
</figure>
}
<button type="button" class="btn" onclick="@(ImageModal).showModal()">@Localizer["Image_Add_Label"]</button>
</div>
<SectionContent SectionName="scripts"> <SectionContent SectionName="scripts">
<script> <script>
@ -199,6 +204,8 @@
</SectionContent> </SectionContent>
@code { @code {
private const string ImageModal = "AddImage";
[Parameter] [Parameter]
public Guid? Id { get; set; } public Guid? Id { get; set; }
[Parameter] [Parameter]
@ -281,6 +288,14 @@
Model.Categories ??= []; Model.Categories ??= [];
context.Update(Article); context.Update(Article);
var existingImages = await context.Set<Article>().Where(a => a.Id == Article.Id)
.SelectMany(a => a.Images).ToListAsync();
foreach (var image in Article.Images) {
context.Entry(image).State =
existingImages.Any(i => i.Id == image.Id) ?
EntityState.Modified : EntityState.Added;
}
var relations = await context.Set<ArticleCategory>() var relations = await context.Set<ArticleCategory>()
.IgnoreQueryFilters().IgnoreAutoIncludes() .IgnoreQueryFilters().IgnoreAutoIncludes()
@ -335,6 +350,11 @@
Model.Categories = selected?.Select(Guid.Parse).ToArray(); Model.Categories = selected?.Select(Guid.Parse).ToArray();
} }
private async Task ImageAdded(ArticleImage image) {
Article.Images.Add(image);
await InvokeAsync(StateHasChanged);
}
private sealed class InputModel { private sealed class InputModel {
public Guid? Id { get; set; } public Guid? Id { get; set; }
@ -346,5 +366,4 @@
public Guid[]? Categories { get; set; } public Guid[]? Categories { get; set; }
public DateTimeOffset? PublishDate { get; set; } public DateTimeOffset? PublishDate { get; set; }
} }
} }

View file

@ -0,0 +1,69 @@
@using Wave.Services
@using Wave.Data
@inject ImageService Images
@inject IStringLocalizer<ArticleEditor> Localizer
<ModalComponent Id="@Id" ShowCloseButton="false">
<ChildContent>
@if (Image != null) {
<figure>
<img src="/images/@(Image)" alt=""/>
</figure>
}
<FileUploadComponent FileUploadedCallback="FileChanged"/>
<InputLabelComponent LabelText="@Localizer["Image_Description_Label"]">
<InputText class="input input-bordered w-full" maxlength="2048"
@bind-Value="@ImageDescription"
placeholder="@Localizer["Image_Description_Placeholder"]"
autocomplete="off" />
</InputLabelComponent>
</ChildContent>
<Actions>
<button class="btn btn-primary" @onclick="Save">@Localizer["Image_Add_Submit"]</button>
<form method="dialog">
<button type="submit" class="btn btn-error" @onclick="Cancel">@Localizer["Image_Add_Abort"]</button>
</form>
</Actions>
</ModalComponent>
@code {
[Parameter]
public required string Id { get; set; }
[Parameter]
public required EventCallback<ArticleImage> ImageAdded { get; set; }
private Guid? Image { get; set; }
private string ImageDescription { get; set; } = string.Empty;
private async Task FileChanged(string tempPath) {
if (Image is { } img) {
Image = null;
Images.Delete(img);
}
Image = await Images.StoreImageAsync(tempPath);
}
private async Task Save() {
if (Image is null) return;
await ImageAdded.InvokeAsync(new ArticleImage {
Id = Image.Value,
ImageDescription = ImageDescription
});
Image = null;
ImageDescription = string.Empty;
}
private void Cancel() {
if (Image is { } img) {
Image = null;
Images.Delete(img);
}
ImageDescription = string.Empty;
}
}

View file

@ -191,4 +191,31 @@
<data name="Tools_Mark_Tooltip" xml:space="preserve"> <data name="Tools_Mark_Tooltip" xml:space="preserve">
<value>Den selektierten Text markieren</value> <value>Den selektierten Text markieren</value>
</data> </data>
<data name="Categories_Label" xml:space="preserve">
<value>Kategorie</value>
</data>
<data name="Image_Add_Label" xml:space="preserve">
<value>Bild Hochladen</value>
</data>
<data name="Image_Description_Label" xml:space="preserve">
<value>Bildbeschreibung</value>
</data>
<data name="Image_Description_Placeholder" xml:space="preserve">
<value>Ein Bild eines Käsekuchen</value>
</data>
<data name="Image_Add_Submit" xml:space="preserve">
<value>Hinzufügen</value>
</data>
<data name="Image_Add_Abort" xml:space="preserve">
<value>Schließen</value>
</data>
<data name="Save_Success" xml:space="preserve">
<value>Artikel Gespeichert</value>
</data>
<data name="Save_Error" xml:space="preserve">
<value>Unbekannter fehler beim speichern des Artikels</value>
</data>
<data name="Image_CopyLink" xml:space="preserve">
<value>Link Kopieren</value>
</data>
</root> </root>

View file

@ -197,4 +197,31 @@
<data name="Tools_Mark_Tooltip" xml:space="preserve"> <data name="Tools_Mark_Tooltip" xml:space="preserve">
<value>Mark the selected text</value> <value>Mark the selected text</value>
</data> </data>
<data name="Categories_Label" xml:space="preserve">
<value>Category</value>
</data>
<data name="Image_Add_Label" xml:space="preserve">
<value>Upload Image</value>
</data>
<data name="Image_Description_Label" xml:space="preserve">
<value>Image Description</value>
</data>
<data name="Image_Description_Placeholder" xml:space="preserve">
<value>A picture of a cheesecake</value>
</data>
<data name="Image_Add_Submit" xml:space="preserve">
<value>Add</value>
</data>
<data name="Image_Add_Abort" xml:space="preserve">
<value>Close</value>
</data>
<data name="Save_Success" xml:space="preserve">
<value>Article Saved</value>
</data>
<data name="Save_Error" xml:space="preserve">
<value>Unknown error saving article</value>
</data>
<data name="Image_CopyLink" xml:space="preserve">
<value>Copy Link</value>
</data>
</root> </root>

File diff suppressed because one or more lines are too long