diff --git a/README.md b/README.md index 2a6f4e04..f2700580 100644 --- a/README.md +++ b/README.md @@ -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` diff --git a/frontend/app/app.module.ts b/frontend/app/app.module.ts index d582dda5..70b2e5b0 100644 --- a/frontend/app/app.module.ts +++ b/frontend/app/app.module.ts @@ -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}, diff --git a/frontend/app/gallery/grid/GridMedia.ts b/frontend/app/gallery/grid/GridMedia.ts index 48f92a50..94afea1f 100644 --- a/frontend/app/gallery/grid/GridMedia.ts +++ b/frontend/app/gallery/grid/GridMedia.ts @@ -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 this.media; + } + } diff --git a/frontend/app/gallery/grid/photo/photo.grid.gallery.component.css b/frontend/app/gallery/grid/photo/photo.grid.gallery.component.css index 77b811ac..8ee32f52 100644 --- a/frontend/app/gallery/grid/photo/photo.grid.gallery.component.css +++ b/frontend/app/gallery/grid/photo/photo.grid.gallery.component.css @@ -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; +} diff --git a/frontend/app/gallery/grid/photo/photo.grid.gallery.component.html b/frontend/app/gallery/grid/photo/photo.grid.gallery.component.html index 784ea3c3..215ff045 100644 --- a/frontend/app/gallery/grid/photo/photo.grid.gallery.component.html +++ b/frontend/app/gallery/grid/photo/photo.grid.gallery.component.html @@ -1,7 +1,14 @@
- +
+ {{gridPhoto.Video.metadata.duration | duration}}
+
-
length: {{renderDuration(VideoData.duration)}}
-
bit rate: {{calcSize(VideoData.bitRate)}}/s
+
duration: {{VideoData.duration | duration}}
+
bit rate: {{calcSize(VideoData.bitRate)}}/s
diff --git a/frontend/app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts b/frontend/app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts index 4fdc2c84..21eba7d5 100644 --- a/frontend/app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts +++ b/frontend/app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.ts @@ -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']; diff --git a/frontend/app/pipes/DurationPipe.ts b/frontend/app/pipes/DurationPipe.ts new file mode 100644 index 00000000..2ac8843b --- /dev/null +++ b/frontend/app/pipes/DurationPipe.ts @@ -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; + } +} + diff --git a/gulpfile.js b/gulpfile.js index 6005bbfa..a1d23dfc 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -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'));