Change change detection of file gallery and metadata

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/3/head
trivernis 3 years ago
parent 232c12ed8b
commit 6073a6517f
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,8 +1,8 @@
<app-image-viewer *ngIf="getContentType() === 'image' && contentUrl" [imageUrl]="contentUrl"></app-image-viewer> <app-image-viewer *ngIf="contentType === 'image' && contentUrl" [imageUrl]="contentUrl"></app-image-viewer>
<app-video-viewer *ngIf="getContentType() === 'video' && this.blobUrl" [blobUrl]="this.blobUrl!"></app-video-viewer> <app-video-viewer *ngIf="contentType === 'video' && this.blobUrl" [blobUrl]="this.blobUrl!"></app-video-viewer>
<app-audio-viewer *ngIf="getContentType() === 'audio' && this.blobUrl" [blobUrl]="this.blobUrl!"></app-audio-viewer> <app-audio-viewer *ngIf="contentType === 'audio' && this.blobUrl" [blobUrl]="this.blobUrl!"></app-audio-viewer>
<div *ngIf="getContentType() === 'other'" class="download-prompt"> <div *ngIf="contentType === 'other'" class="download-prompt">
<span>Unsupported content type <b>{{this.file.mimeType}}</b></span> <span>Unsupported content type <b>{{this.file.mimeType}}</b></span>
<button (click)="this.downloadContent()" color="primary" mat-flat-button>Download</button> <button (click)="this.downloadContent()" color="primary" mat-flat-button>Download</button>
</div> </div>

