From 69937f13e6df692b62efb6c26e4e8243622fc9fd Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Sun, 29 Sep 2024 20:21:58 +0200 Subject: [PATCH 1/4] url fix in MediaEditPage --- WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor b/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor index 461dfcc..386c33f 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor +++ b/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor @@ -4,7 +4,7 @@ @using WatchIt.Common.Model.Series @page "/media/{id:long}/edit" -@page "/media/new/{type}" +@page "/media/new/{type?}" From 450e4a2f9428e4b7de7e34634dd54b3d396a7e14 Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Sun, 29 Sep 2024 23:00:32 +0200 Subject: [PATCH 2/4] new ordering system added --- .../Genres/GenreQueryParameters.cs | 4 +- .../Genres/GenreResponse.cs | 12 ++- .../Media/MediaQueryParameters.cs | 84 +++++++++++++++++++ .../Media/MediaResponse.cs | 22 ++++- .../Movies/MovieQueryParameters.cs | 28 ++++++- .../Movies/MovieResponse.cs | 23 ++++- .../Photos/PhotoQueryParameters.cs | 8 +- .../Photos/PhotoResponse.cs | 14 +++- .../Rating/RatingResponse.cs | 18 ++-- .../Series/SeriesQueryParameters.cs | 30 ++++++- .../Series/SeriesResponse.cs | 23 ++++- .../WatchIt.Common.Query/IQueryOrderable.cs | 9 ++ .../WatchIt.Common.Query/QueryParameters.cs | 29 +++---- .../Components/ListItemComponent.razor | 6 +- .../Components/ListItemComponent.razor.cs | 4 +- .../SearchPage/SearchResultComponent.razor | 4 +- .../SearchPage/SearchResultComponent.razor.cs | 2 +- .../WatchIt.Website/Pages/MediaPage.razor | 2 +- .../WatchIt.Website/Pages/SearchPage.razor | 12 +-- 19 files changed, 275 insertions(+), 59 deletions(-) create mode 100644 WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs create mode 100644 WatchIt.Common/WatchIt.Common.Query/IQueryOrderable.cs diff --git a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs index f5efe40..9b2658c 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreQueryParameters.cs @@ -21,9 +21,9 @@ public class GenreQueryParameters : QueryParameters public override bool IsMeetingConditions(GenreResponse item) => ( - TestString(item.Name, Name) + TestStringWithRegex(item.Name, Name) && - TestString(item.Description, Description) + TestStringWithRegex(item.Description, Description) ); #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs index 357d0d0..022fa80 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Genres/GenreResponse.cs @@ -1,12 +1,22 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; +using WatchIt.Common.Query; namespace WatchIt.Common.Model.Genres; -public class GenreResponse : Genre +public class GenreResponse : Genre, IQueryOrderable { #region PROPERTIES + [JsonIgnore] + public static IDictionary> OrderableProperties { get; } = new Dictionary> + { + { "id", x => x.Id }, + { "name", x => x.Name }, + { "description", x => x.Description } + }; + + [JsonPropertyName("id")] public long Id { get; set; } diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs new file mode 100644 index 0000000..db968ba --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs @@ -0,0 +1,84 @@ +using Microsoft.AspNetCore.Mvc; +using WatchIt.Common.Query; + +namespace WatchIt.Common.Model.Media; + +public class MediaQueryParameters : QueryParameters +{ + #region PROPERTIES + + [FromQuery(Name = "type")] + public MediaType? Type { get; set; } + + [FromQuery(Name = "title")] + public string? Title { get; set; } + + [FromQuery(Name = "original_title")] + public string? OriginalTitle { get; set; } + + [FromQuery(Name = "description")] + public string? Description { get; set; } + + [FromQuery(Name = "release_date")] + public DateOnly? ReleaseDate { get; set; } + + [FromQuery(Name = "release_date_from")] + public DateOnly? ReleaseDateFrom { get; set; } + + [FromQuery(Name = "release_date_to")] + public DateOnly? ReleaseDateTo { get; set; } + + [FromQuery(Name = "length")] + public short? Length { get; set; } + + [FromQuery(Name = "length_from")] + public short? LengthFrom { get; set; } + + [FromQuery(Name = "length_to")] + public short? LengthTo { get; set; } + + [FromQuery(Name = "rating_average")] + public double? RatingAverage { get; set; } + + [FromQuery(Name = "rating_average_from")] + public double? RatingAverageFrom { get; set; } + + [FromQuery(Name = "rating_average_to")] + public double? RatingAverageTo { get; set; } + + [FromQuery(Name = "rating_count")] + public double? RatingCount { get; set; } + + [FromQuery(Name = "rating_count_from")] + public double? RatingCountFrom { get; set; } + + [FromQuery(Name = "rating_count_to")] + public double? RatingCountTo { get; set; } + + #endregion + + + + #region PUBLIC METHODS + + public override bool IsMeetingConditions(MediaResponse item) => + ( + Test(item.Type, Type) + && + TestStringWithRegex(item.Title, Title) + && + TestStringWithRegex(item.OriginalTitle, OriginalTitle) + && + TestStringWithRegex(item.Description, Description) + && + TestComparable(item.ReleaseDate, ReleaseDate, ReleaseDateFrom, ReleaseDateTo) + && + TestComparable(item.Length, Length, LengthFrom, LengthTo) + && + TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) + && + TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) + ); + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs index 325cfb9..4ee0ba9 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Media/MediaResponse.cs @@ -1,17 +1,36 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; +using WatchIt.Common.Model.Rating; +using WatchIt.Common.Query; namespace WatchIt.Common.Model.Media; -public class MediaResponse : Media +public class MediaResponse : Media, IQueryOrderable { #region PROPERTIES + [JsonIgnore] + public static IDictionary> OrderableProperties { get; } = new Dictionary> + { + { "id", x => x.Id }, + { "title", x => x.Title }, + { "original_title", x => x.OriginalTitle }, + { "description", x => x.Description }, + { "release_date", x => x.ReleaseDate }, + { "length", x => x.Length }, + { "rating.average", x => x.Rating.Average }, + { "rating.count", x => x.Rating.Count } + }; + + [JsonPropertyName("id")] public long Id { get; set; } [JsonPropertyName("type")] public MediaType Type { get; set; } + + [JsonPropertyName("rating")] + public RatingResponse Rating { get; set; } #endregion @@ -32,6 +51,7 @@ public class MediaResponse : Media ReleaseDate = media.ReleaseDate; Length = media.Length; Type = mediaType; + Rating = new RatingResponse(media.RatingMedia); } #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs index bffef31..ce0ad56 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs @@ -43,6 +43,24 @@ public class MovieQueryParameters : QueryParameters [FromQuery(Name = "budget_to")] public decimal? BudgetTo { get; set; } + [FromQuery(Name = "rating_average")] + public double? RatingAverage { get; set; } + + [FromQuery(Name = "rating_average_from")] + public double? RatingAverageFrom { get; set; } + + [FromQuery(Name = "rating_average_to")] + public double? RatingAverageTo { get; set; } + + [FromQuery(Name = "rating_count")] + public double? RatingCount { get; set; } + + [FromQuery(Name = "rating_count_from")] + public double? RatingCountFrom { get; set; } + + [FromQuery(Name = "rating_count_to")] + public double? RatingCountTo { get; set; } + #endregion @@ -51,17 +69,21 @@ public class MovieQueryParameters : QueryParameters public override bool IsMeetingConditions(MovieResponse item) => ( - TestString(item.Title, Title) + TestStringWithRegex(item.Title, Title) && - TestString(item.OriginalTitle, OriginalTitle) + TestStringWithRegex(item.OriginalTitle, OriginalTitle) && - TestString(item.Description, Description) + TestStringWithRegex(item.Description, Description) && TestComparable(item.ReleaseDate, ReleaseDate, ReleaseDateFrom, ReleaseDateTo) && TestComparable(item.Length, Length, LengthFrom, LengthTo) && TestComparable(item.Budget, Budget, BudgetFrom, BudgetTo) + && + TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) + && + TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) ); #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs index 9c73e0e..78a230c 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieResponse.cs @@ -1,15 +1,35 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; +using WatchIt.Common.Model.Rating; +using WatchIt.Common.Query; using WatchIt.Database.Model.Media; namespace WatchIt.Common.Model.Movies; -public class MovieResponse : Movie +public class MovieResponse : Movie, IQueryOrderable { #region PROPERTIES + [JsonIgnore] + public static IDictionary> OrderableProperties { get; } = new Dictionary> + { + { "id", x => x.Id }, + { "title", x => x.Title }, + { "original_title", x => x.OriginalTitle }, + { "description", x => x.Description }, + { "release_date", x => x.ReleaseDate }, + { "length", x => x.Length }, + { "budget", x => x.Budget }, + { "rating.average", x => x.Rating.Average }, + { "rating.count", x => x.Rating.Count } + }; + + [JsonPropertyName("id")] public long Id { get; set; } + + [JsonPropertyName("rating")] + public RatingResponse Rating { get; set; } #endregion @@ -30,6 +50,7 @@ public class MovieResponse : Movie ReleaseDate = mediaMovie.Media.ReleaseDate; Length = mediaMovie.Media.Length; Budget = mediaMovie.Budget; + Rating = new RatingResponse(mediaMovie.Media.RatingMedia); } #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoQueryParameters.cs index 99145b5..b9d2794 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoQueryParameters.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoQueryParameters.cs @@ -1,5 +1,7 @@ +using System.Text.Json.Serialization; using Microsoft.AspNetCore.Mvc; using WatchIt.Common.Model.Media; +using WatchIt.Common.Model.Series; using WatchIt.Common.Query; namespace WatchIt.Common.Model.Photos; @@ -34,11 +36,11 @@ public class PhotoQueryParameters : QueryParameters public override bool IsMeetingConditions(PhotoResponse item) => ( - TestString(item.MimeType, MimeType) + TestStringWithRegex(item.MimeType, MimeType) && - TestBoolean(item.Background is not null, IsBackground) + Test(item.Background is not null, IsBackground) && - TestBoolean(item.Background is not null && item.Background.IsUniversalBackground, IsUniversalBackground) + Test(item.Background is not null && item.Background.IsUniversalBackground, IsUniversalBackground) && TestComparable(item.UploadDate, UploadDate, UploadDateFrom, UploadDateTo) ); diff --git a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoResponse.cs index 0b3b6d5..b715235 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Photos/PhotoResponse.cs @@ -1,13 +1,25 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; +using WatchIt.Common.Query; using WatchIt.Database.Model.Media; namespace WatchIt.Common.Model.Photos; -public class PhotoResponse : Photo +public class PhotoResponse : Photo, IQueryOrderable { #region PROPERTIES + [JsonIgnore] + public static IDictionary> OrderableProperties { get; } = new Dictionary> + { + { "id", x => x.Id }, + { "media_id", x => x.MediaId }, + { "mime_type", x => x.MimeType }, + { "is_background", x => x.Background is not null }, + { "is_universal_background", x => x.Background is not null && x.Background.IsUniversalBackground } + }; + + [JsonPropertyName("id")] public Guid Id { get; set; } diff --git a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs index b2b374c..2139fba 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; +using WatchIt.Database.Model.Rating; namespace WatchIt.Common.Model.Rating; @@ -7,11 +8,11 @@ public class RatingResponse { #region PROPERTIES - [JsonPropertyName("rating_average")] - public required double RatingAverage { get; set; } + [JsonPropertyName("average")] + public required double Average { get; set; } - [JsonPropertyName("rating_count")] - public required long RatingCount { get; set; } + [JsonPropertyName("count")] + public required long Count { get; set; } #endregion @@ -21,12 +22,15 @@ public class RatingResponse [JsonConstructor] public RatingResponse() {} - + + [SetsRequiredMembers] + public RatingResponse(IEnumerable ratingMedia) : this(ratingMedia.Any() ? ratingMedia.Average(x => x.Rating) : 0, ratingMedia.Count()) {} + [SetsRequiredMembers] public RatingResponse(double ratingAverage, long ratingCount) { - RatingAverage = ratingAverage; - RatingCount = ratingCount; + Average = ratingAverage; + Count = ratingCount; } #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs index d8797be..acb9e99 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs @@ -37,6 +37,24 @@ public class SeriesQueryParameters : QueryParameters [FromQuery(Name = "has_ended")] public bool? HasEnded { get; set; } + [FromQuery(Name = "rating_average")] + public double? RatingAverage { get; set; } + + [FromQuery(Name = "rating_average_from")] + public double? RatingAverageFrom { get; set; } + + [FromQuery(Name = "rating_average_to")] + public double? RatingAverageTo { get; set; } + + [FromQuery(Name = "rating_count")] + public double? RatingCount { get; set; } + + [FromQuery(Name = "rating_count_from")] + public double? RatingCountFrom { get; set; } + + [FromQuery(Name = "rating_count_to")] + public double? RatingCountTo { get; set; } + #endregion @@ -45,17 +63,21 @@ public class SeriesQueryParameters : QueryParameters public override bool IsMeetingConditions(SeriesResponse item) => ( - TestString(item.Title, Title) + TestStringWithRegex(item.Title, Title) && - TestString(item.OriginalTitle, OriginalTitle) + TestStringWithRegex(item.OriginalTitle, OriginalTitle) && - TestString(item.Description, Description) + TestStringWithRegex(item.Description, Description) && TestComparable(item.ReleaseDate, ReleaseDate, ReleaseDateFrom, ReleaseDateTo) && TestComparable(item.Length, Length, LengthFrom, LengthTo) && - TestBoolean(item.HasEnded, HasEnded) + Test(item.HasEnded, HasEnded) + && + TestComparable(item.Rating.Average, RatingAverage, RatingAverageFrom, RatingAverageTo) + && + TestComparable(item.Rating.Count, RatingCount, RatingCountFrom, RatingCountTo) ); #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs index 2e44003..862d6e0 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesResponse.cs @@ -1,15 +1,35 @@ using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; +using WatchIt.Common.Model.Rating; +using WatchIt.Common.Query; using WatchIt.Database.Model.Media; namespace WatchIt.Common.Model.Series; -public class SeriesResponse : Series +public class SeriesResponse : Series, IQueryOrderable { #region PROPERTIES + [JsonIgnore] + public static IDictionary> OrderableProperties { get; } = new Dictionary> + { + { "id", x => x.Id }, + { "title", x => x.Title }, + { "original_title", x => x.OriginalTitle }, + { "description", x => x.Description }, + { "release_date", x => x.ReleaseDate }, + { "length", x => x.Length }, + { "has_ended", x => x.HasEnded }, + { "rating.average", x => x.Rating.Average }, + { "rating.count", x => x.Rating.Count } + }; + + [JsonPropertyName("id")] public long Id { get; set; } + + [JsonPropertyName("rating")] + public RatingResponse Rating { get; set; } #endregion @@ -30,6 +50,7 @@ public class SeriesResponse : Series ReleaseDate = mediaSeries.Media.ReleaseDate; Length = mediaSeries.Media.Length; HasEnded = mediaSeries.HasEnded; + Rating = new RatingResponse(mediaSeries.Media.RatingMedia); } #endregion diff --git a/WatchIt.Common/WatchIt.Common.Query/IQueryOrderable.cs b/WatchIt.Common/WatchIt.Common.Query/IQueryOrderable.cs new file mode 100644 index 0000000..4d4cdae --- /dev/null +++ b/WatchIt.Common/WatchIt.Common.Query/IQueryOrderable.cs @@ -0,0 +1,9 @@ +using System.Text.Json.Serialization; + +namespace WatchIt.Common.Query; + +public interface IQueryOrderable +{ + [JsonIgnore] + public static abstract IDictionary> OrderableProperties { get; } +} \ No newline at end of file diff --git a/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs b/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs index 7934cdc..77cf1ec 100644 --- a/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs +++ b/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs @@ -52,14 +52,18 @@ public abstract class QueryParameters #region PRIVATE METHODS - protected static bool TestBoolean(bool property, bool? query) => + protected static bool Test(T? property, T? query) => ( query is null || - property == query + ( + property is not null + && + property.Equals(query) + ) ); - protected static bool TestString(string? property, string? regexQuery) => + protected static bool TestStringWithRegex(string? property, string? regexQuery) => ( string.IsNullOrEmpty(regexQuery) || @@ -108,7 +112,7 @@ public abstract class QueryParameters -public abstract class QueryParameters : QueryParameters where T : class +public abstract class QueryParameters : QueryParameters where T : IQueryOrderable { #region PUBLIC METHODS @@ -120,22 +124,9 @@ public abstract class QueryParameters : QueryParameters where T : class if (OrderBy is not null) { - PropertyInfo[] properties = typeof(T).GetProperties(); - foreach (PropertyInfo property in properties) + if (T.OrderableProperties.TryGetValue(OrderBy, out Func? orderFunc)) { - JsonPropertyNameAttribute? attribute = property.GetCustomAttributes(true).FirstOrDefault(); - if (attribute is not null && attribute.Name == OrderBy) - { - if (Order == "asc") - { - data = data.OrderBy(property.GetValue); - } - else - { - data = data.OrderByDescending(property.GetValue); - } - break; - } + data = Order == "asc" ? data.OrderBy(orderFunc) : data.OrderByDescending(orderFunc); } } if (After is not null) diff --git a/WatchIt.Website/WatchIt.Website/Components/ListItemComponent.razor b/WatchIt.Website/WatchIt.Website/Components/ListItemComponent.razor index cb879cc..566d09b 100644 --- a/WatchIt.Website/WatchIt.Website/Components/ListItemComponent.razor +++ b/WatchIt.Website/WatchIt.Website/Components/ListItemComponent.razor @@ -13,10 +13,10 @@
- @(_rating is not null && _rating.RatingCount > 0 ? _rating.RatingAverage : "--")/10 - @if (_rating is not null && _rating.RatingCount > 0) + @(Rating.Count > 0 ? Rating.Average : "--")/10 + @if (Rating.Count > 0) { - @(_rating.RatingCount) + @(Rating.Count) }
diff --git a/WatchIt.Website/WatchIt.Website/Components/ListItemComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/ListItemComponent.razor.cs index 3b72748..bd6713f 100644 --- a/WatchIt.Website/WatchIt.Website/Components/ListItemComponent.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Components/ListItemComponent.razor.cs @@ -11,8 +11,8 @@ public partial class ListItemComponent : ComponentBase [Parameter] public required long Id { get; set; } [Parameter] public required string Name { get; set; } [Parameter] public string? AdditionalNameInfo { get; set; } + [Parameter] public required RatingResponse Rating { get; set; } [Parameter] public required Func, Task> PictureDownloadingTask { get; set; } - [Parameter] public required Func, Task> RatingDownloadingTask { get; set; } [Parameter] public int PictureHeight { get; set; } = 150; #endregion @@ -24,7 +24,6 @@ public partial class ListItemComponent : ComponentBase private bool _loaded; private Picture? _picture; - private RatingResponse? _rating; #endregion @@ -42,7 +41,6 @@ public partial class ListItemComponent : ComponentBase endTasks.AddRange( [ PictureDownloadingTask(Id, picture => _picture = picture), - RatingDownloadingTask(Id, rating => _rating = rating) ]); await Task.WhenAll(endTasks); diff --git a/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor b/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor index 4903e4d..929a974 100644 --- a/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor +++ b/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor @@ -32,8 +32,8 @@ + Rating="@(RatingSource(_items[i]))" + PictureDownloadingTask="@(PictureDownloadingTask)"/> diff --git a/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor.cs index d115cac..2e93844 100644 --- a/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor.cs +++ b/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor.cs @@ -14,10 +14,10 @@ public partial class SearchResultComponent : ComponentBase where [Parameter] public required Func IdSource { get; set; } [Parameter] public required Func NameSource { get; set; } [Parameter] public Func AdditionalNameInfoSource { get; set; } = _ => null; + [Parameter] public required Func RatingSource { get; set; } [Parameter] public required string UrlIdTemplate { get; set; } [Parameter] public required Func>, Task> ItemDownloadingTask { get; set; } [Parameter] public required Func, Task> PictureDownloadingTask { get; set; } - [Parameter] public required Func, Task> RatingDownloadingTask { get; set; } #endregion diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor index ef9ff93..6c144cc 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor +++ b/WatchIt.Website/WatchIt.Website/Pages/MediaPage.razor @@ -137,7 +137,7 @@ else

