On Deck + Misc Fixes and Changes (#1215)
* Added playwright and started writing e2e tests. * To make things easy, disabled other browsers while I get confortable. Added a login flow (assumes my dev env) * More tests on login page * Lots more testing code, trying to figure out auth code. * Ensure we don't track DBs inside config * Added a new date property for when chapters are added to a series which helps with OnDeck calculations. Changed a lot of heavy api calls to use IEnumerable to stream repsonse to UI. * Fixed OnDeck with a new field for when last chapter was added on Series. This is a streamlined way to query. Updated Reading List with NormalizedTitle, CoverImage, CoverImageLocked. * Implemented the ability to read a random item in the reading list and for the reading list to be intact for order. * Tweaked the style for webtoon to not span the whole width, but use max width * When we update a cover image just send an event so we don't need to have logic for when updates occur * Fixed a bad name for entity type on cover updates * Aligned the edit collection tag modal to align with new tab design * Rewrote code for picking the first file for metadata to ensure it always picks the correct file, esp if the first chapter of a series starts with a float (1.1) * Refactored setting LastChapterAdded to ensure we do it on the Series. * Updated Chapter updating in scan loop to avoid nested for loop and an additional loop. * Fixed a bug where locked person fields wouldn't persist between scans. * Updated Contributing to reflect how to view the swagger api
This commit is contained in:
parent
912dfa8a80
commit
3bbb02f574
64 changed files with 3397 additions and 343 deletions
|
|
@ -157,7 +157,7 @@ namespace API.Controllers
|
|||
tag.CoverImageLocked = false;
|
||||
tag.CoverImage = string.Empty;
|
||||
await _eventHub.SendMessageAsync(MessageFactory.CoverUpdate,
|
||||
MessageFactory.CoverUpdateEvent(tag.Id, "collectionTag"), false);
|
||||
MessageFactory.CoverUpdateEvent(tag.Id, "collection"), false);
|
||||
_unitOfWork.CollectionTagRepository.Update(tag);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,6 +88,22 @@ namespace API.Controllers
|
|||
return PhysicalFile(path, "image/" + format, _directoryService.FileSystem.Path.GetFileName(path));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns cover image for a Reading List
|
||||
/// </summary>
|
||||
/// <param name="readingListId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("readinglist-cover")]
|
||||
public async Task<ActionResult> GetReadingListCoverImage(int readingListId)
|
||||
{
|
||||
var path = Path.Join(_directoryService.CoverImageDirectory, await _unitOfWork.ReadingListRepository.GetCoverImageAsync(readingListId));
|
||||
if (string.IsNullOrEmpty(path) || !_directoryService.FileSystem.File.Exists(path)) return BadRequest($"No cover image");
|
||||
var format = _directoryService.FileSystem.Path.GetExtension(path).Replace(".", "");
|
||||
|
||||
Response.AddCacheHeader(path);
|
||||
return PhysicalFile(path, "image/" + format, _directoryService.FileSystem.Path.GetFileName(path));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns image for a given bookmark page
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using API.DTOs.ReadingLists;
|
|||
using API.Entities;
|
||||
using API.Extensions;
|
||||
using API.Helpers;
|
||||
using API.SignalR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace API.Controllers
|
||||
|
|
@ -14,11 +15,13 @@ namespace API.Controllers
|
|||
public class ReadingListController : BaseApiController
|
||||
{
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IEventHub _eventHub;
|
||||
private readonly ChapterSortComparerZeroFirst _chapterSortComparerForInChapterSorting = new ChapterSortComparerZeroFirst();
|
||||
|
||||
public ReadingListController(IUnitOfWork unitOfWork)
|
||||
public ReadingListController(IUnitOfWork unitOfWork, IEventHub eventHub)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_eventHub = eventHub;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -233,9 +236,12 @@ namespace API.Controllers
|
|||
var readingList = await _unitOfWork.ReadingListRepository.GetReadingListByIdAsync(dto.ReadingListId);
|
||||
if (readingList == null) return BadRequest("List does not exist");
|
||||
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(dto.Title))
|
||||
{
|
||||
readingList.Title = dto.Title; // Should I check if this is unique?
|
||||
readingList.NormalizedTitle = Parser.Parser.Normalize(readingList.Title);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(dto.Title))
|
||||
{
|
||||
|
|
@ -244,6 +250,19 @@ namespace API.Controllers
|
|||
|
||||
readingList.Promoted = dto.Promoted;
|
||||
|
||||
readingList.CoverImageLocked = dto.CoverImageLocked;
|
||||
|
||||
if (!dto.CoverImageLocked)
|
||||
{
|
||||
readingList.CoverImageLocked = false;
|
||||
readingList.CoverImage = string.Empty;
|
||||
await _eventHub.SendMessageAsync(MessageFactory.CoverUpdate,
|
||||
MessageFactory.CoverUpdateEvent(readingList.Id, "readingList"), false);
|
||||
_unitOfWork.ReadingListRepository.Update(readingList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
_unitOfWork.ReadingListRepository.Update(readingList);
|
||||
|
||||
if (await _unitOfWork.CommitAsync())
|
||||
|
|
|
|||
|
|
@ -214,13 +214,6 @@ namespace API.Controllers
|
|||
return Ok(await _unitOfWork.SeriesRepository.GetRecentlyUpdatedSeries(userId));
|
||||
}
|
||||
|
||||
[HttpPost("recently-added-chapters")]
|
||||
public async Task<ActionResult<IEnumerable<RecentlyAddedItemDto>>> GetRecentlyAddedChaptersAlt()
|
||||
{
|
||||
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
|
||||
return Ok(await _unitOfWork.SeriesRepository.GetRecentlyAddedChapters(userId));
|
||||
}
|
||||
|
||||
[HttpPost("all")]
|
||||
public async Task<ActionResult<IEnumerable<SeriesDto>>> GetAllSeries(FilterDto filterDto, [FromQuery] UserParams userParams, [FromQuery] int libraryId = 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using API.Data;
|
|||
using API.DTOs.Uploads;
|
||||
using API.Extensions;
|
||||
using API.Services;
|
||||
using API.SignalR;
|
||||
using Flurl.Http;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
|
@ -24,16 +25,18 @@ namespace API.Controllers
|
|||
private readonly ILogger<UploadController> _logger;
|
||||
private readonly ITaskScheduler _taskScheduler;
|
||||
private readonly IDirectoryService _directoryService;
|
||||
private readonly IEventHub _eventHub;
|
||||
|
||||
/// <inheritdoc />
|
||||
public UploadController(IUnitOfWork unitOfWork, IImageService imageService, ILogger<UploadController> logger,
|
||||
ITaskScheduler taskScheduler, IDirectoryService directoryService)
|
||||
ITaskScheduler taskScheduler, IDirectoryService directoryService, IEventHub eventHub)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_imageService = imageService;
|
||||
_logger = logger;
|
||||
_taskScheduler = taskScheduler;
|
||||
_directoryService = directoryService;
|
||||
_eventHub = eventHub;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -145,6 +148,8 @@ namespace API.Controllers
|
|||
if (_unitOfWork.HasChanges())
|
||||
{
|
||||
await _unitOfWork.CommitAsync();
|
||||
await _eventHub.SendMessageAsync(MessageFactory.CoverUpdate,
|
||||
MessageFactory.CoverUpdateEvent(tag.Id, "collection"), false);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
|
@ -158,6 +163,53 @@ namespace API.Controllers
|
|||
return BadRequest("Unable to save cover image to Collection Tag");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces reading list cover image and locks it with a base64 encoded image
|
||||
/// </summary>
|
||||
/// <param name="uploadFileDto"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize(Policy = "RequireAdminRole")]
|
||||
[RequestSizeLimit(8_000_000)]
|
||||
[HttpPost("reading-list")]
|
||||
public async Task<ActionResult> UploadReadingListCoverImageFromUrl(UploadFileDto uploadFileDto)
|
||||
{
|
||||
// Check if Url is non empty, request the image and place in temp, then ask image service to handle it.
|
||||
// See if we can do this all in memory without touching underlying system
|
||||
if (string.IsNullOrEmpty(uploadFileDto.Url))
|
||||
{
|
||||
return BadRequest("You must pass a url to use");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var filePath = _imageService.CreateThumbnailFromBase64(uploadFileDto.Url, $"{ImageService.GetReadingListFormat(uploadFileDto.Id)}");
|
||||
var readingList = await _unitOfWork.ReadingListRepository.GetReadingListByIdAsync(uploadFileDto.Id);
|
||||
|
||||
if (!string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
readingList.CoverImage = filePath;
|
||||
readingList.CoverImageLocked = true;
|
||||
_unitOfWork.ReadingListRepository.Update(readingList);
|
||||
}
|
||||
|
||||
if (_unitOfWork.HasChanges())
|
||||
{
|
||||
await _unitOfWork.CommitAsync();
|
||||
await _eventHub.SendMessageAsync(MessageFactory.CoverUpdate,
|
||||
MessageFactory.CoverUpdateEvent(readingList.Id, "readingList"), false);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e, "There was an issue uploading cover image for Reading List {Id}", uploadFileDto.Id);
|
||||
await _unitOfWork.RollbackAsync();
|
||||
}
|
||||
|
||||
return BadRequest("Unable to save cover image to Reading List");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces chapter cover image and locks it with a base64 encoded image. This will update the parent volume's cover image.
|
||||
/// </summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue