Add start at checkbox in share modal
This commit is contained in:
parent
c9d5c64f98
commit
11b8762f9c
|
@ -51,6 +51,18 @@ function dateToHuman (date: string) {
|
||||||
return datePipe.transform(date, 'medium')
|
return datePipe.transform(date, 'medium')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function durationToString (duration: number) {
|
||||||
|
const hours = Math.floor(duration / 3600)
|
||||||
|
const minutes = Math.floor((duration % 3600) / 60)
|
||||||
|
const seconds = duration % 60
|
||||||
|
|
||||||
|
const minutesPadding = minutes >= 10 ? '' : '0'
|
||||||
|
const secondsPadding = seconds >= 10 ? '' : '0'
|
||||||
|
const displayedHours = hours > 0 ? hours.toString() + ':' : ''
|
||||||
|
|
||||||
|
return displayedHours + minutesPadding + minutes.toString() + ':' + secondsPadding + seconds.toString()
|
||||||
|
}
|
||||||
|
|
||||||
function immutableAssign <A, B> (target: A, source: B) {
|
function immutableAssign <A, B> (target: A, source: B) {
|
||||||
return Object.assign({}, target, source)
|
return Object.assign({}, target, source)
|
||||||
}
|
}
|
||||||
|
@ -114,6 +126,7 @@ function sortBy (obj: any[], key1: string, key2?: string) {
|
||||||
|
|
||||||
export {
|
export {
|
||||||
sortBy,
|
sortBy,
|
||||||
|
durationToString,
|
||||||
objectToUrlEncoded,
|
objectToUrlEncoded,
|
||||||
getParameterByName,
|
getParameterByName,
|
||||||
populateAsyncUserVideoChannels,
|
populateAsyncUserVideoChannels,
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { User } from '../'
|
||||||
import { Video as VideoServerModel, VideoPrivacy, VideoState } from '../../../../../shared'
|
import { Video as VideoServerModel, VideoPrivacy, VideoState } from '../../../../../shared'
|
||||||
import { Avatar } from '../../../../../shared/models/avatars/avatar.model'
|
import { Avatar } from '../../../../../shared/models/avatars/avatar.model'
|
||||||
import { VideoConstant } from '../../../../../shared/models/videos/video-constant.model'
|
import { VideoConstant } from '../../../../../shared/models/videos/video-constant.model'
|
||||||
import { getAbsoluteAPIUrl } from '../misc/utils'
|
import { durationToString, getAbsoluteAPIUrl } from '../misc/utils'
|
||||||
import { peertubeTranslate, ServerConfig } from '../../../../../shared/models'
|
import { peertubeTranslate, ServerConfig } from '../../../../../shared/models'
|
||||||
import { Actor } from '@app/shared/actor/actor.model'
|
import { Actor } from '@app/shared/actor/actor.model'
|
||||||
import { VideoScheduleUpdate } from '../../../../../shared/models/videos/video-schedule-update.model'
|
import { VideoScheduleUpdate } from '../../../../../shared/models/videos/video-schedule-update.model'
|
||||||
|
@ -70,18 +70,6 @@ export class Video implements VideoServerModel {
|
||||||
return '/videos/watch/' + videoUUID
|
return '/videos/watch/' + videoUUID
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createDurationString (duration: number) {
|
|
||||||
const hours = Math.floor(duration / 3600)
|
|
||||||
const minutes = Math.floor((duration % 3600) / 60)
|
|
||||||
const seconds = duration % 60
|
|
||||||
|
|
||||||
const minutesPadding = minutes >= 10 ? '' : '0'
|
|
||||||
const secondsPadding = seconds >= 10 ? '' : '0'
|
|
||||||
const displayedHours = hours > 0 ? hours.toString() + ':' : ''
|
|
||||||
|
|
||||||
return displayedHours + minutesPadding + minutes.toString() + ':' + secondsPadding + seconds.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor (hash: VideoServerModel, translations = {}) {
|
constructor (hash: VideoServerModel, translations = {}) {
|
||||||
const absoluteAPIUrl = getAbsoluteAPIUrl()
|
const absoluteAPIUrl = getAbsoluteAPIUrl()
|
||||||
|
|
||||||
|
@ -95,7 +83,7 @@ export class Video implements VideoServerModel {
|
||||||
this.state = hash.state
|
this.state = hash.state
|
||||||
this.description = hash.description
|
this.description = hash.description
|
||||||
this.duration = hash.duration
|
this.duration = hash.duration
|
||||||
this.durationLabel = Video.createDurationString(hash.duration)
|
this.durationLabel = durationToString(hash.duration)
|
||||||
this.id = hash.id
|
this.id = hash.id
|
||||||
this.uuid = hash.uuid
|
this.uuid = hash.uuid
|
||||||
this.isLocal = hash.isLocal
|
this.isLocal = hash.isLocal
|
||||||
|
|
|
@ -17,6 +17,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group qr-code-group">
|
||||||
|
<label i18n>QR-Code</label>
|
||||||
|
<ngx-qrcode qrc-element-type="url" [qrc-value]="getVideoUrl()" qrc-errorCorrectionLevel="Q"></ngx-qrcode>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label i18n>Embed</label>
|
<label i18n>Embed</label>
|
||||||
<div class="input-group input-group-sm">
|
<div class="input-group input-group-sm">
|
||||||
|
@ -32,15 +37,17 @@
|
||||||
<div i18n *ngIf="notSecure()" class="alert alert-warning">
|
<div i18n *ngIf="notSecure()" class="alert alert-warning">
|
||||||
The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites).
|
The url is not secured (no HTTPS), so the embed video won't work on HTTPS websites (web browsers block non secured HTTP requests on HTTPS websites).
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group qr-code-group">
|
<div *ngIf="currentVideoTimestampString" class="start-at">
|
||||||
<label i18n>QR-Code</label>
|
<my-peertube-checkbox
|
||||||
<ngx-qrcode qrc-element-type="url" [qrc-value]="getVideoUrl()" qrc-errorCorrectionLevel="Q"></ngx-qrcode>
|
inputName="startAt" [(ngModel)]="startAtCheckbox"
|
||||||
</div>
|
i18n-labelText [labelText]="getStartCheckboxLabel()"
|
||||||
|
></my-peertube-checkbox>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer inputs">
|
<div class="modal-footer inputs">
|
||||||
<span i18n class="action-button action-button-cancel" (click)="hide()">Cancel</span>
|
<span i18n class="action-button action-button-cancel" (click)="hide()">Close</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
|
@ -12,3 +12,9 @@
|
||||||
.qr-code-group {
|
.qr-code-group {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.start-at {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { Component, ElementRef, Input, ViewChild } from '@angular/core'
|
import { Component, ElementRef, Input, ViewChild } from '@angular/core'
|
||||||
import { NotificationsService } from 'angular2-notifications'
|
import { NotificationsService } from 'angular2-notifications'
|
||||||
import { VideoDetails } from '../../../shared/video/video-details.model'
|
import { VideoDetails } from '../../../shared/video/video-details.model'
|
||||||
import { buildVideoEmbed } from '../../../../assets/player/utils'
|
import { buildVideoEmbed, buildVideoLink } from '../../../../assets/player/utils'
|
||||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
import { durationToString } from '@app/shared/misc/utils'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-video-share',
|
selector: 'my-video-share',
|
||||||
|
@ -11,9 +12,14 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
styleUrls: [ './video-share.component.scss' ]
|
styleUrls: [ './video-share.component.scss' ]
|
||||||
})
|
})
|
||||||
export class VideoShareComponent {
|
export class VideoShareComponent {
|
||||||
|
@ViewChild('modal') modal: ElementRef
|
||||||
|
|
||||||
@Input() video: VideoDetails = null
|
@Input() video: VideoDetails = null
|
||||||
|
|
||||||
@ViewChild('modal') modal: ElementRef
|
startAtCheckbox = false
|
||||||
|
currentVideoTimestampString: string
|
||||||
|
|
||||||
|
private currentVideoTimestamp: number
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private modalService: NgbModal,
|
private modalService: NgbModal,
|
||||||
|
@ -23,16 +29,21 @@ export class VideoShareComponent {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
show () {
|
show (currentVideoTimestamp?: number) {
|
||||||
|
this.currentVideoTimestamp = Math.floor(currentVideoTimestamp)
|
||||||
|
this.currentVideoTimestampString = durationToString(this.currentVideoTimestamp)
|
||||||
|
|
||||||
this.modalService.open(this.modal)
|
this.modalService.open(this.modal)
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoIframeCode () {
|
getVideoIframeCode () {
|
||||||
return buildVideoEmbed(this.video.embedUrl)
|
const embedUrl = buildVideoLink(this.getVideoTimestampIfEnabled(), this.video.embedUrl)
|
||||||
|
|
||||||
|
return buildVideoEmbed(embedUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoUrl () {
|
getVideoUrl () {
|
||||||
return window.location.href
|
return buildVideoLink(this.getVideoTimestampIfEnabled())
|
||||||
}
|
}
|
||||||
|
|
||||||
notSecure () {
|
notSecure () {
|
||||||
|
@ -42,4 +53,14 @@ export class VideoShareComponent {
|
||||||
activateCopiedMessage () {
|
activateCopiedMessage () {
|
||||||
this.notificationsService.success(this.i18n('Success'), this.i18n('Copied'))
|
this.notificationsService.success(this.i18n('Success'), this.i18n('Copied'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getStartCheckboxLabel () {
|
||||||
|
return this.i18n('Start at {{timestamp}}', { timestamp: this.currentVideoTimestampString })
|
||||||
|
}
|
||||||
|
|
||||||
|
private getVideoTimestampIfEnabled () {
|
||||||
|
if (this.startAtCheckbox === true) return this.currentVideoTimestamp
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,7 +204,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
showShareModal () {
|
showShareModal () {
|
||||||
this.videoShareModal.show()
|
const currentTime = this.player ? this.player.currentTime() : undefined
|
||||||
|
|
||||||
|
this.videoShareModal.show(currentTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
showDownloadModal (event: Event) {
|
showDownloadModal (event: Event) {
|
||||||
|
@ -258,12 +260,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
return this.video.isUnblacklistableBy(this.user)
|
return this.video.isUnblacklistableBy(this.user)
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoPoster () {
|
|
||||||
if (!this.video) return ''
|
|
||||||
|
|
||||||
return this.video.previewUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
getVideoTags () {
|
getVideoTags () {
|
||||||
if (!this.video || Array.isArray(this.video.tags) === false) return []
|
if (!this.video || Array.isArray(this.video.tags) === false) return []
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,8 @@ function isMobile () {
|
||||||
return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
|
return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildVideoLink (time?: number) {
|
function buildVideoLink (time?: number, url?: string) {
|
||||||
const baseEmbedPath = window.location.pathname.replace('/embed/', '/watch/')
|
if (!url) url = window.location.origin + window.location.pathname.replace('/embed/', '/watch/')
|
||||||
const baseEmbedURL = window.location.origin + baseEmbedPath
|
|
||||||
|
|
||||||
if (time) {
|
if (time) {
|
||||||
const timeInt = Math.floor(time)
|
const timeInt = Math.floor(time)
|
||||||
|
@ -33,10 +32,10 @@ function buildVideoLink (time?: number) {
|
||||||
const params = new URLSearchParams(window.location.search)
|
const params = new URLSearchParams(window.location.search)
|
||||||
params.set('start', secondsToTime(timeInt))
|
params.set('start', secondsToTime(timeInt))
|
||||||
|
|
||||||
return baseEmbedURL + '?' + params.toString()
|
return url + '?' + params.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
return baseEmbedURL
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
function timeToInt (time: number | string) {
|
function timeToInt (time: number | string) {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
- [import-videos.js](#import-videosjs)
|
- [import-videos.js](#import-videosjs)
|
||||||
- [upload.js](#uploadjs)
|
- [upload.js](#uploadjs)
|
||||||
- [Server tools](#server-tools)
|
- [Server tools](#server-tools)
|
||||||
|
- [parse-log](#parse-log)
|
||||||
- [create-transcoding-job.js](#create-transcoding-jobjs)
|
- [create-transcoding-job.js](#create-transcoding-jobjs)
|
||||||
- [create-import-video-file-job.js](#create-import-video-file-jobjs)
|
- [create-import-video-file-job.js](#create-import-video-file-jobjs)
|
||||||
- [prune-storage.js](#prune-storagejs)
|
- [prune-storage.js](#prune-storagejs)
|
||||||
|
|
Loading…
Reference in New Issue