@ -1,5 +1,6 @@
import { import {
AfterViewInit, AfterViewInit,
ChangeDetectionStrategy,
Component, Component,
Input, Input,
OnChanges, OnChanges,
@ -11,25 +12,23 @@ import {SafeResourceUrl} from "@angular/platform-browser";
import {File} from "../../../../../api/models/File"; 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 { import {ErrorBrokerService} from "../../../../services/error-broker/error-broker.service";
ErrorBrokerService import {BusyIndicatorComponent} from "../../app-common/busy-indicator/busy-indicator.component";
} from "../../../../services/error-broker/error-broker.service";
import {
BusyIndicatorComponent
} from "../../app-common/busy-indicator/busy-indicator.component";
type ContentType = "image" | "video" | "audio" | "other"; type ContentType = "image" | "video" | "audio" | "other";
@Component({ @Component({
selector: "app-content-viewer", selector: "app-content-viewer",
templateUrl: "./content-viewer.component.html", templateUrl: "./content-viewer.component.html",
styleUrls: ["./content-viewer.component.scss"] styleUrls: ["./content-viewer.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class ContentViewerComponent implements AfterViewInit, OnChanges, OnDestroy { export class ContentViewerComponent implements AfterViewInit, OnChanges, OnDestroy {
@Input() file!: File; @Input() file!: File;
public contentUrl: SafeResourceUrl | undefined; public contentUrl: SafeResourceUrl | undefined;
public blobUrl: SafeResourceUrl | undefined; public blobUrl: SafeResourceUrl | undefined;
public contentType: ContentType = "other";
@ViewChild(BusyIndicatorComponent) busyIndicator!: BusyIndicatorComponent; @ViewChild(BusyIndicatorComponent) busyIndicator!: BusyIndicatorComponent;
@ -40,7 +39,8 @@ export class ContentViewerComponent implements AfterViewInit, OnChanges, OnDestr
} }
public async ngAfterViewInit() { public async ngAfterViewInit() {
if (["audio", "video"].includes(this.getContentType())) { this.contentType = this.getContentType();
if (["audio", "video"].includes(this.contentType)) {
await this.loadBlobUrl(); await this.loadBlobUrl();
} else { } else {
this.contentUrl = this.fileService.buildContentUrl(this.file); this.contentUrl = this.fileService.buildContentUrl(this.file);
@ -49,8 +49,9 @@ export class ContentViewerComponent implements AfterViewInit, OnChanges, OnDestr
public async ngOnChanges(changes: SimpleChanges) { public async ngOnChanges(changes: SimpleChanges) {
if (changes["file"]) { if (changes["file"]) {
if (["audio", "video"].includes( this.contentType = this.getContentType();
this.getContentType()) && this.busyIndicator) {
if (["audio", "video"].includes(this.contentType) && this.busyIndicator) {
await this.loadBlobUrl(); await this.loadBlobUrl();
} else { } else {
this.contentUrl = this.fileService.buildContentUrl(this.file); this.contentUrl = this.fileService.buildContentUrl(this.file);
@ -63,23 +64,6 @@ export class ContentViewerComponent implements AfterViewInit, OnChanges, OnDestr
this.unloadBlobUrl(); this.unloadBlobUrl();
} }
public getContentType(): ContentType {
let mimeParts = this.file.mimeType.split("/");
const type = mimeParts.shift() ?? "other";
const subtype = mimeParts.shift() ?? "*";
switch (type) {
case "image":
return "image";
case "video":
return "video";
case "audio":
return "audio";
default:
return "other";
}
}
public async downloadContent() { public async downloadContent() {
const path = await FileHelper.getFileDownloadLocation(this.file); const path = await FileHelper.getFileDownloadLocation(this.file);
@ -103,6 +87,22 @@ export class ContentViewerComponent implements AfterViewInit, OnChanges, OnDestr
}); });
} }
private getContentType(): ContentType {
let mimeParts = this.file.mimeType.split("/");
const type = mimeParts.shift() ?? "other";
switch (type) {
case "image":
return "image";
case "video":
return "video";
case "audio":
return "audio";
default:
return "other";
}
}
private unloadBlobUrl() { private unloadBlobUrl() {
if (this.blobUrl) { if (this.blobUrl) {
URL?.revokeObjectURL(this.blobUrl as string); URL?.revokeObjectURL(this.blobUrl as string);

@ -3,15 +3,21 @@
<h1>File Metadata</h1> <h1>File Metadata</h1>
<mat-divider></mat-divider> <mat-divider></mat-divider>
</div> </div>
<app-busy-indicator [blurBackground]="true" [busy]="this.loading" [darkenBackground]="false"> <app-busy-indicator [blurBackground]="true" [darkenBackground]="false">
<div class="file-metadata-entries-scroll-container"> <div class="file-metadata-entries-scroll-container">
<div class="file-metadata-entries"> <div class="file-metadata-entries">
<app-editable-metadata-entry *ngIf="fileMetadata" attributeName="Name" [value]="fileMetadata.name ?? ''" (valueChangeEvent)="this.saveFileName($event)"></app-editable-metadata-entry> <app-editable-metadata-entry (valueChangeEvent)="this.saveFileName($event)"
*ngIf="fileMetadata"
[value]="fileMetadata.name ?? ''"
attributeName="Name"></app-editable-metadata-entry>
<app-metadata-entry attributeName="Content Descriptor (CD)">{{file.cd}}</app-metadata-entry> <app-metadata-entry attributeName="Content Descriptor (CD)">{{file.cd}}</app-metadata-entry>
<app-metadata-entry attributeName="Mime Type">{{file.mimeType}}</app-metadata-entry> <app-metadata-entry attributeName="Mime Type">{{file.mimeType}}</app-metadata-entry>
<app-metadata-entry *ngIf="fileMetadata" attributeName="Imported at">{{fileMetadata.import_time.toLocaleString()}}</app-metadata-entry> <app-metadata-entry *ngIf="fileMetadata"
<app-metadata-entry *ngIf="fileMetadata" attributeName="Created at">{{fileMetadata.creation_time.toLocaleString()}}</app-metadata-entry> attributeName="Imported at">{{fileMetadata.import_time.toLocaleString()}}</app-metadata-entry>
<app-metadata-entry *ngIf="fileMetadata" attributeName="Changed at">{{fileMetadata.change_time.toLocaleString()}}</app-metadata-entry> <app-metadata-entry *ngIf="fileMetadata"
attributeName="Created at">{{fileMetadata.creation_time.toLocaleString()}}</app-metadata-entry>
<app-metadata-entry *ngIf="fileMetadata"
attributeName="Changed at">{{fileMetadata.change_time.toLocaleString()}}</app-metadata-entry>
</div> </div>
</div> </div>
</app-busy-indicator> </app-busy-indicator>

@ -1,48 +1,45 @@
import { import {ChangeDetectionStrategy, Component, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from "@angular/core";
Component,
Input,
OnChanges,
OnInit,
SimpleChanges
} from "@angular/core";
import {File} from "../../../../../api/models/File"; import {File} from "../../../../../api/models/File";
import {FileService} from "../../../../services/file/file.service"; import {FileService} from "../../../../services/file/file.service";
import {FileMetadata} from "../../../../../api/api-types/files"; import {FileMetadata} from "../../../../../api/api-types/files";
import {BusyIndicatorComponent} from "../../app-common/busy-indicator/busy-indicator.component";
@Component({ @Component({
selector: "app-file-metadata", selector: "app-file-metadata",
templateUrl: "./file-metadata.component.html", templateUrl: "./file-metadata.component.html",
styleUrls: ["./file-metadata.component.scss"] styleUrls: ["./file-metadata.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class FileMetadataComponent implements OnInit, OnChanges { export class FileMetadataComponent implements OnInit, OnChanges {
@Input() file!: File; @Input() file!: File;
public fileMetadata: FileMetadata | undefined; public fileMetadata: FileMetadata | undefined;
public loading = false;
@ViewChild(BusyIndicatorComponent) busyIndicator!: BusyIndicatorComponent;
constructor(private fileService: FileService) { constructor(private fileService: FileService) {
} }
public async ngOnInit() { public async ngOnInit() {
this.loading = true; await this.busyIndicator.wrapAsyncOperation(async () => {
this.fileMetadata = await this.fileService.getFileMetadata(this.file.id); this.fileMetadata = await this.fileService.getFileMetadata(this.file.id);
this.loading = false; });
} }
public async ngOnChanges(changes:SimpleChanges) { public async ngOnChanges(changes: SimpleChanges) {
if (changes["file"] && (!this.fileMetadata || this.fileMetadata.file_id != this.file.id)) { if (changes["file"] && (!this.fileMetadata || this.fileMetadata.file_id != this.file.id)) {
this.loading = true; await this.busyIndicator.wrapAsyncOperation(async () => {
this.fileMetadata = await this.fileService.getFileMetadata(this.file.id); this.fileMetadata = await this.fileService.getFileMetadata(this.file.id);
this.loading = false; });
} }
} }
public async saveFileName(name: string) { public async saveFileName(name: string) {
this.loading = true; await this.busyIndicator.wrapAsyncOperation(async () => {
const newFile = await this.fileService.updateFileName(this.file.id, name); const newFile = await this.fileService.updateFileName(this.file.id, name);
if (this.fileMetadata) { if (this.fileMetadata) {
this.fileMetadata.name = newFile.name; this.fileMetadata.name = newFile.name;
} }
this.loading = false; });
} }
} }

Loading…
Cancel
Save