2018-05-28 00:04:35 +08:00
|
|
|
import {Component, ElementRef, HostListener, Input, OnChanges, ViewChild, AfterViewInit} from '@angular/core';
|
2018-03-31 03:30:30 +08:00
|
|
|
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
|
|
|
import {Dimension} from '../../../model/IRenderable';
|
|
|
|
import {FullScreenService} from '../../fullscreen.service';
|
2018-05-28 00:04:35 +08:00
|
|
|
import {AgmMap, LatLngBounds, MapsAPILoader} from '@agm/core';
|
2018-03-31 03:30:30 +08:00
|
|
|
import {IconThumbnail, Thumbnail, ThumbnailManagerService} from '../../thumnailManager.service';
|
2018-11-05 02:28:32 +08:00
|
|
|
import {MediaIcon} from '../../MediaIcon';
|
|
|
|
import {Media} from '../../Media';
|
2018-05-10 01:56:02 +08:00
|
|
|
import {PageHelper} from '../../../model/page.helper';
|
2018-11-02 17:40:09 +08:00
|
|
|
import {OrientationTypes} from 'ts-exif-parser';
|
2018-11-05 02:28:32 +08:00
|
|
|
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
2018-11-26 07:26:29 +08:00
|
|
|
import {FileDTO} from '../../../../../common/entities/FileDTO';
|
|
|
|
import {NetworkService} from '../../../model/network/network.service';
|
|
|
|
import {Utils} from '../../../../../common/Utils';
|
|
|
|
import {Config} from '../../../../../common/config/public/Config';
|
|
|
|
import {MapPath, MapService} from '../map.service';
|
2017-02-06 00:27:58 +08:00
|
|
|
|
2018-05-28 00:04:35 +08:00
|
|
|
|
2017-02-06 00:27:58 +08:00
|
|
|
@Component({
|
2018-05-04 07:17:08 +08:00
|
|
|
selector: 'app-gallery-map-lightbox',
|
2017-06-11 04:32:56 +08:00
|
|
|
styleUrls: ['./lightbox.map.gallery.component.css'],
|
|
|
|
templateUrl: './lightbox.map.gallery.component.html',
|
2017-02-06 00:27:58 +08:00
|
|
|
})
|
2018-05-28 00:04:35 +08:00
|
|
|
export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
|
2017-02-06 00:27:58 +08:00
|
|
|
|
2018-11-26 07:26:29 +08:00
|
|
|
@Input() photos: PhotoDTO[];
|
|
|
|
@Input() gpxFiles: FileDTO[];
|
2017-06-11 04:32:56 +08:00
|
|
|
private startPosition = null;
|
|
|
|
public lightboxDimension: Dimension = <Dimension>{top: 0, left: 0, width: 0, height: 0};
|
|
|
|
public mapDimension: Dimension = <Dimension>{top: 0, left: 0, width: 0, height: 0};
|
|
|
|
public visible = false;
|
2018-05-28 00:04:35 +08:00
|
|
|
public controllersVisible = false;
|
2017-06-11 04:32:56 +08:00
|
|
|
public opacity = 1.0;
|
2017-07-21 02:07:19 +08:00
|
|
|
mapPhotos: MapPhoto[] = [];
|
2018-11-26 07:26:29 +08:00
|
|
|
paths: MapPath[][] = [];
|
2017-06-11 04:32:56 +08:00
|
|
|
mapCenter = {latitude: 0, longitude: 0};
|
2017-02-06 00:27:58 +08:00
|
|
|
|
2018-03-31 03:30:30 +08:00
|
|
|
@ViewChild('root') elementRef: ElementRef;
|
2017-02-06 00:27:58 +08:00
|
|
|
|
2017-06-11 04:32:56 +08:00
|
|
|
@ViewChild(AgmMap) map: AgmMap;
|
2017-02-06 00:27:58 +08:00
|
|
|
|
|
|
|
|
2017-07-24 04:36:53 +08:00
|
|
|
constructor(public fullScreenService: FullScreenService,
|
2018-05-28 00:04:35 +08:00
|
|
|
private thumbnailService: ThumbnailManagerService,
|
2018-11-26 07:26:29 +08:00
|
|
|
private mapService: MapService,
|
2018-05-28 00:04:35 +08:00
|
|
|
private mapsAPILoader: MapsAPILoader) {
|
2017-06-11 04:32:56 +08:00
|
|
|
}
|
2017-02-06 00:27:58 +08:00
|
|
|
|
2017-06-11 04:32:56 +08:00
|
|
|
ngOnChanges() {
|
2018-05-04 07:17:08 +08:00
|
|
|
if (this.visible === false) {
|
2017-06-11 04:32:56 +08:00
|
|
|
return;
|
2017-02-06 00:27:58 +08:00
|
|
|
}
|
2017-06-11 04:32:56 +08:00
|
|
|
this.showImages();
|
|
|
|
}
|
|
|
|
|
2018-05-28 00:04:35 +08:00
|
|
|
ngAfterViewInit() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-06-11 04:32:56 +08:00
|
|
|
public show(position: Dimension) {
|
2017-07-25 22:13:21 +08:00
|
|
|
this.hideImages();
|
2017-06-11 04:32:56 +08:00
|
|
|
this.visible = true;
|
|
|
|
this.opacity = 1.0;
|
|
|
|
this.startPosition = position;
|
|
|
|
this.lightboxDimension = position;
|
2018-05-27 09:47:39 +08:00
|
|
|
this.lightboxDimension.top -= PageHelper.ScrollY;
|
2017-06-11 04:32:56 +08:00
|
|
|
this.mapDimension = <Dimension>{
|
|
|
|
top: 0,
|
|
|
|
left: 0,
|
|
|
|
width: this.getScreenWidth(),
|
|
|
|
height: this.getScreenHeight()
|
|
|
|
};
|
2018-05-28 00:04:35 +08:00
|
|
|
this.map.triggerResize().then(() => {
|
|
|
|
this.controllersVisible = true;
|
|
|
|
});
|
2017-06-11 04:32:56 +08:00
|
|
|
|
2018-05-10 01:56:02 +08:00
|
|
|
PageHelper.hideScrollY();
|
2017-06-11 04:32:56 +08:00
|
|
|
|
2017-06-11 04:56:23 +08:00
|
|
|
setTimeout(() => {
|
2017-06-11 04:32:56 +08:00
|
|
|
this.lightboxDimension = <Dimension>{
|
|
|
|
top: 0,
|
|
|
|
left: 0,
|
|
|
|
width: this.getScreenWidth(),
|
|
|
|
height: this.getScreenHeight()
|
|
|
|
};
|
2017-07-25 22:13:21 +08:00
|
|
|
this.showImages();
|
2017-06-11 04:56:23 +08:00
|
|
|
}, 0);
|
2017-06-11 04:32:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public hide() {
|
|
|
|
this.fullScreenService.exitFullScreen();
|
2018-05-28 00:04:35 +08:00
|
|
|
this.controllersVisible = false;
|
2018-05-04 07:17:08 +08:00
|
|
|
const to = this.startPosition;
|
2017-06-11 04:32:56 +08:00
|
|
|
|
2018-05-04 07:17:08 +08:00
|
|
|
// iff target image out of screen -> scroll to there
|
2018-05-27 09:47:39 +08:00
|
|
|
if (PageHelper.ScrollY > to.top || PageHelper.ScrollY + this.getScreenHeight() < to.top) {
|
|
|
|
PageHelper.ScrollY = to.top;
|
2017-02-06 00:27:58 +08:00
|
|
|
}
|
|
|
|
|
2017-06-11 04:32:56 +08:00
|
|
|
this.lightboxDimension = this.startPosition;
|
2018-05-27 09:47:39 +08:00
|
|
|
this.lightboxDimension.top -= PageHelper.ScrollY;
|
2018-05-10 01:56:02 +08:00
|
|
|
PageHelper.showScrollY();
|
2017-06-11 04:32:56 +08:00
|
|
|
this.opacity = 0.0;
|
|
|
|
setTimeout(() => {
|
|
|
|
this.visible = false;
|
|
|
|
this.hideImages();
|
|
|
|
}, 500);
|
|
|
|
}
|
|
|
|
|
|
|
|
showImages() {
|
|
|
|
this.hideImages();
|
|
|
|
|
|
|
|
this.mapPhotos = this.photos.filter(p => {
|
2018-05-28 00:04:35 +08:00
|
|
|
return p.metadata && p.metadata.positionData && p.metadata.positionData.GPSData
|
|
|
|
&& p.metadata.positionData.GPSData.latitude
|
|
|
|
&& p.metadata.positionData.GPSData.longitude;
|
2017-06-11 04:32:56 +08:00
|
|
|
}).map(p => {
|
2017-07-21 02:07:19 +08:00
|
|
|
let width = 500;
|
|
|
|
let height = 500;
|
2018-11-05 02:28:32 +08:00
|
|
|
const rotatedSize = MediaDTO.getRotatedSize(p);
|
2018-11-02 18:44:13 +08:00
|
|
|
if (rotatedSize.width > rotatedSize.height) {
|
|
|
|
height = width * (rotatedSize.height / rotatedSize.width);
|
2017-07-21 02:07:19 +08:00
|
|
|
} else {
|
2018-11-02 18:44:13 +08:00
|
|
|
width = height * (rotatedSize.width / rotatedSize.height);
|
2017-07-21 02:07:19 +08:00
|
|
|
}
|
2018-11-05 02:28:32 +08:00
|
|
|
const iconTh = this.thumbnailService.getIcon(new MediaIcon(p));
|
2017-07-24 04:36:53 +08:00
|
|
|
iconTh.Visible = true;
|
2017-07-21 02:07:19 +08:00
|
|
|
const obj: MapPhoto = {
|
2017-06-11 04:32:56 +08:00
|
|
|
latitude: p.metadata.positionData.GPSData.latitude,
|
|
|
|
longitude: p.metadata.positionData.GPSData.longitude,
|
2017-07-21 02:07:19 +08:00
|
|
|
iconThumbnail: iconTh,
|
2018-11-02 17:40:09 +08:00
|
|
|
orientation: p.metadata.orientation,
|
2017-07-21 02:07:19 +08:00
|
|
|
preview: {
|
|
|
|
width: width,
|
|
|
|
height: height,
|
2018-11-05 02:28:32 +08:00
|
|
|
thumbnail: this.thumbnailService.getLazyThumbnail(new Media(p, width, height))
|
2017-07-21 02:07:19 +08:00
|
|
|
}
|
2017-06-11 04:32:56 +08:00
|
|
|
|
|
|
|
};
|
2018-05-04 07:17:08 +08:00
|
|
|
if (iconTh.Available === true) {
|
2017-07-21 02:07:19 +08:00
|
|
|
obj.iconUrl = iconTh.Src;
|
2017-06-11 04:32:56 +08:00
|
|
|
} else {
|
2017-07-21 02:07:19 +08:00
|
|
|
iconTh.OnLoad = () => {
|
|
|
|
obj.iconUrl = iconTh.Src;
|
2017-06-11 04:32:56 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
});
|
2017-02-06 00:27:58 +08:00
|
|
|
|
2018-11-26 07:26:29 +08:00
|
|
|
if (this.gpxFiles) {
|
|
|
|
this.loadGPXFiles().catch(console.error);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private async loadGPXFiles(): Promise<void> {
|
|
|
|
this.paths = [];
|
|
|
|
for (let i = 0; i < this.gpxFiles.length; i++) {
|
|
|
|
const file = this.gpxFiles[i];
|
|
|
|
const path = await this.mapService.getMapPath(file);
|
|
|
|
if (file !== this.gpxFiles[i]) { // check race condition
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.paths.push(path);
|
|
|
|
}
|
2017-06-11 04:32:56 +08:00
|
|
|
}
|
2017-02-06 00:27:58 +08:00
|
|
|
|
2017-07-25 22:13:21 +08:00
|
|
|
|
2017-07-24 04:36:53 +08:00
|
|
|
public loadPreview(mp: MapPhoto) {
|
|
|
|
mp.preview.thumbnail.load();
|
2017-07-26 05:40:07 +08:00
|
|
|
mp.preview.thumbnail.CurrentlyWaiting = true;
|
2017-07-24 04:36:53 +08:00
|
|
|
}
|
|
|
|
|
2017-06-11 04:32:56 +08:00
|
|
|
hideImages() {
|
2017-07-25 22:13:21 +08:00
|
|
|
this.mapCenter = {longitude: 0, latitude: 0};
|
2017-07-24 04:36:53 +08:00
|
|
|
this.mapPhotos.forEach((mp) => {
|
|
|
|
mp.iconThumbnail.destroy();
|
|
|
|
mp.preview.thumbnail.destroy();
|
|
|
|
});
|
2017-06-11 04:32:56 +08:00
|
|
|
this.mapPhotos = [];
|
|
|
|
}
|
2017-03-20 07:01:41 +08:00
|
|
|
|
2017-03-21 04:37:23 +08:00
|
|
|
|
2017-06-11 04:32:56 +08:00
|
|
|
private getScreenWidth() {
|
|
|
|
return window.innerWidth;
|
|
|
|
}
|
2017-02-06 00:27:58 +08:00
|
|
|
|
2017-06-11 04:32:56 +08:00
|
|
|
private getScreenHeight() {
|
|
|
|
return window.innerHeight;
|
|
|
|
}
|
2017-02-06 00:27:58 +08:00
|
|
|
|
2017-06-11 04:32:56 +08:00
|
|
|
//noinspection JSUnusedGlobalSymbols
|
|
|
|
@HostListener('window:keydown', ['$event'])
|
|
|
|
onKeyPress(e: KeyboardEvent) {
|
2018-05-04 07:17:08 +08:00
|
|
|
if (this.visible !== true) {
|
2017-06-11 04:32:56 +08:00
|
|
|
return;
|
2017-02-06 00:27:58 +08:00
|
|
|
}
|
2018-05-04 07:17:08 +08:00
|
|
|
const event: KeyboardEvent = window.event ? <any>window.event : e;
|
2018-10-22 06:24:17 +08:00
|
|
|
switch (event.key) {
|
|
|
|
case 'Escape': // escape
|
2017-06-11 04:32:56 +08:00
|
|
|
this.hide();
|
|
|
|
break;
|
2017-03-26 04:59:30 +08:00
|
|
|
}
|
2017-06-11 04:32:56 +08:00
|
|
|
}
|
2017-03-26 04:59:30 +08:00
|
|
|
|
2017-02-06 00:27:58 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-07-21 02:07:19 +08:00
|
|
|
export interface MapPhoto {
|
|
|
|
latitude: number;
|
|
|
|
longitude: number;
|
|
|
|
iconUrl?: string;
|
|
|
|
iconThumbnail: IconThumbnail;
|
2018-11-02 17:40:09 +08:00
|
|
|
orientation: OrientationTypes;
|
2017-07-21 02:07:19 +08:00
|
|
|
preview: {
|
|
|
|
width: number;
|
|
|
|
height: number;
|
2017-07-24 04:36:53 +08:00
|
|
|
thumbnail: Thumbnail;
|
2018-05-04 07:17:08 +08:00
|
|
|
};
|
2017-07-21 02:07:19 +08:00
|
|
|
}
|
|
|
|
|