Chapter/Issue level Reviews and Ratings (#3778)

Co-authored-by: Joseph Milazzo <josephmajora@gmail.com>
This commit is contained in:
Fesaa 2025-04-29 18:53:24 +02:00 committed by GitHub
parent 3b8997e46e
commit 4f7625ea77
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
60 changed files with 5097 additions and 497 deletions

View file

@ -19,6 +19,7 @@ public class AppUser : IdentityUser<int>, IHasConcurrencyToken
public ICollection<AppUserRole> UserRoles { get; set; } = null!;
public ICollection<AppUserProgress> Progresses { get; set; } = null!;
public ICollection<AppUserRating> Ratings { get; set; } = null!;
public ICollection<AppUserChapterRating> ChapterRatings { get; set; } = null!;
public AppUserPreferences UserPreferences { get; set; } = null!;
/// <summary>
/// Bookmarks associated with this User

View file

@ -0,0 +1,30 @@
namespace API.Entities;
public class AppUserChapterRating
{
public int Id { get; set; }
/// <summary>
/// A number between 0-5.0 that represents how good a series is.
/// </summary>
public float Rating { get; set; }
/// <summary>
/// If the rating has been explicitly set. Otherwise, the 0.0 rating should be ignored as it's not rated
/// </summary>
public bool HasBeenRated { get; set; }
/// <summary>
/// A short summary the user can write when giving their review.
/// </summary>
public string? Review { get; set; }
/// <summary>
/// An optional tagline for the review
/// </summary>
public int SeriesId { get; set; }
public Series Series { get; set; } = null!;
public int ChapterId { get; set; }
public Chapter Chapter { get; set; } = null!;
// Relationships
public int AppUserId { get; set; }
public AppUser AppUser { get; set; } = null!;
}

View file

@ -26,7 +26,6 @@ public class AppUserRating
public int SeriesId { get; set; }
public Series Series { get; set; } = null!;
// Relationships
public int AppUserId { get; set; }
public AppUser AppUser { get; set; } = null!;

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using API.Entities.Enums;
using API.Entities.Interfaces;
using API.Entities.Metadata;
using API.Entities.Person;
using API.Extensions;
using API.Services.Tasks.Scanner.Parser;
@ -125,6 +126,11 @@ public class Chapter : IEntityDate, IHasReadTimeEstimate, IHasCoverImage
public string WebLinks { get; set; } = string.Empty;
public string ISBN { get; set; } = string.Empty;
/// <summary>
/// (Kavita+) Average rating from Kavita+ metadata
/// </summary>
public float AverageExternalRating { get; set; } = 0f;
#region Locks
public bool AgeRatingLocked { get; set; }
@ -160,6 +166,7 @@ public class Chapter : IEntityDate, IHasReadTimeEstimate, IHasCoverImage
/// </summary>
public ICollection<Genre> Genres { get; set; } = new List<Genre>();
public ICollection<Tag> Tags { get; set; } = new List<Tag>();
public ICollection<AppUserChapterRating> Ratings { get; set; } = [];
public ICollection<AppUserProgress> UserProgress { get; set; }
@ -168,6 +175,9 @@ public class Chapter : IEntityDate, IHasReadTimeEstimate, IHasCoverImage
public Volume Volume { get; set; } = null!;
public int VolumeId { get; set; }
public ICollection<ExternalReview> ExternalReviews { get; set; } = [];
public ICollection<ExternalRating> ExternalRatings { get; set; } = null!;
public void UpdateFrom(ParserInfo info)
{
Files ??= new List<MangaFile>();
@ -192,8 +202,6 @@ public class Chapter : IEntityDate, IHasReadTimeEstimate, IHasCoverImage
/// <returns></returns>
public string GetNumberTitle()
{
// BUG: TODO: On non-english locales, for floats, the range will be 20,5 but the NumberTitle will return 20.5
// Have I fixed this with TryParse CultureInvariant
try
{
if (MinNumber.Is(MaxNumber))

View file

@ -0,0 +1,17 @@
using System.ComponentModel;
namespace API.Entities.Enums;
public enum RatingAuthority
{
/// <summary>
/// Rating was from a User (internet or local)
/// </summary>
[Description("User")]
User = 0,
/// <summary>
/// Rating was from Professional Critics
/// </summary>
[Description("Critic")]
Critic = 1,
}

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using API.Entities.Enums;
using API.Services.Plus;
namespace API.Entities.Metadata;
@ -10,8 +11,13 @@ public class ExternalRating
public int AverageScore { get; set; }
public int FavoriteCount { get; set; }
public ScrobbleProvider Provider { get; set; }
public RatingAuthority Authority { get; set; } = RatingAuthority.User;
public string? ProviderUrl { get; set; }
public int SeriesId { get; set; }
/// <summary>
/// This can be null when for a series-rating
/// </summary>
public int? ChapterId { get; set; }
public ICollection<ExternalSeriesMetadata> ExternalSeriesMetadatas { get; set; } = null!;
}

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using API.Entities.Enums;
using API.Services.Plus;
namespace API.Entities.Metadata;
@ -20,6 +21,7 @@ public class ExternalReview
/// </summary>
public string RawBody { get; set; }
public required ScrobbleProvider Provider { get; set; }
public RatingAuthority Authority { get; set; } = RatingAuthority.User;
public string SiteUrl { get; set; }
/// <summary>
/// Reviewer's username
@ -37,6 +39,7 @@ public class ExternalReview
public int SeriesId { get; set; }
public int? ChapterId { get; set; }
// Relationships
public ICollection<ExternalSeriesMetadata> ExternalSeriesMetadatas { get; set; } = null!;