Fix file status not updating visually

TG-107 #closed

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/18/head
trivernis 2 years ago
parent f033589fcb
commit 71d4287246
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,9 +1,14 @@
import {FileBasicData, FileStatus} from "../api-types/files"; import {FileBasicData, FileStatus} from "../api-types/files";
import {BehaviorSubject, Observable} from "rxjs";
export class File { export class File {
private statusSubject: BehaviorSubject<FileStatus>;
constructor( constructor(
private basicData: FileBasicData, private basicData: FileBasicData,
) { ) {
this.statusSubject = new BehaviorSubject(basicData.status);
} }
public get rawData(): FileBasicData { public get rawData(): FileBasicData {
@ -18,15 +23,20 @@ export class File {
return this.basicData.cd; return this.basicData.cd;
} }
public get status(): FileStatus { public get status(): Observable<FileStatus> {
return this.basicData.status; return this.statusSubject.asObservable();
}
public get mimeType(): string {
return this.basicData.mime_type;
} }
public set status(value: FileStatus) { public setStatus(value: FileStatus) {
this.basicData.status = value; this.basicData.status = value;
this.statusSubject.next(value);
} }
public get mimeType(): string { public getStatus(): FileStatus {
return this.basicData.mime_type; return this.basicData.status;
} }
} }

@ -56,7 +56,7 @@ export class FileActionBaseComponent {
if (changeConfirmed) { if (changeConfirmed) {
await this.errorBroker.try(async () => { await this.errorBroker.try(async () => {
const newFile = await this.fileService.updateFileStatus(files[0].id, status); const newFile = await this.fileService.updateFileStatus(files[0].id, status);
files[0].status = newFile.status; files[0].setStatus(newFile.getStatus());
}); });
} }
} else { } else {
@ -72,7 +72,7 @@ export class FileActionBaseComponent {
files, files,
(file) => this.errorBroker.try(async () => { (file) => this.errorBroker.try(async () => {
const newFile = await this.fileService.updateFileStatus(file.id, status); const newFile = await this.fileService.updateFileStatus(file.id, status);
file.status = newFile.status; file.setStatus(newFile.getStatus());
}) })
); );
} }

@ -5,7 +5,6 @@
<app-file-thumbnail <app-file-thumbnail
(loadEnd)="this.loading = false" (loadEnd)="this.loading = false"
[class.hidden]="this.loading" [class.hidden]="this.loading"
[fileChanged]="this.fileChanged"
[file]="this.entry.data" [file]="this.entry.data"
class="entry-image"></app-file-thumbnail> class="entry-image"></app-file-thumbnail>
</app-busy-indicator> </app-busy-indicator>

@ -13,7 +13,6 @@ import {
import {File} from "../../../../../api/models/File"; import {File} from "../../../../../api/models/File";
import {Selectable} from "../../../../models/Selectable"; import {Selectable} from "../../../../models/Selectable";
import {SchedulingService} from "../../../../services/scheduling/scheduling.service"; import {SchedulingService} from "../../../../services/scheduling/scheduling.service";
import {BehaviorSubject} from "rxjs";
const LOADING_WORK_KEY = "FILE_THUMBNAIL_LOADING"; const LOADING_WORK_KEY = "FILE_THUMBNAIL_LOADING";
@ -26,7 +25,6 @@ const LOADING_WORK_KEY = "FILE_THUMBNAIL_LOADING";
export class FileCardComponent implements OnInit, OnChanges, OnDestroy { export class FileCardComponent implements OnInit, OnChanges, OnDestroy {
@Input() public entry!: Selectable<File>; @Input() public entry!: Selectable<File>;
@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>();
@ -47,9 +45,6 @@ export class FileCardComponent implements OnInit, OnChanges, OnDestroy {
this.cachedId = this.entry.data.id; this.cachedId = this.entry.data.id;
this.loading = true; this.loading = true;
} }
if (changes["fileChanged"]) {
this.fileChanged.subscribe(() => this.changeDetector.markForCheck());
}
} }
public ngOnDestroy(): void { public ngOnDestroy(): void {
@ -62,19 +57,4 @@ export class FileCardComponent implements OnInit, OnChanges, OnDestroy {
console.debug(this.entry.data.id); console.debug(this.entry.data.id);
this.clickEvent.emit(this); this.clickEvent.emit(this);
} }
private setImageDelayed() {
if (this.workId) {
this.schedulingService.cancelWork(LOADING_WORK_KEY, this.workId);
}
this.loading = true;
this.workId = this.schedulingService.addWork(
LOADING_WORK_KEY,
async () => {
await this.schedulingService.delay(0);
this.loading = false;
this.changeDetector.markForCheck();
}
);
}
} }

