Feature/enhancements and more (#1166)

* Moved libraryType into chapter info

* Fixed a bug where you could not reset cover on a series

* Patched in relevant changes from another polish branch

* Refactored invite user setup to shift the checking for accessibility to the backend and always show the link. This will help with users who have some unique setups in docker.

* Refactored invite user to always print the url to setup a new account.

* Single page renderer uses canvasImage rather than re-requesting and relying on cache

* Fixed a rendering issue where fit to split on single on a cover wouldn't force width scaling just for that image

* Fixed a rendering bug with split image functionality

* Added title to copy button

* Fixed a bug in GetContinuePoint when a chapter is added to an already read volume and a new chapter is added loose leaf. The loose leaf would be prioritized over the volume chapter.

Refactored 2 methods from controller into service and unit tested.

* Fixed a bug on opening a volume in series detail that had a chapter added to it after the volume (0 chapter) was read would cause a loose leaf chapter to be opened.

* Added mark as read/actionables on Files in volume detail modal. Fixed a bug where we were showing the wrong page count in a volume detail modal.

* Removed OnDeck page and replaced it with a pre-filtered All-Series. Hooked up the ability to pass read state to the filter via query params. Fixed some spacing on filter post bootstrap update.

* Fixed up some poor documentation on FilterDto.

* Some string equals enhancements to reduce extra allocations

* Fixed an issue when trying to download via a url, to remove query parameters to get the format

* Made an optimization to Normalize method to reduce memory pressure by 100MB over the course of a scan (16k files)

* Adjusted the styles on dashboard for first time setup and used a routerlink rather than href to avoid a fresh load.

* Use framgment on router link

* Hooked in the ability to search by release year (along with series optionally) and series will be returned back.

* Fixed a bug in the filter format code where it was sending the wrong type

* Only show clear all on typeahead when there are at least one selected item

* Cleaned up the styles of the styles of the typeahead

* Removed some dead code

* Implemented the ability to filter against a series name.

* Fixed filter top offset

* Ensure that when we add or remove libraries, the side nav of users gets updated.

* Tweaked the width on the mobile side nav

* Close side nav on clicking overlay on mobile viewport

* Don't show a pointer if the carousel section title is not actually selectable

* Removed the User profile on the side nav so home is always first. Tweaked styles to match

* Fixed up some poor documentation on FilterDto.

* Fixed a bug where Latest read date wasn't being set due to an early short circuit.

* When sending the chapter file, format the title of the FeedEntry more like Series Detail.

* Removed dead code
This commit is contained in:
Joseph Milazzo 2022-03-21 09:26:49 -05:00 committed by GitHub
parent 67d8d3d808
commit 4a93b5c715
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 663 additions and 451 deletions

View file

@ -338,6 +338,12 @@ namespace API.Controllers
/// <summary>
/// Invites a user to the server. Will generate a setup link for continuing setup. If the server is not accessible, no
/// email will be sent.
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[Authorize(Policy = "RequireAdminRole")]
[HttpPost("invite")]
public async Task<ActionResult<string>> InviteUser(InviteUserDto dto)
@ -417,7 +423,9 @@ namespace API.Controllers
var emailLink = GenerateEmailLink(token, "confirm-email", dto.Email);
_logger.LogCritical("[Invite User]: Email Link for {UserName}: {Link}", user.UserName, emailLink);
if (dto.SendEmail)
var host = _environment.IsDevelopment() ? "localhost:4200" : Request.Host.ToString();
var accessible = await _emailService.CheckIfAccessible(host);
if (accessible)
{
await _emailService.SendConfirmationEmail(new ConfirmationEmailDto()
{
@ -426,7 +434,11 @@ namespace API.Controllers
ServerConfirmationLink = emailLink
});
}
return Ok(emailLink);
return Ok(new InviteUserResponse
{
EmailLink = emailLink,
EmailSent = accessible
});
}
catch (Exception)
{

View file

@ -65,6 +65,8 @@ namespace API.Controllers
return Ok(_directoryService.GetTotalSize(files.Select(c => c.FilePath)));
}
[Authorize(Policy="RequireDownloadRole")]
[HttpGet("volume")]
public async Task<ActionResult> DownloadVolume(int volumeId)

View file

