diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs new file mode 100644 index 0000000..1307901 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs @@ -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 +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaType.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaType.cs new file mode 100644 index 0000000..71df0ad --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Media/MediaType.cs @@ -0,0 +1,7 @@ +namespace WatchIt.Common.Model.Media; + +public enum MediaType +{ + Movie, + Series +} \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs index de9adc1..f09ca53 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs @@ -12,6 +12,12 @@ namespace WatchIt.WebAPI.Controllers; [Route("media")] public class MediaController(IMediaControllerService mediaControllerService) { + [HttpGet("{id}")] + [AllowAnonymous] + [ProducesResponseType(typeof(MediaResponse), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetMedia([FromRoute] long id) => await mediaControllerService.GetMedia(id); + [HttpGet("{id}/genres")] [AllowAnonymous] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs index 0e63173..ab543a0 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/IMediaControllerService.cs @@ -5,6 +5,7 @@ namespace WatchIt.WebAPI.Services.Controllers.Media; public interface IMediaControllerService { + Task GetMedia(long mediaId); Task GetGenres(long mediaId); Task PostGenre(long mediaId, short genreId); Task DeleteGenre(long mediaId, short genreId); diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs index b67ad58..daedf0c 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Media/MediaControllerService.cs @@ -13,15 +13,30 @@ public class MediaControllerService(DatabaseContext database, IUserService userS { #region PUBLIC METHODS - public async Task GetGenres(long mediaId) + public async Task 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) { return RequestResult.NotFound(); } - IEnumerable 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 GetGenres(long mediaId) + { + Database.Model.Media.Media? item = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); + if (item is null) + { + return RequestResult.NotFound(); + } + + IEnumerable genres = item.MediaGenres.Select(x => new GenreResponse(x.Genre)); return RequestResult.Ok(genres); } diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Utility/WatchIt.Website.Services.Utility.Configuration/Model/Media.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Utility/WatchIt.Website.Services.Utility.Configuration/Model/Media.cs index f7adb93..bbe65e0 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Utility/WatchIt.Website.Services.Utility.Configuration/Model/Media.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Utility/WatchIt.Website.Services.Utility.Configuration/Model/Media.cs @@ -3,6 +3,7 @@ public class Media { public string Base { get; set; } + public string Get { get; set; } public string GetGenres { get; set; } public string PostGenre { get; set; } public string DeleteGenre { get; set; } diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/IMediaWebAPIService.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/IMediaWebAPIService.cs index 9c79dec..20a851f 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/IMediaWebAPIService.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/IMediaWebAPIService.cs @@ -5,6 +5,7 @@ namespace WatchIt.Website.Services.WebAPI.Media; public interface IMediaWebAPIService { + Task Get(long mediaId, Action successAction = null, Action? notFoundAction = null); Task GetGenres(long mediaId, Action>? successAction = 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? successAction = null, Action? notFoundAction = null); diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/MediaWebAPIService.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/MediaWebAPIService.cs index 6124439..fbdb905 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/MediaWebAPIService.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.WebAPI/WatchIt.Website.Services.WebAPI.Media/MediaWebAPIService.cs @@ -10,6 +10,18 @@ namespace WatchIt.Website.Services.WebAPI.Media; public class MediaWebAPIService(IHttpClientService httpClientService, IConfigurationService configurationService) : BaseWebAPIService(configurationService), IMediaWebAPIService { #region PUBLIC METHODS + + public async Task Get(long mediaId, Action 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>? successAction = null, Action? notFoundAction = null) { diff --git a/WatchIt.Website/WatchIt.Website/App.razor b/WatchIt.Website/WatchIt.Website/App.razor index eb24a1c..0f46276 100644 --- a/WatchIt.Website/WatchIt.Website/App.razor +++ b/WatchIt.Website/WatchIt.Website/App.razor @@ -9,7 +9,7 @@ - + diff --git a/WatchIt.Website/WatchIt.Website/Components/LoadingPageComponent.razor b/WatchIt.Website/WatchIt.Website/Components/LoadingPageComponent.razor new file mode 100644 index 0000000..ea3d99a --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/LoadingPageComponent.razor @@ -0,0 +1,12 @@ +
+
+
+
+
+
+
+

Loading...

+
+
+
+
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/LoadingPageComponent.razor.css b/WatchIt.Website/WatchIt.Website/Components/LoadingPageComponent.razor.css new file mode 100644 index 0000000..7545a1d --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/LoadingPageComponent.razor.css @@ -0,0 +1,11 @@ +/* IDS */ + +#spinner { + width: 5rem; + height: 5rem; +} + +#text { + font-size: 25px; + border-width: 0.4rem; +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor b/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor new file mode 100644 index 0000000..c8a89ca --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor @@ -0,0 +1,45 @@ +@page "/media/{id:long}" +@using System.Text + +@layout MainLayout + + +
+ @if (_loaded) + { + if (string.IsNullOrWhiteSpace(_error)) + { +
+
+ poster +
+
+
+

@_media.Title

+
+
+
+
+
+
+ Test +
+
+
+ } + else + { +
+
+
+

@_error

+
+
+
+ } + } + else + { + + } +
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs new file mode 100644 index 0000000..cb813b2 --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs @@ -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 userTask = AuthenticationService.GetUserAsync(); + Task posterTask = MediaWebAPIService.GetPoster(Id, data => _poster = data); + + await Task.WhenAll( + [ + userTask, + posterTask + ]); + + _user = await userTask; + } + + _loaded = true; + StateHasChanged(); + } + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/MovieDataPage.razor.css b/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.css similarity index 100% rename from WatchIt.Website/WatchIt.Website/Pages/MovieDataPage.razor.css rename to WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.css diff --git a/WatchIt.Website/WatchIt.Website/Pages/MovieDataPage.razor b/WatchIt.Website/WatchIt.Website/Pages/MovieDataPage.razor deleted file mode 100644 index 5707ab5..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/MovieDataPage.razor +++ /dev/null @@ -1 +0,0 @@ -@page "/movies/{id:long}" \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/MovieDataPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/MovieDataPage.razor.cs deleted file mode 100644 index fb86b59..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/MovieDataPage.razor.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Microsoft.AspNetCore.Components; - -namespace WatchIt.Website.Pages; - -public partial class MovieDataPage : ComponentBase -{ -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/WatchIt.Website.csproj b/WatchIt.Website/WatchIt.Website/WatchIt.Website.csproj index 2d461c2..5f45cd9 100644 --- a/WatchIt.Website/WatchIt.Website/WatchIt.Website.csproj +++ b/WatchIt.Website/WatchIt.Website/WatchIt.Website.csproj @@ -37,7 +37,6 @@ - diff --git a/WatchIt.Website/WatchIt.Website/appsettings.json b/WatchIt.Website/WatchIt.Website/appsettings.json index 76032c8..580f26a 100644 --- a/WatchIt.Website/WatchIt.Website/appsettings.json +++ b/WatchIt.Website/WatchIt.Website/appsettings.json @@ -38,6 +38,7 @@ }, "Media": { "Base": "/media", + "Get": "/{0}", "GetGenres": "/{0}/genres", "PostGenre": "/{0}/genres/{1}", "DeleteGenre": "/{0}/genres/{1}", diff --git a/WatchIt.Website/WatchIt.Website/wwwroot/app.css b/WatchIt.Website/WatchIt.Website/wwwroot/app.css index 122f5a6..265d789 100644 --- a/WatchIt.Website/WatchIt.Website/wwwroot/app.css +++ b/WatchIt.Website/WatchIt.Website/wwwroot/app.css @@ -15,6 +15,10 @@ body, html { -webkit-text-fill-color: transparent; } +.mt-9 { + margin-top: 9rem !important; +} + .panel-header { background-color: rgba(0, 0, 0, 0.8); }