mirror of
https://github.com/Kareadita/Kavita.git
synced 2026-01-10 14:10:21 -05:00
* Fixed a bug on bookmark mode not finding correct image for prefetcher. * Fixed up the edit series relationship modal on tablet viewports. * On double page mode, only bookmark 1 page if only 1 pages is renderered on screen. * Added percentage read of a given library and average hours read per week to user stats. * Fixed a bug in the reader with paging in bookmark mode * Added a "This Week" option to top readers history * Added date ranges for reading time. Added dates that don't have anything, but might remove. * On phone, when applying a metadata filter, when clicking apply, collapse the filter automatically. * Disable jump bar and the resuming from last spot when a custom sort is applied. * Ensure all Regex.Replace or Matches have timeouts set * Fixed a long standing bug where fit to height on tablets wouldn't center the image * Streamlined url parsing to be more reliable * Reduced an additional db query in chapter info. * Added a missing task to convert covers to webP and added messaging to help the user understand to run it after modifying the setting. * Changed OPDS to be enabled by default for new installs. This should reduce issues with users being confused about it before it's enabled. * When there are multiple files for a chapter, show a count card on the series detail to help user understand duplicates exist. Made the unread badge smaller to avoid collision. * Added Word Count to user stats and wired up average reading per week. * Fixed word count failing on some epubs * Removed some debug code * Don't give more information than is necessary about file paths for page dimensions. * Fixed a bug where pagination area would be too small when the book's content was less that height on default mode. * Updated Default layout mode to Scroll for books. * Added bytes in the UI and at an API layer for CDisplayEx * Don't log health checks to logs at all. * Changed Word Count to Length to match the way pages work * Made reading time more clear when min hours is 0 * Apply more aggressive coalescing when remapping bad metadata keys for epubs. * Changed the amount of padding between icon and text for side nav item. * Fixed a NPE on book reader (harmless) * Fixed an ordering issue where Volume 1 was a single file but also tagged as Chapter 1 and Volume 2 was Chapter 0. Thus Volume 2 was being selected for continue point when Volume 1 should have been. * When clicking on an activity stream header from dashboard, show the title on the resulting page. * Removed a property that can't be animated * Fixed a typeahead typescript issue * Added Size into Series Info and Added some tooltip and spacing changes to better explain some fields. * Added size for volume drawers and cleaned up some date edge case handling * Fixed an annoying bug where when on mobile opening a view with a metadata filter, Kavita would open the filter automatically.
153 lines
11 KiB
HTML
153 lines
11 KiB
HTML
<!-- IDEA: Move the whole reader drawer into this component and have it self contained -->
|
|
<form [formGroup]="settingsForm">
|
|
<ngb-accordion [closeOthers]="false" #acc="ngbAccordion" [activeIds]="['general-panel', 'reader-panel', 'color-panel']">
|
|
<ngb-panel id="general-panel" title="General Settings">
|
|
<ng-template ngbPanelHeader>
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button" ngbPanelToggle type="button" [attr.aria-expanded]="acc.isExpanded('general-panel')" aria-controls="collapseOne">
|
|
General Settings
|
|
</button>
|
|
</h2>
|
|
</ng-template>
|
|
<ng-template ngbPanelContent>
|
|
<div class="control-container">
|
|
<div class="controls">
|
|
<div class="mb-3">
|
|
<label for="library-type" class="form-label">Font Family</label>
|
|
<select class="form-select" id="library-type" formControlName="bookReaderFontFamily">
|
|
<option [value]="opt" *ngFor="let opt of fontOptions; let i = index">{{opt | titlecase}}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="row g-0 controls">
|
|
<label for="fontsize" class="form-label col-6">Font Size</label>
|
|
<span class="col-6 float-end" style="display: inline-flex;">
|
|
<i class="fa-solid fa-font" style="font-size: 12px;"></i>
|
|
<input type="range" class="form-range ms-2 me-2" id="fontsize" min="50" max="300" step="10" formControlName="bookReaderFontSize" [ngbTooltip]="settingsForm.get('bookReaderFontSize')?.value + '%'">
|
|
<i class="fa-solid fa-font" style="font-size: 24px;"></i>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="row g-0 controls">
|
|
<label for="linespacing" class="form-label col-6">Line Spacing</label>
|
|
<span class="col-6 float-end" style="display: inline-flex;">
|
|
1x
|
|
<input type="range" class="form-range ms-2 me-2" id="linespacing" min="100" max="200" step="10" formControlName="bookReaderLineSpacing" [ngbTooltip]="settingsForm.get('bookReaderLineSpacing')?.value + '%'">
|
|
2.5x
|
|
</span>
|
|
</div>
|
|
|
|
<div class="row g-0 controls">
|
|
<label for="margin" class="form-label col-6">Margin</label>
|
|
<span class="col-6 float-end" style="display: inline-flex;">
|
|
<i class="fa-solid fa-outdent"></i>
|
|
<input type="range" class="form-range ms-2 me-2" id="margin" min="0" max="30" step="5" formControlName="bookReaderMargin" [ngbTooltip]="settingsForm.get('bookReaderMargin')?.value + '%'">
|
|
<i class="fa-solid fa-indent"></i>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="row g-0 justify-content-between mt-2">
|
|
<button (click)="resetSettings()" class="btn btn-primary col">Reset to Defaults</button>
|
|
</div>
|
|
</div>
|
|
</ng-template>
|
|
|
|
</ngb-panel>
|
|
|
|
<ngb-panel id="reader-panel" title="Reader Settings">
|
|
<ng-template ngbPanelHeader>
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button" ngbPanelToggle type="button" [attr.aria-expanded]="acc.isExpanded('reader-panel')" aria-controls="collapseOne">
|
|
Reader Settings
|
|
</button>
|
|
</h2>
|
|
</ng-template>
|
|
<ng-template ngbPanelContent>
|
|
<div class="controls" style="display:flex; justify-content:space-between; align-items:center;">
|
|
<label id="readingdirection" class="form-label">Reading Direction</label>
|
|
<button (click)="toggleReadingDirection()" class="btn btn-icon" aria-labelledby="readingdirection" title="{{readingDirectionModel === ReadingDirection.LeftToRight ? 'Left to Right' : 'Right to Left'}}">
|
|
<i class="fa {{readingDirectionModel === ReadingDirection.LeftToRight ? 'fa-arrow-right' : 'fa-arrow-left'}} " aria-hidden="true"></i>
|
|
<span class="phone-hidden"> {{readingDirectionModel === ReadingDirection.LeftToRight ? 'Left to Right' : 'Right to Left'}}</span>
|
|
</button>
|
|
</div>
|
|
<div class="controls" style="display:flex; justify-content:space-between; align-items:center;">
|
|
<label for="tap-pagination" class="form-label">Tap Pagination <i class="fa fa-info-circle" aria-hidden="true" placement="top" [ngbTooltip]="tapPaginationTooltip" role="button" tabindex="0" aria-describedby="tapPagination-help"></i></label>
|
|
<ng-template #tapPaginationTooltip>Click the edges of the screen to paginate</ng-template>
|
|
<span class="visually-hidden" id="tapPagination-help">
|
|
<ng-container [ngTemplateOutlet]="tapPaginationTooltip"></ng-container>
|
|
</span>
|
|
<div class="form-check form-switch">
|
|
<input type="checkbox" id="tap-pagination" formControlName="bookReaderTapToPaginate" class="form-check-input" aria-labelledby="tapPagination-help">
|
|
<label>{{settingsForm.get('bookReaderTapToPaginate')?.value ? 'On' : 'Off'}} </label>
|
|
</div>
|
|
</div>
|
|
<div class="controls" style="display:flex; justify-content:space-between; align-items:center;">
|
|
<label for="immersive-mode" class="form-label">Immersive Mode <i class="fa fa-info-circle" aria-hidden="true" placement="top" [ngbTooltip]="immersiveModeTooltip" role="button" tabindex="0" aria-describedby="immersiveMode-help"></i></label>
|
|
<ng-template #immersiveModeTooltip>This will hide the menu behind a click on the reader document and turn tap to paginate on</ng-template>
|
|
<span class="visually-hidden" id="immersiveMode-help">
|
|
<ng-container [ngTemplateOutlet]="immersiveModeTooltip"></ng-container>
|
|
</span>
|
|
<div class="form-check form-switch">
|
|
<input type="checkbox" id="immersive-mode" formControlName="bookReaderImmersiveMode" class="form-check-input" aria-labelledby="immersiveMode-help">
|
|
<label>{{settingsForm.get('bookReaderImmersiveMode')?.value ? 'On' : 'Off'}} </label>
|
|
</div>
|
|
</div>
|
|
<!-- TODO: move this inline style into a class -->
|
|
<div class="controls" style="display:flex; justify-content:space-between; align-items:center;">
|
|
<label id="fullscreen" class="form-label">Fullscreen <i class="fa fa-info-circle" aria-hidden="true" placement="top"
|
|
[ngbTooltip]="fullscreenTooltip" role="button" tabindex="1" aria-describedby="fullscreen-help"></i></label>
|
|
<ng-template #fullscreenTooltip>Put reader in fullscreen mode</ng-template>
|
|
<span class="visually-hidden" id="fullscreen-help">
|
|
<ng-container [ngTemplateOutlet]="fullscreenTooltip"></ng-container>
|
|
</span>
|
|
<button (click)="toggleFullscreen()" class="btn btn-icon" aria-labelledby="fullscreen">
|
|
<i class="fa {{this.isFullscreen ? 'fa-compress-alt' : 'fa-expand-alt'}} {{isFullscreen ? 'icon-primary-color' : ''}}" aria-hidden="true"></i>
|
|
<span *ngIf="activeTheme?.isDarkTheme"> {{isFullscreen ? 'Exit' : 'Enter'}}</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="controls">
|
|
<label id="layout-mode" class="form-label" style="margin-bottom:0.5rem">Layout Mode <i class="fa fa-info-circle" aria-hidden="true" placement="top" [ngbTooltip]="layoutTooltip" role="button" tabindex="1" aria-describedby="layout-help"></i></label>
|
|
<ng-template #layoutTooltip>Scroll: Mirrors epub file (usually one long scrolling page per chapter).<br/>1 Column: Creates a single virtual page at a time.<br/>2 Column: Creates two virtual pages at a time laid out side-by-side.</ng-template>
|
|
<span class="visually-hidden" id="layout-help">
|
|
<ng-container [ngTemplateOutlet]="layoutTooltip"></ng-container>
|
|
</span>
|
|
<br>
|
|
<div class="btn-group d-flex justify-content-center" role="group" aria-label="Layout Mode">
|
|
<input type="radio" formControlName="layoutMode" [value]="BookPageLayoutMode.Default" class="btn-check" id="layout-mode-default" autocomplete="off">
|
|
<label class="btn btn-outline-primary" for="layout-mode-default">Scroll</label>
|
|
|
|
<input type="radio" formControlName="layoutMode" [value]="BookPageLayoutMode.Column1" class="btn-check" id="layout-mode-col1" autocomplete="off">
|
|
<label class="btn btn-outline-primary" for="layout-mode-col1">1 Column</label>
|
|
|
|
<input type="radio" formControlName="layoutMode" [value]="BookPageLayoutMode.Column2" class="btn-check" id="layout-mode-col2" autocomplete="off">
|
|
<label class="btn btn-outline-primary" for="layout-mode-col2">2 Column</label>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</ng-template>
|
|
</ngb-panel>
|
|
|
|
<ngb-panel id="color-panel" title="Color Theme">
|
|
<ng-template ngbPanelHeader>
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button" ngbPanelToggle type="button" [attr.aria-expanded]="acc.isExpanded('color-panel')" aria-controls="collapseOne">
|
|
Color Theme
|
|
</button>
|
|
</h2>
|
|
</ng-template>
|
|
<ng-template ngbPanelContent>
|
|
<div class="controls">
|
|
<ng-container *ngFor="let theme of themes">
|
|
<button class="btn btn-icon color" (click)="setTheme(theme.name)" [ngClass]="{'active': activeTheme?.name === theme.name}">
|
|
<div class="dot" [ngStyle]="{'background-color': theme.colorHash}"></div>
|
|
{{theme.name}}
|
|
</button>
|
|
</ng-container>
|
|
</div>
|
|
</ng-template>
|
|
</ngb-panel>
|
|
|
|
</ngb-accordion>
|
|
</form> |