Working arrow navigation
This commit is contained in:
parent
6137d1c0d8
commit
c0edce517a
@ -0,0 +1,25 @@
|
||||
@import "../../../assets/styles/red-variables";
|
||||
@import "../../../assets/styles/red-mixins";
|
||||
|
||||
.breadcrumbs-container {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.breadcrumb {
|
||||
text-decoration: none;
|
||||
color: $accent;
|
||||
font-weight: 600;
|
||||
width: fit-content;
|
||||
white-space: nowrap;
|
||||
|
||||
&:last-child {
|
||||
color: $primary;
|
||||
@include line-clamp(1);
|
||||
}
|
||||
|
||||
.mat-icon {
|
||||
vertical-align: middle;
|
||||
width: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,7 +126,7 @@
|
||||
</div>
|
||||
|
||||
<div class="right-content">
|
||||
<div class="pages" #quickNavigation>
|
||||
<div class="pages" [class.activePanel]="pagesPanelActive" #quickNavigation>
|
||||
<div class="page-number pointer"
|
||||
[ngClass]="{ active: pageNumber === activeViewerPage }"
|
||||
*ngFor="let pageNumber of displayedPages"
|
||||
@ -135,7 +135,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="annotations" #annotations>
|
||||
<div class="annotations" [class.activePanel]="!pagesPanelActive" #annotations>
|
||||
<div *ngFor="let page of displayedPages">
|
||||
<div class="page-separator" attr.anotation-page-header="{{page}}">
|
||||
<span class="all-caps-label"><span translate="page"></span> {{page}}</span>
|
||||
|
||||
@ -69,6 +69,10 @@ redaction-pdf-viewer {
|
||||
width: 0;
|
||||
background: transparent; /* Chrome/Safari/Webkit */
|
||||
}
|
||||
|
||||
&.activePanel {
|
||||
background-color: #FAFAFA;
|
||||
}
|
||||
}
|
||||
|
||||
.pages {
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
import {ChangeDetectorRef, Component, ElementRef, HostListener, NgZone, OnInit, ViewChild} from '@angular/core';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {ManualRedactionEntry, ReanalysisControllerService} from '@redaction/red-ui-http';
|
||||
import {AppStateService} from '../../../state/app-state.service';
|
||||
import {Annotations, WebViewerInstance} from '@pdftron/webviewer';
|
||||
import {PdfViewerComponent} from '../pdf-viewer/pdf-viewer.component';
|
||||
import {AnnotationUtils} from '../../../utils/annotation-utils';
|
||||
import {UserService} from '../../../user/user.service';
|
||||
import {debounce} from '../../../utils/debounce';
|
||||
import { ChangeDetectorRef, Component, ElementRef, HostListener, NgZone, OnInit, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ManualRedactionEntry, ReanalysisControllerService } from '@redaction/red-ui-http';
|
||||
import { AppStateService } from '../../../state/app-state.service';
|
||||
import { Annotations, WebViewerInstance } from '@pdftron/webviewer';
|
||||
import { PdfViewerComponent } from '../pdf-viewer/pdf-viewer.component';
|
||||
import { AnnotationUtils } from '../../../utils/annotation-utils';
|
||||
import { UserService } from '../../../user/user.service';
|
||||
import { debounce } from '../../../utils/debounce';
|
||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||
import {AnnotationFilters} from '../../../utils/types';
|
||||
import {FiltersService} from '../service/filters.service';
|
||||
import {FileDownloadService} from '../service/file-download.service';
|
||||
import {saveAs} from 'file-saver';
|
||||
import {FileType} from '../model/file-type';
|
||||
import {DialogService} from '../../../dialogs/dialog.service';
|
||||
import { AnnotationFilters } from '../../../utils/types';
|
||||
import { FiltersService } from '../service/filters.service';
|
||||
import { FileDownloadService } from '../service/file-download.service';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { FileType } from '../model/file-type';
|
||||
import { DialogService } from '../../../dialogs/dialog.service';
|
||||
|
||||
@Component({
|
||||
selector: 'redaction-file-preview-screen',
|
||||
@ -37,6 +37,7 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
public selectedAnnotation: Annotations.Annotation;
|
||||
public filters: AnnotationFilters;
|
||||
public expandedFilters: AnnotationFilters = {hint: false};
|
||||
public pagesPanelActive = false;
|
||||
private instance: WebViewerInstance;
|
||||
|
||||
constructor(
|
||||
@ -167,7 +168,6 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
|
||||
}
|
||||
|
||||
|
||||
get activeViewerPage() {
|
||||
return this.instance.docViewer.getCurrentPage();
|
||||
}
|
||||
@ -274,8 +274,35 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
handleKeyEvent($event: KeyboardEvent) {
|
||||
$event.preventDefault();
|
||||
|
||||
if (!this.selectedAnnotation) {
|
||||
this.selectAnnotation(this.displayedAnnotations[this.displayedPages[0]].annotations[0]);
|
||||
if ($event.key === 'ArrowLeft' || $event.key === 'ArrowRight') {
|
||||
this.pagesPanelActive = !this.pagesPanelActive;
|
||||
this._changeDetectorRef.detectChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.pagesPanelActive) {
|
||||
this._navigateAnnotations($event);
|
||||
} else {
|
||||
this._navigatePages($event);
|
||||
}
|
||||
}
|
||||
|
||||
private _navigateAnnotations($event: KeyboardEvent) {
|
||||
if (!this.selectedAnnotation || this.activeViewerPage !== this.selectedAnnotation.getPageNumber()) {
|
||||
const pageIdx = this.displayedPages.indexOf(this.activeViewerPage);
|
||||
if (pageIdx !== -1) { // Displayed page has annotations
|
||||
this.selectAnnotation(this.displayedAnnotations[this.activeViewerPage].annotations[0]);
|
||||
} else { // Displayed page doesn't have annotations
|
||||
if ($event.key === 'ArrowDown') {
|
||||
const nextPage = this._nextPageWithAnnotations();
|
||||
this.selectAnnotation(this.displayedAnnotations[nextPage].annotations[0]);
|
||||
} else {
|
||||
const prevPage = this._prevPageWithAnnotations();
|
||||
const prevPageAnnotations = this.displayedAnnotations[prevPage].annotations;
|
||||
this.selectAnnotation(prevPageAnnotations[prevPageAnnotations.length - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
const page = this.selectedAnnotation.getPageNumber();
|
||||
const pageIdx = this.displayedPages.indexOf(page);
|
||||
@ -289,9 +316,7 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
const nextPageAnnotations = this.displayedAnnotations[this.displayedPages[pageIdx + 1]].annotations;
|
||||
this.selectAnnotation(nextPageAnnotations[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($event.key === 'ArrowUp') {
|
||||
} else {
|
||||
if (idx !== 0) { // If not first item in page
|
||||
this.selectAnnotation(annotationsOnPage[idx - 1]);
|
||||
} else if (pageIdx) { // If not first page
|
||||
@ -302,6 +327,58 @@ export class FilePreviewScreenComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
private _navigatePages($event: KeyboardEvent) {
|
||||
const pageIdx = this.displayedPages.indexOf(this.activeViewerPage);
|
||||
|
||||
if ($event.key === 'ArrowDown') {
|
||||
if (pageIdx !== -1) { // If active page has annotations
|
||||
if (pageIdx !== this.displayedPages.length - 1) {
|
||||
this.selectPage(this.displayedPages[pageIdx + 1]);
|
||||
}
|
||||
} else { // If active page doesn't have annotations
|
||||
const nextPage = this._nextPageWithAnnotations();
|
||||
if (nextPage) {
|
||||
this.selectPage(nextPage);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pageIdx !== -1) { // If active page has annotations
|
||||
if (pageIdx !== 0) {
|
||||
this.selectPage(this.displayedPages[pageIdx - 1]);
|
||||
}
|
||||
} else { // If active page doesn't have annotations
|
||||
const prevPage = this._prevPageWithAnnotations();
|
||||
if (prevPage) {
|
||||
this.selectPage(prevPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _nextPageWithAnnotations() {
|
||||
let idx = 0;
|
||||
for (const page of this.displayedPages) {
|
||||
if (page > this.activeViewerPage) {
|
||||
break;
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
return idx < this.displayedPages.length ? this.displayedPages[idx] : null;
|
||||
}
|
||||
|
||||
private _prevPageWithAnnotations() {
|
||||
let idx = this.displayedPages.length - 1;
|
||||
for (const page of this.displayedPages.reverse()) {
|
||||
if (page < this.activeViewerPage) {
|
||||
this.selectPage(this.displayedPages[idx]);
|
||||
this._scrollAnnotations();
|
||||
break;
|
||||
}
|
||||
--idx;
|
||||
}
|
||||
return idx >= 0 ? this.displayedPages[idx] : null;
|
||||
}
|
||||
|
||||
viewerPageChanged($event: number) {
|
||||
this._scrollViews();
|
||||
this._changeDetectorRef.detectChanges();
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
@import "red-variables";
|
||||
@import "red-mixins";
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
@ -172,27 +171,6 @@ html, body {
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumbs-container {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
.breadcrumb {
|
||||
text-decoration: none;
|
||||
color: $accent;
|
||||
font-weight: 600;
|
||||
|
||||
&:last-child {
|
||||
color: $primary;
|
||||
@include line-clamp(1);
|
||||
}
|
||||
|
||||
.mat-icon {
|
||||
vertical-align: middle;
|
||||
width: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
opacity: 0.15;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user