Change thumbnails and images to be directly retrieved from custom schemes

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent dcd20fd758
commit ef9ce713da

@ -1580,12 +1580,13 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]] [[package]]
name = "mediarepo-api" name = "mediarepo-api"
version = "0.6.0" version = "0.7.0"
source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=ddebf4bf0c3e96ede64182ff52bd84f134acc33a#ddebf4bf0c3e96ede64182ff52bd84f134acc33a" source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=acda7307dc58e9ac489b12bab61561a1cbf951eb#acda7307dc58e9ac489b12bab61561a1cbf951eb"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"chrono", "chrono",
"directories", "directories",
"futures",
"mime_guess", "mime_guess",
"parking_lot", "parking_lot",
"rmp-ipc", "rmp-ipc",
@ -1597,6 +1598,7 @@ dependencies = [
"tokio", "tokio",
"toml", "toml",
"tracing", "tracing",
"url",
] ]
[[package]] [[package]]

@ -30,7 +30,7 @@ features = ["env-filter"]
[dependencies.mediarepo-api] [dependencies.mediarepo-api]
git = "https://github.com/Trivernis/mediarepo-api.git" git = "https://github.com/Trivernis/mediarepo-api.git"
rev = "ddebf4bf0c3e96ede64182ff52bd84f134acc33a" rev = "acda7307dc58e9ac489b12bab61561a1cbf951eb"
features = ["tauri-plugin"] features = ["tauri-plugin"]
[features] [features]

@ -61,7 +61,7 @@
} }
], ],
"security": { "security": {
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self' once:" "csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self' once: thumb: content:"
} }
} }
} }

@ -1,6 +1,6 @@
import { import {
Component, Component,
EventEmitter, EventEmitter, Inject,
Input, Input,
OnChanges, OnChanges,
OnInit, OnInit,
@ -9,7 +9,7 @@ import {
} from '@angular/core'; } from '@angular/core';
import {File} from "../../../models/File"; import {File} from "../../../models/File";
import {FileService} from "../../../services/file/file.service"; import {FileService} from "../../../services/file/file.service";
import {SafeResourceUrl} from "@angular/platform-browser"; import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser";
import {ErrorBrokerService} from "../../../services/error-broker/error-broker.service"; import {ErrorBrokerService} from "../../../services/error-broker/error-broker.service";
import {Selectable} from "../../../models/Selectable"; import {Selectable} from "../../../models/Selectable";
@ -26,32 +26,18 @@ export class FileGalleryEntryComponent implements OnInit, OnChanges {
private cachedFile: File | undefined; private cachedFile: File | undefined;
constructor(private fileService: FileService, private errorBroker: ErrorBrokerService) { constructor(@Inject(DomSanitizer) private sanitizer: DomSanitizer, private fileService: FileService, private errorBroker: ErrorBrokerService) {
} }
async ngOnChanges(changes: SimpleChanges): Promise<void> { async ngOnChanges(changes: SimpleChanges): Promise<void> {
if (changes["file"] && (!this.cachedFile || this.file.data.hash !== this.cachedFile!.hash)) { // handle changes to the file when the component is not destroyed if (changes["file"] && (!this.cachedFile || this.file.data.hash !== this.cachedFile!.hash)) { // handle changes to the file when the component is not destroyed
this.cachedFile = this.file.data; this.cachedFile = this.file.data;
this.contentUrl = undefined; this.contentUrl = this.fileService.buildThumbnailUrl(this.file.data, 250, 250);
await this.loadImage();
} }
} }
async ngOnInit() { async ngOnInit() {
this.cachedFile = this.file.data; this.cachedFile = this.file.data;
await this.loadImage(); this.contentUrl = this.fileService.buildThumbnailUrl(this.file.data, 250, 250);
}
async loadImage() {
try {
const hash = this.file.data.hash;
const contentUrl = await this.fileService.getFileThumbnail(this.file.data, 250, 250);
if (this.file.data.hash === hash) { // avoid issues with changed files
this.contentUrl = contentUrl;
}
} catch (err) {
this.errorBroker.showError(err);
}
} }
} }

