diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs index 8a18de1..796c2b5 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs @@ -3,6 +3,7 @@ using System.Text.Json.Serialization; using WatchIt.Common.Model.Genres; using WatchIt.Common.Model.Rating; using WatchIt.Common.Query; +using WatchIt.Database.Model.Rating; namespace WatchIt.Common.Model.Media; @@ -55,7 +56,9 @@ public class MediaResponse : Media, IQueryOrderable ReleaseDate = media.ReleaseDate; Length = media.Length; Type = mediaType; - Rating = RatingResponse.Create(media.RatingMedia); + Rating = RatingResponseBuilder.Initialize() + .Add(media.RatingMedia, x => x.Rating) + .Build(); Genres = media.Genres.Select(x => new GenreResponse(x)).ToList(); } diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRatedResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRatedResponse.cs index 0e1bd31..b1d6db8 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRatedResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieRatedResponse.cs @@ -49,7 +49,9 @@ public class MovieRatedResponse : MovieResponse, IQueryOrderable x.Rating) + .Build(); Genres = mediaMovie.Media.Genres.Select(x => new GenreResponse(x)).ToList(); UserRating = response.Rating; } diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs index 2e25288..a05e782 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs @@ -54,7 +54,9 @@ public class MovieResponse : Movie, IQueryOrderable ReleaseDate = mediaMovie.Media.ReleaseDate; Length = mediaMovie.Media.Length; Budget = mediaMovie.Budget; - Rating = RatingResponse.Create(mediaMovie.Media.RatingMedia); + Rating = RatingResponseBuilder.Initialize() + .Add(mediaMovie.Media.RatingMedia, x => x.Rating) + .Build(); Genres = mediaMovie.Media.Genres.Select(x => new GenreResponse(x)).ToList(); } diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedQueryParameters.cs new file mode 100644 index 0000000..a31d5d4 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedQueryParameters.cs @@ -0,0 +1,106 @@ +using Microsoft.AspNetCore.Mvc; +using WatchIt.Common.Query; + +namespace WatchIt.Common.Model.Persons; + +public class PersonRatedQueryParameters : QueryParameters +{ + #region PROPERTIES + + [FromQuery(Name = "name")] + public string? Name { get; set; } + + [FromQuery(Name = "full_name")] + public string? FullName { get; set; } + + [FromQuery(Name = "description")] + public string? Description { get; set; } + + [FromQuery(Name = "birth_date")] + public DateOnly? BirthDate { get; set; } + + [FromQuery(Name = "birth_date_from")] + public DateOnly? BirthDateFrom { get; set; } + + [FromQuery(Name = "birth_date_to")] + public DateOnly? BirthDateTo { get; set; } + + [FromQuery(Name = "death_date")] + public DateOnly? DeathDate { get; set; } + + [FromQuery(Name = "death_date_from")] + public DateOnly? DeathDateFrom { get; set; } + + [FromQuery(Name = "death_date_to")] + public DateOnly? DeathDateTo { get; set; } + + [FromQuery(Name = "gender_id")] + public short? GenderId { get; set; } + + [FromQuery(Name = "rating_average")] + public decimal? RatingAverage { get; set; } + + [FromQuery(Name = "rating_average_from")] + public decimal? RatingAverageFrom { get; set; } + + [FromQuery(Name = "rating_average_to")] + public decimal? RatingAverageTo { get; set; } + + [FromQuery(Name = "rating_count")] + public long? RatingCount { get; set; } + + [FromQuery(Name = "rating_count_from")] + public long? RatingCountFrom { get; set; } + + [FromQuery(Name = "rating_count_to")] + public long? RatingCountTo { get; set; } + + [FromQuery(Name = "user_rating_average")] + public decimal? UserRatingAverage { get; set; } + + [FromQuery(Name = "user_rating_average_from")] + public decimal? UserRatingAverageFrom { get; set; } + + [FromQuery(Name = "user_rating_average_to")] + public decimal? UserRatingAverageTo { get; set; } + + [FromQuery(Name = "user_rating_count")] + public long? UserRatingCount { get; set; } + + [FromQuery(Name = "user_rating_count_from")] + public long? UserRatingCountFrom { get; set; } + + [FromQuery(Name = "user_rating_count_to")] + public long? UserRatingCountTo { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + protected override bool IsMeetingConditions(PersonRatedResponse item) => + ( + TestStringWithRegex(item.Name, Name) + && + TestStringWithRegex(item.FullName, FullName) + && + TestStringWithRegex(item.Description, Description) + && + TestComparable(item.BirthDate, BirthDate, BirthDateFrom, BirthDateTo) + && + TestComparable(item.DeathDate, DeathDate, DeathDateFrom, DeathDateTo) + && + Test(item.Gender?.Id, GenderId) + && + TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) + && + TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) + && + TestComparable(item.UserRating.Average, UserRatingAverage, UserRatingAverageFrom, UserRatingAverageTo) + && + TestComparable(item.UserRating.Count, UserRatingCount, UserRatingCountFrom, UserRatingCountTo) + ); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedResponse.cs new file mode 100644 index 0000000..fa61b37 --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonRatedResponse.cs @@ -0,0 +1,63 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; +using WatchIt.Common.Model.Genders; +using WatchIt.Common.Model.Rating; +using WatchIt.Common.Query; +using WatchIt.Database.Model.Rating; + +namespace WatchIt.Common.Model.Persons; + +public class PersonRatedResponse : PersonResponse, IQueryOrderable +{ + #region PROPERTIES + + [JsonIgnore] + public static IDictionary> OrderableProperties { get; } = new Dictionary> + { + { "id", x => x.Id }, + { "name", x => x.Name }, + { "full_name", x => x.FullName }, + { "description", x => x.Description }, + { "birth_date", x => x.BirthDate }, + { "death_date", x => x.BirthDate }, + { "gender", x => x.Gender.Name }, + { "rating.average", x => x.Rating.Average }, + { "rating.count", x => x.Rating.Count }, + { "user_rating.average", x => x.UserRating.Average }, + { "user_rating.count", x => x.UserRating.Count } + }; + + [JsonPropertyName("user_rating")] + public RatingResponse UserRating { get; set; } + + #endregion + + + + #region CONSTRUCTORS + + [JsonConstructor] + public PersonRatedResponse() { } + + [SetsRequiredMembers] + public PersonRatedResponse(Database.Model.Person.Person person, IEnumerable actorUserRatings, IEnumerable creatorUserRatings) + { + Id = person.Id; + Name = person.Name; + FullName = person.FullName; + Description = person.Description; + BirthDate = person.BirthDate; + DeathDate = person.DeathDate; + Gender = person.Gender is not null ? new GenderResponse(person.Gender) : null; + Rating = RatingResponseBuilder.Initialize() + .Add(person.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole), x => x.Rating) + .Add(person.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole), x => x.Rating) + .Build(); + UserRating = RatingResponseBuilder.Initialize() + .Add(actorUserRatings, x => x.Rating) + .Add(creatorUserRatings, x => x.Rating) + .Build(); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonResponse.cs index a81e5ab..1b3a264 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Persons/PersonResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Persons/PersonResponse.cs @@ -3,6 +3,7 @@ using System.Text.Json.Serialization; using WatchIt.Common.Model.Genders; using WatchIt.Common.Model.Rating; using WatchIt.Common.Query; +using WatchIt.Database.Model.Rating; namespace WatchIt.Common.Model.Persons; @@ -53,7 +54,10 @@ public class PersonResponse : Person, IQueryOrderable BirthDate = person.BirthDate; DeathDate = person.DeathDate; Gender = person.Gender is not null ? new GenderResponse(person.Gender) : null; - Rating = RatingResponse.Create(person.PersonActorRoles, person.PersonCreatorRoles); + Rating = RatingResponseBuilder.Initialize() + .Add(person.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole), x => x.Rating) + .Add(person.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole), x => x.Rating) + .Build(); } #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs index 9037814..483f298 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs @@ -25,35 +25,11 @@ public class RatingResponse public RatingResponse() {} [SetsRequiredMembers] - private RatingResponse(long ratingSum, long ratingCount) + internal RatingResponse(long ratingSum, long ratingCount) { Average = ratingCount > 0 ? (decimal)ratingSum / ratingCount : 0; Count = ratingCount; } - public static RatingResponse Create(long ratingSum, long ratingCount) => new RatingResponse(ratingSum, ratingCount); - - public static RatingResponse Create(IEnumerable ratingMedia) => Create(ratingMedia, x => x.Rating); - - public static RatingResponse Create(IEnumerable ratingPersonActorRoles) => Create(ratingPersonActorRoles, x => x.Rating); - - public static RatingResponse Create(IEnumerable ratingPersonCreatorRoles) => Create(ratingPersonCreatorRoles, x => x.Rating); - - public static RatingResponse Create(IEnumerable ratingList, Func ratingSelector) => new RatingResponse(ratingList.Sum(x => ratingSelector(x)), ratingList.Count()); - - public static RatingResponse Create(IEnumerable personActorRoles, IEnumerable personCreatorRoles) - { - IEnumerable ratingsActorRoles = personActorRoles.SelectMany(x => x.RatingPersonActorRole); - IEnumerable ratingsCreatorRoles = personCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole); - return Create(ratingsActorRoles, ratingsCreatorRoles); - } - - public static RatingResponse Create(IEnumerable ratingsActorRoles, IEnumerable ratingsCreatorRoles) - { - long ratingSum = ratingsActorRoles.Sum(x => x.Rating) + ratingsCreatorRoles.Sum(x => x.Rating); - long ratingCount = ratingsActorRoles.Count() + ratingsCreatorRoles.Count(); - return new RatingResponse(ratingSum, ratingCount); - } - #endregion } \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponseBuilder.cs b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponseBuilder.cs new file mode 100644 index 0000000..d53b4df --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponseBuilder.cs @@ -0,0 +1,35 @@ +namespace WatchIt.Common.Model.Rating; + +public class RatingResponseBuilder +{ + #region FIELDS + + private long _sum; + private long _count; + + #endregion + + + + #region CONSTRUCTORS + + private RatingResponseBuilder() { } + + public static RatingResponseBuilder Initialize() => new RatingResponseBuilder(); + + #endregion + + + + #region PUBLIC METHODS + + public RatingResponseBuilder Add(IEnumerable collection, Func selector) + { + _sum += collection.Sum(x => selector(x)); + _count += collection.Count(); + return this; + } + public RatingResponse Build() => new RatingResponse(_sum, _count); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRatedResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRatedResponse.cs index 2e47804..0cf7996 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRatedResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesRatedResponse.cs @@ -49,7 +49,9 @@ public class SeriesRatedResponse : SeriesResponse, IQueryOrderable x.Rating) + .Build(); Genres = mediaSeries.Media.Genres.Select(x => new GenreResponse(x)).ToList(); UserRating = response.Rating; } diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs index 17a0f9d..7f1c1e3 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs @@ -54,7 +54,9 @@ public class SeriesResponse : Series, IQueryOrderable ReleaseDate = mediaSeries.Media.ReleaseDate; Length = mediaSeries.Media.Length; HasEnded = mediaSeries.HasEnded; - Rating = RatingResponse.Create(mediaSeries.Media.RatingMedia); + Rating = RatingResponseBuilder.Initialize() + .Add(mediaSeries.Media.RatingMedia, x => x.Rating) + .Build(); Genres = mediaSeries.Media.Genres.Select(x => new GenreResponse(x)).ToList(); } diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs index 1fceee4..3bcb30d 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Controllers/AccountsController.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using WatchIt.Common.Model.Accounts; using WatchIt.Common.Model.Movies; +using WatchIt.Common.Model.Persons; using WatchIt.Common.Model.Series; using WatchIt.WebAPI.Services.Controllers.Accounts; @@ -69,4 +70,10 @@ public class AccountsController(IAccountsControllerService accountsControllerSer [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetAccountRatedSeries([FromRoute]long id, SeriesRatedQueryParameters query) => await accountsControllerService.GetAccountRatedSeries(id, query); + + [HttpGet("{id}/persons")] + [AllowAnonymous] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetAccountRatedPersons([FromRoute]long id, PersonRatedQueryParameters query) => await accountsControllerService.GetAccountRatedPersons(id, query); } \ No newline at end of file diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs index f49a9be..a4151d7 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/AccountsControllerService.cs @@ -7,6 +7,7 @@ using SimpleToolkit.Extensions; using WatchIt.Common.Model.Accounts; using WatchIt.Common.Model.Media; using WatchIt.Common.Model.Movies; +using WatchIt.Common.Model.Persons; using WatchIt.Common.Model.Series; using WatchIt.Database; using WatchIt.Database.Model.Account; @@ -18,6 +19,7 @@ using WatchIt.WebAPI.Services.Utility.Tokens.Exceptions; using WatchIt.WebAPI.Services.Utility.User; using Account = WatchIt.Database.Model.Account.Account; using AccountProfilePicture = WatchIt.Common.Model.Accounts.AccountProfilePicture; +using Person = WatchIt.Database.Model.Person.Person; namespace WatchIt.WebAPI.Services.Controllers.Accounts; @@ -190,6 +192,24 @@ public class AccountsControllerService( response = query.PrepareData(response); return RequestResult.Ok(response); } + + public async Task GetAccountRatedPersons(long id, PersonRatedQueryParameters query) + { + Account? account = await database.Accounts.FirstOrDefaultAsync(x => x.Id == id); + if (account is null) + { + return RequestResult.NotFound(); + } + + IEnumerable actorRolesRatings = account.RatingPersonActorRole; + IEnumerable creatorRolesRatings = account.RatingPersonCreatorRole; + IEnumerable persons = actorRolesRatings.Select(x => x.PersonActorRole.Person) + .Union(creatorRolesRatings.Select(x => x.PersonCreatorRole.Person)); + + IEnumerable response = persons.Select(x => new PersonRatedResponse(x, actorRolesRatings.Where(y => y.PersonActorRole.Person.Id == x.Id), creatorRolesRatings.Where(y => y.PersonCreatorRole.Person.Id == x.Id))); + response = query.PrepareData(response); + return RequestResult.Ok(response); + } #endregion diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs index 5ce20dd..500b256 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Accounts/IAccountsControllerService.cs @@ -1,6 +1,7 @@ using WatchIt.Common.Model.Accounts; using WatchIt.Common.Model.Media; using WatchIt.Common.Model.Movies; +using WatchIt.Common.Model.Persons; using WatchIt.Common.Model.Series; using WatchIt.WebAPI.Services.Controllers.Common; @@ -17,4 +18,5 @@ public interface IAccountsControllerService Task PutAccountInfo(AccountRequest data); Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query); Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters query); + Task GetAccountRatedPersons(long id, PersonRatedQueryParameters query); } \ No newline at end of file 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 46bde20..ac92c5f 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 @@ -118,7 +118,9 @@ public class MediaControllerService(DatabaseContext database, IUserService userS return RequestResult.NotFound(); } - RatingResponse ratingResponse = RatingResponse.Create(item.RatingMedia); + RatingResponse ratingResponse = RatingResponseBuilder.Initialize() + .Add(item.RatingMedia, x => x.Rating) + .Build(); return RequestResult.Ok(ratingResponse); } diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/PersonsControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/PersonsControllerService.cs index 3a80110..a8857aa 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/PersonsControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Persons/PersonsControllerService.cs @@ -335,7 +335,10 @@ public class PersonsControllerService : IPersonsControllerService return RequestResult.NotFound(); } - RatingResponse ratingResponse = RatingResponse.Create(item.PersonActorRoles, item.PersonCreatorRoles); + RatingResponse ratingResponse = RatingResponseBuilder.Initialize() + .Add(item.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole), x => x.Rating) + .Add(item.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole), x => x.Rating) + .Build(); return RequestResult.Ok(ratingResponse); } @@ -347,10 +350,11 @@ public class PersonsControllerService : IPersonsControllerService { return RequestResult.NotFound(); } - - IEnumerable actorRoleRatings = item.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole).Where(x => x.AccountId == userId); - IEnumerable creatorRoleRatings = item.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole).Where(x => x.AccountId == userId); - RatingResponse ratingResponse = RatingResponse.Create(actorRoleRatings, creatorRoleRatings); + + RatingResponse ratingResponse = RatingResponseBuilder.Initialize() + .Add(item.PersonActorRoles.SelectMany(x => x.RatingPersonActorRole).Where(x => x.AccountId == userId), x => x.Rating) + .Add(item.PersonCreatorRoles.SelectMany(x => x.RatingPersonCreatorRole).Where(x => x.AccountId == userId), x => x.Rating) + .Build(); return RequestResult.Ok(ratingResponse); } diff --git a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/RolesControllerService.cs b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/RolesControllerService.cs index d9d88c2..b86b622 100644 --- a/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/RolesControllerService.cs +++ b/WatchIt.WebAPI/WatchIt.WebAPI.Services/WatchIt.WebAPI.Services.Controllers/WatchIt.WebAPI.Services.Controllers.Roles/RolesControllerService.cs @@ -97,7 +97,9 @@ public class RolesControllerService : IRolesControllerService return RequestResult.NotFound(); } - RatingResponse ratingResponse = RatingResponse.Create(item.RatingPersonActorRole); + RatingResponse ratingResponse = RatingResponseBuilder.Initialize() + .Add(item.RatingPersonActorRole, x => x.Rating) + .Build(); return RequestResult.Ok(ratingResponse); } @@ -281,7 +283,9 @@ public class RolesControllerService : IRolesControllerService return RequestResult.NotFound(); } - RatingResponse ratingResponse = RatingResponse.Create(item.RatingPersonCreatorRole); + RatingResponse ratingResponse = RatingResponseBuilder.Initialize() + .Add(item.RatingPersonCreatorRole, x => x.Rating) + .Build(); return RequestResult.Ok(ratingResponse); } diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/AccountsClientService.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/AccountsClientService.cs index d71bb0f..c246c03 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/AccountsClientService.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/AccountsClientService.cs @@ -1,5 +1,6 @@ using WatchIt.Common.Model.Accounts; using WatchIt.Common.Model.Movies; +using WatchIt.Common.Model.Persons; using WatchIt.Common.Model.Series; using WatchIt.Common.Services.HttpClient; using WatchIt.Website.Services.Configuration; @@ -135,6 +136,20 @@ public class AccountsClientService(IHttpClientService httpClientService, IConfig .ExecuteAction(); } + public async Task GetAccountRatedPersons(long id, PersonRatedQueryParameters query, Action>? successAction = null, Action? notFoundAction = null) + { + string url = GetUrl(EndpointsConfiguration.Accounts.GetAccountRatedPersons, id); + HttpRequest request = new HttpRequest(HttpMethodType.Get, url) + { + Query = query + }; + + HttpResponse response = await httpClientService.SendRequestAsync(request); + response.RegisterActionFor2XXSuccess(successAction) + .RegisterActionFor404NotFound(notFoundAction) + .ExecuteAction(); + } + #endregion diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/IAccountsClientService.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/IAccountsClientService.cs index 7a2b0d7..6f16640 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/IAccountsClientService.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Client/Accounts/IAccountsClientService.cs @@ -1,5 +1,6 @@ using WatchIt.Common.Model.Accounts; using WatchIt.Common.Model.Movies; +using WatchIt.Common.Model.Persons; using WatchIt.Common.Model.Series; namespace WatchIt.Website.Services.Client.Accounts; @@ -15,4 +16,5 @@ public interface IAccountsClientService Task PutAccountInfo(AccountRequest data, Action? successAction = null, Action>? badRequestAction = null, Action? unauthorizedAction = null, Action? notFoundAction = null); Task GetAccountRatedMovies(long id, MovieRatedQueryParameters query, Action>? successAction = null, Action? notFoundAction = null); Task GetAccountRatedSeries(long id, SeriesRatedQueryParameters query, Action>? successAction = null, Action? notFoundAction = null); + Task GetAccountRatedPersons(long id, PersonRatedQueryParameters query, Action>? successAction = null, Action? notFoundAction = null); } \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Accounts.cs b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Accounts.cs index 9487bce..5731d34 100644 --- a/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Accounts.cs +++ b/WatchIt.Website/WatchIt.Website.Services/WatchIt.Website.Services.Configuration/Model/Accounts.cs @@ -12,4 +12,5 @@ public class Accounts public string PutAccountInfo { get; set; } public string GetAccountRatedMovies { get; set; } public string GetAccountRatedSeries { get; set; } + public string GetAccountRatedPersons { get; set; } } \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor b/WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor index fa20d1a..6b614f6 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor +++ b/WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor @@ -60,7 +60,8 @@ PosterPlaceholder="@(PosterPlaceholder)" PosterDownloadingTask="@(action => PictureDownloadingTask(id, action))" GlobalRating="@(RatingSource(item))" - SecondaryRating="@(SecondaryRatingSource?.Invoke(item))" + SecondaryRatingSingle="@(SecondaryRatingSingleSource?.Invoke(item))" + SecondaryRatingMultiple="@(SecondaryRatingMultipleSource?.Invoke(item))" SecondaryRatingTitle="@(SecondaryRatingTitle)" GetGlobalRatingMethod="@(action => GetGlobalRatingMethod(id, action))" GetUserRatingMethod="@(GetUserRatingMethod is not null ? (user, actionSuccess, actionNotFound) => GetUserRatingMethod(id, user, actionSuccess, actionNotFound) : null)" diff --git a/WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor.cs index ce6093d..5591ee6 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Components/Common/ListComponent/ListComponent.razor.cs @@ -23,7 +23,8 @@ public partial class ListComponent : ComponentBase where TItem : [Parameter] public required Func NameSource { get; set; } [Parameter] public Func AdditionalNameInfoSource { get; set; } = _ => null; [Parameter] public required Func RatingSource { get; set; } - [Parameter] public Func? SecondaryRatingSource { get; set; } + [Parameter] public Func? SecondaryRatingSingleSource { get; set; } + [Parameter] public Func? SecondaryRatingMultipleSource { get; set; } [Parameter] public string? SecondaryRatingTitle { get; set; } [Parameter] public required string UrlIdTemplate { get; set; } [Parameter] public required Func, Task> PictureDownloadingTask { get; set; } diff --git a/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/ListItemComponent.razor b/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/ListItemComponent.razor index b87ecbd..1832c07 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/ListItemComponent.razor +++ b/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/ListItemComponent.razor @@ -18,7 +18,7 @@ Global rating: - @if (SecondaryRating is not null) + @if (SecondaryRatingSingle is not null || SecondaryRatingMultiple is not null) { @(SecondaryRatingTitle): @@ -39,10 +39,11 @@ EmptyMode="DisplayRatingComponent.DisplayRatingComponentEmptyMode.DoubleDash" Scale="0.85"/> - @if (SecondaryRating is not null) + @if (SecondaryRatingSingle is not null || SecondaryRatingMultiple is not null) { - @@ -53,18 +54,18 @@
@if (_user is null) { - You must be logged in to rate + You must be logged in to rate } else if (!_userRatingLoaded) { -
- - Loading... -
+
+ + Loading... +
} else { - + }
diff --git a/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/ListItemComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/ListItemComponent.razor.cs index 4189a8e..373ebd2 100644 --- a/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/ListItemComponent.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Components/Common/Subcomponents/ListItemComponent.razor.cs @@ -27,7 +27,8 @@ public partial class ListItemComponent : ComponentBase [Parameter] public required Func, Task> PosterDownloadingTask { get; set; } [Parameter] public RatingResponse? GlobalRating { get; set; } - [Parameter] public short? SecondaryRating { get; set; } + [Parameter] public short? SecondaryRatingSingle { get; set; } + [Parameter] public RatingResponse? SecondaryRatingMultiple { get; set; } [Parameter] public string? SecondaryRatingTitle { get; set; } [Parameter] public required Func, Task> GetGlobalRatingMethod { get; set; } [Parameter] public Func, Action, Task>? GetUserRatingMethod { get; set; } diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/PersonsRatedFilterFormComponent.razor b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/PersonsRatedFilterFormComponent.razor new file mode 100644 index 0000000..9b59149 --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/PersonsRatedFilterFormComponent.razor @@ -0,0 +1,88 @@ +@using WatchIt.Common.Model.Genders + +@inherits WatchIt.Website.Components.Common.ListComponent.FilterFormComponent + + + + +
+
+
+ Name + +
+
+
+
+ Full name + +
+
+
+
+ Description + +
+
+
+
+ Birth date + + - + +
+
+
+
+ Death date + + - + +
+
+
+
+ Gender + + + @foreach (GenderResponse gender in _genders) + { + + } + +
+
+
+
+ Rating (count) + + - + +
+
+
+
+ Rating (average) + + - + +
+
+
+
+ User rating (count) + + - + +
+
+
+
+ User rating (average) + + - + +
+
+
+
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/PersonsRatedFilterFormComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/PersonsRatedFilterFormComponent.razor.cs new file mode 100644 index 0000000..5f38b2f --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/Pages/UserPage/Subcomponents/PersonsRatedFilterFormComponent.razor.cs @@ -0,0 +1,49 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Common.Model.Genders; +using WatchIt.Common.Model.Persons; +using WatchIt.Website.Components.Common.ListComponent; +using WatchIt.Website.Services.Client.Genders; + +namespace WatchIt.Website.Components.Pages.UserPage.Subcomponents; + +public partial class PersonsRatedFilterFormComponent : FilterFormComponent +{ + #region SERVICES + + [Inject] private IGendersClientService GendersClientService { get; set; } = default!; + + #endregion + + + + #region FIELDS + + private IEnumerable _genders = []; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + List endTasks = new List(); + + // STEP 0 + endTasks.AddRange( + [ + GendersClientService.GetAllGenders(successAction: data => _genders = data) + ]); + + // END + await Task.WhenAll(endTasks); + + StateHasChanged(); + } + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor b/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor index cc72a42..06cde8a 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor +++ b/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor @@ -1,9 +1,11 @@ @using System.Text @using WatchIt.Common.Model.Movies +@using WatchIt.Common.Model.Persons @using WatchIt.Common.Model.Series @using WatchIt.Website.Components.Pages.UserPage.Panels @using WatchIt.Website.Components.Common.ListComponent @using WatchIt.Website.Components.Pages.UserPage.Subcomponents +@using WatchIt.Website.Services.Client.Persons @page "/user/{id:long?}" @@ -60,7 +62,6 @@ Movies TV Series People - Roles @@ -75,7 +76,7 @@ NameSource="@(item => item.Title)" AdditionalNameInfoSource="@(item => item.ReleaseDate.HasValue ? $" ({item.ReleaseDate.Value.Year})" : null)" RatingSource="@(item => item.Rating)" - SecondaryRatingSource="@(item => _owner ? null : item.UserRating)" + SecondaryRatingSingleSource="@(item => _owner ? null : item.UserRating)" SecondaryRatingTitle="User rating" UrlIdTemplate="/media/{0}" PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))" @@ -99,7 +100,7 @@ NameSource="@(item => item.Title)" AdditionalNameInfoSource="@(item => item.ReleaseDate.HasValue ? $" ({item.ReleaseDate.Value.Year})" : null)" RatingSource="@(item => item.Rating)" - SecondaryRatingSource="@(item => _owner ? null : item.UserRating)" + SecondaryRatingSingleSource="@(item => _owner ? null : item.UserRating)" SecondaryRatingTitle="User rating" UrlIdTemplate="/media/{0}" PictureDownloadingTask="@((id, action) => MediaClientService.GetMediaPoster(id, action))" @@ -115,10 +116,33 @@ - - - - +
+ + + +
diff --git a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs index 7a190ff..2a2985c 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Pages/UserPage.razor.cs @@ -4,6 +4,7 @@ using WatchIt.Website.Layout; using WatchIt.Website.Services.Authentication; using WatchIt.Website.Services.Client.Accounts; using WatchIt.Website.Services.Client.Media; +using WatchIt.Website.Services.Client.Persons; namespace WatchIt.Website.Pages; @@ -15,6 +16,7 @@ public partial class UserPage : ComponentBase [Inject] private IAuthenticationService AuthenticationService { get; set; } = default!; [Inject] private IAccountsClientService AccountsClientService { get; set; } = default!; [Inject] private IMediaClientService MediaClientService { get; set; } = default!; + [Inject] private IPersonsClientService PersonsClientService { get; set; } = default!; #endregion diff --git a/WatchIt.Website/WatchIt.Website/appsettings.json b/WatchIt.Website/WatchIt.Website/appsettings.json index 9116ddb..9d0355d 100644 --- a/WatchIt.Website/WatchIt.Website/appsettings.json +++ b/WatchIt.Website/WatchIt.Website/appsettings.json @@ -25,7 +25,8 @@ "GetAccountInfo": "/{0}/info", "PutAccountInfo": "/info", "GetAccountRatedMovies": "/{0}/movies", - "GetAccountRatedSeries": "/{0}/series" + "GetAccountRatedSeries": "/{0}/series", + "GetAccountRatedPersons": "/{0}/persons" }, "Genders": { "Base": "/genders",