From 40fdc3f3457642aeeef3f72f4bc636a85ee77ae1 Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Sat, 21 Sep 2024 21:11:21 +0200 Subject: [PATCH] media view count incrementation endpoint added, media page loading optimized, media view count incrementation on media page added --- .../MediaController.cs | 12 ++++ .../IMediaControllerService.cs | 8 ++- .../MediaControllerService.cs | 46 ++++++++++-- .../Model/Media.cs | 1 + .../IMediaWebAPIService.cs | 2 + .../MediaWebAPIService.cs | 16 +++++ .../{MediaDataPage.razor => MediaPage.razor} | 0 ...iaDataPage.razor.cs => MediaPage.razor.cs} | 70 +++++++++---------- ...DataPage.razor.css => MediaPage.razor.css} | 0 .../WatchIt.Website/appsettings.json | 1 + 10 files changed, 112 insertions(+), 44 deletions(-) rename WatchIt.Website/WatchIt.Website/Pages/{MediaDataPage.razor => MediaPage.razor} (100%) rename WatchIt.Website/WatchIt.Website/Pages/{MediaDataPage.razor.cs => MediaPage.razor.cs} (57%) rename WatchIt.Website/WatchIt.Website/Pages/{MediaDataPage.razor.css => MediaPage.razor.css} (100%) diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs index 75eb1f5..57388b9 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/MediaController.cs @@ -81,6 +81,18 @@ public class MediaController(IMediaControllerService mediaControllerService) public async Task DeleteMediaRating([FromRoute] long id) => await mediaControllerService.DeleteMediaRating(id); #endregion + + + + #region VIEW COUNT + + [HttpPost("{id}/view")] + [AllowAnonymous] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task PostMediaView([FromRoute] long id) => await mediaControllerService.PostMediaView(id); + + #endregion 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 f700a4a..7e26c60 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 @@ -15,10 +15,12 @@ public interface IMediaControllerService Task GetMediaRatingByUser(long mediaId, long userId); Task PutMediaRating(long mediaId, MediaRatingRequest data); Task DeleteMediaRating(long mediaId); + + Task PostMediaView(long mediaId); - Task GetMediaPoster(long id); - Task PutMediaPoster(long id, MediaPosterRequest data); - Task DeleteMediaPoster(long id); + Task GetMediaPoster(long mediaId); + Task PutMediaPoster(long mediaId, MediaPosterRequest data); + Task DeleteMediaPoster(long mediaId); Task GetPhoto(Guid id); Task GetPhotos(MediaPhotoQueryParameters query); 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 1dd91c8..7f4281d 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 @@ -5,6 +5,7 @@ using WatchIt.Common.Model.Media; using WatchIt.Database; using WatchIt.Database.Model.Media; using WatchIt.Database.Model.Rating; +using WatchIt.Database.Model.ViewCount; using WatchIt.WebAPI.Services.Controllers.Common; using WatchIt.WebAPI.Services.Utility.User; @@ -182,13 +183,46 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.Ok(); } + #endregion + + #region View count + + public async Task PostMediaView(long mediaId) + { + Database.Model.Media.Media? item = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); + if (item is null) + { + return RequestResult.NotFound(); + } + + DateOnly dateNow = DateOnly.FromDateTime(DateTime.Now); + ViewCountMedia? viewCount = await database.ViewCountsMedia.FirstOrDefaultAsync(x => x.MediaId == mediaId && x.Date == dateNow); + if (viewCount is null) + { + viewCount = new ViewCountMedia + { + MediaId = mediaId, + Date = dateNow, + ViewCount = 1 + }; + await database.ViewCountsMedia.AddAsync(viewCount); + } + else + { + viewCount.ViewCount++; + } + await database.SaveChangesAsync(); + + return RequestResult.Ok(); + } + #endregion #region Poster - public async Task GetMediaPoster(long id) + public async Task GetMediaPoster(long mediaId) { - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == id); + Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); if (media is null) { return RequestResult.BadRequest(); @@ -204,7 +238,7 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.Ok(data); } - public async Task PutMediaPoster(long id, MediaPosterRequest data) + public async Task PutMediaPoster(long mediaId, MediaPosterRequest data) { UserValidator validator = userService.GetValidator().MustBeAdmin(); if (!validator.IsValid) @@ -212,7 +246,7 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.Forbidden(); } - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == id); + Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); if (media is null) { return RequestResult.BadRequest(); @@ -236,7 +270,7 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.Ok(); } - public async Task DeleteMediaPoster(long id) + public async Task DeleteMediaPoster(long mediaId) { UserValidator validator = userService.GetValidator().MustBeAdmin(); if (!validator.IsValid) @@ -244,7 +278,7 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.Forbidden(); } - Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == id); + Database.Model.Media.Media? media = await database.Media.FirstOrDefaultAsync(x => x.Id == mediaId); if (media?.MediaPosterImage != null) { 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 c2ff6ab..fb215e2 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 @@ -11,6 +11,7 @@ public class Media public string GetMediaRatingByUser { get; set; } public string PutMediaRating { get; set; } public string DeleteMediaRating { get; set; } + public string PostMediaView { get; set; } public string GetPhotoMediaRandomBackground { get; set; } public string GetPoster { get; set; } public string PutPoster { 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 8868cae..6e9a0df 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 @@ -14,6 +14,8 @@ public interface IMediaWebAPIService Task GetMediaRatingByUser(long mediaId, long userId, Action? successAction = null, Action? notFoundAction = null); Task PutMediaRating(long mediaId, MediaRatingRequest body, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null, Action? notFoundAction = null); Task DeleteMediaRating(long mediaId, Action? successAction = null, Action? unauthorizedAction = null); + + Task PostMediaView(long mediaId, Action? successAction = null, Action? notFoundAction = null); Task GetPhotoMediaRandomBackground(long mediaId, Action? successAction = 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 16b00df..e8541bd 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 @@ -113,6 +113,22 @@ public class MediaWebAPIService(IHttpClientService httpClientService, IConfigura } #endregion + + #region View count + + public async Task PostMediaView(long mediaId, Action? successAction = null, Action? notFoundAction = null) + { + string url = GetUrl(EndpointsConfiguration.Media.PostMediaView, mediaId); + + HttpRequest request = new HttpRequest(HttpMethodType.Post, url); + + HttpResponse response = await httpClientService.SendRequestAsync(request); + response.RegisterActionFor2XXSuccess(successAction) + .RegisterActionFor404NotFound(notFoundAction) + .ExecuteAction(); + } + + #endregion diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor similarity index 100% rename from WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor rename to WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs similarity index 57% rename from WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs rename to WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs index 494706a..b3cfa20 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.cs @@ -9,7 +9,7 @@ using WatchIt.Website.Services.WebAPI.Movies; namespace WatchIt.Website.Pages; -public partial class MediaDataPage : ComponentBase +public partial class MediaPage : ComponentBase { #region SERVICES @@ -56,49 +56,49 @@ public partial class MediaDataPage : ComponentBase { if (firstRender) { - await MediaWebAPIService.GetMedia(Id, data => _media = data, () => _error = $"Media with id {Id} was not found"); - + List step1Tasks = new List(); + List step2Tasks = new List(); + List endTasks = new List(); + + // STEP 0 + step1Tasks.AddRange( + [ + MediaWebAPIService.GetMedia(Id, data => _media = data, () => _error = $"Media with id {Id} was not found") + ]); + + // STEP 1 + await Task.WhenAll(step1Tasks); if (_error is null) { - Task backgroundTask = MediaWebAPIService.GetPhotoMediaRandomBackground(Id, data => _background = data); - Task posterTask = MediaWebAPIService.GetPoster(Id, data => _poster = data); - Task userTask = AuthenticationService.GetUserAsync(); - Task genresTask = MediaWebAPIService.GetMediaGenres(Id, data => _genres = data); - Task globalRatingTask = MediaWebAPIService.GetMediaRating(Id, data => _globalRating = data); - Task specificMediaTask; - if (_media.Type == MediaType.Movie) - { - specificMediaTask = MoviesWebAPIService.Get(Id, data => _movie = data); - } - else - { - // TODO: download tv series info - specificMediaTask = null; - } - - await Task.WhenAll( + step2Tasks.AddRange( [ - userTask, - specificMediaTask, - genresTask, - globalRatingTask, - backgroundTask, - posterTask, + Task.Run(async () => _user = await AuthenticationService.GetUserAsync()) ]); - - _user = await userTask; - } - - if (_user is not null) - { - Task userRatingTask = MediaWebAPIService.GetMediaRatingByUser(Id, _user.Id, data => _userRating = data); - await Task.WhenAll( + endTasks.AddRange( [ - userRatingTask, + MediaWebAPIService.PostMediaView(Id), + MediaWebAPIService.GetPhotoMediaRandomBackground(Id, data => _background = data), + MediaWebAPIService.GetPoster(Id, data => _poster = data), + MediaWebAPIService.GetMediaGenres(Id, data => _genres = data), + MediaWebAPIService.GetMediaRating(Id, data => _globalRating = data), + _media.Type == MediaType.Movie ? MoviesWebAPIService.Get(Id, data => _movie = data) : Task.CompletedTask, ]); } + // STEP 2 + await Task.WhenAll(step2Tasks); + if (_error is null && _user is not null) + { + endTasks.AddRange( + [ + MediaWebAPIService.GetMediaRatingByUser(Id, _user.Id, data => _userRating = data) + ]); + } + + // END + await Task.WhenAll(endTasks); + _loaded = true; StateHasChanged(); } diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.css b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.css similarity index 100% rename from WatchIt.Website/WatchIt.Website/Pages/MediaDataPage.razor.css rename to WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor.css diff --git a/WatchIt.Website/WatchIt.Website/appsettings.json b/WatchIt.Website/WatchIt.Website/appsettings.json index c93fcd9..8da2d13 100644 --- a/WatchIt.Website/WatchIt.Website/appsettings.json +++ b/WatchIt.Website/WatchIt.Website/appsettings.json @@ -46,6 +46,7 @@ "GetMediaRatingByUser": "/{0}/rating/{1}", "PutMediaRating": "/{0}/rating", "DeleteMediaRating": "/{0}/rating", + "PostMediaView": "/{0}/view", "GetPhotoMediaRandomBackground": "/{0}/photos/random_background", "GetPoster": "/{0}/poster",