@ -60,11 +60,11 @@ export class FileContextMenuComponent extends FileActionBaseComponent implements
this.actionDelete = this.actionArchive = this.actionImported = this.actionRestore = false; this.actionDelete = this.actionArchive = this.actionImported = this.actionRestore = false;
for (const file of this.files) { for (const file of this.files) {
this.actionDeletePermantently &&= file.status === "Deleted"; this.actionDeletePermantently &&= file.getStatus() === "Deleted";
this.actionDelete ||= file.status !== "Deleted"; this.actionDelete ||= file.getStatus() !== "Deleted";
this.actionArchive ||= file.status !== "Archived" && file.status !== "Deleted"; this.actionArchive ||= file.getStatus() !== "Archived" && file.getStatus() !== "Deleted";
this.actionImported ||= file.status !== "Imported" && file.status !== "Deleted"; this.actionImported ||= file.getStatus() !== "Imported" && file.getStatus() !== "Deleted";
this.actionRestore ||= file.status === "Deleted"; this.actionRestore ||= file.getStatus() === "Deleted";
} }
} }
} }

@ -24,11 +24,10 @@
<div #previewStripContainer class="file-preview-strip-container"> <div #previewStripContainer class="file-preview-strip-container">
<div *ngFor="let entry of this.previewedEntries; trackBy: trackByFileId" class="file-item"> <div *ngFor="let entry of this.previewedEntries; trackBy: trackByFileId" class="file-item">
<app-file-card (clickEvent)="onEntrySelect($event.entry)" *ngIf="entry" <app-file-card (clickEvent)="onEntrySelect($event.entry)" *ngIf="entry"
[entry]="entry" [fileChanged]="this.fileChanged"></app-file-card> [entry]="entry"></app-file-card>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<app-file-context-menu #fileContextMenu <app-file-context-menu #fileContextMenu
(fileDeleted)="this.fileDeleted.emit($event)" (fileDeleted)="this.fileDeleted.emit($event)"></app-file-context-menu>
(fileStatusChange)="this.onFileStatusChange()"></app-file-context-menu>

