From 4d7a18b15930ff0e3719960eab48b2141b103f0d Mon Sep 17 00:00:00 2001 From: trivernis Date: Mon, 22 Nov 2021 20:19:03 +0100 Subject: [PATCH] Add thumbnail icons for unsupported mediatypes and thumbnails for non-images Signed-off-by: trivernis --- mediarepo-ui/src/app/app.module.ts | 2 + .../content-aware-image.component.html | 3 +- .../content-aware-image.component.ts | 1 + .../file-gallery-entry.component.html | 2 +- .../file-gallery-entry.component.scss | 4 +- .../file-grid-entry.component.html | 5 +-- .../file-thumbnail.component.html | 12 ++++++ .../file-thumbnail.component.scss | 37 ++++++++++++++++ .../file-thumbnail.component.spec.ts | 25 +++++++++++ .../file-thumbnail.component.ts | 43 +++++++++++++++++++ .../filesystem-import.component.ts | 2 +- .../src/app/services/file/file.helper.ts | 19 ++++++++ 12 files changed, 147 insertions(+), 8 deletions(-) create mode 100644 mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.html create mode 100644 mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.scss create mode 100644 mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.spec.ts create mode 100644 mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.ts diff --git a/mediarepo-ui/src/app/app.module.ts b/mediarepo-ui/src/app/app.module.ts index e5a0467..72acc3d 100644 --- a/mediarepo-ui/src/app/app.module.ts +++ b/mediarepo-ui/src/app/app.module.ts @@ -65,6 +65,7 @@ import {VideoViewerComponent} from './components/file-gallery/content-viewer/vid import {HttpClientModule} from "@angular/common/http"; import { AudioViewerComponent } from './components/file-gallery/content-viewer/audio-viewer/audio-viewer.component'; import { BusyIndicatorComponent } from './components/busy-indicator/busy-indicator.component'; +import { FileThumbnailComponent } from './components/file-thumbnail/file-thumbnail.component'; @NgModule({ declarations: [ @@ -99,6 +100,7 @@ import { BusyIndicatorComponent } from './components/busy-indicator/busy-indicat VideoViewerComponent, AudioViewerComponent, BusyIndicatorComponent, + FileThumbnailComponent, ], imports: [ BrowserModule, diff --git a/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.html b/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.html index bf6b6bc..16110fb 100644 --- a/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.html +++ b/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.html @@ -1,4 +1,5 @@
-
diff --git a/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.ts b/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.ts index 7e70e74..46da500 100644 --- a/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.ts +++ b/mediarepo-ui/src/app/components/content-aware-image/content-aware-image.component.ts @@ -11,6 +11,7 @@ export class ContentAwareImageComponent implements OnInit { @Input() imageSrc!: string | SafeResourceUrl; @Input() maximizeHeight: boolean = true; @Input() maximizeWidth: boolean = true; + @Input() borderRadius: string | undefined; @Input() decoding: "async" | "sync" | "auto" = "auto"; @ViewChild("image") image: ElementRef | undefined; diff --git a/mediarepo-ui/src/app/components/file-gallery/file-gallery-entry/file-gallery-entry.component.html b/mediarepo-ui/src/app/components/file-gallery/file-gallery-entry/file-gallery-entry.component.html index 1c4bd51..2fb6f59 100644 --- a/mediarepo-ui/src/app/components/file-gallery/file-gallery-entry/file-gallery-entry.component.html +++ b/mediarepo-ui/src/app/components/file-gallery/file-gallery-entry/file-gallery-entry.component.html @@ -1,4 +1,4 @@
- +
diff --git a/mediarepo-ui/src/app/components/file-gallery/file-gallery-entry/file-gallery-entry.component.scss b/mediarepo-ui/src/app/components/file-gallery/file-gallery-entry/file-gallery-entry.component.scss index 66cc04f..20ecddf 100644 --- a/mediarepo-ui/src/app/components/file-gallery/file-gallery-entry/file-gallery-entry.component.scss +++ b/mediarepo-ui/src/app/components/file-gallery/file-gallery-entry/file-gallery-entry.component.scss @@ -1,6 +1,8 @@ -app-content-aware-image { +app-file-thumbnail { height: 100%; width: 100%; + position: relative; + display: block; } .image-wrapper { diff --git a/mediarepo-ui/src/app/components/file-grid/file-grid-entry/file-grid-entry.component.html b/mediarepo-ui/src/app/components/file-grid/file-grid-entry/file-grid-entry.component.html index a54d73c..042ae95 100644 --- a/mediarepo-ui/src/app/components/file-grid/file-grid-entry/file-grid-entry.component.html +++ b/mediarepo-ui/src/app/components/file-grid/file-grid-entry/file-grid-entry.component.html @@ -1,9 +1,6 @@ - + - - - diff --git a/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.html b/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.html new file mode 100644 index 0000000..8c1fe20 --- /dev/null +++ b/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.html @@ -0,0 +1,12 @@ + +
+ movie + gif +
+
+ image + movie + audiotrack + description +
diff --git a/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.scss b/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.scss new file mode 100644 index 0000000..a904e74 --- /dev/null +++ b/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.scss @@ -0,0 +1,37 @@ +app-content-aware-image { + height: 100%; + width: 100%; +} + +.file-type-icon { + background-color: #303030; +} + +.file-type-icon, .file-icon-overlay { + height: 100%; + width: 100%; + display: flex; + + mat-icon { + align-self: center; + margin: auto; + } +} + +.file-icon-overlay { + position: absolute; + top: 0; + right: 0; +} + +mat-icon.gif-icon { + border-radius: 50%; + background-color: rgba(0, 0, 0, 0.5); + padding: 0.1em; +} + +mat-icon { + font-size: 4em; + height: 1em; + width: 1em; +} diff --git a/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.spec.ts b/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.spec.ts new file mode 100644 index 0000000..3ea5ee9 --- /dev/null +++ b/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FileThumbnailComponent } from './file-thumbnail.component'; + +describe('FileThumbnailComponent', () => { + let component: FileThumbnailComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ FileThumbnailComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(FileThumbnailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.ts b/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.ts new file mode 100644 index 0000000..a57761f --- /dev/null +++ b/mediarepo-ui/src/app/components/file-thumbnail/file-thumbnail.component.ts @@ -0,0 +1,43 @@ +import {Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'; +import {File} from "../../models/File"; +import {FileService} from "../../services/file/file.service"; +import {FileHelper} from "../../services/file/file.helper"; +import {SafeResourceUrl} from "@angular/platform-browser"; + +@Component({ + selector: 'app-file-thumbnail', + templateUrl: './file-thumbnail.component.html', + styleUrls: ['./file-thumbnail.component.scss'] +}) +export class FileThumbnailComponent implements OnInit, OnChanges { + + @Input() file!: File; + + public thumbUrl: SafeResourceUrl | undefined; + + private supportedThumbnailTypes = ["image", "video"] + + constructor(private fileService: FileService) { + } + + public ngOnInit(): void { + this.thumbUrl = this.fileService.buildThumbnailUrl(this.file, 250, 250); + } + + public ngOnChanges(changes: SimpleChanges): void { + if (changes["file"]) { + this.thumbUrl = this.fileService.buildThumbnailUrl(this.file, 250, 250) + } + } + + public getThumbnailSupported(): boolean { + const mimeParts = FileHelper.parseMime(this.file.mime_type); + + return !!mimeParts && this.supportedThumbnailTypes.includes(mimeParts[0]); + } + + public getFileType(): string { + const mimeParts = FileHelper.parseMime(this.file.mime_type); + return (mimeParts && mimeParts[0]) ?? "other"; + } +} diff --git a/mediarepo-ui/src/app/pages/home/import-tab/import-tab-sidebar/filesystem-import/filesystem-import.component.ts b/mediarepo-ui/src/app/pages/home/import-tab/import-tab-sidebar/filesystem-import/filesystem-import.component.ts index 77dcfbe..a55852d 100644 --- a/mediarepo-ui/src/app/pages/home/import-tab/import-tab-sidebar/filesystem-import/filesystem-import.component.ts +++ b/mediarepo-ui/src/app/pages/home/import-tab/import-tab-sidebar/filesystem-import/filesystem-import.component.ts @@ -20,7 +20,7 @@ export class FilesystemImportComponent { public files: FileOsMetadata[] = []; public importOptions = new AddFileOptions(); public filters: DialogFilter[] = [ - {name: "Images", extensions: ["png", "jpg", "jpeg", "webp", "bmp"]}, + {name: "Images", extensions: ["png", "jpg", "jpeg", "webp", "bmp", "gif"]}, {name: "Videos", extensions: ["mp4", "mkv", "wmv", "avi", "webm"]}, {name: "Audio", extensions: ["mp3", "ogg", "wav", "flac", "aac"]}, {name: "Documents", extensions: ["pdf", "doc", "docx", "odf"]}, diff --git a/mediarepo-ui/src/app/services/file/file.helper.ts b/mediarepo-ui/src/app/services/file/file.helper.ts index f99e72a..8469b58 100644 --- a/mediarepo-ui/src/app/services/file/file.helper.ts +++ b/mediarepo-ui/src/app/services/file/file.helper.ts @@ -26,6 +26,25 @@ export class FileHelper { }) } + /** + * Parses a mime into its two components + * @param {string | undefined} mimeType + * @returns {[string, string] | undefined} + */ + public static parseMime(mimeType: string | undefined): [string, string] | undefined { + if (!mimeType) { + return undefined; + } + let mimeParts = mimeType.split("/"); + if (mimeParts.length < 2) { + return undefined; + } + const type = mimeParts[0]; + const subtype = mimeParts[1]; + + return [type, subtype]; + } + /** * Returns the extension for a mime type * @param {string} mime