mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-05-24 00:52:23 -04:00
Release Shakeout (#1340)
* Fixed a bug where analyze series would not force a re-analysis. Fixed a bug where if files weren't changed since last analysis, then series word count got reset to 0. * Fixed epub images not loading in detail drawer * Fixed a bug on double page layout where the reader would be wonky when moving to and from mobile layout. * package-lock.json updated * Cleaned up some wording * Moved a conditional on jump bar * Bugfix for Double Page Rendering skipping pages (#1339) * Bump versions by dotnet-bump-version. * Double (Manga) fixes . Fixed: *ngIf condition, last page loading Double . Added: isLoose, pageAmount, and CanvasImageNextDouble to keep track of double sequence breaks (nn/n/w) . Fixed: ShouldRenderReverseDouble and pageAmount conditions . Added: Setting isLoose on loadPage() . Added: canvasImageNextDouble in loadPage() Co-authored-by: majora2007 <josephmajora@gmail.com> * Added comments for Magunjun's PR. Co-authored-by: Marcelo Guimarães Junior <75567460+magujun@users.noreply.github.com>
This commit is contained in:
parent
3c44d48e70
commit
4fd4ca6f07
@ -273,7 +273,7 @@ namespace API.Controllers
|
||||
[HttpPost("analyze")]
|
||||
public ActionResult AnalyzeSeries(RefreshSeriesDto refreshSeriesDto)
|
||||
{
|
||||
_taskScheduler.AnalyzeFilesForSeries(refreshSeriesDto.LibraryId, refreshSeriesDto.SeriesId);
|
||||
_taskScheduler.AnalyzeFilesForSeries(refreshSeriesDto.LibraryId, refreshSeriesDto.SeriesId, true);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
@ -40,11 +40,11 @@ public class ReaderService : IReaderService
|
||||
private readonly ChapterSortComparer _chapterSortComparer = new ChapterSortComparer();
|
||||
private readonly ChapterSortComparerZeroFirst _chapterSortComparerForInChapterSorting = new ChapterSortComparerZeroFirst();
|
||||
|
||||
public const float MinWordsPerHour = 10260F;
|
||||
public const float MaxWordsPerHour = 30000F;
|
||||
private const float MinWordsPerHour = 10260F;
|
||||
private const float MaxWordsPerHour = 30000F;
|
||||
public const float AvgWordsPerHour = (MaxWordsPerHour + MinWordsPerHour) / 2F;
|
||||
public const float MinPagesPerMinute = 3.33F;
|
||||
public const float MaxPagesPerMinute = 2.75F;
|
||||
private const float MinPagesPerMinute = 3.33F;
|
||||
private const float MaxPagesPerMinute = 2.75F;
|
||||
public const float AvgPagesPerMinute = (MaxPagesPerMinute + MinPagesPerMinute) / 2F;
|
||||
|
||||
|
||||
|
@ -145,6 +145,7 @@ public class WordCountAnalyzerService : IWordCountAnalyzerService
|
||||
private async Task ProcessSeries(Series series, bool forceUpdate = false, bool useFileName = true)
|
||||
{
|
||||
var isEpub = series.Format == MangaFormat.Epub;
|
||||
var existingWordCount = series.WordCount;
|
||||
series.WordCount = 0;
|
||||
foreach (var volume in series.Volumes)
|
||||
{
|
||||
@ -222,6 +223,7 @@ public class WordCountAnalyzerService : IWordCountAnalyzerService
|
||||
series.MinHoursToRead = seriesEstimate.MinHours;
|
||||
series.MaxHoursToRead = seriesEstimate.MaxHours;
|
||||
series.AvgHoursToRead = seriesEstimate.AvgHours;
|
||||
if (series.WordCount == 0) series.WordCount = existingWordCount; // Restore original word count if the file hasn't changed
|
||||
_unitOfWork.SeriesRepository.Update(series);
|
||||
}
|
||||
|
||||
|
18835
UI/Web/package-lock.json
generated
18835
UI/Web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
<div class="container-fluid">
|
||||
<form [formGroup]="settingsForm" *ngIf="serverSettings !== undefined">
|
||||
<p class="text-warning pt-2">Port and Logging Level require a manual restart of Kavita to take effect.</p>
|
||||
<p class="text-warning pt-2">Port, Logging Level, and Swagger require a manual restart of Kavita to take effect.</p>
|
||||
<div class="mb-3">
|
||||
<label for="settings-cachedir" class="form-label">Cache Directory</label> <i class="fa fa-info-circle" placement="right" [ngbTooltip]="cacheDirectoryTooltip" role="button" tabindex="0"></i>
|
||||
<ng-template #cacheDirectoryTooltip>Where the server place temporary files when reading. This will be cleaned up on a regular basis.</ng-template>
|
||||
|
@ -16,8 +16,8 @@
|
||||
<div class="container-fluid" style="overflow: auto">
|
||||
|
||||
<div class="row g-0">
|
||||
<div class="d-none d-md-block col-md-2 col-lg-1">
|
||||
<app-image class="me-2" width="74px" [imageUrl]="chapter.coverImage"></app-image>
|
||||
<div class="d-none d-md-block col-md-2 col-lg-1">
|
||||
<app-image class="me-2" width="74px" [imageUrl]="coverImageUrl"></app-image>
|
||||
</div>
|
||||
<div class="col-md-10 col-lg-11">
|
||||
<ng-container *ngIf="summary.length > 0; else noSummary">
|
||||
|
@ -2,13 +2,12 @@ import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { NgbActiveOffcanvas } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { finalize, Observable, of, take, takeWhile } from 'rxjs';
|
||||
import { finalize, Observable, take, takeWhile } from 'rxjs';
|
||||
import { Download } from 'src/app/shared/_models/download';
|
||||
import { DownloadService } from 'src/app/shared/_services/download.service';
|
||||
import { Breakpoint, UtilityService } from 'src/app/shared/_services/utility.service';
|
||||
import { Chapter } from 'src/app/_models/chapter';
|
||||
import { ChapterMetadata } from 'src/app/_models/chapter-metadata';
|
||||
import { HourEstimateRange } from 'src/app/_models/hour-estimate-range';
|
||||
import { LibraryType } from 'src/app/_models/library';
|
||||
import { MangaFile } from 'src/app/_models/manga-file';
|
||||
import { MangaFormat } from 'src/app/_models/manga-format';
|
||||
@ -51,6 +50,10 @@ export class CardDetailDrawerComponent implements OnInit {
|
||||
chapters: Chapter[] = [];
|
||||
|
||||
imageUrls: Array<string> = [];
|
||||
/**
|
||||
* Cover image for the entity
|
||||
*/
|
||||
coverImageUrl!: string;
|
||||
|
||||
|
||||
actions: ActionItem<any>[] = [];
|
||||
@ -100,6 +103,11 @@ export class CardDetailDrawerComponent implements OnInit {
|
||||
this.isChapter = this.utilityService.isChapter(this.data);
|
||||
|
||||
this.chapter = this.utilityService.isChapter(this.data) ? (this.data as Chapter) : (this.data as Volume).chapters[0];
|
||||
if (this.isChapter) {
|
||||
this.coverImageUrl = this.imageService.getChapterCoverImage(this.data.id);
|
||||
} else {
|
||||
this.coverImageUrl = this.imageService.getVolumeCoverImage(this.data.id);
|
||||
}
|
||||
|
||||
this.imageUrls.push(this.imageService.getChapterCoverImage(this.chapter.id));
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
<app-metadata-filter [filterSettings]="filterSettings" [filterOpen]="filterOpen" (applyFilter)="applyMetadataFilter($event)"></app-metadata-filter>
|
||||
<div class="viewport-container">
|
||||
<div class="content-container">
|
||||
|
||||
<div class="card-container mt-2 mb-2">
|
||||
<virtual-scroller #scroll [items]="items" [bufferAmount]="1" [parentScroll]="parentScroll">
|
||||
<div class="grid row g-0" #container>
|
||||
@ -24,7 +23,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</virtual-scroller>
|
||||
|
||||
|
||||
<p *ngIf="items.length === 0 && !isLoading">
|
||||
<ng-container [ngTemplateOutlet]="noDataTemplate"></ng-container>
|
||||
@ -32,7 +30,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-container [ngTemplateOutlet]="jumpBar" [ngTemplateOutletContext]="{ id: 'jumpbar' }"></ng-container>
|
||||
<ng-container *ngIf="jumpBarKeysToRender.length >= 4" [ngTemplateOutlet]="jumpBar" [ngTemplateOutletContext]="{ id: 'jumpbar' }"></ng-container>
|
||||
</div>
|
||||
<ng-template #cardTemplate>
|
||||
<virtual-scroller #scroll [items]="items" [bufferAmount]="1">
|
||||
@ -55,7 +53,7 @@
|
||||
</div>
|
||||
|
||||
<ng-template #jumpBar>
|
||||
<div class="jump-bar" *ngIf="jumpBarKeysToRender.length >= 4">
|
||||
<div class="jump-bar">
|
||||
<ng-container *ngFor="let jumpKey of jumpBarKeysToRender; let i = index;">
|
||||
<button class="btn btn-link" (click)="scrollTo(jumpKey)">
|
||||
{{jumpKey.title}}
|
||||
|
@ -85,13 +85,16 @@
|
||||
<ng-container *ngIf="series.format === MangaFormat.EPUB && series.wordCount > 0 || series.format !== MangaFormat.EPUB">
|
||||
<div class="col-lg-1 col-md-4 col-sm-4 col-4 mb-2">
|
||||
<app-icon-and-title label="Read Time" [clickable]="false" fontClasses="fa-regular fa-clock">
|
||||
{{readingTime.minHours}}{{readingTime.maxHours !== readingTime.minHours ? ('-' + readingTime.maxHours) : ''}} Hour{{readingTime.minHours > 1 ? 's' : ''}}
|
||||
<ng-container *ngIf="readingTime.maxHours === 0; else normalReadTime"><1 Hour</ng-container>
|
||||
<ng-template #normalReadTime>
|
||||
{{readingTime.minHours}}{{readingTime.maxHours !== readingTime.minHours ? ('-' + readingTime.maxHours) : ''}} Hour{{readingTime.minHours > 1 ? 's' : ''}}
|
||||
</ng-template>
|
||||
</app-icon-and-title>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-container *ngIf="hasReadingProgress && showReadingTimeLeft && readingTimeLeft && readingTimeLeft.avgHours !== 0 ">
|
||||
<ng-container *ngIf="hasReadingProgress && showReadingTimeLeft && readingTimeLeft && readingTimeLeft.avgHours !== 0">
|
||||
<div class="vr d-none d-lg-block m-2"></div>
|
||||
<div class="col-lg-1 col-md-4 col-sm-4 col-4 mb-2">
|
||||
<app-icon-and-title label="Read Left" [clickable]="false" fontClasses="fa-solid fa-clock">
|
||||
|
@ -68,7 +68,7 @@
|
||||
<img #image [src]="canvasImage.src" id="image-1"
|
||||
class="{{getFittingOptionClass()}} {{readerMode === ReaderMode.LeftRight || readerMode === ReaderMode.UpDown ? '' : 'd-none'}} {{showClickOverlay ? 'blur' : ''}}">
|
||||
|
||||
<ng-container *ngIf="(ShouldRenderDoublePage || ShouldRenderReverseDouble) && (this.pageNum + 1 <= maxPages - 1 && this.pageNum > 0)">
|
||||
<ng-container *ngIf="(ShouldRenderDoublePage || ShouldRenderReverseDouble) && (this.pageNum <= maxPages - 1 && this.pageNum > 0)">
|
||||
<img [src]="canvasImage2.src" id="image-2" class="image-2 {{getFittingOptionClass()}} {{readerMode === ReaderMode.LeftRight || readerMode === ReaderMode.UpDown ? '' : 'd-none'}} {{showClickOverlay ? 'blur' : ''}} {{ShouldRenderReverseDouble ? 'reverse' : ''}}">
|
||||
</ng-container>
|
||||
</div>
|
||||
|
@ -114,6 +114,15 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
isLoading = true;
|
||||
|
||||
/**
|
||||
* A temp variable to allow us to update isLoose.
|
||||
*/
|
||||
pageAmount = 0;
|
||||
/**
|
||||
* For double page layout, if only one page will be rendered.
|
||||
*/
|
||||
isLoose = false;
|
||||
|
||||
@ViewChild('reader') reader!: ElementRef;
|
||||
@ViewChild('readingArea') readingArea!: ElementRef;
|
||||
@ViewChild('content') canvas: ElementRef | undefined;
|
||||
@ -128,13 +137,17 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
*/
|
||||
canvasImage2 = new Image();
|
||||
/**
|
||||
* * * Used solely for LayoutMode.Double rendering. Will always hold the previous image in buffer.
|
||||
* Used solely for LayoutMode.Double rendering. Will always hold the previous image in buffer.
|
||||
*/
|
||||
canvasImagePrev = new Image();
|
||||
/**
|
||||
* * * Used solely for LayoutMode.Double rendering. Will always hold the next image in buffer.
|
||||
* Used solely for LayoutMode.Double rendering. Will always hold the next image in buffer.
|
||||
*/
|
||||
canvasImageNext = new Image();
|
||||
/**
|
||||
* Used solely for LayoutMode.DoubleReverse rendering. Will always hold the image after next in buffer.
|
||||
*/
|
||||
canvasImageNextDouble = new Image();
|
||||
/**
|
||||
* Dictates if we use render with canvas or with image. This is only for Splitting.
|
||||
*/
|
||||
@ -285,9 +298,8 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
get ShouldRenderDoublePage() {
|
||||
return (
|
||||
this.layoutMode !== LayoutMode.Single &&
|
||||
this.layoutMode === LayoutMode.Double &&
|
||||
!this.isCoverImage() &&
|
||||
|
||||
!this.isWideImage(this.canvasImage) &&
|
||||
!this.isWideImage(this.canvasImageNext) &&
|
||||
window.innerWidth > window.innerHeight // Don't render double if orientation is portrait, mostly mobile
|
||||
@ -298,18 +310,25 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
return (
|
||||
this.layoutMode === LayoutMode.DoubleReversed &&
|
||||
!this.isCoverImage() &&
|
||||
!this.isCoverImage(this.pageNum - 1) &&
|
||||
!this.isWideImage(this.canvasImage) &&
|
||||
!this.isWideImage(this.canvasImageNext) &&
|
||||
!this.isLoose &&
|
||||
window.innerWidth > window.innerHeight // Don't render double reversed if orientation is portrait, mostly mobile
|
||||
);
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
@HostListener('window:orientationchange', ['$event'])
|
||||
onResize() {
|
||||
onResize() {
|
||||
if (window.innerWidth > window.innerHeight) {
|
||||
this.generalSettingsForm.get('layoutMode')?.enable();
|
||||
return;
|
||||
};
|
||||
if (this.layoutMode === LayoutMode.Single || this.readerMode === ReaderMode.Webtoon) return;
|
||||
if (window.innerWidth > window.innerHeight) return;
|
||||
|
||||
this.generalSettingsForm.get('layoutMode')?.setValue(LayoutMode.Single);
|
||||
this.generalSettingsForm.get('layoutMode')?.disable();
|
||||
this.toastr.info('Layout mode switched to Single due to insufficient space to render double layout');
|
||||
}
|
||||
|
||||
@ -955,6 +974,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
pageAmount = (
|
||||
!this.isCoverImage(this.pageNum - 1) &&
|
||||
!this.isWideImage(this.canvasImagePrev) &&
|
||||
!this.isWideImage(this.canvasImageNextDouble) &&
|
||||
!this.isSecondLastImage() &&
|
||||
!this.isLastImage()
|
||||
? 2 : 1);
|
||||
@ -972,6 +992,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.pagingDirection = PAGING_DIRECTION.FORWARD;
|
||||
if (this.isNoSplit() || notInSplit) {
|
||||
this.setPageNum(this.pageNum + pageAmount);
|
||||
this.pageAmount = pageAmount;
|
||||
|
||||
if (this.readerMode !== ReaderMode.Webtoon) {
|
||||
this.canvasImage.src = this.getPageUrl(this.pageNum);
|
||||
@ -1002,7 +1023,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
pageAmount = (
|
||||
!this.isCoverImage() &&
|
||||
!this.isCoverImage(this.pageNum - 1) &&
|
||||
!this.isWideImage() &&
|
||||
!this.isWideImage(this.canvasImage) &&
|
||||
!this.isWideImage(this.canvasImageNext)
|
||||
? 2 : 1);
|
||||
}
|
||||
@ -1233,11 +1254,13 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
loadPage() {
|
||||
this.isLoading = true;
|
||||
this.canvasImage2.src = '';
|
||||
this.isLoose = (this.pageAmount === 1 ? true : false);
|
||||
this.canvasImage.src = this.getPageUrl(this.pageNum);
|
||||
|
||||
if (this.layoutMode !== LayoutMode.Single) {
|
||||
this.canvasImagePrev.src = this.getPageUrl(this.pageNum + (this.layoutMode !== LayoutMode.DoubleReversed ? - 1 : + 1));
|
||||
this.canvasImageNext.src = this.getPageUrl(this.pageNum + (this.layoutMode !== LayoutMode.DoubleReversed ? + 1 : - 1));
|
||||
this.canvasImageNextDouble.src = this.getPageUrl(this.pageNum + 2);
|
||||
if (this.ShouldRenderDoublePage || this.ShouldRenderReverseDouble) {
|
||||
this.canvasImage2.src = this.canvasImageNext.src;
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
<img #img class="lazyload" [src]="imageService.placeholderImage" [attr.data-src]="imageUrl"
|
||||
(error)="imageService.updateErroredImage($event)"
|
||||
aria-hidden="true">
|
||||
<!-- TODO: Need to think about how to not lazyload but also handle broken images-->
|
||||
<!-- <img #img [src]="imageUrl" aria-hidden="true"> -->
|
||||
aria-hidden="true">
|
Loading…
x
Reference in New Issue
Block a user