@ -19,7 +19,6 @@ import {SafeResourceUrl} from "@angular/platform-browser";
import {Selectable} from "../../../../../models/Selectable"; import {Selectable} from "../../../../../models/Selectable";
import {TabService} from "../../../../../services/tab/tab.service"; import {TabService} from "../../../../../services/tab/tab.service";
import {Key} from "w3c-keys"; import {Key} from "w3c-keys";
import {BehaviorSubject} from "rxjs";
@Component({ @Component({
selector: "app-file-gallery", selector: "app-file-gallery",
@ -43,7 +42,6 @@ export class FileGalleryComponent implements OnChanges, OnInit, AfterViewInit, A
public entries: Selectable<File>[] = []; public entries: Selectable<File>[] = [];
public selectedFile: Selectable<File> | undefined; public selectedFile: Selectable<File> | undefined;
public fileContentUrl: SafeResourceUrl | undefined; public fileContentUrl: SafeResourceUrl | undefined;
public fileChanged = new BehaviorSubject<void>(undefined);
public selectedIndex = 0; public selectedIndex = 0;
public imageViewHeightPercent = 80; public imageViewHeightPercent = 80;
@ -182,10 +180,6 @@ export class FileGalleryComponent implements OnChanges, OnInit, AfterViewInit, A
return item?.data.id; return item?.data.id;
} }
public onFileStatusChange(): void {
this.fileChanged.next();
}
public togglePreviewStrip(): void { public togglePreviewStrip(): void {
if (this.previewStripVisible) { if (this.previewStripVisible) {
this.imageViewHeightPercent = 100; this.imageViewHeightPercent = 100;

@ -14,7 +14,7 @@
(contextmenu)="this.selectEntryWhenNotSelected(gridEntry); fileContextMenu.onContextMenu($event, this.getSelectedFiles())" (contextmenu)="this.selectEntryWhenNotSelected(gridEntry); fileContextMenu.onContextMenu($event, this.getSelectedFiles())"
(dblClickEvent)="fileOpen.emit($event.entry.data)" (dblClickEvent)="fileOpen.emit($event.entry.data)"
*ngIf="gridEntry" *ngIf="gridEntry"
[entry]="gridEntry" [fileChanged]="this.fileChanged"></app-file-card> [entry]="gridEntry"></app-file-card>
<div *ngIf="!gridEntry" class="empty-grid-entry"></div> <div *ngIf="!gridEntry" class="empty-grid-entry"></div>
</ng-container> </ng-container>
</div> </div>
@ -23,8 +23,7 @@
</div> </div>
<app-file-context-menu #fileContextMenu <app-file-context-menu #fileContextMenu
(fileDeleted)="this.fileDeleted.emit($event)" (fileDeleted)="this.fileDeleted.emit($event)">
(fileStatusChange)="this.onFileStatusChange()">
<button (click)="this.fileOpen.emit(fileContextMenu.files[0])" <button (click)="this.fileOpen.emit(fileContextMenu.files[0])"
*ngIf="fileContextMenu.files.length === 1" *ngIf="fileContextMenu.files.length === 1"
content-before="" content-before=""

@ -20,7 +20,6 @@ import {TabService} from "../../../../../services/tab/tab.service";
import {FileService} from "../../../../../services/file/file.service"; import {FileService} from "../../../../../services/file/file.service";
import {Selectable} from "../../../../../models/Selectable"; import {Selectable} from "../../../../../models/Selectable";
import {Key} from "w3c-keys"; import {Key} from "w3c-keys";
import {BehaviorSubject} from "rxjs";
import {LoggingService} from "../../../../../services/logging/logging.service"; import {LoggingService} from "../../../../../services/logging/logging.service";
@Component({ @Component({
@ -41,7 +40,6 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit, Afte
@ViewChild("virtualScrollGrid") virtualScroll!: CdkVirtualScrollViewport; @ViewChild("virtualScrollGrid") virtualScroll!: CdkVirtualScrollViewport;
@ViewChild("inner") inner!: ElementRef<HTMLDivElement>; @ViewChild("inner") inner!: ElementRef<HTMLDivElement>;
public fileChanged = new BehaviorSubject<void>(undefined);
public selectedEntries: Selectable<File>[] = []; public selectedEntries: Selectable<File>[] = [];
public partitionedGridEntries: (Selectable<File> | undefined)[][] = []; public partitionedGridEntries: (Selectable<File> | undefined)[][] = [];
@ -195,10 +193,6 @@ export class FileGridComponent implements OnChanges, OnInit, AfterViewInit, Afte
return item?.data.id; return item?.data.id;
} }
public onFileStatusChange(): void {
this.fileChanged.next();
}
public calculateColumnCount() { public calculateColumnCount() {
if (this.inner && this.inner.nativeElement) { if (this.inner && this.inner.nativeElement) {
const width = Math.abs(this.inner.nativeElement.clientWidth); const width = Math.abs(this.inner.nativeElement.clientWidth);

@ -71,7 +71,7 @@ export class FileMultiviewComponent extends FileActionBaseComponent implements A
let deletePermanently = true; let deletePermanently = true;
for (const file of files) { for (const file of files) {
deletePermanently &&= file.status === "Deleted"; deletePermanently &&= file.getStatus() === "Deleted";
} }
if (deletePermanently) { if (deletePermanently) {

@ -13,7 +13,7 @@
<ng-icon *ngIf="fileType === 'audio'" name="mat-audiotrack"></ng-icon> <ng-icon *ngIf="fileType === 'audio'" name="mat-audiotrack"></ng-icon>
<ng-icon *ngIf="fileType === 'text'" name="mat-description"></ng-icon> <ng-icon *ngIf="fileType === 'text'" name="mat-description"></ng-icon>
</div> </div>
<div *ngIf="file.status !== 'Archived'" class="file-status-icon"> <div *ngIf="(file.status | async) !== 'Archived'" class="file-status-icon">
<ng-icon *ngIf="file.status === 'Deleted'" name="mat-auto-delete"></ng-icon> <ng-icon *ngIf="(file.status | async) === 'Deleted'" name="mat-auto-delete"></ng-icon>
<ng-icon *ngIf="file.status === 'Imported'" name="mat-fiber-new"></ng-icon> <ng-icon *ngIf="(file.status | async) === 'Imported'" name="mat-fiber-new"></ng-icon>
</div> </div>

@ -1,5 +1,4 @@
import { import {
AfterViewChecked,
AfterViewInit, AfterViewInit,
ChangeDetectionStrategy, ChangeDetectionStrategy,
ChangeDetectorRef, ChangeDetectorRef,
@ -14,7 +13,6 @@ import {File} from "../../../../../api/models/File";
import {FileService} from "../../../../services/file/file.service"; import {FileService} from "../../../../services/file/file.service";
import {FileHelper} from "../../../../services/file/file.helper"; import {FileHelper} from "../../../../services/file/file.helper";
import {SafeResourceUrl} from "@angular/platform-browser"; import {SafeResourceUrl} from "@angular/platform-browser";
import {BehaviorSubject} from "rxjs";
@Component({ @Component({
selector: "app-file-thumbnail", selector: "app-file-thumbnail",
@ -22,10 +20,9 @@ import {BehaviorSubject} from "rxjs";
styleUrls: ["./file-thumbnail.component.scss"], styleUrls: ["./file-thumbnail.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class FileThumbnailComponent implements OnChanges, AfterViewInit, AfterViewChecked { export class FileThumbnailComponent implements OnChanges, AfterViewInit {
@Input() file!: File; @Input() file!: File;
@Input() public fileChanged: BehaviorSubject<void> = new BehaviorSubject<void>(undefined);
@Output() loadEnd = new EventEmitter<void>(); @Output() loadEnd = new EventEmitter<void>();
public thumbUrl: SafeResourceUrl | undefined; public thumbUrl: SafeResourceUrl | undefined;
@ -34,7 +31,6 @@ export class FileThumbnailComponent implements OnChanges, AfterViewInit, AfterVi
public displayError = false; public displayError = false;
private supportedThumbnailTypes = ["image", "video"]; private supportedThumbnailTypes = ["image", "video"];
private previousStatus = "imported";
constructor(private changeDetector: ChangeDetectorRef, private fileService: FileService) { constructor(private changeDetector: ChangeDetectorRef, private fileService: FileService) {
} }
@ -45,13 +41,6 @@ export class FileThumbnailComponent implements OnChanges, AfterViewInit, AfterVi
} }
} }
public ngAfterViewChecked(): void {
if (this.file && this.file.status != this.previousStatus) {
this.previousStatus = this.file.status;
this.changeDetector.markForCheck();
}
}
public async ngOnChanges(changes: SimpleChanges) { public async ngOnChanges(changes: SimpleChanges) {
if (changes["file"]) { if (changes["file"]) {
this.thumbUrl = this.fileService.buildThumbnailUrl(this.file, this.thumbUrl = this.fileService.buildThumbnailUrl(this.file,
@ -61,9 +50,6 @@ export class FileThumbnailComponent implements OnChanges, AfterViewInit, AfterVi
this.thumbnailSupported = this.getThumbnailSupported(); this.thumbnailSupported = this.getThumbnailSupported();
this.displayError = false; this.displayError = false;
} }
if (changes["fileChanged"]) {
this.fileChanged.subscribe(() => this.changeDetector.markForCheck());
}
} }
public onImageLoadError(): void { public onImageLoadError(): void {

Loading…
Cancel
Save