- Global rating: @(_globalRating.RatingCount == 0 ? "no ratings" : $"{Math.Round(_globalRating.RatingAverage, 1)}/10") + Global rating: @(_globalRating.Count == 0 ? "no ratings" : $"{Math.Round(_globalRating.Average, 1)}/10")

diff --git a/WatchIt.Website/WatchIt.Website/Pages/SearchPage.razor b/WatchIt.Website/WatchIt.Website/Pages/SearchPage.razor index 48e98dc..c0bb6e3 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/SearchPage.razor +++ b/WatchIt.Website/WatchIt.Website/Pages/SearchPage.razor @@ -37,10 +37,10 @@ IdSource="@(item => item.Id)" NameSource="@(item => item.Title)" AdditionalNameInfoSource="@(item => item.ReleaseDate.HasValue ? $" ({item.ReleaseDate.Value.Year})" : null)" - Query="@(new MovieQueryParameters { Title = DecodedQuery })" + RatingSource="@(item => item.Rating)" + Query="@(new MovieQueryParameters { Title = DecodedQuery, OrderBy = "rating.count" })" ItemDownloadingTask="@(MoviesWebAPIService.GetAllMovies)" - PictureDownloadingTask="@((id, action) => MediaWebAPIService.GetMediaPoster(id, action))" - RatingDownloadingTask="@((id, action) => MediaWebAPIService.GetMediaRating(id, action))"/> + PictureDownloadingTask="@((id, action) => MediaWebAPIService.GetMediaPoster(id, action))"/>
@@ -52,10 +52,10 @@ IdSource="@(item => item.Id)" NameSource="@(item => item.Title)" AdditionalNameInfoSource="@(item => item.ReleaseDate.HasValue ? $" ({item.ReleaseDate.Value.Year})" : null)" - Query="@(new SeriesQueryParameters { Title = DecodedQuery })" + RatingSource="@(item => item.Rating)" + Query="@(new SeriesQueryParameters { Title = DecodedQuery, OrderBy = "rating.count" })" ItemDownloadingTask="@(SeriesWebAPIService.GetAllSeries)" - PictureDownloadingTask="@((id, action) => MediaWebAPIService.GetMediaPoster(id, action))" - RatingDownloadingTask="@((id, action) => MediaWebAPIService.GetMediaRating(id, action))"/> + PictureDownloadingTask="@((id, action) => MediaWebAPIService.GetMediaPoster(id, action))"/>
} From 6d372531844a6f598c2231e250e14fddfaf619fd Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Tue, 1 Oct 2024 01:12:47 +0200 Subject: [PATCH 3/4] ListPage version for movies added --- .../Components/ListPage/ListComponent.razor | 0 .../ListPage/ListComponent.razor.cs | 7 ++ .../ListPage/ListComponent.razor.css | 0 .../SearchPage/SearchResultComponent.razor | 2 +- .../WatchIt.Website/Layout/MainLayout.razor | 8 +- .../WatchIt.Website/Pages/ListPage.razor | 88 +++++++++++++++++ .../WatchIt.Website/Pages/ListPage.razor.cs | 96 +++++++++++++++++++ .../WatchIt.Website/Pages/ListPage.razor.css | 0 .../WatchIt.Website/Pages/MediaEditPage.razor | 2 +- 9 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor create mode 100644 WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.cs create mode 100644 WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.css create mode 100644 WatchIt.Website/WatchIt.Website/Pages/ListPage.razor create mode 100644 WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.cs create mode 100644 WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.css diff --git a/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor b/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor new file mode 100644 index 0000000..e69de29 diff --git a/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.cs new file mode 100644 index 0000000..7233ffe --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.cs @@ -0,0 +1,7 @@ +using Microsoft.AspNetCore.Components; + +namespace WatchIt.Website.Components.ListPage; + +public partial class ListComponent : ComponentBase +{ +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.css b/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.css new file mode 100644 index 0000000..e69de29 diff --git a/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor b/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor index 929a974..a448ee8 100644 --- a/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor +++ b/WatchIt.Website/WatchIt.Website/Components/SearchPage/SearchResultComponent.razor @@ -51,7 +51,7 @@ else { - Saving... + Loading... } diff --git a/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor b/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor index ca49395..d1c94b7 100644 --- a/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor +++ b/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor @@ -32,7 +32,13 @@ } else { - + + Lists + + Movies + TV Series + + } diff --git a/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor b/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor new file mode 100644 index 0000000..9a185eb --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor @@ -0,0 +1,88 @@ +@layout MainLayout + +@page "/lists/movies" +@using WatchIt.Common.Model.Movies + +
+ @if (_loaded) + { + if (string.IsNullOrWhiteSpace(_error)) + { +
+
+
+
+
+
+

Movies database

+
+
+ +
+
+ +
+
+
+
+
+
+ foreach (MovieResponse item in _items) + { +
+ +
+ } + if (!_allItemsLoaded) + { +
+
+
+
+ @if (!_itemsLoading) + { + Load more + } + else + { + + Load more + } +
+
+
+
+ } + } + else + { +
+
+ +
+
+ } + } + else + { +
+
+
+ +
+
+
+ } +
+ + \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.cs new file mode 100644 index 0000000..e97ea7a --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.cs @@ -0,0 +1,96 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Common.Model.Movies; +using WatchIt.Website.Services.WebAPI.Media; +using WatchIt.Website.Services.WebAPI.Movies; + +namespace WatchIt.Website.Pages; + +public partial class ListPage : ComponentBase +{ + #region SERVICES + + [Inject] private IMoviesWebAPIService MoviesWebAPIService { get; set; } = default!; + [Inject] private IMediaWebAPIService MediaWebAPIService { get; set; } = default!; + + #endregion + + + + #region PARAMETERS + + + + #endregion + + + + #region FIELDS + + private bool _loaded; + private string? _error; + + private MovieQueryParameters _query = new MovieQueryParameters { OrderBy = "rating.average" }; + private List _items = new List(); + private bool _allItemsLoaded; + private bool _itemsLoading; + + #endregion + + + + #region PUBLIC METHODS + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + // INIT + _query.First = 5; + + List endTasks = new List(); + + // STEP 0 + endTasks.AddRange( + [ + MoviesWebAPIService.GetAllMovies(_query, data => + { + _items.AddRange(data); + if (data.Count() < 5) + { + _allItemsLoaded = true; + } + else + { + _query.After = 5; + } + }) + ]); + + // END + await Task.WhenAll(endTasks); + + _loaded = true; + StateHasChanged(); + } + } + + private async Task DownloadItems() + { + _itemsLoading = true; + await MoviesWebAPIService.GetAllMovies(_query, data => + { + _items.AddRange(data); + if (data.Count() < 5) + { + _allItemsLoaded = true; + } + else + { + _query.After += 5; + } + _itemsLoading = false; + }); + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.css b/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.css new file mode 100644 index 0000000..e69de29 diff --git a/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor b/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor index 386c33f..68b0d51 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor +++ b/WatchIt.Website/WatchIt.Website/Pages/MediaEditPage.razor @@ -50,7 +50,7 @@
-

@(_media is not null ? "Edit" : "Create new") @(_movieRequest is not null ? "movie" : "series")@(_media is not null ? $" \"{_media.Title}\"" : string.Empty)

+

@(_media is not null ? "Edit" : "Create new") @(_movieRequest is not null ? "movie" : "series")@(_media is not null ? $" \"{_media.Title}\"" : string.Empty)

From 42a66167265d510499541ae8c0406c1dd9c42192 Mon Sep 17 00:00:00 2001 From: Mateusz Skoczek Date: Wed, 2 Oct 2024 01:08:52 +0200 Subject: [PATCH 4/4] database page finished --- .../Media/MediaQueryParameters.cs | 12 +- .../Movies/MovieQueryParameters.cs | 12 +- .../Rating/RatingResponse.cs | 6 +- .../Series/SeriesQueryParameters.cs | 12 +- .../WatchIt.Common.Query/QueryParameters.cs | 12 +- .../MediaControllerService.cs | 6 +- WatchIt.Website/WatchIt.Website/App.razor | 1 + .../DatabasePage/DatabasePageComponent.razor | 91 ++++++++++++ .../DatabasePageComponent.razor.cs | 139 ++++++++++++++++++ .../DatabasePageComponent.razor.css} | 0 .../DatabasePage/FilterFormComponent.cs | 22 +++ .../MoviesFilterFormComponent.razor | 66 +++++++++ .../SeriesFilterFormComponent.razor | 69 +++++++++ .../ListPage/ListComponent.razor.cs | 7 - .../WatchIt.Website/Layout/MainLayout.razor | 6 +- .../WatchIt.Website/Pages/AuthPage.razor | 4 +- .../WatchIt.Website/Pages/DatabasePage.razor | 63 ++++++++ .../Pages/DatabasePage.razor.cs | 58 ++++++++ .../DatabasePage.razor.css} | 0 .../WatchIt.Website/Pages/ListPage.razor | 88 ----------- .../WatchIt.Website/Pages/ListPage.razor.cs | 96 ------------ .../WatchIt.Website/Pages/ListPage.razor.css | 0 .../WatchIt.Website/_Imports.razor | 3 +- 23 files changed, 548 insertions(+), 225 deletions(-) create mode 100644 WatchIt.Website/WatchIt.Website/Components/DatabasePage/DatabasePageComponent.razor create mode 100644 WatchIt.Website/WatchIt.Website/Components/DatabasePage/DatabasePageComponent.razor.cs rename WatchIt.Website/WatchIt.Website/Components/{ListPage/ListComponent.razor => DatabasePage/DatabasePageComponent.razor.css} (100%) create mode 100644 WatchIt.Website/WatchIt.Website/Components/DatabasePage/FilterFormComponent.cs create mode 100644 WatchIt.Website/WatchIt.Website/Components/DatabasePage/MoviesFilterFormComponent.razor create mode 100644 WatchIt.Website/WatchIt.Website/Components/DatabasePage/SeriesFilterFormComponent.razor delete mode 100644 WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.cs create mode 100644 WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor create mode 100644 WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor.cs rename WatchIt.Website/WatchIt.Website/{Components/ListPage/ListComponent.razor.css => Pages/DatabasePage.razor.css} (100%) delete mode 100644 WatchIt.Website/WatchIt.Website/Pages/ListPage.razor delete mode 100644 WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.cs delete mode 100644 WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.css diff --git a/WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs index db968ba..3977d12 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Media/MediaQueryParameters.cs @@ -38,22 +38,22 @@ public class MediaQueryParameters : QueryParameters public short? LengthTo { get; set; } [FromQuery(Name = "rating_average")] - public double? RatingAverage { get; set; } + public decimal? RatingAverage { get; set; } [FromQuery(Name = "rating_average_from")] - public double? RatingAverageFrom { get; set; } + public decimal? RatingAverageFrom { get; set; } [FromQuery(Name = "rating_average_to")] - public double? RatingAverageTo { get; set; } + public decimal? RatingAverageTo { get; set; } [FromQuery(Name = "rating_count")] - public double? RatingCount { get; set; } + public long? RatingCount { get; set; } [FromQuery(Name = "rating_count_from")] - public double? RatingCountFrom { get; set; } + public long? RatingCountFrom { get; set; } [FromQuery(Name = "rating_count_to")] - public double? RatingCountTo { get; set; } + public long? RatingCountTo { get; set; } #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs index ce0ad56..aec1df9 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Movies/MovieQueryParameters.cs @@ -44,22 +44,22 @@ public class MovieQueryParameters : QueryParameters public decimal? BudgetTo { get; set; } [FromQuery(Name = "rating_average")] - public double? RatingAverage { get; set; } + public decimal? RatingAverage { get; set; } [FromQuery(Name = "rating_average_from")] - public double? RatingAverageFrom { get; set; } + public decimal? RatingAverageFrom { get; set; } [FromQuery(Name = "rating_average_to")] - public double? RatingAverageTo { get; set; } + public decimal? RatingAverageTo { get; set; } [FromQuery(Name = "rating_count")] - public double? RatingCount { get; set; } + public long? RatingCount { get; set; } [FromQuery(Name = "rating_count_from")] - public double? RatingCountFrom { get; set; } + public long? RatingCountFrom { get; set; } [FromQuery(Name = "rating_count_to")] - public double? RatingCountTo { get; set; } + public long? RatingCountTo { get; set; } #endregion diff --git a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs index 2139fba..cc86fb2 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Rating/RatingResponse.cs @@ -9,7 +9,7 @@ public class RatingResponse #region PROPERTIES [JsonPropertyName("average")] - public required double Average { get; set; } + public required decimal Average { get; set; } [JsonPropertyName("count")] public required long Count { get; set; } @@ -24,10 +24,10 @@ public class RatingResponse public RatingResponse() {} [SetsRequiredMembers] - public RatingResponse(IEnumerable ratingMedia) : this(ratingMedia.Any() ? ratingMedia.Average(x => x.Rating) : 0, ratingMedia.Count()) {} + public RatingResponse(IEnumerable ratingMedia) : this(ratingMedia.Any() ? (decimal)ratingMedia.Average(x => x.Rating) : 0, ratingMedia.Count()) {} [SetsRequiredMembers] - public RatingResponse(double ratingAverage, long ratingCount) + public RatingResponse(decimal ratingAverage, long ratingCount) { Average = ratingAverage; Count = ratingCount; diff --git a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs index acb9e99..f4594c0 100644 --- a/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs +++ b/WatchIt.Common/WatchIt.Common.Model/Series/SeriesQueryParameters.cs @@ -38,22 +38,22 @@ public class SeriesQueryParameters : QueryParameters public bool? HasEnded { get; set; } [FromQuery(Name = "rating_average")] - public double? RatingAverage { get; set; } + public decimal? RatingAverage { get; set; } [FromQuery(Name = "rating_average_from")] - public double? RatingAverageFrom { get; set; } + public decimal? RatingAverageFrom { get; set; } [FromQuery(Name = "rating_average_to")] - public double? RatingAverageTo { get; set; } + public decimal? RatingAverageTo { get; set; } [FromQuery(Name = "rating_count")] - public double? RatingCount { get; set; } + public long? RatingCount { get; set; } [FromQuery(Name = "rating_count_from")] - public double? RatingCountFrom { get; set; } + public long? RatingCountFrom { get; set; } [FromQuery(Name = "rating_count_to")] - public double? RatingCountTo { get; set; } + public long? RatingCountTo { get; set; } #endregion diff --git a/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs b/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs index 77cf1ec..d946e85 100644 --- a/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs +++ b/WatchIt.Common/WatchIt.Common.Query/QueryParameters.cs @@ -1,4 +1,5 @@ -using System.Reflection; +using System.Globalization; +using System.Reflection; using System.Text; using System.Text.Json.Serialization; using System.Text.RegularExpressions; @@ -38,7 +39,12 @@ public abstract class QueryParameters FromQueryAttribute? attribute = property.GetCustomAttributes(true).FirstOrDefault(); if (value is not null && attribute is not null) { - string query = $"{attribute.Name}={value}"; + string valueString = (value switch + { + decimal d => d.ToString(CultureInfo.InvariantCulture), + _ => value.ToString() + })!; + string query = $"{attribute.Name}={valueString}"; queries.Add(query); } } @@ -92,7 +98,7 @@ public abstract class QueryParameters ( property is not null && - property.CompareTo(from) > 0 + property.CompareTo(from) >= 0 ) ) && 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 454cd97..295d923 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 @@ -107,10 +107,8 @@ public class MediaControllerService(DatabaseContext database, IUserService userS { return RequestResult.NotFound(); } - - double ratingAverage = item.RatingMedia.Any() ? item.RatingMedia.Average(x => x.Rating) : 0; - long ratingCount = item.RatingMedia.Count(); - RatingResponse ratingResponse = new RatingResponse(ratingAverage, ratingCount); + + RatingResponse ratingResponse = new RatingResponse(item.RatingMedia); return RequestResult.Ok(ratingResponse); } diff --git a/WatchIt.Website/WatchIt.Website/App.razor b/WatchIt.Website/WatchIt.Website/App.razor index 2992e8c..fb9b08f 100644 --- a/WatchIt.Website/WatchIt.Website/App.razor +++ b/WatchIt.Website/WatchIt.Website/App.razor @@ -12,6 +12,7 @@ + diff --git a/WatchIt.Website/WatchIt.Website/Components/DatabasePage/DatabasePageComponent.razor b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/DatabasePageComponent.razor new file mode 100644 index 0000000..10b6ed6 --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/DatabasePageComponent.razor @@ -0,0 +1,91 @@ +@typeparam TItem where TItem : WatchIt.Common.Query.IQueryOrderable +@typeparam TQuery where TQuery : WatchIt.Common.Query.QueryParameters + + + + +
+
+
+
+
+