@ -11,6 +11,7 @@ using API.Entities;
using API.Entities.Enums;
using API.Extensions;
using API.Services;
using API.SignalR;
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@ -26,16 +27,18 @@ namespace API.Controllers
private readonly IMapper _mapper;
private readonly ITaskScheduler _taskScheduler;
private readonly IUnitOfWork _unitOfWork;
private readonly IEventHub _eventHub;
public LibraryController(IDirectoryService directoryService,
ILogger<LibraryController> logger, IMapper mapper, ITaskScheduler taskScheduler,
IUnitOfWork unitOfWork)
IUnitOfWork unitOfWork, IEventHub eventHub)
{
_directoryService = directoryService;
_logger = logger;
_mapper = mapper;
_taskScheduler = taskScheduler;
_unitOfWork = unitOfWork;
_eventHub = eventHub;
}
/// <summary>
@ -73,6 +76,8 @@ namespace API.Controllers
_logger.LogInformation("Created a new library: {LibraryName}", library.Name);
_taskScheduler.ScanLibrary(library.Id);
await _eventHub.SendMessageAsync(MessageFactory.LibraryModified,
MessageFactory.LibraryModifiedEvent(library.Id, "create"), false);
return Ok();
}
@ -191,6 +196,9 @@ namespace API.Controllers
await _unitOfWork.CommitAsync();
_taskScheduler.CleanupChapters(chapterIds);
}
await _eventHub.SendMessageAsync(MessageFactory.LibraryModified,
MessageFactory.LibraryModifiedEvent(libraryId, "delete"), false);
return Ok(true);
}
catch (Exception ex)

View file

@ -745,9 +745,18 @@ public class OpdsController : BaseApiController
var fileType = _downloadService.GetContentTypeFromFile(mangaFile.FilePath);
var filename = Uri.EscapeDataString(Path.GetFileName(mangaFile.FilePath) ?? string.Empty);
var libraryType = await _unitOfWork.LibraryRepository.GetLibraryTypeAsync(series.LibraryId);
var volume = await _unitOfWork.VolumeRepository.GetVolumeDtoAsync(volumeId, await GetUser(apiKey));
var title = $"{series.Name} - {SeriesService.FormatChapterTitle(chapter, libraryType)}";
var title = $"{series.Name} - ";
if (volume.Chapters.Count == 1)
{
SeriesService.RenameVolumeName(volume.Chapters.First(), volume, libraryType);
title += $"{volume.Name}";
}
else
{
title = $"{series.Name} - {SeriesService.FormatChapterTitle(chapter, libraryType)}";
}
// Chunky requires a file at the end. Our API ignores this
var accLink =

View file

@ -109,14 +109,7 @@ namespace API.Controllers
public async Task<ActionResult> MarkRead(MarkReadDto markReadDto)
{
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername(), AppUserIncludes.Progress);
var volumes = await _unitOfWork.VolumeRepository.GetVolumes(markReadDto.SeriesId);
user.Progresses ??= new List<AppUserProgress>();
foreach (var volume in volumes)
{
_readerService.MarkChaptersAsRead(user, markReadDto.SeriesId, volume.Chapters);
}
_unitOfWork.UserRepository.Update(user);
await _readerService.MarkSeriesAsRead(user, markReadDto.SeriesId);
if (await _unitOfWork.CommitAsync())
{
@ -137,14 +130,7 @@ namespace API.Controllers
public async Task<ActionResult> MarkUnread(MarkReadDto markReadDto)
{
var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername(), AppUserIncludes.Progress);
var volumes = await _unitOfWork.VolumeRepository.GetVolumes(markReadDto.SeriesId);
user.Progresses ??= new List<AppUserProgress>();
foreach (var volume in volumes)
{
_readerService.MarkChaptersAsUnread(user, markReadDto.SeriesId, volume.Chapters);
}
_unitOfWork.UserRepository.Update(user);
await _readerService.MarkSeriesAsUnread(user, markReadDto.SeriesId);
if (await _unitOfWork.CommitAsync())
{

View file

@ -46,7 +46,7 @@ namespace API.Controllers
public async Task<ActionResult<string>> GetImageFromFile(UploadUrlDto dto)
{
var dateString = $"{DateTime.Now.ToShortDateString()}_{DateTime.Now.ToLongTimeString()}".Replace("/", "_").Replace(":", "_");
var format = _directoryService.FileSystem.Path.GetExtension(dto.Url).Replace(".", "");
var format = _directoryService.FileSystem.Path.GetExtension(dto.Url.Split('?')[0]).Replace(".", "");
var path = await dto.Url
.DownloadFileAsync(_directoryService.TempDirectory, $"coverupload_{dateString}.{format}");