RED-10144: fixed multi-selection randomly activating.
This commit is contained in:
parent
428f1dd5fb
commit
4526138fae
@ -58,6 +58,7 @@ import { PageExclusionComponent } from '../page-exclusion/page-exclusion.compone
|
|||||||
import { PagesComponent } from '../pages/pages.component';
|
import { PagesComponent } from '../pages/pages.component';
|
||||||
import { ReadonlyBannerComponent } from '../readonly-banner/readonly-banner.component';
|
import { ReadonlyBannerComponent } from '../readonly-banner/readonly-banner.component';
|
||||||
import { DocumentInfoComponent } from '../document-info/document-info.component';
|
import { DocumentInfoComponent } from '../document-info/document-info.component';
|
||||||
|
import { getLast } from '@utils/functions';
|
||||||
|
|
||||||
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
|
const COMMAND_KEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape'];
|
||||||
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
const ALL_HOTKEY_ARRAY = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'];
|
||||||
@ -348,6 +349,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
|||||||
this.pdf.navigateTo(this.#nextPageWithAnnotations());
|
this.pdf.navigateTo(this.#nextPageWithAnnotations());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Debounce(15)
|
||||||
navigateAnnotations($event: KeyboardEvent) {
|
navigateAnnotations($event: KeyboardEvent) {
|
||||||
const currentPage = untracked(this.pdf.currentPage);
|
const currentPage = untracked(this.pdf.currentPage);
|
||||||
const activeAnnotations = untracked(this.activeAnnotations);
|
const activeAnnotations = untracked(this.activeAnnotations);
|
||||||
@ -366,7 +368,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
|||||||
const prevPage = this.#prevPageWithAnnotations();
|
const prevPage = this.#prevPageWithAnnotations();
|
||||||
const prevPageAnnotations = this.displayedAnnotations.get(prevPage);
|
const prevPageAnnotations = this.displayedAnnotations.get(prevPage);
|
||||||
|
|
||||||
return this.listingService.selectAnnotations(prevPageAnnotations[prevPageAnnotations.length - 1]);
|
return this.listingService.selectAnnotations(getLast(prevPageAnnotations));
|
||||||
}
|
}
|
||||||
|
|
||||||
const page = this._firstSelectedAnnotation.pageNumber;
|
const page = this._firstSelectedAnnotation.pageNumber;
|
||||||
@ -403,7 +405,7 @@ export class FileWorkloadComponent extends AutoUnsubscribe implements OnInit, On
|
|||||||
for (let i = previousPageIdx; i >= 0; i--) {
|
for (let i = previousPageIdx; i >= 0; i--) {
|
||||||
const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]);
|
const prevPageAnnotations = this.displayedAnnotations.get(this.displayedPages[i]);
|
||||||
if (prevPageAnnotations) {
|
if (prevPageAnnotations) {
|
||||||
this.listingService.selectAnnotations(prevPageAnnotations[prevPageAnnotations.length - 1]);
|
this.listingService.selectAnnotations(getLast(prevPageAnnotations));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,16 @@
|
|||||||
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
import { AnnotationWrapper } from '@models/file/annotation.wrapper';
|
||||||
import { Injectable, OnDestroy } from '@angular/core';
|
import { effect, Injectable, untracked } from '@angular/core';
|
||||||
import { EntitiesService, ListingService, SearchService } from '@iqser/common-ui';
|
import { EntitiesService, ListingService, SearchService } from '@iqser/common-ui';
|
||||||
import { filter, tap } from 'rxjs/operators';
|
|
||||||
import { MultiSelectService } from './multi-select.service';
|
import { MultiSelectService } from './multi-select.service';
|
||||||
import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service';
|
import { PdfViewer } from '../../pdf-viewer/services/pdf-viewer.service';
|
||||||
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
|
import { REDAnnotationManager } from '../../pdf-viewer/services/annotation-manager.service';
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
import { FilterService } from '@iqser/common-ui/lib/filtering';
|
import { FilterService } from '@iqser/common-ui/lib/filtering';
|
||||||
import { SortingService } from '@iqser/common-ui/lib/sorting';
|
import { SortingService } from '@iqser/common-ui/lib/sorting';
|
||||||
|
import { toSignal } from '@angular/core/rxjs-interop';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AnnotationsListingService extends ListingService<AnnotationWrapper> implements OnDestroy {
|
export class AnnotationsListingService extends ListingService<AnnotationWrapper> {
|
||||||
readonly #subscriptions: Subscription;
|
readonly selectedLength = toSignal(this.selectedLength$);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected readonly _filterService: FilterService,
|
protected readonly _filterService: FilterService,
|
||||||
@ -24,23 +23,22 @@ export class AnnotationsListingService extends ListingService<AnnotationWrapper>
|
|||||||
) {
|
) {
|
||||||
super(_filterService, _searchService, _entitiesService, _sortingService);
|
super(_filterService, _searchService, _entitiesService, _sortingService);
|
||||||
|
|
||||||
this.#subscriptions = this.selectedLength$
|
effect(
|
||||||
.pipe(
|
() => {
|
||||||
filter(length => length > 1),
|
if (this.selectedLength() > 1) {
|
||||||
tap(() => this._multiSelectService.activate()),
|
this._multiSelectService.activate();
|
||||||
)
|
|
||||||
.subscribe();
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
ngOnDestroy() {
|
{ allowSignalWrites: true },
|
||||||
this.#subscriptions.unsubscribe();
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
selectAnnotations(annotations: AnnotationWrapper[] | AnnotationWrapper) {
|
selectAnnotations(annotations: AnnotationWrapper[] | AnnotationWrapper) {
|
||||||
annotations = Array.isArray(annotations) ? annotations : [annotations];
|
annotations = Array.isArray(annotations) ? annotations : [annotations];
|
||||||
const pageNumber = annotations[annotations.length - 1].pageNumber;
|
const pageNumber = annotations[annotations.length - 1].pageNumber;
|
||||||
|
|
||||||
const annotationsToSelect = this._multiSelectService.active() ? [...this.selected, ...annotations] : annotations;
|
const multiSelectActive = untracked(this._multiSelectService.active);
|
||||||
|
const annotationsToSelect = multiSelectActive ? [...this.selected, ...annotations] : annotations;
|
||||||
this.#selectAnnotations(annotationsToSelect, pageNumber);
|
this.#selectAnnotations(annotationsToSelect, pageNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,16 +47,18 @@ export class AnnotationsListingService extends ListingService<AnnotationWrapper>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._multiSelectService.inactive()) {
|
const multiSelectInactive = untracked(this._multiSelectService.inactive);
|
||||||
|
if (multiSelectInactive) {
|
||||||
this._annotationManager.deselect();
|
this._annotationManager.deselect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pageNumber === this._pdf.currentPage()) {
|
const currentPage = untracked(this._pdf.currentPage);
|
||||||
|
if (pageNumber === currentPage) {
|
||||||
return this._annotationManager.jumpAndSelect(annotations);
|
return this._annotationManager.jumpAndSelect(annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._pdf.navigateTo(pageNumber);
|
this._pdf.navigateTo(pageNumber);
|
||||||
// wait for page to be loaded and to draw annotations
|
// wait for page to be loaded and to draw annotations
|
||||||
setTimeout(() => this._annotationManager.jumpAndSelect(annotations), 300);
|
setTimeout(() => this._annotationManager.jumpAndSelect(annotations), 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { computed, Injectable, Signal, signal } from '@angular/core';
|
import { computed, Injectable, Signal, signal, untracked } from '@angular/core';
|
||||||
import { ViewModeService } from './view-mode.service';
|
import { ViewModeService } from './view-mode.service';
|
||||||
import { FilePreviewStateService } from './file-preview-state.service';
|
import { FilePreviewStateService } from './file-preview-state.service';
|
||||||
import { ViewMode, ViewModes } from '@red/domain';
|
import { ViewMode, ViewModes } from '@red/domain';
|
||||||
@ -13,13 +13,17 @@ export class MultiSelectService {
|
|||||||
|
|
||||||
readonly #active = signal(false);
|
readonly #active = signal(false);
|
||||||
|
|
||||||
constructor(protected readonly _viewModeService: ViewModeService, protected readonly _state: FilePreviewStateService) {
|
constructor(
|
||||||
|
protected readonly _viewModeService: ViewModeService,
|
||||||
|
protected readonly _state: FilePreviewStateService,
|
||||||
|
) {
|
||||||
this.active = this.#active.asReadonly();
|
this.active = this.#active.asReadonly();
|
||||||
this.inactive = computed(() => !this.#active());
|
this.inactive = computed(() => !this.#active());
|
||||||
}
|
}
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
if (this.enabled()) {
|
const enabled = untracked(this.enabled);
|
||||||
|
if (enabled) {
|
||||||
this.#active.set(true);
|
this.#active.set(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user