Working arrow navigation

This commit is contained in:
Adina Țeudan 2020-10-23 20:59:40 +03:00
parent 6137d1c0d8
commit c0edce517a
5 changed files with 129 additions and 45 deletions

View File

@ -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;
}
}
}

View File

@ -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>

View File

@ -69,6 +69,10 @@ redaction-pdf-viewer {
width: 0;
background: transparent; /* Chrome/Safari/Webkit */
}
&.activePanel {
background-color: #FAFAFA;
}
}
.pages {

View File

@ -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();

View File

@ -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;