SaveProgress
This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"terminal.explorerKind": "integrated"
|
||||||
|
}
|
||||||
@@ -1,351 +0,0 @@
|
|||||||
@page "/GlobalList"
|
|
||||||
@rendermode InteractiveServer
|
|
||||||
|
|
||||||
@using Microsoft.AspNetCore.Authorization
|
|
||||||
@using CouchLog.Data
|
|
||||||
@using Microsoft.AspNetCore.Identity
|
|
||||||
@using Microsoft.EntityFrameworkCore
|
|
||||||
|
|
||||||
@inject ApplicationDbContext CouchLogDB
|
|
||||||
@inject UserManager<ApplicationUser> UserManager
|
|
||||||
@inject AuthenticationStateProvider AuthenticationStateProvider
|
|
||||||
@inject NavigationManager NavigationManager
|
|
||||||
|
|
||||||
@attribute [Authorize]
|
|
||||||
|
|
||||||
<PageTitle>GlobalList</PageTitle>
|
|
||||||
|
|
||||||
<MudContainer>
|
|
||||||
@*Top of the Page*@
|
|
||||||
<MudStack Row="true" AlignItems="AlignItems.Center">
|
|
||||||
@*Page Title*@
|
|
||||||
<MudText Typo="Typo.h2" Style="font-weight: bold;">Global List</MudText>
|
|
||||||
|
|
||||||
@*Spacer*@
|
|
||||||
<MudSpacer />
|
|
||||||
|
|
||||||
@*Button for adding GlobalEntity*@
|
|
||||||
<MudTooltip Text="Add GlobalEntity">
|
|
||||||
<MudFab StartIcon="@Icons.Material.Filled.Add" Color="Color.Primary"/>
|
|
||||||
</MudTooltip>
|
|
||||||
</MudStack>
|
|
||||||
</MudContainer>
|
|
||||||
|
|
||||||
<div class="container-fluid mt-4">
|
|
||||||
<!-- #region CreateEntity -->
|
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
||||||
<h2>Global List</h2>
|
|
||||||
<button class="btn btn-info" type="button" @onclick="ToogleCollapseNewGlobalEntity">@(isCollapseNewGlobalEntityOpen ? "X" : "Add Entity")</button>
|
|
||||||
</div>
|
|
||||||
<div class="collapse @(isCollapseNewGlobalEntityOpen ? "show" : "")" id="CollapseCreateNewGlobalEntity">
|
|
||||||
<div class="mb-4 align-items-center CreateNewGlobalEntity-Container">
|
|
||||||
<EditForm Model="@GlobalEntity" OnSubmit="CreateNewGlobalEntity" FormName="CreateNewGlobalEntityForm">
|
|
||||||
<DataAnnotationsValidator />
|
|
||||||
<ValidationSummary />
|
|
||||||
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="Title" class="form-label">Title</label>
|
|
||||||
<InputText id="Title" class="form-control" @bind-Value="GlobalEntity.Title"></InputText>
|
|
||||||
<ValidationMessage For="@(() => GlobalEntity.Title)"></ValidationMessage>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="Type" class="form-label">Type</label>
|
|
||||||
<select id="Type" class="form-select" @bind="SelectedMediaTypeId">
|
|
||||||
@foreach(MediaType Type in MediaTypes)
|
|
||||||
{
|
|
||||||
<option value="@Type.Id">@Type.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="Picture" class="form-label">Picture</label>
|
|
||||||
<InputFile OnChange="@LoadImage" accept="image/*" />
|
|
||||||
@if (!string.IsNullOrEmpty(ImageString))
|
|
||||||
{
|
|
||||||
<img src="@ImageString" style="max-width: 256px; max-height: 256px;" />
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<label for="Genres" class="form-label">Genres</label>
|
|
||||||
@foreach(Genre Genre in Genres)
|
|
||||||
{
|
|
||||||
<button class="btn-primary btn me-2" value="@Genre.Id" type="button" @onclick="() => AddGenreToList(Genre.Id)">@Genre.Name</button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="mb-3">
|
|
||||||
<InputCheckbox DisplayName="isPrivate" @bind-Value="isPrivate" ></InputCheckbox>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn-success btn">Create new Global Entity</button>
|
|
||||||
</EditForm>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- #endregion -->
|
|
||||||
|
|
||||||
<!-- #region Show Entitys -->
|
|
||||||
<div class="row g-4">
|
|
||||||
@foreach (var Entity in GlobalEntities)
|
|
||||||
{
|
|
||||||
if (!Entity.IsPrivate || (Entity.IsPrivate && (Entity.CreatorId == AppUser.Id)))
|
|
||||||
{
|
|
||||||
<div name="Enity-Container" class="col-6 col-md-4 col-lg-2 col-xl-2 mb-4 Entity-Container">
|
|
||||||
<div name="Entity-Container-Card" class="Entity-Container-Card">
|
|
||||||
|
|
||||||
<div class="Entity-Container-Menu-Button dropdown ms-1">
|
|
||||||
<button type="button" class="Entity-Container-Menu-Button btn menu-btn" data-bs-toggle="modal" data-bs-target="#modal-@Entity.Id">⋮</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal fade" id="@Entity.Id" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="staticBackdropLabel">Modal title</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
This is a vertically centered modal.
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
||||||
<button type="button" class="btn btn-primary">Understood</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div name="Enity-Container-Image" class="">
|
|
||||||
<a href="javascript:void(0)" class="Entity-Container-Image">
|
|
||||||
<img src="/@Entity.PicturePath" alt="" class="Entity-Container-Image" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div name="Entity-Container-Data" class="">
|
|
||||||
<h3 class="">@Entity.Title</h3>
|
|
||||||
</div>
|
|
||||||
<div name="Entity-Container-Button" class="d-flex Entity-Container-Button" style="gap: 10px;">
|
|
||||||
<button class="btn btn-info" type="button" @onclick="() => AddToPrivateList(Entity)">
|
|
||||||
@(IsInPrivateList(Entity.Id) ? "Added" : "Add to Private List")
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-info" type="button" @onclick="() => throw new NotImplementedException()">Add to Shared List</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal fade" id="modal-@Entity.Id" tabindex="-1" aria-hidden="true">
|
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title">Optionen</h5>
|
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<button class="btn btn-danger" type="button" @onclick="() => DeleteEntity(Entity)">Delete Entity</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<!-- #endregion -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code
|
|
||||||
{
|
|
||||||
private List<MediaType> MediaTypes = new List<MediaType>();
|
|
||||||
private List<Genre> Genres = new List<Genre>();
|
|
||||||
private List<GlobalEntity> GlobalEntities = new List<GlobalEntity>();
|
|
||||||
private List<int> GenreIds = new List<int>();
|
|
||||||
private HashSet<int> UserPrivateEntityIds = new();
|
|
||||||
private IBrowserFile? Picture;
|
|
||||||
System.Security.Claims.ClaimsPrincipal User = new();
|
|
||||||
ApplicationUser AppUser = null!;
|
|
||||||
private GlobalEntity GlobalEntity = new();
|
|
||||||
private bool isCollapseNewGlobalEntityOpen = false;
|
|
||||||
private int SelectedMediaTypeId;
|
|
||||||
private bool isPrivate = false;
|
|
||||||
private string ImageString = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <exception cref="NotImplementedException"></exception>
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
GlobalEntities = await CouchLogDB.GlobalEntities.OrderByDescending(Entity => Entity.CreationTime).ToListAsync();
|
|
||||||
MediaTypes = await CouchLogDB.MediaType.OrderBy(Type => Type.Id).ToListAsync();
|
|
||||||
Genres = await CouchLogDB.Genres.OrderBy(Genre => Genre.Name).ToListAsync();
|
|
||||||
|
|
||||||
var AuthState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
|
||||||
User = AuthState.User;
|
|
||||||
|
|
||||||
AppUser = (await UserManager.GetUserAsync(User))!;
|
|
||||||
|
|
||||||
if (AppUser == null)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
var TempUserPrivateEntityIds = await CouchLogDB.PrivateEntities
|
|
||||||
.Where(p => p.UserId == AppUser.Id)
|
|
||||||
.Select(p => p.GlobalEntityId)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
UserPrivateEntityIds = TempUserPrivateEntityIds.ToHashSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task LoadImage(InputFileChangeEventArgs e)
|
|
||||||
{
|
|
||||||
Picture = e.File;
|
|
||||||
|
|
||||||
foreach(var file in e.GetMultipleFiles())
|
|
||||||
{
|
|
||||||
using var stream = file.OpenReadStream();
|
|
||||||
using var ms = new MemoryStream();
|
|
||||||
await stream.CopyToAsync(ms);
|
|
||||||
ImageString = $"data:{file.ContentType};base64,{Convert.ToBase64String(ms.ToArray())}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="eventArgs"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private async Task LoadFiles(InputFileChangeEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
Picture = eventArgs.File;
|
|
||||||
|
|
||||||
//Byte[] Buffer = new byte[Picture.Size];
|
|
||||||
//await Picture.OpenReadStream().ReadAsync(Buffer);
|
|
||||||
//await Picture.OpenReadStream(maxAllowedSize: 10_000_000).ReadAsync(Buffer);
|
|
||||||
|
|
||||||
//string Base64 = Convert.ToBase64String(Buffer);
|
|
||||||
//ImagePreviewUrl = $"data:{Picture.ContentType};base64,{Base64}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
private void ToogleCollapseNewGlobalEntity()
|
|
||||||
{
|
|
||||||
isCollapseNewGlobalEntityOpen = !isCollapseNewGlobalEntityOpen;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
private async Task CreateNewGlobalEntity()
|
|
||||||
{
|
|
||||||
if (Picture is null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("No Picture selected.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AppUser is null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("User not loaded or not logged in.");
|
|
||||||
}
|
|
||||||
|
|
||||||
//Save Picture and Name it
|
|
||||||
string NewFileName = $"{GlobalEntity.Title.Replace(" ", "-")}-{Guid.NewGuid()}{Path.GetExtension(Picture.Name)}";
|
|
||||||
string PicturePath = Path.Combine("wwwroot", "Pictures", NewFileName);
|
|
||||||
using FileStream FileStream = File.Create(PicturePath);
|
|
||||||
await Picture.OpenReadStream().CopyToAsync(FileStream);
|
|
||||||
//await Picture.OpenReadStream(maxAllowedSize: 10_000_000).CopyToAsync(FileStream);
|
|
||||||
|
|
||||||
GlobalEntity.PicturePath = $"Pictures/{NewFileName}";
|
|
||||||
GlobalEntity.CreatorId = AppUser.Id;
|
|
||||||
GlobalEntity.TypeId = SelectedMediaTypeId;
|
|
||||||
GlobalEntity.CreationTime = DateTime.Now;
|
|
||||||
GlobalEntity.IsPrivate = isPrivate;
|
|
||||||
|
|
||||||
CouchLogDB.Add(GlobalEntity);
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
|
|
||||||
foreach(int GenreId in GenreIds)
|
|
||||||
{
|
|
||||||
LinkTableGlobalGenre LinkTableGlobalGenre = new() { GenreId = GenreId, GlobalEntityId = GlobalEntity.Id };
|
|
||||||
CouchLogDB.Add(LinkTableGlobalGenre);
|
|
||||||
}
|
|
||||||
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="GolbalEntityId"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private bool IsInPrivateList(int GolbalEntityId)
|
|
||||||
{
|
|
||||||
return UserPrivateEntityIds.Contains(GolbalEntityId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="GlobalEntity"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private async Task AddToPrivateList(GlobalEntity GlobalEntity)
|
|
||||||
{
|
|
||||||
if(User.Identity?.IsAuthenticated == true)
|
|
||||||
{
|
|
||||||
if(!IsInPrivateList(GlobalEntity.Id))
|
|
||||||
{
|
|
||||||
if (AppUser is null)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("User not loaded or not logged in.");
|
|
||||||
}
|
|
||||||
|
|
||||||
PrivateEntity PrivateEntity = new()
|
|
||||||
{
|
|
||||||
UserId = AppUser.Id,
|
|
||||||
CreationTime = DateTime.Now,
|
|
||||||
GlobalEntityId = GlobalEntity.Id,
|
|
||||||
UserWatchStatusId = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
CouchLogDB.PrivateEntities.Add(PrivateEntity);
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
|
|
||||||
UserPrivateEntityIds.Add(GlobalEntity.Id);
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddGenreToList(int GenreId)
|
|
||||||
{
|
|
||||||
if (!GenreIds.Contains(GenreId))
|
|
||||||
{
|
|
||||||
GenreIds.Add(GenreId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeleteEntity(GlobalEntity entity)
|
|
||||||
{
|
|
||||||
if(entity.PicturePath != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.Delete(Path.Combine("wwwroot", entity.PicturePath));
|
|
||||||
}
|
|
||||||
catch(Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CouchLogDB.GlobalEntities.Remove(entity);
|
|
||||||
|
|
||||||
await CouchLogDB.SaveChangesAsync();
|
|
||||||
|
|
||||||
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
/*For Development*/
|
|
||||||
/** {
|
|
||||||
outline: 1px solid red !important;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
.Entity-Container {
|
|
||||||
color:aliceblue
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container:hover {
|
|
||||||
color: rgba(0,255,255,0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Card {
|
|
||||||
position: relative;
|
|
||||||
max-width: 275px;
|
|
||||||
background: #111;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 15px;
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
text-align: center;
|
|
||||||
gap: 0.75rem;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.Entity-Container-Card h2 {
|
|
||||||
color: #0ff;
|
|
||||||
font-size: 2rem;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Card::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: -50%;
|
|
||||||
left: -50%;
|
|
||||||
width: 200%;
|
|
||||||
height: 200%;
|
|
||||||
background: linear-gradient( 0deg, transparent, transparent 30%, rgba(0,255,255,0.3) );
|
|
||||||
transform: rotate(-45deg);
|
|
||||||
transition: all 0.5s ease;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Card:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
box-shadow: 0 0 20px rgba(0,255,255,0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Card:hover::before {
|
|
||||||
opacity: 1;
|
|
||||||
transform: rotate(-45deg) translateY(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Image {
|
|
||||||
margin: 4px;
|
|
||||||
margin-top: 6px;
|
|
||||||
max-width: 256px;
|
|
||||||
max-height: 256px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Button {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column
|
|
||||||
}
|
|
||||||
|
|
||||||
.CreateNewGlobalEntity-Container {
|
|
||||||
background: #111;
|
|
||||||
border-radius: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Entity-Container-Menu-Button {
|
|
||||||
position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
right: 7.5px;
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
color: #0dcaf0;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
@using CouchLog.Data
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
|
||||||
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
@using CouchLog.Data
|
||||||
|
@using Microsoft.AspNetCore.Identity
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
|
||||||
|
@inject ApplicationDbContext CouchLogDB
|
||||||
|
@inject UserManager<ApplicationUser> UserManager
|
||||||
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
|
<MudDialog>
|
||||||
|
<TitleContent>
|
||||||
|
<MudText Typo="Typo.h6">
|
||||||
|
Add Global Entity
|
||||||
|
</MudText>
|
||||||
|
</TitleContent>
|
||||||
|
<DialogContent>
|
||||||
|
<EditForm Model="@newGlobalEntity" OnSubmit="CreateNewGlobalEntity">
|
||||||
|
<DataAnnotationsValidator />
|
||||||
|
<ValidationSummary />
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="Title" class="form-label">Title</label>
|
||||||
|
<InputText id="Title" class="form-control" @bind-Value="newGlobalEntity.Title"></InputText>
|
||||||
|
<ValidationMessage For="@(() => newGlobalEntity.Title)"></ValidationMessage>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="Type" class="form-label">Type</label>
|
||||||
|
<select id="Type" class="form-select" @bind="SelectedMediaTypeId">
|
||||||
|
@foreach(MediaType Type in MediaTypes)
|
||||||
|
{
|
||||||
|
<option value="@Type.Id">@Type.Name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
@*<div class="mb-3">
|
||||||
|
<label for="Picture" class="form-label">Picture</label>
|
||||||
|
<InputFile OnChange="@LoadImage" accept="image/*" />
|
||||||
|
@if (!string.IsNullOrEmpty(ImageString))
|
||||||
|
{
|
||||||
|
<img src="@ImageString" style="max-width: 256px; max-height: 256px;" />
|
||||||
|
}
|
||||||
|
</div>*@
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="Genres" class="form-label">Genres</label>
|
||||||
|
@foreach(Genre Genre in Genres)
|
||||||
|
{
|
||||||
|
<button class="btn-primary btn me-2" value="@Genre.Id" type="button" @onclick="() => AddGenreIdToGenreIdList(Genre.Id)">@Genre.Name</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<InputCheckbox DisplayName="isPrivate" @bind-Value="IsPrivate" ></InputCheckbox>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn-success btn">Create new Global Entity</button>
|
||||||
|
</EditForm>
|
||||||
|
</DialogContent>
|
||||||
|
|
||||||
|
@*Dialog Footer*@
|
||||||
|
<DialogActions>
|
||||||
|
<MudButton OnClick="Cancel">Cancel</MudButton>
|
||||||
|
</DialogActions>
|
||||||
|
</MudDialog>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private ApplicationUser AppUser = null!;
|
||||||
|
|
||||||
|
[CascadingParameter]
|
||||||
|
private IMudDialogInstance MudDialog { get; set; }
|
||||||
|
private void Cancel() => MudDialog.Cancel();
|
||||||
|
|
||||||
|
|
||||||
|
private List<MediaType> MediaTypes = new();
|
||||||
|
private List<Genre> Genres = new();
|
||||||
|
|
||||||
|
#region ForNewGlobalEntity
|
||||||
|
private GlobalEntity newGlobalEntity = new();
|
||||||
|
private IBrowserFile? Picture;
|
||||||
|
private int SelectedMediaTypeId;
|
||||||
|
private bool IsPrivate;
|
||||||
|
private List<int> GenreIds = new ();
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
var AuthState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
|
||||||
|
var User = AuthState.User;
|
||||||
|
AppUser = (await UserManager.GetUserAsync(User))!;
|
||||||
|
|
||||||
|
if(AppUser == null)
|
||||||
|
{
|
||||||
|
throw new Exception("Not Authenticated");
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaTypes = await CouchLogDB.MediaType.OrderBy(Type => Type.Id).ToListAsync();
|
||||||
|
Genres = await CouchLogDB.Genres.OrderBy(Type => Type.Id).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task CreateNewGlobalEntity()
|
||||||
|
{
|
||||||
|
if (Picture is null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("No Picture selected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AppUser is null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("User not loaded or not logged in.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Save Picture and Name it
|
||||||
|
string NewFileName = $"{newGlobalEntity.Title.Replace(" ", "-")}-{Guid.NewGuid()}{Path.GetExtension(Picture.Name)}";
|
||||||
|
string PicturePath = Path.Combine("wwwroot", "Pictures", NewFileName);
|
||||||
|
using FileStream FileStream = File.Create(PicturePath);
|
||||||
|
await Picture.OpenReadStream().CopyToAsync(FileStream);
|
||||||
|
//await Picture.OpenReadStream(maxAllowedSize: 10_000_000).CopyToAsync(FileStream);
|
||||||
|
|
||||||
|
newGlobalEntity.PicturePath = $"Pictures/{NewFileName}";
|
||||||
|
newGlobalEntity.CreatorId = AppUser.Id;
|
||||||
|
newGlobalEntity.TypeId = SelectedMediaTypeId;
|
||||||
|
newGlobalEntity.CreationTime = DateTime.Now;
|
||||||
|
newGlobalEntity.IsPrivate = IsPrivate;
|
||||||
|
|
||||||
|
CouchLogDB.Add(newGlobalEntity);
|
||||||
|
await CouchLogDB.SaveChangesAsync();
|
||||||
|
|
||||||
|
foreach(int GenreId in GenreIds)
|
||||||
|
{
|
||||||
|
LinkTableGlobalGenre LinkTableGlobalGenre = new() { GenreId = GenreId, GlobalEntityId = newGlobalEntity.Id };
|
||||||
|
CouchLogDB.Add(LinkTableGlobalGenre);
|
||||||
|
}
|
||||||
|
|
||||||
|
await CouchLogDB.SaveChangesAsync();
|
||||||
|
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddGenreIdToGenreIdList(int GenreId)
|
||||||
|
{
|
||||||
|
if (!GenreIds.Contains(GenreId))
|
||||||
|
{
|
||||||
|
GenreIds.Add(GenreId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
45
CouchLog/Components/Pages/GlobalList/GlobalList.razor
Normal file
45
CouchLog/Components/Pages/GlobalList/GlobalList.razor
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
@page "/GlobalList"
|
||||||
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
@using CouchLog.Data
|
||||||
|
@using Microsoft.AspNetCore.Identity
|
||||||
|
@using Microsoft.EntityFrameworkCore
|
||||||
|
@using CouchLog.Components.Pages.GlobalList.Dialogs
|
||||||
|
|
||||||
|
@inject ApplicationDbContext CouchLogDB
|
||||||
|
@inject UserManager<ApplicationUser> UserManager
|
||||||
|
@inject AuthenticationStateProvider AuthenticationStateProvider
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject IDialogService DialogService
|
||||||
|
|
||||||
|
@attribute [Authorize]
|
||||||
|
|
||||||
|
<PageTitle>GlobalList</PageTitle>
|
||||||
|
|
||||||
|
<MudContainer>
|
||||||
|
@*Top of the Page*@
|
||||||
|
<MudContainer>
|
||||||
|
<MudStack Row="true" AlignItems="AlignItems.Center">
|
||||||
|
@*Page Title*@
|
||||||
|
<MudText Typo="Typo.h3" Style="font-weight: bold;">Global List</MudText>
|
||||||
|
|
||||||
|
@*Spacer*@
|
||||||
|
<MudSpacer />
|
||||||
|
|
||||||
|
@*Button for adding GlobalEntity*@
|
||||||
|
<MudTooltip Text="Add GlobalEntity">
|
||||||
|
<MudFab StartIcon="@Icons.Material.Filled.Add" Color="Color.Primary" OnClick="OpenAddNewGlobalEntityDialog"/>
|
||||||
|
</MudTooltip>
|
||||||
|
</MudStack>
|
||||||
|
</MudContainer>
|
||||||
|
</MudContainer>
|
||||||
|
|
||||||
|
|
||||||
|
@code
|
||||||
|
{
|
||||||
|
private async Task OpenAddNewGlobalEntityDialog()
|
||||||
|
{
|
||||||
|
var dialog = await DialogService.ShowAsync<AddNewGlobalEntityDialog>("Add new Global Entity");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,13 @@
|
|||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Information",
|
||||||
"Microsoft.AspNetCore": "Warning"
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
},
|
||||||
|
"Console": {
|
||||||
|
"FormatterName": "simple",
|
||||||
|
"FormatterOptions": {
|
||||||
|
"TimestampFormat": "[HH:mm:ss]",
|
||||||
|
"SingleLine": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AllowedHosts": "*"
|
"AllowedHosts": "*"
|
||||||
|
|||||||
Reference in New Issue
Block a user