@ -89,9 +89,7 @@ export class FileGalleryComponent implements OnChanges, OnInit {
*/ */
async loadSelectedFile() { async loadSelectedFile() {
if (this.selectedFile) { if (this.selectedFile) {
this.fileContentUrl = undefined; this.fileContentUrl = this.fileService.buildContentUrl(this.selectedFile.data)
this.fileContentUrl = await this.fileService.readFile(
this.selectedFile.data);
} }
} }

@ -5,7 +5,8 @@ import {
Input, Input,
OnChanges, OnChanges,
OnInit, OnInit,
Output, SimpleChanges, Output,
SimpleChanges,
ViewChild ViewChild
} from '@angular/core'; } from '@angular/core';
import {File} from "../../../models/File"; import {File} from "../../../models/File";
@ -15,45 +16,34 @@ import {SafeResourceUrl} from "@angular/platform-browser";
import {GridEntry} from "./GridEntry"; import {GridEntry} from "./GridEntry";
@Component({ @Component({
selector: 'app-file-grid-entry', selector: 'app-file-grid-entry',
templateUrl: './file-grid-entry.component.html', templateUrl: './file-grid-entry.component.html',
styleUrls: ['./file-grid-entry.component.scss'] styleUrls: ['./file-grid-entry.component.scss']
}) })
export class FileGridEntryComponent implements OnInit, OnChanges { export class FileGridEntryComponent implements OnInit, OnChanges {
@ViewChild("card") card!: ElementRef; @ViewChild("card") card!: ElementRef;
@Input() public gridEntry!: GridEntry; @Input() public gridEntry!: GridEntry;
@Output() clickEvent = new EventEmitter<FileGridEntryComponent>(); @Output() clickEvent = new EventEmitter<FileGridEntryComponent>();
@Output() dblClickEvent = new EventEmitter<FileGridEntryComponent>(); @Output() dblClickEvent = new EventEmitter<FileGridEntryComponent>();
contentUrl: SafeResourceUrl | undefined; contentUrl: SafeResourceUrl | undefined;
private cachedFile: File | undefined; private cachedFile: File | undefined;
constructor(private fileService: FileService, private errorBroker: ErrorBrokerService) { constructor(private fileService: FileService, private errorBroker: ErrorBrokerService) {
} }
async ngOnInit() {
this.cachedFile = this.gridEntry.file;
await this.loadImage();
}
async ngOnChanges(changes: SimpleChanges) {
if (changes["file"] && (!this.cachedFile || this.gridEntry.file.hash !== this.cachedFile.hash)) {
this.cachedFile = this.gridEntry.file;
await this.loadImage();
}
}
async loadImage() { async ngOnInit() {
try { this.cachedFile = this.gridEntry.file;
const hash = this.gridEntry.file.hash; this.contentUrl = this.fileService.buildThumbnailUrl(this.gridEntry.file,
const contentUrl = await this.fileService.getFileThumbnail(this.gridEntry.file, 250, 250); 250, 250);
}
if (this.gridEntry.file.hash === hash) { // avoid issues with changed files async ngOnChanges(changes: SimpleChanges) {
this.contentUrl = contentUrl; if (changes["file"] && (!this.cachedFile || this.gridEntry.file.hash !== this.cachedFile.hash)) {
} this.cachedFile = this.gridEntry.file;
} catch (err) { this.contentUrl = this.fileService.buildThumbnailUrl(this.gridEntry.file,
this.errorBroker.showError(err); 250, 250);
}
} }
}
} }

@ -90,4 +90,24 @@ export class FileService {
public async updateFileName(file: File, name: string): Promise<File> { public async updateFileName(file: File, name: string): Promise<File> {
return await invoke<File>("plugin:mediarepo|update_file_name", {id: file.id, name}) return await invoke<File>("plugin:mediarepo|update_file_name", {id: file.id, name})
} }
/**
* Builds a safe thumbnail url that accesses custom scheme for thumbnails
* @param {File} file
* @param {number} height
* @param {number} width
* @returns {SafeResourceUrl}
*/
public buildThumbnailUrl(file: File, height: number, width: number): SafeResourceUrl {
return this.sanitizer.bypassSecurityTrustResourceUrl(`thumb://${file.hash}?width=${250}&height=${250}`)
}
/**
* Builds a safe content url that accesses custom scheme for thumbnails
* @param {File} file
* @returns {SafeResourceUrl}
*/
public buildContentUrl(file: File): SafeResourceUrl {
return this.sanitizer.bypassSecurityTrustResourceUrl(`content://${file.hash}`)
}
} }

Loading…
Cancel
Save