@(Title)

+
+
+
+ Order by + + + +
+
+
+
+ + + + + + Filters + + @(ChildContent) + + + + +
+ +
+
+
+
+ @if (_loaded) + { + if (string.IsNullOrWhiteSpace(_error)) + { + foreach (TItem item in _items) + { +
+ +
+ } + if (!_allItemsLoaded) + { +
+
+ @if (!_itemsLoading) + { + Load more + } + else + { + + Loading... + } +
+
+ } + } + else + { + + } + } + else + { +
+ +
+ } +
+
+ \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/DatabasePage/DatabasePageComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/DatabasePageComponent.razor.cs new file mode 100644 index 0000000..84ff2b8 --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/DatabasePageComponent.razor.cs @@ -0,0 +1,139 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Common.Model; +using WatchIt.Common.Model.Movies; +using WatchIt.Common.Model.Rating; +using WatchIt.Common.Query; + +namespace WatchIt.Website.Components.DatabasePage; + +public partial class DatabasePageComponent : ComponentBase where TItem : IQueryOrderable where TQuery : QueryParameters +{ + #region SERVICES + + [Inject] private NavigationManager NavigationManager { get; set; } = default!; + + #endregion + + + + #region PARAMETERS + + [Parameter] public required string Title { get; set; } + [Parameter] public required Func IdSource { get; set; } + [Parameter] public required Func NameSource { get; set; } + [Parameter] public Func AdditionalNameInfoSource { get; set; } = _ => null; + [Parameter] public required Func RatingSource { get; set; } + [Parameter] public required string UrlIdTemplate { get; set; } + [Parameter] public required Func, Task> PictureDownloadingTask { get; set; } + [Parameter] public required Func>, Task> ItemDownloadingTask { get; set; } + [Parameter] public required Dictionary SortingOptions { get; set; } + [Parameter] public required RenderFragment ChildContent { get; set; } + + #endregion + + + + #region FIELDS + + private bool _loaded; + private string? _error; + + private List _items = new List(); + private bool _allItemsLoaded; + private bool _itemsLoading; + + #endregion + + + + #region PROPERTIES + + public TQuery Query { get; set; } = Activator.CreateInstance()!; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + // INIT + Query.OrderBy = SortingOptions.Keys.First(); + Query.First = 100; + + List endTasks = new List(); + + // STEP 0 + endTasks.AddRange( + [ + ItemDownloadingTask(Query, data => + { + _items.AddRange(data); + if (data.Count() < 100) + { + _allItemsLoaded = true; + } + else + { + Query.After = 100; + } + }) + ]); + + // END + await Task.WhenAll(endTasks); + + _loaded = true; + StateHasChanged(); + } + } + + private async Task DownloadItems() + { + _itemsLoading = true; + await ItemDownloadingTask(Query, AppendNewItems); + } + + private async Task SortingAscendingChanged(ChangeEventArgs args) + { + Query.Order = (bool)args.Value! ? "asc" : "desc"; + await UpdateItems(); + } + + private async Task SortingOptionChanged(ChangeEventArgs args) + { + Query.OrderBy = args.Value!.ToString(); + await UpdateItems(); + } + + private async Task FilterApplied() => await UpdateItems(); + + private async Task UpdateItems() + { + _loaded = false; + Query.First = 100; + Query.After = null; + _items.Clear(); + await ItemDownloadingTask(Query, AppendNewItems); + _loaded = true; + } + + private void AppendNewItems(IEnumerable items) + { + _items.AddRange(items); + if (items.Count() < 100) + { + _allItemsLoaded = true; + } + else + { + Query.After += 100; + } + _itemsLoading = false; + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/DatabasePageComponent.razor.css similarity index 100% rename from WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor rename to WatchIt.Website/WatchIt.Website/Components/DatabasePage/DatabasePageComponent.razor.css diff --git a/WatchIt.Website/WatchIt.Website/Components/DatabasePage/FilterFormComponent.cs b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/FilterFormComponent.cs new file mode 100644 index 0000000..26fa16d --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/FilterFormComponent.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Common.Query; + +namespace WatchIt.Website.Components.DatabasePage; + +public abstract class FilterFormComponent : ComponentBase where TItem : IQueryOrderable where TQuery : QueryParameters +{ + #region PARAMETERS + + [CascadingParameter] + protected DatabasePageComponent Parent { get; set; } + + #endregion + + + + #region FIELDS + + protected TQuery? Query => Parent?.Query; + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/DatabasePage/MoviesFilterFormComponent.razor b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/MoviesFilterFormComponent.razor new file mode 100644 index 0000000..d24e473 --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/MoviesFilterFormComponent.razor @@ -0,0 +1,66 @@ +@inherits FilterFormComponent + + + + +
+
+
+ Title + +
+
+
+
+ Original title + +
+
+
+
+ Description + +
+
+
+
+ Release date + + - + +
+
+
+
+ Length + + - + +
+
+
+
+ Budget + + - + +
+
+
+
+ Rating (count) + + - + +
+
+
+
+ Rating (average) + + - + +
+
+
+
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/DatabasePage/SeriesFilterFormComponent.razor b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/SeriesFilterFormComponent.razor new file mode 100644 index 0000000..1bad8cc --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Components/DatabasePage/SeriesFilterFormComponent.razor @@ -0,0 +1,69 @@ +@inherits FilterFormComponent + + +
+
+
+ Title + +
+
+
+
+ Original title + +
+
+
+
+ Description + +
+
+
+
+ Release date + + - + +
+
+
+
+ Length + + - + +
+
+
+
+ Has ended +
+ + + + + + +
+
+
+
+
+ Rating (count) + + - + +
+
+
+
+ Rating (average) + + - + +
+
+
+
\ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.cs b/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.cs deleted file mode 100644 index 7233ffe..0000000 --- a/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Microsoft.AspNetCore.Components; - -namespace WatchIt.Website.Components.ListPage; - -public partial class ListComponent : ComponentBase -{ -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor b/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor index d1c94b7..6e23112 100644 --- a/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor +++ b/WatchIt.Website/WatchIt.Website/Layout/MainLayout.razor @@ -33,10 +33,10 @@ else { - Lists + Database - Movies - TV Series + Movies + TV Series diff --git a/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor b/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor index 39efc0c..0becab5 100644 --- a/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor +++ b/WatchIt.Website/WatchIt.Website/Pages/AuthPage.razor @@ -89,9 +89,9 @@ }
- + - +
diff --git a/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor b/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor new file mode 100644 index 0000000..c96d375 --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor @@ -0,0 +1,63 @@ +@using WatchIt.Common.Model.Movies +@using WatchIt.Common.Model.Series +@using WatchIt.Website.Components.DatabasePage + +@page "/database/{type?}" + + + +@if (_loaded) +{ + switch (Type) + { + case "movies": + + + + break; + case "series": + + + + break; + } + +} +else +{ +
+ +
+} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor.cs new file mode 100644 index 0000000..186a3b7 --- /dev/null +++ b/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor.cs @@ -0,0 +1,58 @@ +using Microsoft.AspNetCore.Components; +using WatchIt.Website.Components.DatabasePage; +using WatchIt.Website.Services.WebAPI.Media; +using WatchIt.Website.Services.WebAPI.Movies; +using WatchIt.Website.Services.WebAPI.Series; + +namespace WatchIt.Website.Pages; + +public partial class DatabasePage : ComponentBase +{ + #region SERVICES + + [Inject] private NavigationManager NavigationManager { get; set; } = default!; + [Inject] private IMediaWebAPIService MediaWebAPIService { get; set; } = default!; + [Inject] private IMoviesWebAPIService MoviesWebAPIService { get; set; } = default!; + [Inject] private ISeriesWebAPIService SeriesWebAPIService { get; set; } = default!; + + #endregion + + + + #region PARAMETERS + + [Parameter] public string? Type { get; set; } + + #endregion + + + + #region FIELDS + + private static IEnumerable _databaseTypes = ["movies", "series"]; + + private bool _loaded; + + #endregion + + + + #region PRIVATE METHODS + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + // INIT + if (!_databaseTypes.Contains(Type)) + { + NavigationManager.NavigateTo($"/database/{_databaseTypes.First()}"); + } + + _loaded = true; + StateHasChanged(); + } + } + + #endregion +} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.css b/WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor.css similarity index 100% rename from WatchIt.Website/WatchIt.Website/Components/ListPage/ListComponent.razor.css rename to WatchIt.Website/WatchIt.Website/Pages/DatabasePage.razor.css diff --git a/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor b/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor deleted file mode 100644 index 9a185eb..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor +++ /dev/null @@ -1,88 +0,0 @@ -@layout MainLayout - -@page "/lists/movies" -@using WatchIt.Common.Model.Movies - -
- @if (_loaded) - { - if (string.IsNullOrWhiteSpace(_error)) - { -
-
-
-
-
-
-

Movies database

-
-
- -
-
- -
-
-
-
-
-
- foreach (MovieResponse item in _items) - { -
- -
- } - if (!_allItemsLoaded) - { -
-
-
-
- @if (!_itemsLoading) - { - Load more - } - else - { - - Load more - } -
-
-
-
- } - } - else - { -
-
- -
-
- } - } - else - { -
-
-
- -
-
-
- } -
- - \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.cs b/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.cs deleted file mode 100644 index e97ea7a..0000000 --- a/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.cs +++ /dev/null @@ -1,96 +0,0 @@ -using Microsoft.AspNetCore.Components; -using WatchIt.Common.Model.Movies; -using WatchIt.Website.Services.WebAPI.Media; -using WatchIt.Website.Services.WebAPI.Movies; - -namespace WatchIt.Website.Pages; - -public partial class ListPage : ComponentBase -{ - #region SERVICES - - [Inject] private IMoviesWebAPIService MoviesWebAPIService { get; set; } = default!; - [Inject] private IMediaWebAPIService MediaWebAPIService { get; set; } = default!; - - #endregion - - - - #region PARAMETERS - - - - #endregion - - - - #region FIELDS - - private bool _loaded; - private string? _error; - - private MovieQueryParameters _query = new MovieQueryParameters { OrderBy = "rating.average" }; - private List _items = new List(); - private bool _allItemsLoaded; - private bool _itemsLoading; - - #endregion - - - - #region PUBLIC METHODS - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - // INIT - _query.First = 5; - - List endTasks = new List(); - - // STEP 0 - endTasks.AddRange( - [ - MoviesWebAPIService.GetAllMovies(_query, data => - { - _items.AddRange(data); - if (data.Count() < 5) - { - _allItemsLoaded = true; - } - else - { - _query.After = 5; - } - }) - ]); - - // END - await Task.WhenAll(endTasks); - - _loaded = true; - StateHasChanged(); - } - } - - private async Task DownloadItems() - { - _itemsLoading = true; - await MoviesWebAPIService.GetAllMovies(_query, data => - { - _items.AddRange(data); - if (data.Count() < 5) - { - _allItemsLoaded = true; - } - else - { - _query.After += 5; - } - _itemsLoading = false; - }); - } - - #endregion -} \ No newline at end of file diff --git a/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.css b/WatchIt.Website/WatchIt.Website/Pages/ListPage.razor.css deleted file mode 100644 index e69de29..0000000 diff --git a/WatchIt.Website/WatchIt.Website/_Imports.razor b/WatchIt.Website/WatchIt.Website/_Imports.razor index b8693f8..3a478f4 100644 --- a/WatchIt.Website/WatchIt.Website/_Imports.razor +++ b/WatchIt.Website/WatchIt.Website/_Imports.razor @@ -15,4 +15,5 @@ @using WatchIt.Website.Services.Utility.Authentication @using WatchIt.Website.Services.WebAPI.Accounts @using WatchIt.Website.Services.WebAPI.Media -@using Blazorise \ No newline at end of file +@using Blazorise +@using Blazorise.Bootstrap5 \ No newline at end of file