movie page added
This commit is contained in:
36
WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs
Normal file
36
WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace WatchIt.Common.Model.Media;
|
||||||
|
|
||||||
|
public class MediaResponse : Media
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
public MediaType Type { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
[JsonConstructor]
|
||||||
|
public MediaResponse() {}
|
||||||
|
|
||||||
|
[SetsRequiredMembers]
|
||||||
|
public MediaResponse(Database.Model.Media.Media media, MediaType mediaType)
|
||||||
|
{
|
||||||
|
Id = media.Id;
|
||||||
|
Title = media.Title;
|
||||||
|
OriginalTitle = media.OriginalTitle;
|
||||||
|
Description = media.Description;
|
||||||
|
ReleaseDate = media.ReleaseDate;
|
||||||
|
Length = media.Length;
|
||||||
|
Type = mediaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
7
WatchIt.Common/WatchIt.Common.Model/Media/MediaType.cs
Normal file
7
WatchIt.Common/WatchIt.Common.Model/Media/MediaType.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace WatchIt.Common.Model.Media;
|
||||||
|
|
||||||
|
public enum MediaType
|
||||||
|
{
|
||||||
|
Movie,
|
||||||
|
Series
|
||||||
|
}
|
||||||
@@ -12,6 +12,12 @@ namespace WatchIt.WebAPI.Controllers;
|
|||||||
[Route("media")]
|
[Route("media")]
|
||||||
public class MediaController(IMediaControllerService mediaControllerService)
|
public class MediaController(IMediaControllerService mediaControllerService)
|
||||||
{
|
{
|
||||||
|
[HttpGet("{id}")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
[ProducesResponseType(typeof(MediaResponse), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<ActionResult> GetMedia([FromRoute] long id) => await mediaControllerService.GetMedia(id);
|
||||||
|
|
||||||
[HttpGet("{id}/genres")]
|
[HttpGet("{id}/genres")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[ProducesResponseType(typeof(IEnumerable<GenreResponse>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(IEnumerable<GenreResponse>), StatusCodes.Status200OK)]
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace WatchIt.WebAPI.Services.Controllers.Media;
|
|||||||
|
|
||||||
public interface IMediaControllerService
|
public interface IMediaControllerService
|
||||||
{
|
{
|
||||||
|
Task<RequestResult> GetMedia(long mediaId);
|
||||||
Task<RequestResult> GetGenres(long mediaId);
|
Task<RequestResult> GetGenres(long mediaId);
|
||||||
Task<RequestResult> PostGenre(long mediaId, short genreId);
|
Task<RequestResult> PostGenre(long mediaId, short genreId);
|
||||||
Task<RequestResult> DeleteGenre(long mediaId, short genreId);
|
Task<RequestResult> DeleteGenre(long mediaId, short genreId);
|
||||||
|
|||||||
@@ -13,15 +13,30 @@ public class MediaControllerService(DatabaseContext database, IUserService userS
|
|||||||
{
|
{
|
||||||
#region PUBLIC METHODS
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
public async Task<RequestResult> GetGenres(long mediaId)
|
public async Task<RequestResult> GetMedia(long mediaId)
|
||||||
{
|
{
|
||||||
MediaMovie? item = await database.MediaMovies.FirstOrDefaultAsync(x => x.Id == mediaId);
|
Database.Model.Media.Media? item = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId);
|
||||||
if (item is null)
|
if (item is null)
|
||||||
{
|
{
|
||||||
return RequestResult.NotFound();
|
return RequestResult.NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<GenreResponse> genres = item.Media.MediaGenres.Select(x => new GenreResponse(x.Genre));
|
MediaMovie? movie = await database.MediaMovies.FirstOrDefaultAsync(x => x.Id == mediaId);
|
||||||
|
|
||||||
|
MediaResponse mediaResponse = new MediaResponse(item, movie is not null ? MediaType.Movie : MediaType.Series);
|
||||||
|
|
||||||
|
return RequestResult.Ok(mediaResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RequestResult> GetGenres(long mediaId)
|
||||||
|
{
|
||||||
|
Database.Model.Media.Media? item = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId);
|
||||||
|
if (item is null)
|
||||||
|
{
|
||||||
|
return RequestResult.NotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<GenreResponse> genres = item.MediaGenres.Select(x => new GenreResponse(x.Genre));
|
||||||
return RequestResult.Ok(genres);
|
return RequestResult.Ok(genres);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
public class Media
|
public class Media
|
||||||
{
|
{
|
||||||
public string Base { get; set; }
|
public string Base { get; set; }
|
||||||
|
public string Get { get; set; }
|
||||||
public string GetGenres { get; set; }
|
public string GetGenres { get; set; }
|
||||||
public string PostGenre { get; set; }
|
public string PostGenre { get; set; }
|
||||||
public string DeleteGenre { get; set; }
|
public string DeleteGenre { get; set; }
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace WatchIt.Website.Services.WebAPI.Media;
|
|||||||
|
|
||||||
public interface IMediaWebAPIService
|
public interface IMediaWebAPIService
|
||||||
{
|
{
|
||||||
|
Task Get(long mediaId, Action<MediaResponse> successAction = null, Action? notFoundAction = null);
|
||||||
Task GetGenres(long mediaId, Action<IEnumerable<GenreResponse>>? successAction = null, Action? notFoundAction = null);
|
Task GetGenres(long mediaId, Action<IEnumerable<GenreResponse>>? successAction = null, Action? notFoundAction = null);
|
||||||
Task PostGenre(long mediaId, long genreId, Action? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null, Action? notFoundAction = null);
|
Task PostGenre(long mediaId, long genreId, Action? successAction = null, Action? unauthorizedAction = null, Action? forbiddenAction = null, Action? notFoundAction = null);
|
||||||
Task GetPhotoRandomBackground(Action<MediaPhotoResponse>? successAction = null, Action? notFoundAction = null);
|
Task GetPhotoRandomBackground(Action<MediaPhotoResponse>? successAction = null, Action? notFoundAction = null);
|
||||||
|
|||||||
@@ -11,6 +11,18 @@ public class MediaWebAPIService(IHttpClientService httpClientService, IConfigura
|
|||||||
{
|
{
|
||||||
#region PUBLIC METHODS
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public async Task Get(long mediaId, Action<MediaResponse> successAction = null, Action? notFoundAction = null)
|
||||||
|
{
|
||||||
|
string url = GetUrl(EndpointsConfiguration.Media.Get, mediaId);
|
||||||
|
|
||||||
|
HttpRequest request = new HttpRequest(HttpMethodType.Get, url);
|
||||||
|
|
||||||
|
HttpResponse response = await httpClientService.SendRequestAsync(request);
|
||||||
|
response.RegisterActionFor2XXSuccess(successAction)
|
||||||
|
.RegisterActionFor404NotFound(notFoundAction)
|
||||||
|
.ExecuteAction();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task GetGenres(long mediaId, Action<IEnumerable<GenreResponse>>? successAction = null, Action? notFoundAction = null)
|
public async Task GetGenres(long mediaId, Action<IEnumerable<GenreResponse>>? successAction = null, Action? notFoundAction = null)
|
||||||
{
|
{
|
||||||
string url = GetUrl(EndpointsConfiguration.Media.GetGenres, mediaId);
|
string url = GetUrl(EndpointsConfiguration.Media.GetGenres, mediaId);
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||||
|
|
||||||
<!-- CSS -->
|
<!-- CSS -->
|
||||||
<link rel="stylesheet" href="app.css?version=0.13"/>
|
<link rel="stylesheet" href="app.css?version=0.14"/>
|
||||||
<link rel="stylesheet" href="WatchIt.Website.styles.css?version=0.12"/>
|
<link rel="stylesheet" href="WatchIt.Website.styles.css?version=0.12"/>
|
||||||
|
|
||||||
<!-- BOOTSTRAP -->
|
<!-- BOOTSTRAP -->
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="d-flex flex-column m-5">
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<div id="spinner" class="spinner-border text-dark"></div>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<p id="text" class="text-dark">Loading...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/* IDS */
|
||||||
|
|
||||||
|
#spinner {
|
||||||
|
width: 5rem;
|
||||||
|
height: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#text {
|
||||||
|
font-size: 25px;
|
||||||
|
border-width: 0.4rem;
|
||||||
|
}
|
||||||
45
WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor
Normal file
45
WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
@page "/media/{id:long}"
|
||||||
|
@using System.Text
|
||||||
|
|
||||||
|
@layout MainLayout
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container-fluid p-1 gy-2 gx-2">
|
||||||
|
@if (_loaded)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(_error))
|
||||||
|
{
|
||||||
|
<div class="row mt-9">
|
||||||
|
<div class="col-auto">
|
||||||
|
<img class="rounded-2 shadow" src="@(_poster is not null ? $"data:{_poster.MimeType};base64,{Encoding.UTF8.GetString(_poster.Image)}" : "assets/poster.png")" alt="poster" width="200" height="333"/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="d-flex h-100">
|
||||||
|
<h1 class="align-self-end font-weight-bold">@_media.Title</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col">
|
||||||
|
<div class="rounded-3 panel panel-regular">
|
||||||
|
Test
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="row">
|
||||||
|
<div class="col rounded-3 panel panel-regular m-1">
|
||||||
|
<div>
|
||||||
|
<h2 class="text-danger">@_error</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<LoadingPageComponent/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
72
WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs
Normal file
72
WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using WatchIt.Common.Model.Media;
|
||||||
|
using WatchIt.Website.Services.Utility.Authentication;
|
||||||
|
using WatchIt.Website.Services.WebAPI.Media;
|
||||||
|
using WatchIt.Website.Services.WebAPI.Movies;
|
||||||
|
|
||||||
|
namespace WatchIt.Website.Pages;
|
||||||
|
|
||||||
|
public partial class MediaDataPage : ComponentBase
|
||||||
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
[Inject] public NavigationManager NavigationManager { get; set; } = default!;
|
||||||
|
[Inject] public IAuthenticationService AuthenticationService { get; set; } = default!;
|
||||||
|
[Inject] public IMoviesWebAPIService MoviesWebAPIService { get; set; } = default!;
|
||||||
|
[Inject] public IMediaWebAPIService MediaWebAPIService { get; set; } = default!;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PARAMETERS
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public long Id { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region FIELDS
|
||||||
|
|
||||||
|
private bool _loaded = false;
|
||||||
|
private string? _error;
|
||||||
|
|
||||||
|
private MediaResponse? _media;
|
||||||
|
private MediaPosterResponse? _poster;
|
||||||
|
private User? _user;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
await MediaWebAPIService.Get(Id, data => _media = data, () => _error = $"Media with id {Id} was not found");
|
||||||
|
|
||||||
|
if (_error is null)
|
||||||
|
{
|
||||||
|
Task<User?> userTask = AuthenticationService.GetUserAsync();
|
||||||
|
Task posterTask = MediaWebAPIService.GetPoster(Id, data => _poster = data);
|
||||||
|
|
||||||
|
await Task.WhenAll(
|
||||||
|
[
|
||||||
|
userTask,
|
||||||
|
posterTask
|
||||||
|
]);
|
||||||
|
|
||||||
|
_user = await userTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
_loaded = true;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
@page "/movies/{id:long}"
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
|
|
||||||
namespace WatchIt.Website.Pages;
|
|
||||||
|
|
||||||
public partial class MovieDataPage : ComponentBase
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@@ -37,7 +37,6 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AdditionalFiles Include="Layout\MainLayout.razor" />
|
<AdditionalFiles Include="Layout\MainLayout.razor" />
|
||||||
<AdditionalFiles Include="Pages\Home.razor" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
},
|
},
|
||||||
"Media": {
|
"Media": {
|
||||||
"Base": "/media",
|
"Base": "/media",
|
||||||
|
"Get": "/{0}",
|
||||||
"GetGenres": "/{0}/genres",
|
"GetGenres": "/{0}/genres",
|
||||||
"PostGenre": "/{0}/genres/{1}",
|
"PostGenre": "/{0}/genres/{1}",
|
||||||
"DeleteGenre": "/{0}/genres/{1}",
|
"DeleteGenre": "/{0}/genres/{1}",
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ body, html {
|
|||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mt-9 {
|
||||||
|
margin-top: 9rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
.panel-header {
|
.panel-header {
|
||||||
background-color: rgba(0, 0, 0, 0.8);
|
background-color: rgba(0, 0, 0, 0.8);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user