person page created, small fixes

This commit is contained in:
2024-10-22 02:34:02 +02:00
Unverified
parent d768c61871
commit bcd4628ba2
13 changed files with 224 additions and 41 deletions

View File

@@ -12,6 +12,7 @@ public interface IPersonsWebAPIService
Task DeletePerson(long id, Action? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null); Task DeletePerson(long id, Action? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null);
Task GetPersonsViewRank(int? first = null, int? days = null, Action<IEnumerable<PersonResponse>>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null); Task GetPersonsViewRank(int? first = null, int? days = null, Action<IEnumerable<PersonResponse>>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null);
Task PostPersonView(long personId, Action? successAction = null, Action? notFoundAction = null);
Task GetPersonPhoto(long id, Action<PersonPhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null); Task GetPersonPhoto(long id, Action<PersonPhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? notFoundAction = null);
Task PutPersonPhoto(long id, PersonPhotoRequest data, Action<PersonPhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null); Task PutPersonPhoto(long id, PersonPhotoRequest data, Action<PersonPhotoResponse>? successAction = null, Action<IDictionary<string, string[]>>? badRequestAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null);

View File

@@ -139,7 +139,7 @@ public class PersonsWebAPIService : BaseWebAPIService, IPersonsWebAPIService
.ExecuteAction(); .ExecuteAction();
} }
public async Task PostPersonsView(long personId, Action? successAction = null, Action? notFoundAction = null) public async Task PostPersonView(long personId, Action? successAction = null, Action? notFoundAction = null)
{ {
string url = GetUrl(EndpointsConfiguration.Persons.PostPersonsView, personId); string url = GetUrl(EndpointsConfiguration.Persons.PostPersonsView, personId);

View File

@@ -0,0 +1,22 @@
<div class="container-grid mt-grid">
<div class="row">
<div class="col-auto">
<PictureComponent Picture="@(_poster)" Placeholder="@(PosterPlaceholder)" AlternativeText="poster" Height="350"/>
</div>
<div class="col">
<div class="d-flex flex-column justify-content-end h-100">
<h1 class="fw-bold title-shadow">@(Name)</h1>
<div class="d-flex flex-column gap-3">
@if (!string.IsNullOrWhiteSpace(Subname))
{
<span class="fst-italic description-shadow">@(Subname)</span>
}
@if (!string.IsNullOrWhiteSpace(Description))
{
<span class="description-shadow">@(Description)</span>
}
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,51 @@
using Microsoft.AspNetCore.Components;
using WatchIt.Common.Model;
namespace WatchIt.Website.Components.Common.Panels;
public partial class ItemPageHeaderPanelComponent : ComponentBase
{
#region PARAMETERS
[Parameter] public required string Name { get; set; }
[Parameter] public string? Subname { get; set; }
[Parameter] public string? Description { get; set; }
[Parameter] public required string PosterPlaceholder { get; set; }
[Parameter] public required Func<Action<Picture>, Task> GetPosterMethod { get; set; }
#endregion
#region FIELDS
private Picture? _poster;
#endregion
#region PRIVATE METHODS
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
List<Task> endTasks = new List<Task>(1);
// STEP 0
endTasks.AddRange(
[
GetPosterMethod(data => _poster = data)
]);
// END
await Task.WhenAll(endTasks);
StateHasChanged();
}
}
#endregion
}

View File

@@ -0,0 +1,13 @@
/* CLASSES */
.mt-grid {
margin-top: 9rem !important;
}
.title-shadow {
text-shadow: 2px 2px 2px #000;
}
.description-shadow {
text-shadow: 1px 1px 1px #000;
}

View File

