mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-27 02:09:16 +02:00
implementing infobox for videos
This commit is contained in:
parent
6b5508c9e6
commit
7030a289b7
@ -11,6 +11,8 @@ import {ProjectPath} from '../ProjectPath';
|
|||||||
import {Config} from '../../common/config/private/Config';
|
import {Config} from '../../common/config/private/Config';
|
||||||
import {UserDTO} from '../../common/entities/UserDTO';
|
import {UserDTO} from '../../common/entities/UserDTO';
|
||||||
import {RandomQuery} from '../model/interfaces/IGalleryManager';
|
import {RandomQuery} from '../model/interfaces/IGalleryManager';
|
||||||
|
import {MediaDTO} from '../../common/entities/MediaDTO';
|
||||||
|
import {VideoDTO} from '../../common/entities/VideoDTO';
|
||||||
|
|
||||||
|
|
||||||
const LOG_TAG = '[GalleryMWs]';
|
const LOG_TAG = '[GalleryMWs]';
|
||||||
@ -71,8 +73,28 @@ export class GalleryMWs {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const cleanUpMedia = (media: MediaDTO[]) => {
|
||||||
|
media.forEach(m => {
|
||||||
|
if (MediaDTO.isPhoto(m)) {
|
||||||
|
delete (<VideoDTO>m).metadata.bitRate;
|
||||||
|
delete (<VideoDTO>m).metadata.duration;
|
||||||
|
} else if (MediaDTO.isVideo(m)) {
|
||||||
|
delete (<PhotoDTO>m).metadata.cameraData;
|
||||||
|
delete (<PhotoDTO>m).metadata.orientation;
|
||||||
|
delete (<PhotoDTO>m).metadata.orientation;
|
||||||
|
delete (<PhotoDTO>m).metadata.keywords;
|
||||||
|
delete (<PhotoDTO>m).metadata.positionData;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
if (cw.directory) {
|
if (cw.directory) {
|
||||||
removeDirs(cw.directory);
|
removeDirs(cw.directory);
|
||||||
|
// TODO: remove when typeorm inheritance is fixed
|
||||||
|
cleanUpMedia(cw.directory.media);
|
||||||
|
}
|
||||||
|
if (cw.searchResult) {
|
||||||
|
cleanUpMedia(cw.searchResult.media);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,11 @@ export class Utils {
|
|||||||
return JSON.parse(JSON.stringify(object));
|
return JSON.parse(JSON.stringify(object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static zeroPrefix(value, length: number) {
|
||||||
|
const ret = '00000' + value;
|
||||||
|
return ret.substr(ret.length - length);
|
||||||
|
}
|
||||||
|
|
||||||
static equalsFilter(object: any, filter: any): boolean {
|
static equalsFilter(object: any, filter: any): boolean {
|
||||||
if (typeof filter !== 'object' || filter == null) {
|
if (typeof filter !== 'object' || filter == null) {
|
||||||
return object === filter;
|
return object === filter;
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="details-sub row">
|
<div class="details-sub row">
|
||||||
<div class="col-4">{{media.metadata.size.width}} x {{media.metadata.size.height}}</div>
|
<div class="col-4">{{media.metadata.size.width}} x {{media.metadata.size.height}}</div>
|
||||||
<div class="col-4">{{calcMpx()}}MP</div>
|
<div class="col-4" *ngIf="isPhoto()">{{calcMpx()}}MP</div>
|
||||||
<div class="col-4" *ngIf="media.metadata.fileSize">{{calcFileSize()}}</div>
|
<div class="col-4" *ngIf="media.metadata.fileSize">{{calcSize(media.metadata.fileSize)}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,6 +35,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row" *ngIf="VideoData">
|
||||||
|
<div class="col-2">
|
||||||
|
<span class="details-icon oi oi-video"></span>
|
||||||
|
</div>
|
||||||
|
<div class="col-10">
|
||||||
|
<div class="details-main">
|
||||||
|
{{"Video"}}
|
||||||
|
</div>
|
||||||
|
<div class="details-sub row">
|
||||||
|
<div class="col-6" *ngIf="VideoData.duration">length: {{renderDuration(VideoData.duration)}}</div>
|
||||||
|
<div class="col-6" *ngIf="VideoData.bitRate">bit rate: {{calcSize(VideoData.bitRate)}}/s</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row" *ngIf="CameraData">
|
<div class="row" *ngIf="CameraData">
|
||||||
<div class="col-2">
|
<div class="col-2">
|
||||||
<span class="details-icon oi oi-camera-slr"></span>
|
<span class="details-icon oi oi-camera-slr"></span>
|
||||||
@ -67,8 +83,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="details-sub row" *ngIf="hasGPS()">
|
<div class="details-sub row" *ngIf="hasGPS()">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
{{media.metadata.positionData.GPSData.latitude.toFixed(3)}},
|
{{PositionData.GPSData.latitude.toFixed(3)}},
|
||||||
{{media.metadata.positionData.GPSData.longitude.toFixed(3)}}
|
{{PositionData.GPSData.longitude.toFixed(3)}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -80,11 +96,11 @@
|
|||||||
[zoomControl]="false"
|
[zoomControl]="false"
|
||||||
[streetViewControl]="false"
|
[streetViewControl]="false"
|
||||||
[zoom]="10"
|
[zoom]="10"
|
||||||
[latitude]="media.metadata.positionData.GPSData.latitude"
|
[latitude]="PositionData.GPSData.latitude"
|
||||||
[longitude]="media.metadata.positionData.GPSData.longitude">
|
[longitude]="PositionData.GPSData.longitude">
|
||||||
<agm-marker
|
<agm-marker
|
||||||
[latitude]="media.metadata.positionData.GPSData.latitude"
|
[latitude]="PositionData.GPSData.latitude"
|
||||||
[longitude]="media.metadata.positionData.GPSData.longitude">
|
[longitude]="PositionData.GPSData.longitude">
|
||||||
</agm-marker>
|
</agm-marker>
|
||||||
</agm-map>
|
</agm-map>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import {Component, ElementRef, EventEmitter, Input, Output} from '@angular/core';
|
import {Component, ElementRef, EventEmitter, Input, Output} from '@angular/core';
|
||||||
import {CameraMetadata, PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
import {CameraMetadata, PhotoDTO, PositionMetaData} from '../../../../../common/entities/PhotoDTO';
|
||||||
import {Config} from '../../../../../common/config/public/Config';
|
import {Config} from '../../../../../common/config/public/Config';
|
||||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||||
|
import {VideoDTO, VideoMetadata} from '../../../../../common/entities/VideoDTO';
|
||||||
|
import {Utils} from '../../../../../common/Utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-info-panel',
|
selector: 'app-info-panel',
|
||||||
@ -18,14 +20,26 @@ export class InfoPanelLightboxComponent {
|
|||||||
this.mapEnabled = Config.Client.Map.enabled;
|
this.mapEnabled = Config.Client.Map.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isPhoto() {
|
||||||
|
return this.media && MediaDTO.isPhoto(this.media);
|
||||||
|
}
|
||||||
|
|
||||||
calcMpx() {
|
calcMpx() {
|
||||||
return (this.media.metadata.size.width * this.media.metadata.size.height / 1000000).toFixed(2);
|
return (this.media.metadata.size.width * this.media.metadata.size.height / 1000000).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
calcFileSize() {
|
renderDuration(time: number) {
|
||||||
|
const h = Math.floor(time / 1000 / 60 / 60);
|
||||||
|
time %= 1000 * 60 * 60;
|
||||||
|
const m = Math.floor(time / 1000 / 60);
|
||||||
|
time %= 1000 * 60;
|
||||||
|
const s = Math.floor(time / 1000);
|
||||||
|
return Utils.zeroPrefix(h, 2) + ':' + Utils.zeroPrefix(m, 2) + ':' + Utils.zeroPrefix(s, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
calcSize(size: number) {
|
||||||
const postFixes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
const postFixes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||||
let index = 0;
|
let index = 0;
|
||||||
let size = this.media.metadata.fileSize;
|
|
||||||
while (size > 1000 && index < postFixes.length - 1) {
|
while (size > 1000 && index < postFixes.length - 1) {
|
||||||
size /= 1000;
|
size /= 1000;
|
||||||
index++;
|
index++;
|
||||||
@ -52,8 +66,18 @@ export class InfoPanelLightboxComponent {
|
|||||||
return '1/' + (1 / f);
|
return '1/' + (1 / f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get VideoData(): VideoMetadata {
|
||||||
|
if (typeof (<VideoDTO>this.media).metadata.bitRate === 'undefined') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (<VideoDTO>this.media).metadata;
|
||||||
|
}
|
||||||
|
|
||||||
hasPositionData(): boolean {
|
hasPositionData(): boolean {
|
||||||
return MediaDTO.hasPositionData(this.media);
|
return !!(<PhotoDTO>this.media).metadata.positionData &&
|
||||||
|
!!((<PhotoDTO>this.media).metadata.positionData.city ||
|
||||||
|
(<PhotoDTO>this.media).metadata.positionData.state ||
|
||||||
|
(<PhotoDTO>this.media).metadata.positionData.country);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasGPS() {
|
hasGPS() {
|
||||||
@ -61,6 +85,10 @@ export class InfoPanelLightboxComponent {
|
|||||||
(<PhotoDTO>this.media).metadata.positionData.GPSData.latitude && (<PhotoDTO>this.media).metadata.positionData.GPSData.longitude;
|
(<PhotoDTO>this.media).metadata.positionData.GPSData.latitude && (<PhotoDTO>this.media).metadata.positionData.GPSData.longitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get PositionData(): PositionMetaData {
|
||||||
|
return (<PhotoDTO>this.media).metadata.positionData;
|
||||||
|
}
|
||||||
|
|
||||||
getPositionText(): string {
|
getPositionText(): string {
|
||||||
if (!(<PhotoDTO>this.media).metadata.positionData) {
|
if (!(<PhotoDTO>this.media).metadata.positionData) {
|
||||||
return '';
|
return '';
|
||||||
|
@ -17,7 +17,7 @@ input[type="range"]::-webkit-slider-runnable-track {
|
|||||||
*/
|
*/
|
||||||
input[type="range"]::-webkit-slider-thumb {
|
input[type="range"]::-webkit-slider-thumb {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
width: 10px; /* 1 */
|
width: 1px; /* 1 */
|
||||||
height: 10px;
|
height: 10px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
box-shadow: -100vw 0 0 100vw white;
|
box-shadow: -100vw 0 0 100vw white;
|
||||||
@ -31,7 +31,7 @@ input[type="range"]::-moz-range-track {
|
|||||||
input[type="range"]::-moz-range-thumb {
|
input[type="range"]::-moz-range-thumb {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
width: 10px;
|
width: 1px;
|
||||||
box-shadow: -100vw 0 0 100vw white;
|
box-shadow: -100vw 0 0 100vw white;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ input[type="range"]::-ms-fill-lower {
|
|||||||
input[type="range"]::-ms-thumb {
|
input[type="range"]::-ms-thumb {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
width: 10px;
|
width: 1px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,10 @@ app-gallery-lightbox-photo {
|
|||||||
opacity: 0.1;
|
opacity: 0.1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#controllers-container.dim-controls-video {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
#swipeable-container{
|
#swipeable-container{
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
@ -16,52 +16,53 @@
|
|||||||
id="controllers-container"
|
id="controllers-container"
|
||||||
#controls
|
#controls
|
||||||
[style.width.px]="getPhotoFrameWidth()"
|
[style.width.px]="getPhotoFrameWidth()"
|
||||||
[ngClass]="!controllersDimmed ? 'dim-controls': ''">
|
[ngClass]="!controllersDimmed ? (activePhoto && activePhoto.gridPhoto.isVideo() ? 'dim-controls-video' :'dim-controls'): ''">
|
||||||
|
|
||||||
|
<div class="controls controls-top">
|
||||||
|
<a *ngIf="activePhoto"
|
||||||
|
class="highlight control-button"
|
||||||
|
[href]="activePhoto.gridPhoto.getPhotoPath()"
|
||||||
|
[download]="activePhoto.gridPhoto.media.name">
|
||||||
|
<span class="oi oi-data-transfer-download"
|
||||||
|
title="download" i18n-title></span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class=" highlight control-button" (click)="toggleInfoPanel()"
|
||||||
|
title="info" i18n-title>
|
||||||
|
<span class="oi oi-info"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="fullScreenService.isFullScreenEnabled()"
|
||||||
|
class=" highlight control-button"
|
||||||
|
(click)="fullScreenService.exitFullScreen()"
|
||||||
|
title="toggle fullscreen" i18n-title>
|
||||||
|
<span class="oi oi-fullscreen-exit">
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="!fullScreenService.isFullScreenEnabled()"
|
||||||
|
class="highlight control-button"
|
||||||
|
(click)="fullScreenService.showFullScreen(root)"
|
||||||
|
title="toggle fullscreen" i18n-title>
|
||||||
|
<span class="oi oi-fullscreen-enter">
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="highlight control-button"
|
||||||
|
(click)="hide()"
|
||||||
|
title="close" i18n-title>
|
||||||
|
<span class="oi oi-x">
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="swipeable-container"
|
<div id="swipeable-container"
|
||||||
(swipeleft)="nextImage()"
|
(swipeleft)="nextImage()"
|
||||||
(swiperight)="prevImage()"
|
(swiperight)="prevImage()"
|
||||||
(swipeup)="hide()"
|
(swipeup)="hide()"
|
||||||
(click)="photo.playPause()">
|
(click)="photo.playPause()">
|
||||||
|
|
||||||
<div class="controls controls-top">
|
|
||||||
<a *ngIf="activePhoto"
|
|
||||||
class="highlight control-button"
|
|
||||||
[href]="activePhoto.gridPhoto.getPhotoPath()"
|
|
||||||
[download]="activePhoto.gridPhoto.media.name">
|
|
||||||
<span class="oi oi-data-transfer-download"
|
|
||||||
title="download" i18n-title></span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class=" highlight control-button" (click)="toggleInfoPanel()"
|
|
||||||
title="info" i18n-title>
|
|
||||||
<span class="oi oi-info"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="fullScreenService.isFullScreenEnabled()"
|
|
||||||
class=" highlight control-button"
|
|
||||||
(click)="fullScreenService.exitFullScreen()"
|
|
||||||
title="toggle fullscreen" i18n-title>
|
|
||||||
<span class="oi oi-fullscreen-exit">
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="!fullScreenService.isFullScreenEnabled()"
|
|
||||||
class="highlight control-button"
|
|
||||||
(click)="fullScreenService.showFullScreen(root)"
|
|
||||||
title="toggle fullscreen" i18n-title>
|
|
||||||
<span class="oi oi-fullscreen-enter">
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="highlight control-button"
|
|
||||||
(click)="hide()"
|
|
||||||
title="close" i18n-title>
|
|
||||||
<span class="oi oi-x">
|
|
||||||
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="navigation-arrow highlight"
|
<div class="navigation-arrow highlight"
|
||||||
*ngIf="navigation.hasPrev" title="key: left arrow" id="leftArrow" i18n-title
|
*ngIf="navigation.hasPrev" title="key: left arrow" id="leftArrow" i18n-title
|
||||||
@ -72,7 +73,7 @@
|
|||||||
(click)="nextImage()"><span
|
(click)="nextImage()"><span
|
||||||
class="oi oi-chevron-right"></span></div>
|
class="oi oi-chevron-right"></span></div>
|
||||||
|
|
||||||
<div class="controls controls-playback" *ngIf="activePhoto && activePhoto.gridPhoto.isPhoto()">
|
<div class="controls controls-playback" *ngIf="activePhoto && activePhoto.gridPhoto.isPhoto()">
|
||||||
<span class="oi oi-media-pause highlight control-button"
|
<span class="oi oi-media-pause highlight control-button"
|
||||||
[ngClass]="playBackState == 0 ? 'button-disabled':''"
|
[ngClass]="playBackState == 0 ? 'button-disabled':''"
|
||||||
(click)="pause()"
|
(click)="pause()"
|
||||||
@ -109,7 +110,7 @@
|
|||||||
<app-info-panel *ngIf="activePhoto && infoPanelVisible"
|
<app-info-panel *ngIf="activePhoto && infoPanelVisible"
|
||||||
id="info-panel"
|
id="info-panel"
|
||||||
[style.width.px]="infoPanelWidth"
|
[style.width.px]="infoPanelWidth"
|
||||||
[media]="activePhoto.gridPhoto.photo"
|
[media]="activePhoto.gridPhoto.media"
|
||||||
(closed)="hideInfoPanel()">
|
(closed)="hideInfoPanel()">
|
||||||
|
|
||||||
</app-info-panel>
|
</app-info-panel>
|
||||||
|
@ -62,7 +62,7 @@ export class GalleryLightboxMediaComponent implements OnChanges {
|
|||||||
|
|
||||||
public get VideoVolume(): number {
|
public get VideoVolume(): number {
|
||||||
if (!this.video) {
|
if (!this.video) {
|
||||||
return 100;
|
return 1;
|
||||||
}
|
}
|
||||||
return this.video.nativeElement.volume;
|
return this.video.nativeElement.volume;
|
||||||
}
|
}
|
||||||
@ -88,7 +88,7 @@ export class GalleryLightboxMediaComponent implements OnChanges {
|
|||||||
|
|
||||||
public get Muted(): boolean {
|
public get Muted(): boolean {
|
||||||
if (!this.video) {
|
if (!this.video) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
return this.video.nativeElement.muted;
|
return this.video.nativeElement.muted;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user