diff --git a/src/backend/middlewares/thumbnail/PhotoConverterMWs.ts b/src/backend/middlewares/thumbnail/PhotoConverterMWs.ts index 46cf5908..b00c6339 100644 --- a/src/backend/middlewares/thumbnail/PhotoConverterMWs.ts +++ b/src/backend/middlewares/thumbnail/PhotoConverterMWs.ts @@ -17,7 +17,7 @@ export class PhotoConverterMWs { const convertedVideo = PhotoProcessing.generateConvertedPath(fullMediaPath, Config.Server.Media.Photo.Converting.resolution); - // check if transcoded video exist + // check if converted photo exist if (fs.existsSync(convertedVideo) === true) { req.resultPipe = convertedVideo; return next(); diff --git a/src/frontend/app/ui/gallery/grid/photo/photo.grid.gallery.component.ts b/src/frontend/app/ui/gallery/grid/photo/photo.grid.gallery.component.ts index 7170e58e..1806d26f 100644 --- a/src/frontend/app/ui/gallery/grid/photo/photo.grid.gallery.component.ts +++ b/src/frontend/app/ui/gallery/grid/photo/photo.grid.gallery.component.ts @@ -24,13 +24,12 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy { infoBarVisible = false; animationTimer: number = null; - readonly SearchTypes: typeof SearchTypes; + readonly SearchTypes: typeof SearchTypes = SearchTypes; searchEnabled = true; wasInView: boolean = null; constructor(private thumbnailService: ThumbnailManagerService) { - this.SearchTypes = SearchTypes; this.searchEnabled = Config.Client.Search.enabled; } diff --git a/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.css b/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.css index a6b53494..d32aa097 100644 --- a/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.css +++ b/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.css @@ -56,3 +56,16 @@ .modal-header { padding: 0.4rem 1rem; } + + +.keywords a { + color: #212529; +} + +.keywords a:hover { + text-decoration: underline; +} + +.keywords .oi-person{ + margin-right: 2px; +} diff --git a/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.html b/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.html index ef41b108..0ef077c4 100644 --- a/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.html +++ b/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.html @@ -61,6 +61,7 @@ +
@@ -83,6 +84,29 @@
+ +
+
+ +
+
+ + + # + {{keyword.value}} + + #{{keyword.value}} + , + +
+
+ +
diff --git a/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts b/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts index 533c0050..6923ffdb 100644 --- a/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts +++ b/src/frontend/app/ui/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts @@ -1,26 +1,31 @@ -import {Component, EventEmitter, Input, Output} from '@angular/core'; -import {CameraMetadata, PhotoDTO, PositionMetaData} from '../../../../../../common/entities/PhotoDTO'; +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {CameraMetadata, PhotoDTO, PhotoMetadata, PositionMetaData} from '../../../../../../common/entities/PhotoDTO'; import {Config} from '../../../../../../common/config/public/Config'; import {MediaDTO} from '../../../../../../common/entities/MediaDTO'; import {VideoDTO, VideoMetadata} from '../../../../../../common/entities/VideoDTO'; import {Utils} from '../../../../../../common/Utils'; import {QueryService} from '../../../../model/query.service'; import {MapService} from '../../map/map.service'; +import {SearchTypes} from '../../../../../../common/entities/AutoCompleteItem'; @Component({ selector: 'app-info-panel', styleUrls: ['./info-panel.lightbox.gallery.component.css'], templateUrl: './info-panel.lightbox.gallery.component.html', }) -export class InfoPanelLightboxComponent { +export class InfoPanelLightboxComponent implements OnInit { @Input() media: MediaDTO; @Output() closed = new EventEmitter(); public readonly mapEnabled: boolean; + public readonly searchEnabled: boolean; + keywords: { value: string, type: SearchTypes }[] = null; + readonly SearchTypes: typeof SearchTypes = SearchTypes; constructor(public queryService: QueryService, public mapService: MapService) { this.mapEnabled = Config.Client.Map.enabled; + this.searchEnabled = Config.Client.Search.enabled; } get FullPath(): string { @@ -46,6 +51,21 @@ export class InfoPanelLightboxComponent { return (this.media).metadata.cameraData; } + ngOnInit() { + const metadata = this.media.metadata as PhotoMetadata; + if ((metadata.keywords && metadata.keywords.length > 0) || + (metadata.faces && metadata.faces.length > 0)) { + this.keywords = []; + if (Config.Client.Faces.enabled) { + const names: string[] = (metadata.faces || []).map(f => f.name); + this.keywords = names.filter((name, index) => names.indexOf(name) === index) + .map(n => ({value: n, type: SearchTypes.person})); + } + this.keywords = this.keywords.concat((metadata.keywords || []).map(k => ({value: k, type: SearchTypes.keyword}))); + } + + } + isPhoto() { return this.media && MediaDTO.isPhoto(this.media); }