@@ -2,7 +2,7 @@
@if (_loaded) @if (_loaded)
{ {
<div class="vstack gap-3"> <div class="vstack gap-3">
<PictureComponent Picture="@(_pictureSelected)" Placeholder="@(PicturePlaceholder)" AlternativeText="poster" Width="@(ContentWidth)"/> <PictureComponent Picture="@(_pictureSelected)" Placeholder="@(PicturePlaceholder)" AlternativeText="poster" Width="@(ContentWidth)" AspectRatio="PictureComponent.PictureComponentAspectRatio.Default"/>
<InputFile class="form-control content-width" OnChange="Load" disabled="@(!Id.HasValue)" autocomplete="off"/> <InputFile class="form-control content-width" OnChange="Load" disabled="@(!Id.HasValue)" autocomplete="off"/>
@if (_pictureChanged || _pictureSaved is not null) @if (_pictureChanged || _pictureSaved is not null)
{ {

View File

@@ -1,7 +1 @@
<img id="imgObject" class="rounded-2 shadow object-fit-cover @(Class)" src="@(Picture is not null ? Picture.ToString() : Placeholder)" alt="@(AlternativeText)" @attributes="@(_attributes)"/> <img id="imgObject" class="rounded-2 shadow object-fit-cover @(Class)" src="@(Picture is not null ? Picture.ToString() : Placeholder)" alt="@(AlternativeText)" @attributes="@(_attributes)" style="aspect-ratio: @(AspectRatio.ToString());"/>
<style>
#imgObject {
aspect-ratio: @(AspectRatio.ToString());
}
</style>

View File

@@ -30,32 +30,13 @@ else
{ {
if (string.IsNullOrWhiteSpace(_error)) if (string.IsNullOrWhiteSpace(_error))
{ {
<div class="row mt-9">
<div class="col-auto">
<PictureComponent Picture="@(_poster)" Placeholder="/assets/media_poster.png" AlternativeText="poster" Width="200"/>
</div>
<div class="col">
<div class="d-flex h-100">
<div class="container-grid align-self-end">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<h1 class="align-self-end title-shadow"> <ItemPageHeaderPanelComponent Name="@(_media.Title)"
<strong>@_media.Title</strong> Subname="@(_media.OriginalTitle)"
</h1> Description="@(_media.Description)"
</div> PosterPlaceholder="/assets/media_poster.png"
</div> GetPosterMethod="@(action => MediaWebAPIService.GetMediaPoster(_media.Id, action))"/>
@if (!string.IsNullOrWhiteSpace(_media.Description))
{
<div class="row">
<div class="col">
<div class="description-shadow">
@_media.Description
</div>
</div>
</div>
}
</div>
</div>
</div> </div>
</div> </div>
<div class="row mt-3 gx-3"> <div class="row mt-3 gx-3">
@@ -68,12 +49,6 @@ else
<div class="metadata-pill"> <div class="metadata-pill">
<strong>@(_media.Type == MediaType.Movie ? "Movie" : "TV Series")</strong> <strong>@(_media.Type == MediaType.Movie ? "Movie" : "TV Series")</strong>
</div> </div>
@if (!string.IsNullOrWhiteSpace(_media.OriginalTitle))
{
<div class="metadata-pill">
<strong>Original title:</strong> @_media.OriginalTitle
</div>
}
@if (_media.ReleaseDate is not null) @if (_media.ReleaseDate is not null)
{ {
<div class="metadata-pill"> <div class="metadata-pill">

View File

@@ -90,7 +90,6 @@ public partial class MediaPage : ComponentBase
[ [
MediaWebAPIService.PostMediaView(Id), MediaWebAPIService.PostMediaView(Id),
MediaWebAPIService.GetMediaPhotoRandomBackground(Id, data => Layout.BackgroundPhoto = data), MediaWebAPIService.GetMediaPhotoRandomBackground(Id, data => Layout.BackgroundPhoto = data),
MediaWebAPIService.GetMediaPoster(Id, data => _poster = data),
MediaWebAPIService.GetMediaGenres(Id, data => _genres = data), MediaWebAPIService.GetMediaGenres(Id, data => _genres = data),
MediaWebAPIService.GetMediaRating(Id, data => _globalRating = data), MediaWebAPIService.GetMediaRating(Id, data => _globalRating = data),
_media.Type == MediaType.Movie ? MoviesWebAPIService.GetMovie(Id, data => _movie = data) : SeriesWebAPIService.GetSeries(Id, data => _series = data), _media.Type == MediaType.Movie ? MoviesWebAPIService.GetMovie(Id, data => _movie = data) : SeriesWebAPIService.GetSeries(Id, data => _series = data),

View File

@@ -0,0 +1,51 @@
@using System.Text
@page "/person/{id:long}"
@{
StringBuilder sb = new StringBuilder(" - WatchIt");
if (!_loaded) { sb.Insert(0, "Loading..."); }
else if (_person is null) { sb.Insert(0, "Error"); }
else { sb.Insert(0, _person.Name); }
<PageTitle>@(sb.ToString())</PageTitle>
}
<div class="container-grid">
@if (_loaded)
{
if (_person is not null)
{
<div class="row">
<div class="col">
<ItemPageHeaderPanelComponent Name="@(_person.Name)"
Subname="@(_person.FullName)"
Description="@(_person.Description)"
PosterPlaceholder="/assets/person_poster.png"
GetPosterMethod="@(action => PersonsWebAPIService.GetPersonPhoto(_person.Id, action))"/>
</div>
</div>
}
else
{
<div class="row">
<div class="col">
<ErrorPanelComponent ErrorMessage="@($"Person with ID {Id} was not found")"/>
</div>
</div>
}
}
else
{
<div class="row">
<div class="col">
<div class="m-5">
<LoadingComponent/>
</div>
</div>
</div>
}
</div>

View File

@@ -0,0 +1,72 @@
using Microsoft.AspNetCore.Components;
using WatchIt.Common.Model.Persons;
using WatchIt.Website.Layout;
using WatchIt.Website.Services.WebAPI.Persons;
namespace WatchIt.Website.Pages;
public partial class PersonPage : ComponentBase
{
#region SERVICES
[Inject] private IPersonsWebAPIService PersonsWebAPIService { get; set; } = default!;
#endregion
#region PARAMETERS
[Parameter] public long Id { get; set; }
[CascadingParameter] public MainLayout Layout { get; set; } = default!;
#endregion
#region FIELDS
private bool _loaded;
private PersonResponse? _person;
#endregion
#region PRIVATE METHODS
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
// INIT
Layout.BackgroundPhoto = null;
List<Task> step1Tasks = new List<Task>(1);
List<Task> endTasks = new List<Task>(1);
// STEP 0
step1Tasks.AddRange(
[
PersonsWebAPIService.GetPerson(Id, data => _person = data)
]);
// STEP 1
await Task.WhenAll(step1Tasks);
endTasks.AddRange(
[
PersonsWebAPIService.PostPersonView(Id),
]);
// END
await Task.WhenAll(endTasks);
_loaded = true;
StateHasChanged();
}
}
#endregion
}

View File

@@ -51,4 +51,9 @@
<PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.1" /> <PackageReference Include="Blazorise.Icons.FontAwesome" Version="1.6.1" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Components\Pages\PersonPage\Panels\" />
<Folder Include="Components\Pages\PersonPage\Subcomponents\" />
</ItemGroup>
</Project> </Project>