Revert "Unify ChapterRating with Rating"
This wasn't working out, there is still some duplicate code. But not that much, and from the API, there is no different. Hooray!
This commit is contained in:
parent
052b3f9fe4
commit
184cf46533
21 changed files with 389 additions and 87 deletions
|
|
@ -399,7 +399,7 @@ public class ChapterController : BaseApiController
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("chapter-detail-plus")]
|
[HttpGet("chapter-detail-plus")]
|
||||||
public async Task<ChapterDetailPlusDto> ChapterDetailPlus([FromQuery] int seriesId, [FromQuery] int chapterId)
|
public async Task<ChapterDetailPlusDto> ChapterDetailPlus([FromQuery] int chapterId)
|
||||||
{
|
{
|
||||||
var ret = new ChapterDetailPlusDto();
|
var ret = new ChapterDetailPlusDto();
|
||||||
|
|
||||||
|
|
@ -408,7 +408,7 @@ public class ChapterController : BaseApiController
|
||||||
.OrderByDescending(review => review.Username.Equals(User.GetUsername()) ? 1 : 0)
|
.OrderByDescending(review => review.Username.Equals(User.GetUsername()) ? 1 : 0)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
var ownRating = await _unitOfWork.UserRepository.GetUserRatingAsync(seriesId, User.GetUserId(), chapterId);
|
var ownRating = await _unitOfWork.UserRepository.GetUserChapterRatingAsync(User.GetUserId(), chapterId);
|
||||||
if (ownRating != null)
|
if (ownRating != null)
|
||||||
{
|
{
|
||||||
ret.Rating = ownRating.Rating;
|
ret.Rating = ownRating.Rating;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Threading.Tasks;
|
||||||
using API.Data;
|
using API.Data;
|
||||||
using API.Data.Repositories;
|
using API.Data.Repositories;
|
||||||
using API.DTOs.SeriesDetail;
|
using API.DTOs.SeriesDetail;
|
||||||
|
using API.Entities;
|
||||||
using API.Entities.Enums;
|
using API.Entities.Enums;
|
||||||
using API.Extensions;
|
using API.Extensions;
|
||||||
using API.Helpers.Builders;
|
using API.Helpers.Builders;
|
||||||
|
|
@ -39,15 +40,37 @@ public class ReviewController : BaseApiController
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<ActionResult<UserReviewDto>> UpdateReview(UpdateUserReviewDto dto)
|
public async Task<ActionResult<UserReviewDto>> UpdateReview(UpdateUserReviewDto dto)
|
||||||
{
|
{
|
||||||
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Ratings);
|
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Ratings | AppUserIncludes.ChapterRatings);
|
||||||
if (user == null) return Unauthorized();
|
if (user == null) return Unauthorized();
|
||||||
|
|
||||||
var ratingBuilder = new RatingBuilder(await _unitOfWork.UserRepository.GetUserRatingAsync(dto.SeriesId, user.Id, dto.ChapterId));
|
UserReviewDto review;
|
||||||
|
if (dto.ChapterId != null)
|
||||||
|
{
|
||||||
|
review = await UpdateChapterReview(user, dto, dto.ChapterId.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
review = await UpdateSeriesReview(user, dto);
|
||||||
|
}
|
||||||
|
_unitOfWork.UserRepository.Update(user);
|
||||||
|
|
||||||
|
await _unitOfWork.CommitAsync();
|
||||||
|
|
||||||
|
if (dto.ChapterId == null)
|
||||||
|
{
|
||||||
|
BackgroundJob.Enqueue(() =>
|
||||||
|
_scrobblingService.ScrobbleReviewUpdate(user.Id, dto.SeriesId, string.Empty, dto.Body));
|
||||||
|
}
|
||||||
|
return Ok(review);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<UserReviewDto> UpdateSeriesReview(AppUser user, UpdateUserReviewDto dto)
|
||||||
|
{
|
||||||
|
var ratingBuilder = new RatingBuilder(await _unitOfWork.UserRepository.GetUserRatingAsync(dto.SeriesId, user.Id));
|
||||||
|
|
||||||
var rating = ratingBuilder
|
var rating = ratingBuilder
|
||||||
.WithBody(dto.Body)
|
.WithBody(dto.Body)
|
||||||
.WithSeriesId(dto.SeriesId)
|
.WithSeriesId(dto.SeriesId)
|
||||||
.WithChapterId(dto.ChapterId)
|
|
||||||
.WithTagline(string.Empty)
|
.WithTagline(string.Empty)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
|
@ -55,14 +78,24 @@ public class ReviewController : BaseApiController
|
||||||
{
|
{
|
||||||
user.Ratings.Add(rating);
|
user.Ratings.Add(rating);
|
||||||
}
|
}
|
||||||
_unitOfWork.UserRepository.Update(user);
|
return _mapper.Map<UserReviewDto>(rating);
|
||||||
|
}
|
||||||
|
|
||||||
await _unitOfWork.CommitAsync();
|
private async Task<UserReviewDto> UpdateChapterReview(AppUser user, UpdateUserReviewDto dto, int chapterId)
|
||||||
|
{
|
||||||
|
var ratingBuilder = new ChapterRatingBuilder(await _unitOfWork.UserRepository.GetUserChapterRatingAsync(user.Id, chapterId));
|
||||||
|
|
||||||
|
var rating = ratingBuilder
|
||||||
|
.WithBody(dto.Body)
|
||||||
|
.WithSeriesId(dto.SeriesId)
|
||||||
|
.WithChapterId(chapterId)
|
||||||
|
.Build();
|
||||||
|
|
||||||
BackgroundJob.Enqueue(() =>
|
if (rating.Id == 0)
|
||||||
_scrobblingService.ScrobbleReviewUpdate(user.Id, dto.SeriesId, string.Empty, dto.Body));
|
{
|
||||||
return Ok(_mapper.Map<UserReviewDto>(rating));
|
user.ChapterRatings.Add(rating);
|
||||||
|
}
|
||||||
|
return _mapper.Map<UserReviewDto>(rating);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -76,7 +109,14 @@ public class ReviewController : BaseApiController
|
||||||
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Ratings);
|
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(User.GetUserId(), AppUserIncludes.Ratings);
|
||||||
if (user == null) return Unauthorized();
|
if (user == null) return Unauthorized();
|
||||||
|
|
||||||
user.Ratings = user.Ratings.Where(r => !(r.SeriesId == seriesId && r.ChapterId == chapterId)).ToList();
|
if (chapterId != null)
|
||||||
|
{
|
||||||
|
user.ChapterRatings = user.ChapterRatings.Where(r => r.ChapterId != chapterId).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user.Ratings = user.Ratings.Where(r => r.SeriesId != seriesId).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
_unitOfWork.UserRepository.Update(user);
|
_unitOfWork.UserRepository.Update(user);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,9 @@
|
||||||
using System.Collections.Generic;
|
using System.Linq;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using API.Constants;
|
using API.Constants;
|
||||||
using API.Data;
|
using API.Data;
|
||||||
using API.Data.Repositories;
|
using API.Data.Repositories;
|
||||||
using API.DTOs;
|
using API.DTOs;
|
||||||
using API.DTOs.SeriesDetail;
|
|
||||||
using API.Extensions;
|
using API.Extensions;
|
||||||
using API.Services;
|
using API.Services;
|
||||||
using API.SignalR;
|
using API.SignalR;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ public class UserReviewDto
|
||||||
/// The series this is for
|
/// The series this is for
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int SeriesId { get; set; }
|
public int SeriesId { get; set; }
|
||||||
public int? VolumeId { get; set; }
|
|
||||||
public int? ChapterId { get; set; }
|
public int? ChapterId { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The library this series belongs in
|
/// The library this series belongs in
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ public sealed class DataContext : IdentityDbContext<AppUser, AppRole, int,
|
||||||
public DbSet<EmailHistory> EmailHistory { get; set; } = null!;
|
public DbSet<EmailHistory> EmailHistory { get; set; } = null!;
|
||||||
public DbSet<MetadataSettings> MetadataSettings { get; set; } = null!;
|
public DbSet<MetadataSettings> MetadataSettings { get; set; } = null!;
|
||||||
public DbSet<MetadataFieldMapping> MetadataFieldMapping { get; set; } = null!;
|
public DbSet<MetadataFieldMapping> MetadataFieldMapping { get; set; } = null!;
|
||||||
|
public DbSet<AppUserChapterRating> AppUserChapterRating { get; set; } = null!;
|
||||||
public DbSet<ExternalChapterReview> ExternalChapterReview { get; set; } = null!;
|
public DbSet<ExternalChapterReview> ExternalChapterReview { get; set; } = null!;
|
||||||
public DbSet<ExternalChapterMetadata> ExternalChapterMetadata { get; set; } = null!;
|
public DbSet<ExternalChapterMetadata> ExternalChapterMetadata { get; set; } = null!;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
namespace API.Data.Migrations
|
namespace API.Data.Migrations
|
||||||
{
|
{
|
||||||
[DbContext(typeof(DataContext))]
|
[DbContext(typeof(DataContext))]
|
||||||
[Migration("20250428141809_ChapterRating")]
|
[Migration("20250428151027_ChapterRating")]
|
||||||
partial class ChapterRating
|
partial class ChapterRating
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|
@ -198,6 +198,41 @@ namespace API.Data.Migrations
|
||||||
b.ToTable("AppUserBookmark");
|
b.ToTable("AppUserBookmark");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserChapterRating", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AppUserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ChapterId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("HasBeenRated")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<float>("Rating")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<string>("Review")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SeriesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
|
b.HasIndex("ChapterId");
|
||||||
|
|
||||||
|
b.HasIndex("SeriesId");
|
||||||
|
|
||||||
|
b.ToTable("AppUserChapterRating");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("API.Entities.AppUserCollection", b =>
|
modelBuilder.Entity("API.Entities.AppUserCollection", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
|
|
@ -553,9 +588,6 @@ namespace API.Data.Migrations
|
||||||
b.Property<int>("AppUserId")
|
b.Property<int>("AppUserId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<int?>("ChapterId")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<bool>("HasBeenRated")
|
b.Property<bool>("HasBeenRated")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
|
@ -575,8 +607,6 @@ namespace API.Data.Migrations
|
||||||
|
|
||||||
b.HasIndex("AppUserId");
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
b.HasIndex("ChapterId");
|
|
||||||
|
|
||||||
b.HasIndex("SeriesId");
|
b.HasIndex("SeriesId");
|
||||||
|
|
||||||
b.ToTable("AppUserRating");
|
b.ToTable("AppUserRating");
|
||||||
|
|
@ -2705,6 +2735,33 @@ namespace API.Data.Migrations
|
||||||
b.Navigation("AppUser");
|
b.Navigation("AppUser");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserChapterRating", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
.WithMany("ChapterRatings")
|
||||||
|
.HasForeignKey("AppUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("API.Entities.Chapter", "Chapter")
|
||||||
|
.WithMany("Ratings")
|
||||||
|
.HasForeignKey("ChapterId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("API.Entities.Series", "Series")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("SeriesId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("AppUser");
|
||||||
|
|
||||||
|
b.Navigation("Chapter");
|
||||||
|
|
||||||
|
b.Navigation("Series");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("API.Entities.AppUserCollection", b =>
|
modelBuilder.Entity("API.Entities.AppUserCollection", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("API.Entities.AppUser", "AppUser")
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
|
@ -2811,10 +2868,6 @@ namespace API.Data.Migrations
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.HasOne("API.Entities.Chapter", "Chapter")
|
|
||||||
.WithMany("Ratings")
|
|
||||||
.HasForeignKey("ChapterId");
|
|
||||||
|
|
||||||
b.HasOne("API.Entities.Series", "Series")
|
b.HasOne("API.Entities.Series", "Series")
|
||||||
.WithMany("Ratings")
|
.WithMany("Ratings")
|
||||||
.HasForeignKey("SeriesId")
|
.HasForeignKey("SeriesId")
|
||||||
|
|
@ -2823,8 +2876,6 @@ namespace API.Data.Migrations
|
||||||
|
|
||||||
b.Navigation("AppUser");
|
b.Navigation("AppUser");
|
||||||
|
|
||||||
b.Navigation("Chapter");
|
|
||||||
|
|
||||||
b.Navigation("Series");
|
b.Navigation("Series");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -3449,6 +3500,8 @@ namespace API.Data.Migrations
|
||||||
{
|
{
|
||||||
b.Navigation("Bookmarks");
|
b.Navigation("Bookmarks");
|
||||||
|
|
||||||
|
b.Navigation("ChapterRatings");
|
||||||
|
|
||||||
b.Navigation("Collections");
|
b.Navigation("Collections");
|
||||||
|
|
||||||
b.Navigation("DashboardStreams");
|
b.Navigation("DashboardStreams");
|
||||||
|
|
@ -10,11 +10,41 @@ namespace API.Data.Migrations
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.AddColumn<int>(
|
migrationBuilder.CreateTable(
|
||||||
name: "ChapterId",
|
name: "AppUserChapterRating",
|
||||||
table: "AppUserRating",
|
columns: table => new
|
||||||
type: "INTEGER",
|
{
|
||||||
nullable: true);
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
Rating = table.Column<float>(type: "REAL", nullable: false),
|
||||||
|
HasBeenRated = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
Review = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
SeriesId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
ChapterId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
AppUserId = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_AppUserChapterRating", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AppUserChapterRating_AspNetUsers_AppUserId",
|
||||||
|
column: x => x.AppUserId,
|
||||||
|
principalTable: "AspNetUsers",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AppUserChapterRating_Chapter_ChapterId",
|
||||||
|
column: x => x.ChapterId,
|
||||||
|
principalTable: "Chapter",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_AppUserChapterRating_Series_SeriesId",
|
||||||
|
column: x => x.SeriesId,
|
||||||
|
principalTable: "Series",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateTable(
|
migrationBuilder.CreateTable(
|
||||||
name: "ExternalChapterMetadata",
|
name: "ExternalChapterMetadata",
|
||||||
|
|
@ -84,10 +114,20 @@ namespace API.Data.Migrations
|
||||||
});
|
});
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_AppUserRating_ChapterId",
|
name: "IX_AppUserChapterRating_AppUserId",
|
||||||
table: "AppUserRating",
|
table: "AppUserChapterRating",
|
||||||
|
column: "AppUserId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AppUserChapterRating_ChapterId",
|
||||||
|
table: "AppUserChapterRating",
|
||||||
column: "ChapterId");
|
column: "ChapterId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_AppUserChapterRating_SeriesId",
|
||||||
|
table: "AppUserChapterRating",
|
||||||
|
column: "SeriesId");
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
migrationBuilder.CreateIndex(
|
||||||
name: "IX_ExternalChapterMetadata_ChapterId",
|
name: "IX_ExternalChapterMetadata_ChapterId",
|
||||||
table: "ExternalChapterMetadata",
|
table: "ExternalChapterMetadata",
|
||||||
|
|
@ -98,21 +138,13 @@ namespace API.Data.Migrations
|
||||||
name: "IX_ExternalChapterMetadataExternalChapterReview_ExternalReviewsId",
|
name: "IX_ExternalChapterMetadataExternalChapterReview_ExternalReviewsId",
|
||||||
table: "ExternalChapterMetadataExternalChapterReview",
|
table: "ExternalChapterMetadataExternalChapterReview",
|
||||||
column: "ExternalReviewsId");
|
column: "ExternalReviewsId");
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_AppUserRating_Chapter_ChapterId",
|
|
||||||
table: "AppUserRating",
|
|
||||||
column: "ChapterId",
|
|
||||||
principalTable: "Chapter",
|
|
||||||
principalColumn: "Id");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
{
|
{
|
||||||
migrationBuilder.DropForeignKey(
|
migrationBuilder.DropTable(
|
||||||
name: "FK_AppUserRating_Chapter_ChapterId",
|
name: "AppUserChapterRating");
|
||||||
table: "AppUserRating");
|
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "ExternalChapterMetadataExternalChapterReview");
|
name: "ExternalChapterMetadataExternalChapterReview");
|
||||||
|
|
@ -122,14 +154,6 @@ namespace API.Data.Migrations
|
||||||
|
|
||||||
migrationBuilder.DropTable(
|
migrationBuilder.DropTable(
|
||||||
name: "ExternalChapterReview");
|
name: "ExternalChapterReview");
|
||||||
|
|
||||||
migrationBuilder.DropIndex(
|
|
||||||
name: "IX_AppUserRating_ChapterId",
|
|
||||||
table: "AppUserRating");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "ChapterId",
|
|
||||||
table: "AppUserRating");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -195,6 +195,41 @@ namespace API.Data.Migrations
|
||||||
b.ToTable("AppUserBookmark");
|
b.ToTable("AppUserBookmark");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserChapterRating", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("AppUserId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("ChapterId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("HasBeenRated")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<float>("Rating")
|
||||||
|
.HasColumnType("REAL");
|
||||||
|
|
||||||
|
b.Property<string>("Review")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SeriesId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
|
b.HasIndex("ChapterId");
|
||||||
|
|
||||||
|
b.HasIndex("SeriesId");
|
||||||
|
|
||||||
|
b.ToTable("AppUserChapterRating");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("API.Entities.AppUserCollection", b =>
|
modelBuilder.Entity("API.Entities.AppUserCollection", b =>
|
||||||
{
|
{
|
||||||
b.Property<int>("Id")
|
b.Property<int>("Id")
|
||||||
|
|
@ -550,9 +585,6 @@ namespace API.Data.Migrations
|
||||||
b.Property<int>("AppUserId")
|
b.Property<int>("AppUserId")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
b.Property<int?>("ChapterId")
|
|
||||||
.HasColumnType("INTEGER");
|
|
||||||
|
|
||||||
b.Property<bool>("HasBeenRated")
|
b.Property<bool>("HasBeenRated")
|
||||||
.HasColumnType("INTEGER");
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
|
@ -572,8 +604,6 @@ namespace API.Data.Migrations
|
||||||
|
|
||||||
b.HasIndex("AppUserId");
|
b.HasIndex("AppUserId");
|
||||||
|
|
||||||
b.HasIndex("ChapterId");
|
|
||||||
|
|
||||||
b.HasIndex("SeriesId");
|
b.HasIndex("SeriesId");
|
||||||
|
|
||||||
b.ToTable("AppUserRating");
|
b.ToTable("AppUserRating");
|
||||||
|
|
@ -2702,6 +2732,33 @@ namespace API.Data.Migrations
|
||||||
b.Navigation("AppUser");
|
b.Navigation("AppUser");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("API.Entities.AppUserChapterRating", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
.WithMany("ChapterRatings")
|
||||||
|
.HasForeignKey("AppUserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("API.Entities.Chapter", "Chapter")
|
||||||
|
.WithMany("Ratings")
|
||||||
|
.HasForeignKey("ChapterId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("API.Entities.Series", "Series")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("SeriesId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("AppUser");
|
||||||
|
|
||||||
|
b.Navigation("Chapter");
|
||||||
|
|
||||||
|
b.Navigation("Series");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("API.Entities.AppUserCollection", b =>
|
modelBuilder.Entity("API.Entities.AppUserCollection", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("API.Entities.AppUser", "AppUser")
|
b.HasOne("API.Entities.AppUser", "AppUser")
|
||||||
|
|
@ -2808,10 +2865,6 @@ namespace API.Data.Migrations
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.HasOne("API.Entities.Chapter", "Chapter")
|
|
||||||
.WithMany("Ratings")
|
|
||||||
.HasForeignKey("ChapterId");
|
|
||||||
|
|
||||||
b.HasOne("API.Entities.Series", "Series")
|
b.HasOne("API.Entities.Series", "Series")
|
||||||
.WithMany("Ratings")
|
.WithMany("Ratings")
|
||||||
.HasForeignKey("SeriesId")
|
.HasForeignKey("SeriesId")
|
||||||
|
|
@ -2820,8 +2873,6 @@ namespace API.Data.Migrations
|
||||||
|
|
||||||
b.Navigation("AppUser");
|
b.Navigation("AppUser");
|
||||||
|
|
||||||
b.Navigation("Chapter");
|
|
||||||
|
|
||||||
b.Navigation("Series");
|
b.Navigation("Series");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -3446,6 +3497,8 @@ namespace API.Data.Migrations
|
||||||
{
|
{
|
||||||
b.Navigation("Bookmarks");
|
b.Navigation("Bookmarks");
|
||||||
|
|
||||||
|
b.Navigation("ChapterRatings");
|
||||||
|
|
||||||
b.Navigation("Collections");
|
b.Navigation("Collections");
|
||||||
|
|
||||||
b.Navigation("DashboardStreams");
|
b.Navigation("DashboardStreams");
|
||||||
|
|
|
||||||
|
|
@ -315,14 +315,14 @@ public class ChapterRepository : IChapterRepository
|
||||||
public async Task<int> GetAverageUserRating(int chapterId, int userId)
|
public async Task<int> GetAverageUserRating(int chapterId, int userId)
|
||||||
{
|
{
|
||||||
// If there is 0 or 1 rating and that rating is you, return 0 back
|
// If there is 0 or 1 rating and that rating is you, return 0 back
|
||||||
var countOfRatingsThatAreUser = await _context.AppUserRating
|
var countOfRatingsThatAreUser = await _context.AppUserChapterRating
|
||||||
.Where(r => r.ChapterId == chapterId && r.HasBeenRated)
|
.Where(r => r.ChapterId == chapterId && r.HasBeenRated)
|
||||||
.CountAsync(u => u.AppUserId == userId);
|
.CountAsync(u => u.AppUserId == userId);
|
||||||
if (countOfRatingsThatAreUser == 1)
|
if (countOfRatingsThatAreUser == 1)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
var avg = (await _context.AppUserRating
|
var avg = (await _context.AppUserChapterRating
|
||||||
.Where(r => r.ChapterId == chapterId && r.HasBeenRated)
|
.Where(r => r.ChapterId == chapterId && r.HasBeenRated)
|
||||||
.AverageAsync(r => (int?) r.Rating));
|
.AverageAsync(r => (int?) r.Rating));
|
||||||
return avg.HasValue ? (int) (avg.Value * 20) : 0;
|
return avg.HasValue ? (int) (avg.Value * 20) : 0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#nullable enable
|
#nullable enable
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using API.Entities.Metadata;
|
using API.Entities.Metadata;
|
||||||
|
|
|
||||||
|
|
@ -758,7 +758,7 @@ public class SeriesRepository : ISeriesRepository
|
||||||
foreach (var s in series)
|
foreach (var s in series)
|
||||||
{
|
{
|
||||||
s.PagesRead = userProgress.Where(p => p.SeriesId == s.Id).Sum(p => p.PagesRead);
|
s.PagesRead = userProgress.Where(p => p.SeriesId == s.Id).Sum(p => p.PagesRead);
|
||||||
var rating = userRatings.SingleOrDefault(r => r.SeriesId == s.Id && r.ChapterId == null);
|
var rating = userRatings.SingleOrDefault(r => r.SeriesId == s.Id);
|
||||||
if (rating != null)
|
if (rating != null)
|
||||||
{
|
{
|
||||||
s.UserRating = rating.Rating;
|
s.UserRating = rating.Rating;
|
||||||
|
|
@ -2177,14 +2177,14 @@ public class SeriesRepository : ISeriesRepository
|
||||||
{
|
{
|
||||||
// If there is 0 or 1 rating and that rating is you, return 0 back
|
// If there is 0 or 1 rating and that rating is you, return 0 back
|
||||||
var countOfRatingsThatAreUser = await _context.AppUserRating
|
var countOfRatingsThatAreUser = await _context.AppUserRating
|
||||||
.Where(r => r.SeriesId == seriesId && r.HasBeenRated && r.ChapterId == null)
|
.Where(r => r.SeriesId == seriesId && r.HasBeenRated)
|
||||||
.CountAsync(u => u.AppUserId == userId);
|
.CountAsync(u => u.AppUserId == userId);
|
||||||
if (countOfRatingsThatAreUser == 1)
|
if (countOfRatingsThatAreUser == 1)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
var avg = (await _context.AppUserRating
|
var avg = (await _context.AppUserRating
|
||||||
.Where(r => r.SeriesId == seriesId && r.HasBeenRated && r.ChapterId == null)
|
.Where(r => r.SeriesId == seriesId && r.HasBeenRated)
|
||||||
.AverageAsync(r => (int?) r.Rating));
|
.AverageAsync(r => (int?) r.Rating));
|
||||||
return avg.HasValue ? (int) (avg.Value * 20) : 0;
|
return avg.HasValue ? (int) (avg.Value * 20) : 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ public enum AppUserIncludes
|
||||||
SideNavStreams = 4096,
|
SideNavStreams = 4096,
|
||||||
ExternalSources = 8192,
|
ExternalSources = 8192,
|
||||||
Collections = 16384, // 2^14
|
Collections = 16384, // 2^14
|
||||||
|
ChapterRatings = 1 << 15,
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IUserRepository
|
public interface IUserRepository
|
||||||
|
|
@ -64,7 +65,8 @@ public interface IUserRepository
|
||||||
Task<IEnumerable<AppUser>> GetAdminUsersAsync();
|
Task<IEnumerable<AppUser>> GetAdminUsersAsync();
|
||||||
Task<bool> IsUserAdminAsync(AppUser? user);
|
Task<bool> IsUserAdminAsync(AppUser? user);
|
||||||
Task<IList<string>> GetRoles(int userId);
|
Task<IList<string>> GetRoles(int userId);
|
||||||
Task<AppUserRating?> GetUserRatingAsync(int seriesId, int userId, int? chapterId = null);
|
Task<AppUserRating?> GetUserRatingAsync(int seriesId, int userId);
|
||||||
|
Task<AppUserChapterRating?> GetUserChapterRatingAsync(int userId, int chapterId);
|
||||||
Task<IList<UserReviewDto>> GetUserRatingDtosForSeriesAsync(int seriesId, int userId);
|
Task<IList<UserReviewDto>> GetUserRatingDtosForSeriesAsync(int seriesId, int userId);
|
||||||
Task<IList<UserReviewDto>> GetUserRatingDtosForChapterAsync(int chapterId, int userId);
|
Task<IList<UserReviewDto>> GetUserRatingDtosForChapterAsync(int chapterId, int userId);
|
||||||
Task<AppUserPreferences?> GetPreferencesAsync(string username);
|
Task<AppUserPreferences?> GetPreferencesAsync(string username);
|
||||||
|
|
@ -584,10 +586,17 @@ public class UserRepository : IUserRepository
|
||||||
return await _userManager.GetRolesAsync(user);
|
return await _userManager.GetRolesAsync(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<AppUserRating?> GetUserRatingAsync(int seriesId, int userId, int? chapterId = null)
|
public async Task<AppUserRating?> GetUserRatingAsync(int seriesId, int userId)
|
||||||
{
|
{
|
||||||
return await _context.AppUserRating
|
return await _context.AppUserRating
|
||||||
.Where(r => r.SeriesId == seriesId && r.AppUserId == userId && r.ChapterId == chapterId)
|
.Where(r => r.SeriesId == seriesId && r.AppUserId == userId)
|
||||||
|
.SingleOrDefaultAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<AppUserChapterRating?> GetUserChapterRatingAsync(int userId, int chapterId)
|
||||||
|
{
|
||||||
|
return await _context.AppUserChapterRating
|
||||||
|
.Where(r => r.AppUserId == userId && r.ChapterId == chapterId)
|
||||||
.SingleOrDefaultAsync();
|
.SingleOrDefaultAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -595,7 +604,7 @@ public class UserRepository : IUserRepository
|
||||||
{
|
{
|
||||||
return await _context.AppUserRating
|
return await _context.AppUserRating
|
||||||
.Include(r => r.AppUser)
|
.Include(r => r.AppUser)
|
||||||
.Where(r => r.SeriesId == seriesId && r.ChapterId == null)
|
.Where(r => r.SeriesId == seriesId)
|
||||||
.Where(r => r.AppUser.UserPreferences.ShareReviews || r.AppUserId == userId)
|
.Where(r => r.AppUser.UserPreferences.ShareReviews || r.AppUserId == userId)
|
||||||
.OrderBy(r => r.AppUserId == userId)
|
.OrderBy(r => r.AppUserId == userId)
|
||||||
.ThenBy(r => r.Rating)
|
.ThenBy(r => r.Rating)
|
||||||
|
|
@ -606,7 +615,7 @@ public class UserRepository : IUserRepository
|
||||||
|
|
||||||
public async Task<IList<UserReviewDto>> GetUserRatingDtosForChapterAsync(int chapterId, int userId)
|
public async Task<IList<UserReviewDto>> GetUserRatingDtosForChapterAsync(int chapterId, int userId)
|
||||||
{
|
{
|
||||||
return await _context.AppUserRating
|
return await _context.AppUserChapterRating
|
||||||
.Include(r => r.AppUser)
|
.Include(r => r.AppUser)
|
||||||
.Where(r => r.ChapterId == chapterId)
|
.Where(r => r.ChapterId == chapterId)
|
||||||
.Where(r => r.AppUser.UserPreferences.ShareReviews || r.AppUserId == userId)
|
.Where(r => r.AppUser.UserPreferences.ShareReviews || r.AppUserId == userId)
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ public class AppUser : IdentityUser<int>, IHasConcurrencyToken
|
||||||
public ICollection<AppUserRole> UserRoles { get; set; } = null!;
|
public ICollection<AppUserRole> UserRoles { get; set; } = null!;
|
||||||
public ICollection<AppUserProgress> Progresses { get; set; } = null!;
|
public ICollection<AppUserProgress> Progresses { get; set; } = null!;
|
||||||
public ICollection<AppUserRating> Ratings { get; set; } = null!;
|
public ICollection<AppUserRating> Ratings { get; set; } = null!;
|
||||||
|
public ICollection<AppUserChapterRating> ChapterRatings { get; set; } = null!;
|
||||||
public AppUserPreferences UserPreferences { get; set; } = null!;
|
public AppUserPreferences UserPreferences { get; set; } = null!;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Bookmarks associated with this User
|
/// Bookmarks associated with this User
|
||||||
|
|
|
||||||
30
API/Entities/AppUserChapterRating.cs
Normal file
30
API/Entities/AppUserChapterRating.cs
Normal 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!;
|
||||||
|
}
|
||||||
|
|
@ -26,10 +26,6 @@ public class AppUserRating
|
||||||
public int SeriesId { get; set; }
|
public int SeriesId { get; set; }
|
||||||
public Series Series { get; set; } = null!;
|
public Series Series { get; set; } = null!;
|
||||||
|
|
||||||
public int? ChapterId { get; set; } = null;
|
|
||||||
public Chapter? Chapter { get; set; } = null;
|
|
||||||
|
|
||||||
|
|
||||||
// Relationships
|
// Relationships
|
||||||
public int AppUserId { get; set; }
|
public int AppUserId { get; set; }
|
||||||
public AppUser AppUser { get; set; } = null!;
|
public AppUser AppUser { get; set; } = null!;
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ public class Chapter : IEntityDate, IHasReadTimeEstimate, IHasCoverImage
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ICollection<Genre> Genres { get; set; } = new List<Genre>();
|
public ICollection<Genre> Genres { get; set; } = new List<Genre>();
|
||||||
public ICollection<Tag> Tags { get; set; } = new List<Tag>();
|
public ICollection<Tag> Tags { get; set; } = new List<Tag>();
|
||||||
public ICollection<AppUserRating> Ratings { get; set; } = [];
|
public ICollection<AppUserChapterRating> Ratings { get; set; } = [];
|
||||||
|
|
||||||
public ICollection<AppUserProgress> UserProgress { get; set; }
|
public ICollection<AppUserProgress> UserProgress { get; set; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,11 @@ public static class IncludesExtensions
|
||||||
.ThenInclude(c => c.Items);
|
.ThenInclude(c => c.Items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (includeFlags.HasFlag(AppUserIncludes.ChapterRatings))
|
||||||
|
{
|
||||||
|
query = query.Include(u => u.ChapterRatings);
|
||||||
|
}
|
||||||
|
|
||||||
return query.AsSplitQuery();
|
return query.AsSplitQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,16 @@ public class AutoMapperProfiles : Profile
|
||||||
.ForMember(dest => dest.Username,
|
.ForMember(dest => dest.Username,
|
||||||
opt =>
|
opt =>
|
||||||
opt.MapFrom(src => src.AppUser.UserName));
|
opt.MapFrom(src => src.AppUser.UserName));
|
||||||
|
CreateMap<AppUserChapterRating, UserReviewDto>()
|
||||||
|
.ForMember(dest => dest.LibraryId,
|
||||||
|
opt =>
|
||||||
|
opt.MapFrom(src => src.Series.LibraryId))
|
||||||
|
.ForMember(dest => dest.Body,
|
||||||
|
opt =>
|
||||||
|
opt.MapFrom(src => src.Review))
|
||||||
|
.ForMember(dest => dest.Username,
|
||||||
|
opt =>
|
||||||
|
opt.MapFrom(src => src.AppUser.UserName));
|
||||||
|
|
||||||
CreateMap<AppUserProgress, ProgressDto>()
|
CreateMap<AppUserProgress, ProgressDto>()
|
||||||
.ForMember(dest => dest.PageNum,
|
.ForMember(dest => dest.PageNum,
|
||||||
|
|
|
||||||
40
API/Helpers/Builders/AppUserChapterRatingBuilder.cs
Normal file
40
API/Helpers/Builders/AppUserChapterRatingBuilder.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#nullable enable
|
||||||
|
using System;
|
||||||
|
using API.Entities;
|
||||||
|
|
||||||
|
namespace API.Helpers.Builders;
|
||||||
|
|
||||||
|
public class ChapterRatingBuilder : IEntityBuilder<AppUserChapterRating>
|
||||||
|
{
|
||||||
|
private readonly AppUserChapterRating _rating;
|
||||||
|
public AppUserChapterRating Build() => _rating;
|
||||||
|
|
||||||
|
public ChapterRatingBuilder(AppUserChapterRating? rating = null)
|
||||||
|
{
|
||||||
|
_rating = rating ?? new AppUserChapterRating();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChapterRatingBuilder WithSeriesId(int seriesId)
|
||||||
|
{
|
||||||
|
_rating.SeriesId = seriesId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChapterRatingBuilder WithChapterId(int chapterId)
|
||||||
|
{
|
||||||
|
_rating.ChapterId = chapterId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChapterRatingBuilder WithRating(int rating)
|
||||||
|
{
|
||||||
|
_rating.Rating = Math.Clamp(rating, 0, 5);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChapterRatingBuilder WithBody(string body)
|
||||||
|
{
|
||||||
|
_rating.Review = body;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,12 +20,6 @@ public class RatingBuilder : IEntityBuilder<AppUserRating>
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RatingBuilder WithChapterId(int? chapterId)
|
|
||||||
{
|
|
||||||
_rating.ChapterId = chapterId;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public RatingBuilder WithRating(int rating)
|
public RatingBuilder WithRating(int rating)
|
||||||
{
|
{
|
||||||
_rating.Rating = Math.Clamp(rating, 0, 5);
|
_rating.Rating = Math.Clamp(rating, 0, 5);
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,19 @@ public class RatingService: IRatingService
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> UpdateRating(AppUser user, UpdateRatingDto updateRatingDto)
|
public async Task<bool> UpdateRating(AppUser user, UpdateRatingDto updateRatingDto)
|
||||||
|
{
|
||||||
|
if (updateRatingDto.ChapterId != null)
|
||||||
|
{
|
||||||
|
return await UpdateChapterRating(user, updateRatingDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await UpdateSeriesRating(user, updateRatingDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<bool> UpdateSeriesRating(AppUser user, UpdateRatingDto updateRatingDto)
|
||||||
{
|
{
|
||||||
var userRating =
|
var userRating =
|
||||||
await _unitOfWork.UserRepository.GetUserRatingAsync(updateRatingDto.SeriesId, user.Id, updateRatingDto.ChapterId) ??
|
await _unitOfWork.UserRepository.GetUserRatingAsync(updateRatingDto.SeriesId, user.Id) ??
|
||||||
new AppUserRating();
|
new AppUserRating();
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|
@ -47,7 +57,6 @@ public class RatingService: IRatingService
|
||||||
userRating.Rating = Math.Clamp(updateRatingDto.UserRating, 0f, 5f);
|
userRating.Rating = Math.Clamp(updateRatingDto.UserRating, 0f, 5f);
|
||||||
userRating.HasBeenRated = true;
|
userRating.HasBeenRated = true;
|
||||||
userRating.SeriesId = updateRatingDto.SeriesId;
|
userRating.SeriesId = updateRatingDto.SeriesId;
|
||||||
userRating.ChapterId = updateRatingDto.ChapterId;
|
|
||||||
|
|
||||||
if (userRating.Id == 0)
|
if (userRating.Id == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -75,4 +84,45 @@ public class RatingService: IRatingService
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<bool> UpdateChapterRating(AppUser user, UpdateRatingDto updateRatingDto)
|
||||||
|
{
|
||||||
|
if (updateRatingDto.ChapterId == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var userRating =
|
||||||
|
await _unitOfWork.UserRepository.GetUserChapterRatingAsync(user.Id, updateRatingDto.ChapterId.Value) ??
|
||||||
|
new AppUserChapterRating();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
userRating.Rating = Math.Clamp(updateRatingDto.UserRating, 0f, 5f);
|
||||||
|
userRating.HasBeenRated = true;
|
||||||
|
userRating.SeriesId = updateRatingDto.SeriesId;
|
||||||
|
userRating.ChapterId = updateRatingDto.ChapterId.Value;
|
||||||
|
|
||||||
|
if (userRating.Id == 0)
|
||||||
|
{
|
||||||
|
user.ChapterRatings ??= new List<AppUserChapterRating>();
|
||||||
|
user.ChapterRatings.Add(userRating);
|
||||||
|
}
|
||||||
|
|
||||||
|
_unitOfWork.UserRepository.Update(user);
|
||||||
|
|
||||||
|
await _unitOfWork.CommitAsync();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "There was an exception saving rating");
|
||||||
|
}
|
||||||
|
|
||||||
|
await _unitOfWork.RollbackAsync();
|
||||||
|
user.ChapterRatings?.Remove(userRating);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue