Add rating to chapter page & volume (if one chapter)
This commit is contained in:
parent
e96cb0fde9
commit
8ccc2b5801
18 changed files with 226 additions and 47 deletions
|
|
@ -28,13 +28,16 @@ public class ChapterController : BaseApiController
|
|||
private readonly ILocalizationService _localizationService;
|
||||
private readonly IEventHub _eventHub;
|
||||
private readonly ILogger<ChapterController> _logger;
|
||||
private readonly IRatingService _ratingService;
|
||||
|
||||
public ChapterController(IUnitOfWork unitOfWork, ILocalizationService localizationService, IEventHub eventHub, ILogger<ChapterController> logger)
|
||||
public ChapterController(IUnitOfWork unitOfWork, ILocalizationService localizationService, IEventHub eventHub, ILogger<ChapterController> logger,
|
||||
IRatingService ratingService)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_localizationService = localizationService;
|
||||
_eventHub = eventHub;
|
||||
_logger = logger;
|
||||
_ratingService = ratingService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -403,4 +406,15 @@ public class ChapterController : BaseApiController
|
|||
return await _unitOfWork.UserRepository.GetUserRatingDtosForChapterAsync(chapterId, User.GetUserId());
|
||||
}
|
||||
|
||||
[HttpPost("update-rating")]
|
||||
public async Task<ActionResult> UpdateRating(UpdateChapterRatingDto dto)
|
||||
{
|
||||
if (await _ratingService.UpdateChapterRating(User.GetUserId(), dto))
|
||||
{
|
||||
return Ok();
|
||||
}
|
||||
|
||||
return BadRequest(await _localizationService.Translate(User.GetUserId(), "generic-error"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,4 +38,15 @@ public class RatingController : BaseApiController
|
|||
FavoriteCount = 0
|
||||
});
|
||||
}
|
||||
|
||||
[HttpGet("overall/chapter")]
|
||||
public async Task<ActionResult<RatingDto>> GetOverallChapterRating([FromQuery] int chapterId)
|
||||
{
|
||||
return Ok(new RatingDto
|
||||
{
|
||||
Provider = ScrobbleProvider.Kavita,
|
||||
AverageScore = await _unitOfWork.ChapterRepository.GetAverageUserRating(chapterId, User.GetUserId()),
|
||||
FavoriteCount = 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7
API/DTOs/UpdateChapterRatingDto.cs
Normal file
7
API/DTOs/UpdateChapterRatingDto.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace API.DTOs;
|
||||
|
||||
public class UpdateChapterRatingDto
|
||||
{
|
||||
public int ChapterId { get; init; }
|
||||
public float Rating { get; init; }
|
||||
}
|
||||
|
|
@ -48,6 +48,7 @@ public interface IChapterRepository
|
|||
Task<ChapterDto> AddChapterModifiers(int userId, ChapterDto chapter);
|
||||
IEnumerable<Chapter> GetChaptersForSeries(int seriesId);
|
||||
Task<IList<Chapter>> GetAllChaptersForSeries(int seriesId);
|
||||
Task<int> GetAverageUserRating(int chapterId, int userId);
|
||||
}
|
||||
public class ChapterRepository : IChapterRepository
|
||||
{
|
||||
|
|
@ -310,4 +311,20 @@ public class ChapterRepository : IChapterRepository
|
|||
.ThenInclude(cp => cp.Person)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<int> GetAverageUserRating(int chapterId, int userId)
|
||||
{
|
||||
// If there is 0 or 1 rating and that rating is you, return 0 back
|
||||
var countOfRatingsThatAreUser = await _context.AppUserChapterRating
|
||||
.Where(r => r.ChapterId == chapterId && r.HasBeenRated)
|
||||
.CountAsync(u => u.AppUserId == userId);
|
||||
if (countOfRatingsThatAreUser == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
var avg = (await _context.AppUserChapterRating
|
||||
.Where(r => r.ChapterId == chapterId && r.HasBeenRated)
|
||||
.AverageAsync(r => (int?) r.Rating));
|
||||
return avg.HasValue ? (int) (avg.Value * 20) : 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ public interface IUserRepository
|
|||
Task<bool> IsUserAdminAsync(AppUser? user);
|
||||
Task<IList<string>> GetRoles(int userId);
|
||||
Task<AppUserRating?> GetUserRatingAsync(int seriesId, int userId);
|
||||
Task<AppUserChapterRating?> GetUserChapterRatingAsync(int chapterId, int userId);
|
||||
Task<IList<UserReviewDto>> GetUserRatingDtosForSeriesAsync(int seriesId, int userId);
|
||||
Task<IList<UserReviewDto>> GetUserRatingDtosForVolumeAsync(int volumeId, int userId);
|
||||
Task<IList<UserReviewDto>> GetUserRatingDtosForChapterAsync(int chapterId, int userId);
|
||||
|
|
@ -592,6 +593,12 @@ public class UserRepository : IUserRepository
|
|||
.Where(r => r.SeriesId == seriesId && r.AppUserId == userId)
|
||||
.SingleOrDefaultAsync();
|
||||
}
|
||||
public async Task<AppUserChapterRating?> GetUserChapterRatingAsync(int chapterId, int userId)
|
||||
{
|
||||
return await _context.AppUserChapterRating
|
||||
.Where(r => r.ChapterId == chapterId && r.AppUserId == userId)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<IList<UserReviewDto>> GetUserRatingDtosForSeriesAsync(int seriesId, int userId)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ public static class ApplicationServiceExtensions
|
|||
services.AddScoped<IMediaErrorService, MediaErrorService>();
|
||||
services.AddScoped<IMediaConversionService, MediaConversionService>();
|
||||
services.AddScoped<IStreamService, StreamService>();
|
||||
services.AddScoped<IRatingService, RatingService>();
|
||||
|
||||
services.AddScoped<IScannerService, ScannerService>();
|
||||
services.AddScoped<IProcessSeries, ProcessSeries>();
|
||||
|
|
|
|||
63
API/Services/RatingService.cs
Normal file
63
API/Services/RatingService.cs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using API.Data;
|
||||
using API.Data.Repositories;
|
||||
using API.DTOs;
|
||||
using API.Entities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace API.Services;
|
||||
|
||||
public interface IRatingService
|
||||
{
|
||||
Task<bool> UpdateChapterRating(int userId, UpdateChapterRatingDto dto);
|
||||
}
|
||||
|
||||
public class RatingService: IRatingService
|
||||
{
|
||||
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly ILogger<RatingService> _logger;
|
||||
|
||||
public RatingService(IUnitOfWork unitOfWork, ILogger<RatingService> logger)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateChapterRating(int userId, UpdateChapterRatingDto dto)
|
||||
{
|
||||
var user = await _unitOfWork.UserRepository.GetUserByIdAsync(userId, AppUserIncludes.ChapterRatings);
|
||||
if (user == null) throw new UnauthorizedAccessException();
|
||||
|
||||
var rating = await _unitOfWork.UserRepository.GetUserChapterRatingAsync(dto.ChapterId, userId) ?? new AppUserChapterRating();
|
||||
|
||||
rating.Rating = Math.Clamp(dto.Rating, 0, 5);
|
||||
rating.HasBeenRated = true;
|
||||
rating.ChapterId = dto.ChapterId;
|
||||
|
||||
if (rating.Id == 0)
|
||||
{
|
||||
user.ChapterRatings.Add(rating);
|
||||
}
|
||||
|
||||
_unitOfWork.UserRepository.Update(user);
|
||||
|
||||
try
|
||||
{
|
||||
if (!_unitOfWork.HasChanges() || await _unitOfWork.CommitAsync())
|
||||
{
|
||||
// Scrobble Update?
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "There was an exception while updating chapter rating");
|
||||
}
|
||||
|
||||
await _unitOfWork.RollbackAsync();
|
||||
user.ChapterRatings.Remove(rating);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue