mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-01-12 04:23:09 +02:00
adding video indicator for videos
This commit is contained in:
parent
5625f37d6b
commit
d7eb805186
@ -137,7 +137,7 @@ apt-get install build-essential libkrb5-dev gcc g++
|
||||
* Setup page
|
||||
* Random photo url
|
||||
* You can generate an url that returns a random photo from your gallery. You can use this feature to develop 3rd party applications, like: changing desktop background
|
||||
* video support - `future plan`
|
||||
* video support
|
||||
* **Markdown based blogging support** - `future plan`
|
||||
* you can write some note in the blog.md for every directory
|
||||
* bug free :) - `In progress`
|
||||
|
@ -74,6 +74,7 @@ import {RandomQueryBuilderGalleryComponent} from './gallery/random-query-builder
|
||||
import {RandomPhotoSettingsComponent} from './settings/random-photo/random-photo.settings.component';
|
||||
import {FixOrientationPipe} from './gallery/FixOrientationPipe';
|
||||
import {VideoSettingsComponent} from './settings/video/video.settings.component';
|
||||
import {DurationPipe} from './pipes/DurationPipe';
|
||||
|
||||
@Injectable()
|
||||
export class GoogleMapsConfig {
|
||||
@ -170,7 +171,8 @@ export function translationsFactory(locale: string) {
|
||||
StringifyRole,
|
||||
IconizeSortingMethod,
|
||||
StringifySortingMethod,
|
||||
FixOrientationPipe
|
||||
FixOrientationPipe,
|
||||
DurationPipe
|
||||
],
|
||||
providers: [
|
||||
{provide: UrlSerializer, useClass: CustomUrlSerializer},
|
||||
|
@ -2,6 +2,7 @@ import {Media} from '../Media';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {OrientationTypes} from 'ts-exif-parser';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {VideoDTO} from '../../../../common/entities/VideoDTO';
|
||||
|
||||
export class GridMedia extends Media {
|
||||
|
||||
@ -22,5 +23,9 @@ export class GridMedia extends Media {
|
||||
return MediaDTO.isVideo(this.media);
|
||||
}
|
||||
|
||||
get Video(): VideoDTO {
|
||||
return <VideoDTO>this.media;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -82,7 +82,6 @@ img {
|
||||
|
||||
a {
|
||||
color: white;
|
||||
|
||||
}
|
||||
|
||||
.photo-keywords {
|
||||
@ -92,3 +91,11 @@ a {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.video-indicator{
|
||||
font-size: large;
|
||||
padding: 10px;
|
||||
position: absolute;
|
||||
transform: translate(-100%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
@ -1,7 +1,14 @@
|
||||
<div #photoContainer class="photo-container" (mouseover)="mouseOver()" (mouseout)="mouseOut()">
|
||||
<img #img [src]="thumbnail.Src | fixOrientation:gridPhoto.media.metadata.orientation | async"
|
||||
|
||||
|
||||
<img #img [src]="thumbnail.Src | fixOrientation:gridPhoto.Orientation | async"
|
||||
*ngIf="thumbnail.Available">
|
||||
|
||||
<div *ngIf="gridPhoto.isVideo()" class="video-indicator"
|
||||
[style.marginTop.px]="-container.nativeElement.offsetHeight"
|
||||
[style.marginLeft.px]="container.nativeElement.offsetWidth">
|
||||
{{gridPhoto.Video.metadata.duration | duration}} <span class="oi oi-video"></span></div>
|
||||
|
||||
<app-gallery-grid-photo-loading
|
||||
[error]="thumbnail.Error"
|
||||
[animate]="thumbnail.loading"
|
||||
|
@ -45,8 +45,8 @@
|
||||
{{"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 class="col-6" *ngIf="VideoData.duration"><ng-container i18n>duration</ng-container>: {{VideoData.duration | duration}}</div>
|
||||
<div class="col-6" *ngIf="VideoData.bitRate"><ng-container i18n>bit rate</ng-container>: {{calcSize(VideoData.bitRate)}}/s</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -28,14 +28,6 @@ export class InfoPanelLightboxComponent {
|
||||
return (this.media.metadata.size.width * this.media.metadata.size.height / 1000000).toFixed(2);
|
||||
}
|
||||
|
||||
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'];
|
||||
|
30
frontend/app/pipes/DurationPipe.ts
Normal file
30
frontend/app/pipes/DurationPipe.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import {Pipe, PipeTransform} from '@angular/core';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
|
||||
|
||||
@Pipe({name: 'duration'})
|
||||
export class DurationPipe implements PipeTransform {
|
||||
constructor(private i18n: I18n) {
|
||||
}
|
||||
|
||||
transform(time: number): string {
|
||||
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);
|
||||
|
||||
let str = '';
|
||||
if (h > 0) {
|
||||
str += h + this.i18n({value: 'h', meaning: 'hour'});
|
||||
}
|
||||
if (m > 0) {
|
||||
str += m + this.i18n({value: 'm', meaning: 'minute'});
|
||||
}
|
||||
if (s > 0) {
|
||||
str += s + this.i18n({value: 's', meaning: 'second'});
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,8 @@ gulp.task('build-frontend', function (done) {
|
||||
});
|
||||
|
||||
gulp.task('copy-static', function () {
|
||||
return gulp.src([
|
||||
return gulp.src([
|
||||
"backend/model/diagnostics/blank.jpg",
|
||||
"README.md",
|
||||
"LICENSE"], {base: "."})
|
||||
.pipe(gulp.dest('./release'));
|
||||
|
Loading…
Reference in New Issue
Block a user