From ce91b056b36fb7ba237f2e1b826fc935f1245cd1 Mon Sep 17 00:00:00 2001 From: Joe Milazzo Date: Sun, 31 Aug 2025 14:38:23 -0500 Subject: [PATCH] Shakeout from the Annotation System (#4011) Co-authored-by: Amelia <77553571+Fesaa@users.noreply.github.com> --- .../ManualMigrateBookReadingProgress.cs | 99 +++++++++++-------- API/Entities/Enums/HightlightColor.cs | 11 --- API/Services/BookService.cs | 19 +++- UI/Web/src/app/_pipes/highlight-color.pipe.ts | 18 ---- .../_services/epub-reader-settings.service.ts | 5 +- .../annotation-card.component.html | 2 +- .../annotation-card.component.scss | 2 +- .../epub-highlight.component.ts | 3 +- .../view-toc-drawer.component.ts | 3 +- .../book-line-overlay.component.ts | 9 +- .../book-reader/book-reader.component.html | 68 ++++++------- .../book-reader/book-reader.component.scss | 8 +- .../book-reader/book-reader.component.ts | 81 +++++++++------ .../_models/annotations/annotation.ts | 9 -- 14 files changed, 176 insertions(+), 161 deletions(-) delete mode 100644 API/Entities/Enums/HightlightColor.cs delete mode 100644 UI/Web/src/app/_pipes/highlight-color.pipe.ts diff --git a/API/Data/ManualMigrations/v0.8.8/ManualMigrateBookReadingProgress.cs b/API/Data/ManualMigrations/v0.8.8/ManualMigrateBookReadingProgress.cs index 3a5b14539..e03d7de59 100644 --- a/API/Data/ManualMigrations/v0.8.8/ManualMigrateBookReadingProgress.cs +++ b/API/Data/ManualMigrations/v0.8.8/ManualMigrateBookReadingProgress.cs @@ -28,63 +28,80 @@ public static class ManualMigrateBookReadingProgress public static async Task Migrate(DataContext context, IUnitOfWork unitOfWork, ILogger logger) { - if (await context.ManualMigrationHistory.AnyAsync(m => m.Name == "ManualMigrateBookReadingProgress")) { return; } - - logger.LogCritical("Running ManualMigrateBookReadingProgress migration - Please be patient, this may take some time. This is not an error"); - var bookProgress = await context.AppUserProgresses - .Where(p => p.BookScrollId != null && (p.BookScrollId.StartsWith(OldScope) || p.BookScrollId.StartsWith(NewScope))) + // Disable change tracking so that LastUpdated isn't updated breaking stats + var originalAutoDetectChanges = context.ChangeTracker.AutoDetectChangesEnabled; + context.ChangeTracker.AutoDetectChangesEnabled = false; + + try + { + var bookProgress = await context.AppUserProgresses + .Where(p => p.BookScrollId != null && + (p.BookScrollId.StartsWith(OldScope) || p.BookScrollId.StartsWith(NewScope))) + .AsNoTracking() .ToListAsync(); - foreach (var progress in bookProgress) - { - if (string.IsNullOrEmpty(progress.BookScrollId)) continue; + foreach (var progress in bookProgress) + { + if (string.IsNullOrEmpty(progress.BookScrollId)) continue; - if (progress.BookScrollId.StartsWith(OldScope)) + if (progress.BookScrollId.StartsWith(OldScope)) + { + progress.BookScrollId = progress.BookScrollId.Replace(OldScope, ReplacementScope); + context.AppUserProgresses.Update(progress); + } + else if (progress.BookScrollId.StartsWith(NewScope)) + { + progress.BookScrollId = progress.BookScrollId.Replace(NewScope, ReplacementScope); + context.AppUserProgresses.Update(progress); + } + } + + if (unitOfWork.HasChanges()) { - progress.BookScrollId = progress.BookScrollId.Replace(OldScope, ReplacementScope); - context.AppUserProgresses.Update(progress); - } else if (progress.BookScrollId.StartsWith(NewScope)) + await context.SaveChangesAsync(); + } + + var ptocEntries = await context.AppUserTableOfContent + .Where(p => p.BookScrollId != null && + (p.BookScrollId.StartsWith(OldScope) || p.BookScrollId.StartsWith(NewScope))) + .AsNoTracking() + .ToListAsync(); + + foreach (var ptoc in ptocEntries) { - progress.BookScrollId = progress.BookScrollId.Replace(NewScope, ReplacementScope); - context.AppUserProgresses.Update(progress); + if (string.IsNullOrEmpty(ptoc.BookScrollId)) continue; + + if (ptoc.BookScrollId.StartsWith("id", StringComparison.InvariantCultureIgnoreCase)) continue; + + if (ptoc.BookScrollId.StartsWith(OldScope)) + { + ptoc.BookScrollId = ptoc.BookScrollId.Replace(OldScope, ReplacementScope); + context.AppUserTableOfContent.Update(ptoc); + } + else if (ptoc.BookScrollId.StartsWith(NewScope)) + { + ptoc.BookScrollId = ptoc.BookScrollId.Replace(NewScope, ReplacementScope); + context.AppUserTableOfContent.Update(ptoc); + } + } + + if (unitOfWork.HasChanges()) + { + await context.SaveChangesAsync(); } } - - if (unitOfWork.HasChanges()) + finally { - await context.SaveChangesAsync(); - } - - var ptocEntries = await context.AppUserTableOfContent - .Where(p => p.BookScrollId != null && (p.BookScrollId.StartsWith(OldScope) || p.BookScrollId.StartsWith(NewScope))) - .ToListAsync(); - - foreach (var ptoc in ptocEntries) - { - if (string.IsNullOrEmpty(ptoc.BookScrollId)) continue; - - if (ptoc.BookScrollId.StartsWith(OldScope)) - { - ptoc.BookScrollId = ptoc.BookScrollId.Replace(OldScope, ReplacementScope); - context.AppUserTableOfContent.Update(ptoc); - } else if (ptoc.BookScrollId.StartsWith(NewScope)) - { - ptoc.BookScrollId = ptoc.BookScrollId.Replace(NewScope, ReplacementScope); - context.AppUserTableOfContent.Update(ptoc); - } - } - - if (unitOfWork.HasChanges()) - { - await context.SaveChangesAsync(); + // Restore original setting + context.ChangeTracker.AutoDetectChangesEnabled = originalAutoDetectChanges; } await context.ManualMigrationHistory.AddAsync(new ManualMigrationHistory() diff --git a/API/Entities/Enums/HightlightColor.cs b/API/Entities/Enums/HightlightColor.cs deleted file mode 100644 index dc60b46e8..000000000 --- a/API/Entities/Enums/HightlightColor.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace API.Entities.Enums; - -/// -/// Color of the highlight -/// -/// Color may not match exactly due to theming -public enum HightlightColor -{ - Blue = 1, - Green = 2, -} diff --git a/API/Services/BookService.cs b/API/Services/BookService.cs index 95dc7d67c..7b2e2ac79 100644 --- a/API/Services/BookService.cs +++ b/API/Services/BookService.cs @@ -321,9 +321,22 @@ public partial class BookService : IBookService foreach (var bookmark in ptocBookmarks.Where(b => !string.IsNullOrEmpty(b.BookScrollId))) { - var unscopedSelector = bookmark.BookScrollId!.Replace("//BODY/APP-ROOT[1]/DIV[1]/DIV[1]/DIV[1]/APP-BOOK-READER[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]", "//BODY").ToLowerInvariant(); - var elem = doc.DocumentNode.SelectSingleNode(unscopedSelector); - elem?.PrependChild(HtmlNode.CreateNode($"")); + try + { + var unscopedSelector = bookmark.BookScrollId! + .Replace( + "//BODY/APP-ROOT[1]/DIV[1]/DIV[1]/DIV[1]/APP-BOOK-READER[1]/DIV[1]/DIV[2]/DIV[1]/DIV[1]/DIV[1]", + "//BODY").ToLowerInvariant(); + var elem = doc.DocumentNode.SelectSingleNode(unscopedSelector); + if (elem == null) continue; + + elem.PrependChild(HtmlNode.CreateNode( + $"")); + } + catch (Exception) + { + // Swallow + } } } diff --git a/UI/Web/src/app/_pipes/highlight-color.pipe.ts b/UI/Web/src/app/_pipes/highlight-color.pipe.ts deleted file mode 100644 index f831d0695..000000000 --- a/UI/Web/src/app/_pipes/highlight-color.pipe.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {Pipe, PipeTransform} from '@angular/core'; -import {HighlightColor} from "../book-reader/_models/annotations/annotation"; - -@Pipe({ - name: 'highlightColor' -}) -export class HighlightColorPipe implements PipeTransform { - - transform(value: HighlightColor): string { - switch (value) { - case HighlightColor.Blue: - return 'blue'; - case HighlightColor.Green: - return 'green'; - } - } - -} diff --git a/UI/Web/src/app/_services/epub-reader-settings.service.ts b/UI/Web/src/app/_services/epub-reader-settings.service.ts index fd4fb83f6..75109b4c9 100644 --- a/UI/Web/src/app/_services/epub-reader-settings.service.ts +++ b/UI/Web/src/app/_services/epub-reader-settings.service.ts @@ -218,7 +218,7 @@ export class EpubReaderSettingsService { this._currentSeriesId.set(seriesId); this._currentReadingProfile.set(readingProfile); - // Load parent profile if needed + // Load parent profile if needed, otherwise profile is its own parent if (readingProfile.kind === ReadingProfileKind.Implicit) { try { const parent = await firstValueFrom(this.readingProfileService.getForSeries(seriesId, true)); @@ -226,6 +226,8 @@ export class EpubReaderSettingsService { } catch (error) { console.error('Failed to load parent reading profile:', error); } + } else { + this._parentReadingProfile.set(readingProfile); } // Setup defaults and update signals @@ -575,7 +577,6 @@ export class EpubReaderSettingsService { this.settingsForm.valueChanges.pipe( debounceTime(500), distinctUntilChanged(), - skip(1), // Skip initial form creation takeUntilDestroyed(this.destroyRef), filter(() => !this.isUpdatingFromForm), tap(() => this.updateImplicitProfile()), diff --git a/UI/Web/src/app/book-reader/_components/_annotations/annotation-card/annotation-card.component.html b/UI/Web/src/app/book-reader/_components/_annotations/annotation-card/annotation-card.component.html index 659cff3e6..2f1586f91 100644 --- a/UI/Web/src/app/book-reader/_components/_annotations/annotation-card/annotation-card.component.html +++ b/UI/Web/src/app/book-reader/_components/_annotations/annotation-card/annotation-card.component.html @@ -1,5 +1,5 @@ -
+
{{ annotation().ownerUsername }} diff --git a/UI/Web/src/app/book-reader/_components/_annotations/annotation-card/annotation-card.component.scss b/UI/Web/src/app/book-reader/_components/_annotations/annotation-card/annotation-card.component.scss index 220abcc7f..0ba4d486a 100644 --- a/UI/Web/src/app/book-reader/_components/_annotations/annotation-card/annotation-card.component.scss +++ b/UI/Web/src/app/book-reader/_components/_annotations/annotation-card/annotation-card.component.scss @@ -1,4 +1,4 @@ -.card { +.annotation-card { max-width: 400px; } diff --git a/UI/Web/src/app/book-reader/_components/_annotations/epub-highlight/epub-highlight.component.ts b/UI/Web/src/app/book-reader/_components/_annotations/epub-highlight/epub-highlight.component.ts index 2ef83e7df..315f9ae92 100644 --- a/UI/Web/src/app/book-reader/_components/_annotations/epub-highlight/epub-highlight.component.ts +++ b/UI/Web/src/app/book-reader/_components/_annotations/epub-highlight/epub-highlight.component.ts @@ -1,5 +1,5 @@ import {Component, computed, DestroyRef, effect, ElementRef, inject, input, model, ViewChild} from '@angular/core'; -import {Annotation, HighlightColor} from "../../../_models/annotations/annotation"; +import {Annotation} from "../../../_models/annotations/annotation"; import {EpubReaderMenuService} from "../../../../_services/epub-reader-menu.service"; import {AnnotationService} from "../../../../_services/annotation.service"; import {SlotColorPipe} from "../../../../_pipes/slot-color.pipe"; @@ -21,7 +21,6 @@ export class EpubHighlightComponent { private readonly destroyRef = inject(DestroyRef); showHighlight = model(true); - color = input(HighlightColor.Blue); annotation = model.required(); diff --git a/UI/Web/src/app/book-reader/_components/_drawers/view-toc-drawer/view-toc-drawer.component.ts b/UI/Web/src/app/book-reader/_components/_drawers/view-toc-drawer/view-toc-drawer.component.ts index 476cc585b..676cdd4cd 100644 --- a/UI/Web/src/app/book-reader/_components/_drawers/view-toc-drawer/view-toc-drawer.component.ts +++ b/UI/Web/src/app/book-reader/_components/_drawers/view-toc-drawer/view-toc-drawer.component.ts @@ -61,7 +61,8 @@ export class ViewTocDrawerComponent { } loadChapterPage(event: {pageNum: number, part: string}) { - const evt = {pageNumber: event.pageNum, part: `id("${event.part}")`} as LoadPageEvent; + const part = event.part.length === 0 ? '' : `id("${event.part}")`; + const evt = {pageNumber: event.pageNum, part: part} as LoadPageEvent; this.loadPage.emit(evt); } diff --git a/UI/Web/src/app/book-reader/_components/book-line-overlay/book-line-overlay.component.ts b/UI/Web/src/app/book-reader/_components/book-line-overlay/book-line-overlay.component.ts index 1c773f4bb..92522c087 100644 --- a/UI/Web/src/app/book-reader/_components/book-line-overlay/book-line-overlay.component.ts +++ b/UI/Web/src/app/book-reader/_components/book-line-overlay/book-line-overlay.component.ts @@ -154,18 +154,23 @@ export class BookLineOverlayComponent implements OnInit { return; } + // On mobile, first selection might not match as users can select after the fact. Recalculate + const windowText = window.getSelection(); + const selectedText = windowText?.toString() === '' ? this.selectedText : windowText?.toString() ?? this.selectedText; + if (this.mode === BookLineOverlayMode.Annotate) { + const createAnnotation = { id: 0, xPath: this.startXPath, endingXPath: this.endXPath, - selectedText: this.selectedText, + selectedText: selectedText, comment: '', containsSpoiler: false, pageNumber: this.pageNumber, selectedSlotIndex: 0, chapterTitle: '', - highlightCount: this.selectedText.length, + highlightCount: selectedText.length, ownerUserId: 0, ownerUsername: '', createdUtc: '', diff --git a/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.html b/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.html index b4259ca93..10dd95601 100644 --- a/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.html +++ b/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.html @@ -46,10 +46,9 @@ [ngClass]="{'immersive': immersiveMode() && actionBarVisible}" [innerHtml]="page()" (click)="toggleMenu($event)" (mousedown)="mouseDown($event)" (wheel)="onWheel($event)">
- @if ((scrollbarNeeded() || layoutMode() !== BookPageLayoutMode.Default) && !(writingStyle() === WritingStyle.Vertical && layoutMode() === BookPageLayoutMode.Default)) { -
- + @if (shouldShowBottomActionBar()) { +
+
}
@@ -116,49 +115,46 @@ } - + +
+ - @if (!immersiveMode() || epubMenuService.isDrawerOpen() || actionBarVisible()) { -
- - - @if (!this.adhocPageHistory.isEmpty()) { - - } + } -
- @if(!isLoading()) { - +
+ @if(!isLoading()) { + {{t('page-num-label', {page: virtualizedPageNum()})}} / {{virtualizedMaxPages()}} - {{t('completion-label', {percent: (virtualizedPageNum() / virtualizedMaxPages()) | percent})}} - @if (readingTimeLeftResource.value(); as timeLeft) { - , - + {{t('completion-label', {percent: (virtualizedPageNum() / virtualizedMaxPages()) | percent})}} + @if (readingTimeLeftResource.value(); as timeLeft) { + , + - {{timeLeft! | readTimeLeft:true }} + {{timeLeft! | readTimeLeft:true }} - } } -
- - + }
- } + + +
diff --git a/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.scss b/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.scss index 8084f5fef..5857b3ccb 100644 --- a/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.scss +++ b/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.scss @@ -287,8 +287,8 @@ $action-bar-height: 38px; .bottom-bar { position: fixed; width: 100%; - bottom: 0px; - left: 0px; + bottom: 0; + left: 0; writing-mode: horizontal-tb; } @@ -374,7 +374,7 @@ $pagination-opacity: 0; cursor: pointer; &.immersive { - top: 0px; + top: 0; } &.no-pointer-events { @@ -397,7 +397,7 @@ $pagination-opacity: 0; cursor: pointer; &.immersive { - top: 0px; + top: 0; } } diff --git a/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.ts b/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.ts index 4dc4ff58f..a4e0644ea 100644 --- a/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.ts +++ b/UI/Web/src/app/book-reader/_components/book-reader/book-reader.component.ts @@ -100,6 +100,12 @@ const minImageSize = { width: 100 }; +/** + * A slight delay before scrolling, to ensure everything has rendered correctly + * Ex. after jumping in the ToC + */ +const SCROLL_DELAY = 10; + @Component({ selector: 'app-book-reader', templateUrl: './book-reader.component.html', @@ -208,7 +214,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { */ isLineOverlayOpen = model(false); /** - * If the action bar is visible + * If the action bar (menu bars) is visible */ actionBarVisible = model(true); /** @@ -368,7 +374,6 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { protected readonly writingStyle = this.readerSettingsService.writingStyle; protected readonly clickToPaginate = this.readerSettingsService.clickToPaginate; - //protected columnWidth = this.readerSettingsService.columnWidth; protected columnWidth!: Signal; protected columnHeight!: Signal; protected verticalBookContentWidth!: Signal; @@ -416,8 +421,30 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { const isDrawerOpen = this.epubMenuService.isDrawerOpen(); const actionBarVisible = this.actionBarVisible(); - return !immersiveMode || isDrawerOpen || actionBarVisible; - }) + return actionBarVisible || !immersiveMode || isDrawerOpen; + }); + + shouldShowBottomActionBar = computed(() => { + const layoutMode = this.layoutMode(); + const scrollbarNeeded = this.scrollbarNeeded(); + const writingStyle = this.writingStyle(); + const immersiveMode = this.immersiveMode(); + const actionBarVisible = this.actionBarVisible(); + const isDrawerOpen = this.epubMenuService.isDrawerOpen(); + + const isColumnMode = layoutMode !== BookPageLayoutMode.Default; + const isVerticalLayout = writingStyle === WritingStyle.Vertical; + + + const baseCondition = (scrollbarNeeded || isColumnMode) + && !(isVerticalLayout && !isColumnMode); + + const showForVerticalDefault = !isColumnMode && isVerticalLayout; + + const otherCondition = !immersiveMode || isDrawerOpen || actionBarVisible; + + return (baseCondition || showForVerticalDefault) && otherCondition; + }); isNextPageDisabled() { @@ -495,13 +522,18 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { this.cdRef.markForCheck(); this.columnWidth = computed(() => { - switch (this.layoutMode()) { + const layoutMode = this.layoutMode(); + const writingStyle = this.writingStyle(); + + const base = writingStyle === WritingStyle.Vertical ? this.pageHeight() : this.pageWidth(); + + switch (layoutMode) { case BookPageLayoutMode.Default: return 'unset'; case BookPageLayoutMode.Column1: - return ((this.pageWidth() / 2) - 4) + 'px'; + return ((base / 2) - 4) + 'px'; case BookPageLayoutMode.Column2: - return (this.pageWidth() / 4) + 'px' + return (base / 4) + 'px' default: return 'unset'; } @@ -892,28 +924,16 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { // Attempt to restore the reading position this.snapScrollOnResize(); - // const resumeElement = this.getFirstVisibleElementXPath(); - // const layoutMode = this.layoutMode(); - // if (layoutMode !== BookPageLayoutMode.Default && resumeElement !== null && resumeElement !== undefined) { - // - // //const element = this.getElementFromXPath(resumeElement); - // //console.log('Resuming from resize to element: ', element); - // - // this.scrollTo(resumeElement, 30); // This works pretty well, but not perfect - // } } /** - * Only applies to non BookPageLayoutMode.Default and non-WritingStyle Horizontal + * Only applies to non BookPageLayoutMode. Default and WritingStyle Horizontal * @private */ private snapScrollOnResize() { const layoutMode = this.layoutMode(); if (layoutMode === BookPageLayoutMode.Default) return; - // NOTE: Need to test on one of these books to validate - // || this.writingStyle() === WritingStyle.Horizontal - const resumeElement = this.getFirstVisibleElementXPath() ?? null; if (resumeElement !== null) { @@ -1171,7 +1191,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { }); this.firstLoad = false; - }, 10); + }, SCROLL_DELAY); }); } @@ -1379,31 +1399,31 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { if (layoutMode === BookPageLayoutMode.Default) { if (writingStyle === WritingStyle.Vertical) { - setTimeout(()=> this.scrollService.scrollToX(this.bookContentElemRef.nativeElement.clientWidth, this.reader.nativeElement)); + setTimeout(()=> this.scrollService.scrollToX(this.bookContentElemRef.nativeElement.clientWidth, this.reader.nativeElement), SCROLL_DELAY); return; } - setTimeout(() => this.scrollService.scrollTo(0, this.reader.nativeElement)); + setTimeout(() => this.scrollService.scrollTo(0, this.reader.nativeElement), SCROLL_DELAY); return; } if (writingStyle === WritingStyle.Vertical) { if (this.pagingDirection === PAGING_DIRECTION.BACKWARDS) { - setTimeout(() => this.scrollService.scrollTo(this.bookContentElemRef.nativeElement.scrollHeight, this.bookContentElemRef.nativeElement, 'auto')); + setTimeout(() => this.scrollService.scrollTo(this.bookContentElemRef.nativeElement.scrollHeight, this.bookContentElemRef.nativeElement, 'auto'), SCROLL_DELAY); return; } - setTimeout(() => this.scrollService.scrollTo(0, this.bookContentElemRef.nativeElement,'auto' )); + setTimeout(() => this.scrollService.scrollTo(0, this.bookContentElemRef.nativeElement,'auto' ), SCROLL_DELAY); return; } // We need to check if we are paging back, because we need to adjust the scroll if (this.pagingDirection === PAGING_DIRECTION.BACKWARDS) { - setTimeout(() => this.scrollService.scrollToX(this.bookContentElemRef.nativeElement.scrollWidth, this.bookContentElemRef.nativeElement)); + setTimeout(() => this.scrollService.scrollToX(this.bookContentElemRef.nativeElement.scrollWidth, this.bookContentElemRef.nativeElement), SCROLL_DELAY); return; } - setTimeout(() => this.scrollService.scrollToX(0, this.bookContentElemRef.nativeElement)); + setTimeout(() => this.scrollService.scrollToX(0, this.bookContentElemRef.nativeElement), SCROLL_DELAY); } private setupAnnotationElements() { @@ -1568,6 +1588,8 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { * @returns Total Page width (excluding margin) */ pageWidth = computed(() => { + this.windowWidth(); // Ensure re-compute when windows size changes (element clientWidth isn't a signal) + const marginLeft = this.pageStyles()['margin-left']; const columnGapModifier = this.layoutMode() === BookPageLayoutMode.Default ? 0 : 1; if (this.readingSectionElemRef == null) return 0; @@ -1878,12 +1900,12 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { case WritingStyle.Vertical: const windowWidth = window.innerWidth || document.documentElement.clientWidth; const scrollLeft = element.getBoundingClientRect().left + window.scrollX - (windowWidth - element.getBoundingClientRect().width); - setTimeout(() => this.scrollService.scrollToX(scrollLeft, this.reader.nativeElement, 'smooth'), 10); + setTimeout(() => this.scrollService.scrollToX(scrollLeft, this.reader.nativeElement, 'smooth'), SCROLL_DELAY); break; case WritingStyle.Horizontal: const fromTopOffset = element.getBoundingClientRect().top + window.scrollY + TOP_OFFSET; // We need to use a delay as webkit browsers (aka Apple devices) don't always have the document rendered by this point - setTimeout(() => this.scrollService.scrollTo(fromTopOffset, this.reader.nativeElement), 10); + setTimeout(() => this.scrollService.scrollTo(fromTopOffset, this.reader.nativeElement), SCROLL_DELAY); } } @@ -2116,7 +2138,6 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy { Math.abs(this.mousePosition.y - event.clientY) <= mouseOffset ) { this.actionBarVisible.update(v => !v); - this.cdRef.markForCheck(); } } diff --git a/UI/Web/src/app/book-reader/_models/annotations/annotation.ts b/UI/Web/src/app/book-reader/_models/annotations/annotation.ts index 7986d6d91..b0b3d07c7 100644 --- a/UI/Web/src/app/book-reader/_models/annotations/annotation.ts +++ b/UI/Web/src/app/book-reader/_models/annotations/annotation.ts @@ -1,12 +1,3 @@ -export enum HighlightColor { - Blue = 1, - Green = 2, -} - -export const allHighlightColors = [HighlightColor.Blue, HighlightColor.Green]; - - - export interface Annotation { id: number;