Change Selectable<T> to store selected as a behaviour subject

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/3/head
trivernis 2 years ago
parent d3700932db
commit 4568afe6f9
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,5 +1,5 @@
<mat-card #card (click)="clickEvent.emit(this)" (dblclick)="dblClickEvent.emit(this)" <mat-card #card (click)="clickEvent.emit(this)" (dblclick)="dblClickEvent.emit(this)"
[ngClass]="{'selected': entry.selected}"> [class.selected]="this.entry.selected | async">
<mat-card-content> <mat-card-content>
<app-busy-indicator [busy]="this.loading"> <app-busy-indicator [busy]="this.loading">
<app-file-thumbnail *ngIf="!loading" <app-file-thumbnail *ngIf="!loading"

@ -1,5 +1,4 @@
import { import {
AfterViewChecked,
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
Component, Component,
@ -26,23 +25,22 @@ const LOADING_WORK_KEY = "FILE_THUMBNAIL_LOADING";
styleUrls: ["./file-card.component.scss"], styleUrls: ["./file-card.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class FileCardComponent implements OnInit, OnChanges, OnDestroy, AfterViewChecked { export class FileCardComponent implements OnInit, OnChanges, OnDestroy {
@ViewChild("card") card!: ElementRef; @ViewChild("card") card!: ElementRef;
@Input() public entry!: Selectable<File>; @Input() public entry!: Selectable<File>;
@Input() public fileChanged: BehaviorSubject<void> = new BehaviorSubject<void>(undefined); @Input() public fileChanged: BehaviorSubject<void> = new BehaviorSubject<void>(undefined);
@Output() clickEvent = new EventEmitter<FileCardComponent>(); @Output() clickEvent = new EventEmitter<FileCardComponent>();
@Output() dblClickEvent = new EventEmitter<FileCardComponent>(); @Output() dblClickEvent = new EventEmitter<FileCardComponent>();
public loading = false; public loading = false;
private cachedId: number | undefined; private cachedId: number | undefined;
private workId: number | undefined; private workId: number | undefined;
private selectedPrevious = false;
constructor(private changeDetector: ChangeDetectorRef, private schedulingService: SchedulingService) { constructor(private changeDetector: ChangeDetectorRef, private schedulingService: SchedulingService) {
} }
async ngOnInit() { async ngOnInit() {
this.cachedId = this.entry.data.id; this.cachedId = this.entry.data.id;
this.selectedPrevious = this.entry.selected;
this.setImageDelayed(); this.setImageDelayed();
} }
@ -56,13 +54,6 @@ export class FileCardComponent implements OnInit, OnChanges, OnDestroy, AfterVie
} }
} }
public ngAfterViewChecked(): void {
if (this.entry.selected != this.selectedPrevious) {
this.selectedPrevious = this.entry.selected;
this.changeDetector.markForCheck();
}
}
public ngOnDestroy(): void { public ngOnDestroy(): void {
if (this.workId) { if (this.workId) {
this.schedulingService.cancelWork(LOADING_WORK_KEY, this.workId); this.schedulingService.cancelWork(LOADING_WORK_KEY, this.workId);

@ -80,14 +80,14 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit {
setSelectedFile(clickedEntry: Selectable<File>) { setSelectedFile(clickedEntry: Selectable<File>) {
if (!(this.shiftClicked || this.ctrlClicked) && this.selectedEntries.length > 0) { if (!(this.shiftClicked || this.ctrlClicked) && this.selectedEntries.length > 0) {
this.selectedEntries.forEach(entry => { this.selectedEntries.forEach(entry => {
if (entry !== clickedEntry) entry.selected = false; if (entry !== clickedEntry) entry.unselect();
}); });
this.selectedEntries = []; this.selectedEntries = [];
} }
if (this.shiftClicked && this.selectedEntries.length > 0) { if (this.shiftClicked && this.selectedEntries.length > 0) {
this.handleShiftSelect(clickedEntry); this.handleShiftSelect(clickedEntry);
} else { } else {
clickedEntry.selected = !clickedEntry.selected; clickedEntry.selected.next(!clickedEntry.selected.value);
if (!clickedEntry.selected) { if (!clickedEntry.selected) {
const index = this.selectedEntries.indexOf(clickedEntry); const index = this.selectedEntries.indexOf(clickedEntry);
if (index > -1) { if (index > -1) {
@ -213,7 +213,7 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit {
this.virtualScroll?.scrollToIndex(scrollToIndex); this.virtualScroll?.scrollToIndex(scrollToIndex);
if (selectedEntry) { if (selectedEntry) {
selectedEntry.selected = true; selectedEntry.select();
this.selectedEntries.push(selectedEntry); this.selectedEntries.push(selectedEntry);
} }
} }
@ -225,7 +225,7 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit {
const newSelection: Selectable<File>[] = this.gridEntries.filter( const newSelection: Selectable<File>[] = this.gridEntries.filter(
entry => this.selectedEntries.findIndex( entry => this.selectedEntries.findIndex(
e => e.data.id == entry.data.id) >= 0); e => e.data.id == entry.data.id) >= 0);
newSelection.forEach(entry => entry.selected = true); newSelection.forEach(entry => entry.select());
this.selectedEntries = newSelection; this.selectedEntries = newSelection;
} }
@ -240,7 +240,7 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit {
for (const gridEntry of this.gridEntries) { for (const gridEntry of this.gridEntries) {
if (found) { if (found) {
gridEntry.selected = true; gridEntry.select();
this.selectedEntries.push(gridEntry); this.selectedEntries.push(gridEntry);
if (gridEntry === clickedEntry || gridEntry == lastEntry) { if (gridEntry === clickedEntry || gridEntry == lastEntry) {
return; return;
@ -248,7 +248,7 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit {
} else if (gridEntry === lastEntry || gridEntry === clickedEntry) { } else if (gridEntry === lastEntry || gridEntry === clickedEntry) {
found = true; found = true;
if (gridEntry === clickedEntry) { if (gridEntry === clickedEntry) {
gridEntry.selected = true; gridEntry.select();
this.selectedEntries.push(gridEntry); this.selectedEntries.push(gridEntry);
} }
} }

@ -1,12 +1,18 @@
import {BehaviorSubject} from "rxjs";
export class Selectable<T> { export class Selectable<T> {
constructor(public data: T, public selected: boolean) {
public selected: BehaviorSubject<boolean>;
constructor(public data: T, selected: boolean) {
this.selected = new BehaviorSubject<boolean>(selected);
} }
public select() { public select() {
this.selected = true; this.selected.next(true);
} }
public unselect() { public unselect() {
this.selected = false; this.selected.next(false);
} }
} }

Loading…
Cancel
Save