Drawers, Estimated Reading Time, Korean Parsing Support (#1297)
* Started building out idea around detail drawer. Need code from word count to continue * Fixed the logic for caluclating time to read on comics * Adding styles * more styling fixes * Cleaned up the styles a bit more so it's at least functional. Not sure on the feature, might abandon. * Pulled Robbie's changes in and partially migrated them to the drawer. * Add offset overrides for offcanvas so it takes our header into account * Implemented a basic time left to finish the series (or at least what's in Kavita). Rough around the edges. * Cleaned up the drawer code. * Added Quick Catch ups to recommended page. Updated the timeout for scan tasks to ensure we don't run 2 at the same time. * Quick catchups implemented * Added preliminary support for Korean filename parsing. Reduced an array alloc that is called many thousands of times per scan. * Fixing drawer overflow * Fixed a calculation bug with average reading time. * Small spacing changes to drawer * Don't show estimated reading time if the user hasn't read anything * Bump eventsource from 1.1.1 to 2.0.2 in /UI/Web Bumps [eventsource](https://github.com/EventSource/eventsource) from 1.1.1 to 2.0.2. - [Release notes](https://github.com/EventSource/eventsource/releases) - [Changelog](https://github.com/EventSource/eventsource/blob/master/HISTORY.md) - [Commits](https://github.com/EventSource/eventsource/compare/v1.1.1...v2.0.2) --- updated-dependencies: - dependency-name: eventsource dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> * Added image to series detail drawer Co-authored-by: Robbie Davis <robbie@therobbiedavis.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
parent
d796bcdc0a
commit
63475722ea
40 changed files with 883 additions and 144 deletions
|
|
@ -149,4 +149,18 @@ public class MetadataController : BaseApiController
|
|||
IsoCode = c.IetfLanguageTag
|
||||
}).Where(l => !string.IsNullOrEmpty(l.IsoCode));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns summary for the chapter
|
||||
/// </summary>
|
||||
/// <param name="chapterId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("chapter-summary")]
|
||||
public async Task<ActionResult<string>> GetChapterSummary(int chapterId)
|
||||
{
|
||||
if (chapterId <= 0) return BadRequest("Chapter does not exist");
|
||||
var chapter = await _unitOfWork.ChapterRepository.GetChapterAsync(chapterId);
|
||||
if (chapter == null) return BadRequest("Chapter does not exist");
|
||||
return Ok(chapter.Summary);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using API.Data.Repositories;
|
|||
using API.DTOs;
|
||||
using API.DTOs.Reader;
|
||||
using API.Entities;
|
||||
using API.Entities.Enums;
|
||||
using API.Extensions;
|
||||
using API.Services;
|
||||
using API.Services.Tasks;
|
||||
|
|
@ -627,5 +628,46 @@ namespace API.Controllers
|
|||
return await _readerService.GetPrevChapterIdAsync(seriesId, volumeId, currentChapterId, userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// For the current user, returns an estimate on how long it would take to finish reading the series.
|
||||
/// </summary>
|
||||
/// <remarks>For Epubs, this does not check words inside a chapter due to overhead so may not work in all cases.</remarks>
|
||||
/// <param name="seriesId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("time-left")]
|
||||
public async Task<ActionResult<HourEstimateRangeDto>> GetEstimateToCompletion(int seriesId)
|
||||
{
|
||||
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
|
||||
var series = await _unitOfWork.SeriesRepository.GetSeriesDtoByIdAsync(seriesId, userId);
|
||||
|
||||
// Get all sum of all chapters with progress that is complete then subtract from series. Multiply by modifiers
|
||||
var progress = await _unitOfWork.AppUserProgressRepository.GetUserProgressForSeriesAsync(seriesId, userId);
|
||||
if (series.Format == MangaFormat.Epub)
|
||||
{
|
||||
var chapters =
|
||||
await _unitOfWork.ChapterRepository.GetChaptersByIdsAsync(progress.Select(p => p.ChapterId).ToList());
|
||||
// Word count
|
||||
var progressCount = chapters.Sum(c => c.WordCount);
|
||||
var wordsLeft = series.WordCount - progressCount;
|
||||
return Ok(new HourEstimateRangeDto()
|
||||
{
|
||||
MinHours = (int) Math.Round((wordsLeft / ReaderService.MinWordsPerHour)),
|
||||
MaxHours = (int) Math.Round((wordsLeft / ReaderService.MaxWordsPerHour)),
|
||||
AvgHours = (int) Math.Round((wordsLeft / ReaderService.AvgWordsPerHour)),
|
||||
HasProgress = progressCount > 0
|
||||
});
|
||||
}
|
||||
|
||||
var progressPageCount = progress.Sum(p => p.PagesRead);
|
||||
var pagesLeft = series.Pages - progressPageCount;
|
||||
return Ok(new HourEstimateRangeDto()
|
||||
{
|
||||
MinHours = (int) Math.Round((pagesLeft / ReaderService.MinPagesPerMinute / 60F)),
|
||||
MaxHours = (int) Math.Round((pagesLeft / ReaderService.MaxPagesPerMinute / 60F)),
|
||||
AvgHours = (int) Math.Round((pagesLeft / ReaderService.AvgPagesPerMinute / 60F)),
|
||||
HasProgress = progressPageCount > 0
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public class RecommendedController : BaseApiController
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// Quick Reads are series that are less than 2K pages in total.
|
||||
/// Quick Reads are series that should be readable in less than 10 in total and are not Ongoing in release.
|
||||
/// </summary>
|
||||
/// <param name="libraryId">Library to restrict series to</param>
|
||||
/// <returns></returns>
|
||||
|
|
@ -35,6 +35,24 @@ public class RecommendedController : BaseApiController
|
|||
return Ok(series);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quick Catchup Reads are series that should be readable in less than 10 in total and are Ongoing in release.
|
||||
/// </summary>
|
||||
/// <param name="libraryId">Library to restrict series to</param>
|
||||
/// <param name="userParams"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("quick-catchup-reads")]
|
||||
public async Task<ActionResult<PagedList<SeriesDto>>> GetQuickCatchupReads(int libraryId, [FromQuery] UserParams userParams)
|
||||
{
|
||||
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername());
|
||||
|
||||
userParams ??= new UserParams();
|
||||
var series = await _unitOfWork.SeriesRepository.GetQuickCatchupReads(user.Id, libraryId, userParams);
|
||||
|
||||
Response.AddPaginationHeader(series.CurrentPage, series.PageSize, series.TotalCount, series.TotalPages);
|
||||
return Ok(series);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Highly Rated based on other users ratings. Will pull series with ratings > 4.0, weighted by count of other users.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -394,6 +394,8 @@ namespace API.Controllers
|
|||
return Ok(await _unitOfWork.SeriesRepository.GetRelatedSeries(userId, seriesId));
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Authorize(Policy="RequireAdminRole")]
|
||||
[HttpPost("update-related")]
|
||||
public async Task<ActionResult> UpdateRelatedSeries(UpdateRelatedSeriesDto dto)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue