mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Bugfix/webtoon lastpage (#757)
* Some small changes to how maxPage is handled for better page tracking on webtoon reader. * Fixed a bug in cover image selection (#756) * Refactored webtoon reader to report page progress exactly as manga reader does. In addition, manga reader moved progress saving to setPageNumber making them the same.
This commit is contained in:
parent
a0db5b0e41
commit
6eb5c34695
@ -95,7 +95,7 @@ namespace API.Controllers
|
|||||||
var settings = await _unitOfWork.SettingsRepository.GetSettingsDtoAsync();
|
var settings = await _unitOfWork.SettingsRepository.GetSettingsDtoAsync();
|
||||||
if (!settings.EnableAuthentication && !registerDto.IsAdmin)
|
if (!settings.EnableAuthentication && !registerDto.IsAdmin)
|
||||||
{
|
{
|
||||||
_logger.LogInformation("User {UserName} is being registered as non-admin with no server authentication. Using default password.", registerDto.Username);
|
_logger.LogInformation("User {UserName} is being registered as non-admin with no server authentication. Using default password", registerDto.Username);
|
||||||
registerDto.Password = AccountService.DefaultPassword;
|
registerDto.Password = AccountService.DefaultPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +138,22 @@ namespace API.Services
|
|||||||
|
|
||||||
if (!string.IsNullOrEmpty(nonNestedFile)) return nonNestedFile;
|
if (!string.IsNullOrEmpty(nonNestedFile)) return nonNestedFile;
|
||||||
|
|
||||||
|
// Check the first folder and sort within that to see if we can find a file, else fallback to first file with basic sort.
|
||||||
|
// Get first folder, then sort within that
|
||||||
|
var firstDirectoryFile = fullNames.OrderBy(Path.GetDirectoryName, new NaturalSortComparer()).FirstOrDefault();
|
||||||
|
if (!string.IsNullOrEmpty(firstDirectoryFile))
|
||||||
|
{
|
||||||
|
var firstDirectory = Path.GetDirectoryName(firstDirectoryFile);
|
||||||
|
if (!string.IsNullOrEmpty(firstDirectory))
|
||||||
|
{
|
||||||
|
var firstDirectoryResult = fullNames.Where(f => firstDirectory.Equals(Path.GetDirectoryName(f)))
|
||||||
|
.OrderBy(Path.GetFileName, new NaturalSortComparer())
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(firstDirectoryResult)) return firstDirectoryResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var result = fullNames
|
var result = fullNames
|
||||||
.OrderBy(Path.GetFileName, new NaturalSortComparer())
|
.OrderBy(Path.GetFileName, new NaturalSortComparer())
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
@ -159,7 +175,7 @@ namespace API.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public string GetCoverImage(string archivePath, string fileName)
|
public string GetCoverImage(string archivePath, string fileName)
|
||||||
{
|
{
|
||||||
if (archivePath == null || !IsValidArchive(archivePath)) return String.Empty;
|
if (archivePath == null || !IsValidArchive(archivePath)) return string.Empty;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var libraryHandler = CanOpen(archivePath);
|
var libraryHandler = CanOpen(archivePath);
|
||||||
|
@ -218,7 +218,7 @@ namespace API.Services
|
|||||||
var stopwatch = Stopwatch.StartNew();
|
var stopwatch = Stopwatch.StartNew();
|
||||||
var totalTime = 0L;
|
var totalTime = 0L;
|
||||||
_logger.LogInformation("[MetadataService] Refreshing Library {LibraryName}. Total Items: {TotalSize}. Total Chunks: {TotalChunks} with {ChunkSize} size", library.Name, chunkInfo.TotalSize, chunkInfo.TotalChunks, chunkInfo.ChunkSize);
|
_logger.LogInformation("[MetadataService] Refreshing Library {LibraryName}. Total Items: {TotalSize}. Total Chunks: {TotalChunks} with {ChunkSize} size", library.Name, chunkInfo.TotalSize, chunkInfo.TotalChunks, chunkInfo.ChunkSize);
|
||||||
await _messageHub.Clients.All.SendAsync(SignalREvents.ScanLibraryProgress,
|
await _messageHub.Clients.All.SendAsync(SignalREvents.RefreshMetadataProgress,
|
||||||
MessageFactory.RefreshMetadataProgressEvent(library.Id, 0F));
|
MessageFactory.RefreshMetadataProgressEvent(library.Id, 0F));
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
@ -281,11 +281,11 @@ namespace API.Services
|
|||||||
chunk * chunkInfo.ChunkSize, (chunk * chunkInfo.ChunkSize) + nonLibrarySeries.Count, chunkInfo.TotalSize, stopwatch.ElapsedMilliseconds, library.Name);
|
chunk * chunkInfo.ChunkSize, (chunk * chunkInfo.ChunkSize) + nonLibrarySeries.Count, chunkInfo.TotalSize, stopwatch.ElapsedMilliseconds, library.Name);
|
||||||
}
|
}
|
||||||
var progress = Math.Max(0F, Math.Min(100F, i * 1F / chunkInfo.TotalChunks));
|
var progress = Math.Max(0F, Math.Min(100F, i * 1F / chunkInfo.TotalChunks));
|
||||||
await _messageHub.Clients.All.SendAsync(SignalREvents.ScanLibraryProgress,
|
await _messageHub.Clients.All.SendAsync(SignalREvents.RefreshMetadataProgress,
|
||||||
MessageFactory.RefreshMetadataProgressEvent(library.Id, progress));
|
MessageFactory.RefreshMetadataProgressEvent(library.Id, progress));
|
||||||
}
|
}
|
||||||
|
|
||||||
await _messageHub.Clients.All.SendAsync(SignalREvents.ScanLibraryProgress,
|
await _messageHub.Clients.All.SendAsync(SignalREvents.RefreshMetadataProgress,
|
||||||
MessageFactory.RefreshMetadataProgressEvent(library.Id, 100F));
|
MessageFactory.RefreshMetadataProgressEvent(library.Id, 100F));
|
||||||
|
|
||||||
_logger.LogInformation("[MetadataService] Updated metadata for {SeriesNumber} series in library {LibraryName} in {ElapsedMilliseconds} milliseconds total", chunkInfo.TotalSize, library.Name, totalTime);
|
_logger.LogInformation("[MetadataService] Updated metadata for {SeriesNumber} series in library {LibraryName} in {ElapsedMilliseconds} milliseconds total", chunkInfo.TotalSize, library.Name, totalTime);
|
||||||
|
@ -187,7 +187,7 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* On scroll in document, calculate if the user/javascript has scrolled to the current image element (and it's visible), update that scrolling has ended completely,
|
* On scroll in document, calculate if the user/javascript has scrolled to the current image element (and it's visible), update that scrolling has ended completely,
|
||||||
* and calculate the direction the scrolling is occuring. This is used for prefetching.
|
* and calculate the direction the scrolling is occuring. This is not used for prefetching.
|
||||||
* @param event Scroll Event
|
* @param event Scroll Event
|
||||||
*/
|
*/
|
||||||
handleScrollEvent(event?: any) {
|
handleScrollEvent(event?: any) {
|
||||||
@ -247,11 +247,11 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
if (this.atTop && this.pageNum > 0) {
|
if (this.atTop && this.pageNum > 0) {
|
||||||
this.atTop = false;
|
this.atTop = false;
|
||||||
}
|
}
|
||||||
// debug mode will add an extra pixel from the image border + (this.debug ? 1 : 0)
|
|
||||||
if (totalScroll === totalHeight && !this.atBottom) {
|
if (totalScroll === totalHeight && !this.atBottom) {
|
||||||
this.atBottom = true;
|
this.atBottom = true;
|
||||||
this.setPageNum(this.totalPages);
|
this.setPageNum(this.totalPages);
|
||||||
this.debugLog('At last page, saving last page ', this.totalPages);
|
|
||||||
// Scroll user back to original location
|
// Scroll user back to original location
|
||||||
this.previousScrollHeightMinusTop = this.getScrollTop();
|
this.previousScrollHeightMinusTop = this.getScrollTop();
|
||||||
requestAnimationFrame(() => document.documentElement.scrollTop = this.previousScrollHeightMinusTop + (SPACER_SCROLL_INTO_PX / 2));
|
requestAnimationFrame(() => document.documentElement.scrollTop = this.previousScrollHeightMinusTop + (SPACER_SCROLL_INTO_PX / 2));
|
||||||
@ -312,19 +312,6 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
rect.left <= (window.innerWidth || document.documentElement.clientWidth)
|
rect.left <= (window.innerWidth || document.documentElement.clientWidth)
|
||||||
) {
|
) {
|
||||||
const topX = (window.innerHeight || document.documentElement.clientHeight);
|
const topX = (window.innerHeight || document.documentElement.clientHeight);
|
||||||
const bottomX = this.getScrollTop();
|
|
||||||
|
|
||||||
// Check if the image is mostly above the cuttoff point
|
|
||||||
const cuttoffPoint = bottomX - ((bottomX - topX) / 2);
|
|
||||||
// without this, it will only trigger once you get the top of the image to the top of the screen: && rect.bottom > cuttoffPoint
|
|
||||||
// with it, it will trigger at half way
|
|
||||||
//console.log('Cutoff point: ', cuttoffPoint);
|
|
||||||
//return rect.top <= cuttoffPoint ; // && rect.bottom > cuttoffPoint
|
|
||||||
// console.log('device height: ', topX);
|
|
||||||
// console.log('image ' + elem.getAttribute('page') + ' top: ', rect.top);
|
|
||||||
// console.log('amount scrolled down: ', rect.top / topX);
|
|
||||||
// console.log('cutoff point: ', cuttoffPoint);
|
|
||||||
|
|
||||||
return Math.abs(rect.top / topX) <= 0.25;
|
return Math.abs(rect.top / topX) <= 0.25;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -428,6 +415,7 @@ export class InfiniteScrollerComponent implements OnInit, OnChanges, OnDestroy {
|
|||||||
* Performs the scroll for the current page element. Updates any state variables needed.
|
* Performs the scroll for the current page element. Updates any state variables needed.
|
||||||
*/
|
*/
|
||||||
scrollToCurrentPage() {
|
scrollToCurrentPage() {
|
||||||
|
this.debugLog('Scrolling to ', this.pageNum);
|
||||||
this.currentPageElem = document.querySelector('img#page-' + this.pageNum);
|
this.currentPageElem = document.querySelector('img#page-' + this.pageNum);
|
||||||
if (!this.currentPageElem) { return; }
|
if (!this.currentPageElem) { return; }
|
||||||
|
|
||||||
|
@ -426,7 +426,7 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
this.maxPages = results.chapterInfo.pages;
|
this.maxPages = results.chapterInfo.pages;
|
||||||
let page = results.progress.pageNum;
|
let page = results.progress.pageNum;
|
||||||
if (page > this.maxPages) {
|
if (page > this.maxPages) {
|
||||||
page = this.maxPages - 1;
|
page = this.maxPages;
|
||||||
}
|
}
|
||||||
this.setPageNum(page);
|
this.setPageNum(page);
|
||||||
|
|
||||||
@ -900,16 +900,6 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
loadPage() {
|
loadPage() {
|
||||||
if (!this.canvas || !this.ctx) { return; }
|
if (!this.canvas || !this.ctx) { return; }
|
||||||
|
|
||||||
// Due to the fact that we start at image 0, but page 1, we need the last page to have progress as page + 1 to be completed
|
|
||||||
let pageNum = this.pageNum;
|
|
||||||
if (this.pageNum == this.maxPages - 1) {
|
|
||||||
pageNum = this.pageNum + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.incognitoMode) {
|
|
||||||
this.readerService.saveProgress(this.seriesId, this.volumeId, this.chapterId, pageNum).pipe(take(1)).subscribe(() => {/* No operation */});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.canvasImage = this.cachedImages.current();
|
this.canvasImage = this.cachedImages.current();
|
||||||
if (this.readerService.imageUrlToPageNum(this.canvasImage.src) !== this.pageNum || this.canvasImage.src === '' || !this.canvasImage.complete) {
|
if (this.readerService.imageUrlToPageNum(this.canvasImage.src) !== this.pageNum || this.canvasImage.src === '' || !this.canvasImage.complete) {
|
||||||
@ -987,6 +977,16 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Due to the fact that we start at image 0, but page 1, we need the last page to have progress as page + 1 to be completed
|
||||||
|
let tempPageNum = this.pageNum;
|
||||||
|
if (this.pageNum == this.maxPages - 1) {
|
||||||
|
tempPageNum = this.pageNum + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.incognitoMode) {
|
||||||
|
this.readerService.saveProgress(this.seriesId, this.volumeId, this.chapterId, tempPageNum).pipe(take(1)).subscribe(() => {/* No operation */});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
goToPage(pageNum: number) {
|
goToPage(pageNum: number) {
|
||||||
@ -1066,8 +1066,6 @@ export class MangaReaderComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
|
|
||||||
handleWebtoonPageChange(updatedPageNum: number) {
|
handleWebtoonPageChange(updatedPageNum: number) {
|
||||||
this.setPageNum(updatedPageNum);
|
this.setPageNum(updatedPageNum);
|
||||||
if (this.incognitoMode) return;
|
|
||||||
this.readerService.saveProgress(this.seriesId, this.volumeId, this.chapterId, this.pageNum).pipe(take(1)).subscribe(() => {/* No operation */});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user