V0.1.2 #80

Merged
Penry merged 2 commits from v0.1.2 into main 2026-07-09 00:02:14 +02:00
6 changed files with 383 additions and 26 deletions
Showing only changes of commit 4b90abd58a - Show all commits

No files matched your search

@@ -1,9 +1,11 @@
@using CouchLog.Data
<MudCard>
<MudPaper Elevation="0" Style="position: relative;">
<MudCardMedia Image="@GlobalEntity.PicturePath" Height="400" Style="object-fit: contain;"/>
<MudIconButton Icon="@Icons.Material.Rounded.Edit" Style="position: absolute; top: 8px; right: 8px; z-index: 1; background: black" Color="Color.Primary" />
<MudPaper Elevation="0" Style="position: relative;" @onmouseenter="@(() => _showEditOverlay = true)" @onmouseleave="@(() => _showEditOverlay = false)">
<MudCardMedia Image="@($"{GlobalEntity.PicturePath}?v={DateTime.Now.Ticks}")" Height="400" Style="object-fit: contain;"/>
<MudOverlay Visible="@_showEditOverlay" DarkBackground="true" Absolute="true">
<MudIconButton Icon="@Icons.Material.Rounded.Edit" Color="Color.Primary" OnClick="@(()=> OnEdit.InvokeAsync(GlobalEntity))" />
</MudOverlay>
</MudPaper>
<MudCardContent>
<MudTooltip Text="@GlobalEntity.Title">
@@ -37,4 +39,7 @@
[Parameter] public EventCallback<GlobalEntity> OnAddToPrivate { get; set; }
[Parameter] public EventCallback<GlobalEntity> OnAddToShared { get; set; }
[Parameter] public EventCallback<GlobalEntity> OnEdit { get; set; }
private bool _showEditOverlay;
}
@@ -22,10 +22,10 @@
</TitleContent>
<DialogContent>
<EditForm EditContext="_editContext" OnSubmit="HandleSubmit">
<EditForm EditContext="_editContext" OnSubmit="HandleSubmit" id="New-Global-Entity-Form">
<DataAnnotationsValidator />
<MudStack Row="true" Spacing="3" AlignItems="AlignItems.Start" Style="min-height: 400px;">
<MudStack Row="true" Spacing="3" AlignItems="AlignItems.Start" Style="min-height: 400px;" Breakpoint="Breakpoint.SmAndDown">
<!--<editor-fold desc="Picture-Upload">-->
<MudPaper Class="pa-0" Elevation="0" Width="280px" MinWidth="280px">
@if (!string.IsNullOrWhiteSpace(_imagePreview))
@@ -43,13 +43,12 @@
Accept="image/*"
InputClass="null"
Class="mud-file-upload-dragarea">
<SelectedTemplate Context="SelectedTemplateContext"/>
<SelectedTemplate Context="selectedTemplateContext"/>
</MudFileUpload>
}
</MudPaper>
<!--</editor-fold>-->
<MudPaper Class="flex-grow-1" Elevation="0">
<MudPaper Class="flex-grow-1" Elevation="0" MinWidth="200px">
<MudStack Spacing="3">
<MudTextField @bind-Value="_form.Title"
@@ -78,17 +77,6 @@
}
</MudSelect>
<MudCheckBox @bind-Value="_isPrivate" Label="Is Private" Color="Color.Primary" />
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Success" Disabled="_isSaving" Class="mt-3">
@if (_isSaving)
{
<MudProgressCircular Indeterminate="true" Size="Size.Small" Class="mr-2" />
<span>Saving...</span>
}
else
{
<span>Create Global Entity</span>
}
</MudButton>
</MudStack>
</MudPaper>
</MudStack>
@@ -96,7 +84,18 @@
</DialogContent>
<DialogActions>
<MudButton OnClick="Cancel" Variant="Variant.Text" Disabled="_isSaving">Cancel</MudButton>
<MudButton OnClick="Cancel" Variant="Variant.Filled" Color="Color.Error" Disabled="_isSaving" Class="mt-3">Cancel</MudButton>
<MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Success" Disabled="_isSaving" Class="mt-3" form="New-Global-Entity-Form">
@if (_isSaving)
{
<MudProgressCircular Indeterminate="true" Size="Size.Small" Class="mr-2"/>
<span>Saving...</span>
}
else
{
<span>Create Global Entity</span>
}
</MudButton>
</DialogActions>
</MudDialog>
@@ -1,4 +1,8 @@
@using CouchLog.Data
@using Microsoft.EntityFrameworkCore
@inject ApplicationDbContext CouchLogDb
@inject ISnackbar Snackbar
<MudDialog>
<TitleContent>
@@ -6,11 +10,92 @@
</TitleContent>
<DialogContent>
<MudStack Row="true" Spacing="3" AlignItems="AlignItems.Start" Style="min-height: 400px;" Breakpoint="Breakpoint.SmAndDown">
<!--<editor-fold desc="Picture-Upload">-->
@if (!string.IsNullOrWhiteSpace(_imagePreview))
{
<MudPaper Class="pa-0" Elevation="0" Width="280px" MinWidth="280px" Style="position: relative" @onmouseenter="@(() => _showChangePictureOverlay = true)" @onmouseleave="@(() => _showChangePictureOverlay = false)">
<MudImage Src="@_imagePreview"
ObjectFit="ObjectFit.Contain"
Class="rounded"
Style="width: 280px; height: 400px;"/>
<MudOverlay Visible="@_showChangePictureOverlay" DarkBackground="true" Absolute="true">
<MudIconButton Icon="@Icons.Material.Rounded.Edit" Color="Color.Primary" OnClick="@(() => PrepareForNewImage())"/>
</MudOverlay>
</MudPaper>
}
else
{
<MudPaper Class="pa-0" Elevation="0" Width="280px" MinWidth="280px" Style="position: relative">
<MudFileUpload @bind-Files="_pictureFile"
DragAndDrop="true"
OnFilesChanged="OnPictureUploaded"
Accept="image/*"
InputClass="null"
Class="mud-file-upload-dragarea">
<SelectedTemplate Context="selectedTemplateContext"/>
</MudFileUpload>
</MudPaper>
}
<!--</editor-fold>-->
<MudPaper Class="flex-grow-1" Elevation="0" MinWidth="200px">
<MudStack Spacing="3">
<MudTextField @bind-Value="_editedGlobalEntity.Title"
Label="Title"
Variant="Variant.Outlined" />
<MudSelect T="int"
@bind-Value="_editedGlobalEntity.TypeId"
Label="Type"
Variant="Variant.Outlined">
@foreach (var type in _mediaTypes)
{
<MudSelectItem T="int" Value="@type.Id">@type.Name</MudSelectItem>
}
</MudSelect>
<MudSelect T="int"
Label="Genres"
MultiSelection="true"
@bind-SelectedValues="_selectedGenreIds"
Variant="Variant.Outlined">
@foreach (var genre in _genres)
{
<MudSelectItem T="int" Value="@genre.Id">@genre.Name</MudSelectItem>
}
</MudSelect>
<MudCheckBox @bind-Value="_isPrivate" Label="Is Private" Color="Color.Primary" />
@if (AppUser.Id == _editedGlobalEntity.CreatorId)
{
<MudButton OnClick="HandleDelete"
StartIcon="@Icons.Material.Filled.Delete"
Variant="Variant.Filled"
Color="Color.Error">
Delete
</MudButton>
}
else
{
<AuthorizeView Roles="Admin">
<Authorized>
<MudButton OnClick="HandleDelete"
StartIcon="@Icons.Material.Filled.Delete"
Variant="Variant.Filled"
Color="Color.Error">
Delete
</MudButton>
</Authorized>
</AuthorizeView>
}
</MudStack>
</MudPaper>
</MudStack>
</DialogContent>
<DialogActions>
<MudButton OnClick="Cancel" Variant="Variant.Text">Cancel</MudButton>
<MudButton OnClick="Cancel" Variant="Variant.Filled" Color="Color.Error">Cancel</MudButton>
<MudButton OnClick="SaveChanges" Variant="Variant.Filled" Color="Color.Success">Save Changes</MudButton>
</DialogActions>
</MudDialog>
@@ -19,10 +104,237 @@
[CascadingParameter] private IMudDialogInstance Dialog { get; set; } = null!;
[Parameter] public GlobalEntity GlobalEntity { get; set; } = null!;
[Parameter] public ApplicationUser AppUser { get; set; } = null!;
[Inject] private IDialogService DialogService { get; set; }
private GlobalEntity _editedGlobalEntity = null!;
private string? _imagePreview;
private IBrowserFile? _pictureFile;
private List<MediaType> _mediaTypes = new();
private IReadOnlyCollection<int> _selectedGenreIds = Array.Empty<int>();
private List<Genre> _genres = new();
private bool _isPrivate;
private bool _showChangePictureOverlay;
private string _oldImageBase64;
private string _placeHolder = "data:image/png;base64,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 truncated
protected override async Task OnInitializedAsync()
{
await CouchLogDb.GlobalEntities
.Include(x => x.MediaType)
.Include(x => x.LinkTableGlobalGenres)
.LoadAsync();
_editedGlobalEntity = new GlobalEntity
{
//Required
Id = GlobalEntity.Id,
CreatorId = GlobalEntity.CreatorId,
CreationTime = GlobalEntity.CreationTime,
TypeId = GlobalEntity.TypeId,
//Editable
Title = GlobalEntity.Title,
MediaType = GlobalEntity.MediaType,
LinkTableGlobalGenres = GlobalEntity.LinkTableGlobalGenres,
IsPrivate = GlobalEntity.IsPrivate,
PicturePath = GlobalEntity.PicturePath,
};
await GetImagePreview();
_mediaTypes = await CouchLogDb.MediaType.OrderBy(t => t.Id).ToListAsync();
_selectedGenreIds = GlobalEntity.LinkTableGlobalGenres.Select(x => x.GenreId).ToList();
//var newGenreIds = new HashSet<int>(_selectedGenreIds);
_genres = await CouchLogDb.Genres.OrderBy(t => t.Id).ToListAsync();
_isPrivate = _editedGlobalEntity.IsPrivate;
}
private async Task GetImagePreview()
{
if (_editedGlobalEntity.PicturePath == null)
{
_imagePreview = _placeHolder;
return;
}
string path = Path.Combine("wwwroot", _editedGlobalEntity.PicturePath);
byte[] imageArray;
string base64Image = "";
try
{
imageArray = await File.ReadAllBytesAsync(path);
base64Image = Convert.ToBase64String(imageArray);
}
catch (Exception ex)
{
}
if (!String.IsNullOrWhiteSpace(base64Image))
{
_imagePreview = $"data:image/jpeg;base64,{base64Image}";
_oldImageBase64 = _imagePreview;
}
else
{
_imagePreview = _placeHolder;
}
}
private async Task PrepareForNewImage()
{
if (_imagePreview != _placeHolder)
{
_imagePreview = null;
}
else
{
_imagePreview = null;
}
}
private async Task OnPictureUploaded()
{
if (_pictureFile == null)
{
Snackbar.Add("No file selected!", Severity.Warning);
return;
}
if (_pictureFile.Size > 5242880)
{
Snackbar.Add("File size exceeds 5MB!", Severity.Error);
return;
}
await using var stream = _pictureFile.OpenReadStream(5242880);
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
var _pictureContentType = _pictureFile.ContentType;
var _pictureExtension = Path.GetExtension(_pictureFile.Name);
var _pictureBase64 = Convert.ToBase64String(ms.ToArray());
_imagePreview = $"data:{_pictureFile.ContentType};base64,{_pictureBase64}";
}
private async Task HandleDelete()
{
//TODO: Add Message Box
File.Delete(Path.Combine("wwwroot", _editedGlobalEntity.PicturePath));
Dialog.Close(DialogResult.Ok((_editedGlobalEntity, true)));
}
private bool CheckForChanges()
{
if (_editedGlobalEntity.Title != GlobalEntity.Title)
{
return true;
}
if(_editedGlobalEntity.TypeId != GlobalEntity.TypeId)
{
return true;
}
var newGenresHashSet = new HashSet<int>(_selectedGenreIds);
var oldGenereIds = GlobalEntity.LinkTableGlobalGenres.Select(g => g.GenreId);
if (!newGenresHashSet.SetEquals(oldGenereIds))
{
Snackbar.Add("Selected genre id is", Severity.Warning);
return true;
}
if (_editedGlobalEntity.IsPrivate != GlobalEntity.IsPrivate)
{
return true;
}
if (_imagePreview != _oldImageBase64)
{
return true;
}
return false;
}
private void UpdateGenreLinks()
{
var currentGenreIds = GlobalEntity.LinkTableGlobalGenres.Select(g => g.GenreId).ToHashSet();
var selectedGenreIds = _selectedGenreIds.ToHashSet();
var toRemove = GlobalEntity.LinkTableGlobalGenres
.Where(g => !selectedGenreIds.Contains(g.GenreId))
.ToList();
foreach (var link in toRemove)
{
GlobalEntity.LinkTableGlobalGenres.Remove(link);
}
var toAdd = selectedGenreIds.Where(id => !currentGenreIds.Contains(id));
foreach (var genreId in toAdd)
{
GlobalEntity.LinkTableGlobalGenres.Add(new LinkTableGlobalGenre
{
GlobalEntityId = GlobalEntity.Id,
GenreId = genreId
});
}
}
private async Task SaveImageToFile(string dataUrl, string targetPath)
{
if (string.IsNullOrWhiteSpace(dataUrl))
{
return;
}
var commaIndex = dataUrl.IndexOf(',');
if (commaIndex < 0)
{
return;
}
string base64Data = dataUrl.Substring(commaIndex + 1);
byte[] imageBytes = Convert.FromBase64String(base64Data);
await File.WriteAllBytesAsync(targetPath, imageBytes);
}
private async Task SaveChanges()
{
if (CheckForChanges())
{
bool? result = await DialogService.ShowMessageBoxAsync(
"Warning",
"Do you really want to save does changes?",
yesText:"Save", cancelText:"Cancel");
if (result == true)
{
GlobalEntity.Title = _editedGlobalEntity.Title;
GlobalEntity.TypeId = _editedGlobalEntity.TypeId;
GlobalEntity.MediaType = _editedGlobalEntity.MediaType;
UpdateGenreLinks();
GlobalEntity.IsPrivate = _editedGlobalEntity.IsPrivate;
GlobalEntity.LastChange = DateTime.UtcNow;
SaveImageToFile(_imagePreview, Path.Combine("wwwroot", _editedGlobalEntity.PicturePath));
await CouchLogDb.SaveChangesAsync();
Dialog.Close(DialogResult.Ok((GlobalEntity, false)));
}
}
else
{
Snackbar.Add("You changed nothing so there is nothing to save!", Severity.Info);
Cancel();
}
}
private void Cancel()
{
Dialog.Cancel();
}
}
S
}
@@ -82,7 +82,8 @@
<GlobalEntityCard GlobalEntity="globalEntity"
UserPrivateEntityIds="_userPrivateEntityIds"
OnAddToPrivate="AddGlobalEntityToPrivateList"
OnAddToShared="AddGlobalEntityToSharedList"/>
OnAddToShared="AddGlobalEntityToSharedList"
OnEdit="OpenEditGlobalEntityDialog"/>
</MudItem>
}
</MudGrid>
@@ -165,6 +166,44 @@
await OnNewEntity(entity);
}
}
private async Task OpenEditGlobalEntityDialog(GlobalEntity globalEntity)
{
var parameters = new DialogParameters<EditGlobalEntityDialog>
{
{ x => x.GlobalEntity, globalEntity },
{ x => x.AppUser, _appUser}
};
var dialog = await DialogService.ShowAsync<EditGlobalEntityDialog>("Edit Global Entity", parameters);
var result = await dialog.Result;
if (!result!.Canceled && result.Data is ValueTuple<GlobalEntity, bool> data)
{
if (data.Item2)
{
CouchLogDb.GlobalEntities.Remove(data.Item1);
await CouchLogDb.SaveChangesAsync();
_globalEntities.RemoveAll(x => x.Id == data.Item1.Id);
if (_currentPage > TotalPages)
_currentPage = Math.Max(1, TotalPages);
StateHasChanged();
}
if (!data.Item2)
{
int index = _globalEntities.FindIndex(x => x.Id == data.Item1.Id);
if (index >= 0)
{
_globalEntities[index] = data.Item1;
}
StateHasChanged();
}
}
}
public async Task AddGlobalEntityToPrivateList(GlobalEntity globalEntity)
{
@@ -17,7 +17,9 @@
<MudStack Class="pa-3" Spacing="2">
<!--<editor-fold desc="Options">-->
<MudStack Row="true" AlignItems="AlignItems.Center" Justify="Justify.SpaceBetween">
<MudText Typo="Typo.h6" Style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">@PrivateEntity.GlobalEntity.Title</MudText>
<MudTooltip Text="@PrivateEntity.GlobalEntity.Title">
<MudText Typo="Typo.h6" Style="display: block; max-width: 250px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">@PrivateEntity.GlobalEntity.Title</MudText>
</MudTooltip>
<MudMenu Icon="@Icons.Material.Filled.MoreVert" Color="Color.Default" Dense="true">
<MudMenuItem>Edit</MudMenuItem>
<MudMenuItem OnClick="@(() => OnRemove.InvokeAsync())">Remove</MudMenuItem>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB