Add ability to share playlists in modal
This commit is contained in:
parent
4891e4c77b
commit
951b582f52
|
@ -7,7 +7,7 @@ import { DropdownAction, Video, VideoService } from '@app/shared/shared-main'
|
||||||
import { VideoBlockService } from '@app/shared/shared-moderation'
|
import { VideoBlockService } from '@app/shared/shared-moderation'
|
||||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||||
import { VideoBlacklist, VideoBlacklistType } from '@shared/models'
|
import { VideoBlacklist, VideoBlacklistType } from '@shared/models'
|
||||||
import { buildVideoEmbed, buildVideoLink } from 'src/assets/player/utils'
|
import { buildVideoOrPlaylistEmbed, buildVideoLink } from 'src/assets/player/utils'
|
||||||
import { environment } from 'src/environments/environment'
|
import { environment } from 'src/environments/environment'
|
||||||
import { DomSanitizer } from '@angular/platform-browser'
|
import { DomSanitizer } from '@angular/platform-browser'
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ export class VideoBlockListComponent extends RestTable implements OnInit, AfterV
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoEmbed (entry: VideoBlacklist) {
|
getVideoEmbed (entry: VideoBlacklist) {
|
||||||
return buildVideoEmbed(
|
return buildVideoOrPlaylistEmbed(
|
||||||
buildVideoLink({
|
buildVideoLink({
|
||||||
baseUrl: `${environment.embedUrl}/videos/embed/${entry.video.uuid}`,
|
baseUrl: `${environment.embedUrl}/videos/embed/${entry.video.uuid}`,
|
||||||
title: false,
|
title: false,
|
||||||
|
|
|
@ -135,7 +135,7 @@ export class VideoCommentComponent implements OnInit, OnChanges {
|
||||||
this.comment.account = null
|
this.comment.account = null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isUserLoggedIn() && this.authService.getUser().account.id !== this.comment.account.id) {
|
if (this.isUserLoggedIn() && this.comment.isDeleted === false && this.authService.getUser().account.id !== this.comment.account.id) {
|
||||||
this.prependModerationActions = [
|
this.prependModerationActions = [
|
||||||
{
|
{
|
||||||
label: this.i18n('Report comment'),
|
label: this.i18n('Report comment'),
|
||||||
|
|
|
@ -6,18 +6,56 @@
|
||||||
|
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="playlist" *ngIf="hasPlaylist()">
|
<div class="playlist" *ngIf="hasPlaylist()">
|
||||||
<div class="title-page title-page-single" i18n>Share the playlist</div>
|
<div class="title-page title-page-single" i18n>Share the playlist</div>
|
||||||
|
|
||||||
<my-input-readonly-copy [value]="getPlaylistUrl()"></my-input-readonly-copy>
|
<div ngbNav #nav="ngbNav" class="nav-tabs" [(activeId)]="activePlaylistId">
|
||||||
|
|
||||||
|
<ng-container ngbNavItem="url">
|
||||||
|
<a ngbNavLink i18n>URL</a>
|
||||||
|
|
||||||
|
<ng-template ngbNavContent>
|
||||||
|
<div class="nav-content">
|
||||||
|
|
||||||
|
<my-input-readonly-copy [value]="getPlaylistUrl()"></my-input-readonly-copy>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container ngbNavItem="qrcode">
|
||||||
|
<a ngbNavLink i18n>QR-Code</a>
|
||||||
|
|
||||||
|
<ng-template ngbNavContent>
|
||||||
|
<div class="nav-content">
|
||||||
|
<qrcode [qrdata]="getPlaylistUrl()" [size]="256" level="Q"></qrcode>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container ngbNavItem="embed">
|
||||||
|
<a ngbNavLink i18n>Embed</a>
|
||||||
|
|
||||||
|
<ng-template ngbNavContent>
|
||||||
|
<div class="nav-content">
|
||||||
|
<my-input-readonly-copy [value]="getPlaylistIframeCode()"></my-input-readonly-copy>
|
||||||
|
|
||||||
|
<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).
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div [ngbNavOutlet]="nav"></div>
|
||||||
|
|
||||||
<div class="filters">
|
<div class="filters">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<my-peertube-checkbox
|
<my-peertube-checkbox inputName="includeVideoInPlaylist" [(ngModel)]="includeVideoInPlaylist" i18n-labelText
|
||||||
inputName="includeVideoInPlaylist" [(ngModel)]="includeVideoInPlaylist"
|
labelText="Share the playlist at this video position"></my-peertube-checkbox>
|
||||||
i18n-labelText labelText="Share the playlist at this video position"
|
|
||||||
></my-peertube-checkbox>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -27,7 +65,7 @@
|
||||||
<div class="video">
|
<div class="video">
|
||||||
<div class="title-page title-page-single" *ngIf="hasPlaylist()" i18n>Share the video</div>
|
<div class="title-page title-page-single" *ngIf="hasPlaylist()" i18n>Share the video</div>
|
||||||
|
|
||||||
<div ngbNav #nav="ngbNav" class="nav-tabs" [(activeId)]="activeId">
|
<div ngbNav #nav="ngbNav" class="nav-tabs" [(activeId)]="activeVideoId">
|
||||||
|
|
||||||
<ng-container ngbNavItem="url">
|
<ng-container ngbNavItem="url">
|
||||||
<a ngbNavLink i18n>URL</a>
|
<a ngbNavLink i18n>URL</a>
|
||||||
|
@ -137,7 +175,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-container *ngIf="isInEmbedTab()">
|
<ng-container *ngIf="isVideoInEmbedTab()">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<my-peertube-checkbox
|
<my-peertube-checkbox
|
||||||
inputName="title" [(ngModel)]="customizations.title"
|
inputName="title" [(ngModel)]="customizations.title"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Component, ElementRef, Input, ViewChild } from '@angular/core'
|
import { Component, ElementRef, Input, ViewChild } from '@angular/core'
|
||||||
import { buildVideoEmbed, buildVideoLink } from '../../../../assets/player/utils'
|
import { buildVideoOrPlaylistEmbed, buildVideoLink, buildPlaylistLink } from '../../../../assets/player/utils'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { VideoCaption } from '@shared/models'
|
import { VideoCaption } from '@shared/models'
|
||||||
import { VideoDetails } from '@app/shared/shared-main'
|
import { VideoDetails } from '@app/shared/shared-main'
|
||||||
|
@ -24,6 +24,8 @@ type Customizations = {
|
||||||
peertubeLink: boolean
|
peertubeLink: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TabId = 'url' | 'qrcode' | 'embed'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-video-share',
|
selector: 'my-video-share',
|
||||||
templateUrl: './video-share.component.html',
|
templateUrl: './video-share.component.html',
|
||||||
|
@ -36,14 +38,18 @@ export class VideoShareComponent {
|
||||||
@Input() videoCaptions: VideoCaption[] = []
|
@Input() videoCaptions: VideoCaption[] = []
|
||||||
@Input() playlist: VideoPlaylist = null
|
@Input() playlist: VideoPlaylist = null
|
||||||
|
|
||||||
activeId: 'url' | 'qrcode' | 'embed' = 'url'
|
activeVideoId: TabId = 'url'
|
||||||
|
activePlaylistId: TabId = 'url'
|
||||||
|
|
||||||
customizations: Customizations
|
customizations: Customizations
|
||||||
isAdvancedCustomizationCollapsed = true
|
isAdvancedCustomizationCollapsed = true
|
||||||
includeVideoInPlaylist = false
|
includeVideoInPlaylist = false
|
||||||
|
|
||||||
|
private playlistPosition: number = null
|
||||||
|
|
||||||
constructor (private modalService: NgbModal) { }
|
constructor (private modalService: NgbModal) { }
|
||||||
|
|
||||||
show (currentVideoTimestamp?: number) {
|
show (currentVideoTimestamp?: number, currentPlaylistPosition?: number) {
|
||||||
let subtitle: string
|
let subtitle: string
|
||||||
if (this.videoCaptions.length !== 0) {
|
if (this.videoCaptions.length !== 0) {
|
||||||
subtitle = this.videoCaptions[0].language.id
|
subtitle = this.videoCaptions[0].language.id
|
||||||
|
@ -70,19 +76,28 @@ export class VideoShareComponent {
|
||||||
peertubeLink: true
|
peertubeLink: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.playlistPosition = currentPlaylistPosition
|
||||||
|
|
||||||
this.modalService.open(this.modal, { centered: true })
|
this.modalService.open(this.modal, { centered: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoIframeCode () {
|
getVideoIframeCode () {
|
||||||
const options = this.getOptions(this.video.embedUrl)
|
const options = this.getVideoOptions(this.video.embedUrl)
|
||||||
|
|
||||||
const embedUrl = buildVideoLink(options)
|
const embedUrl = buildVideoLink(options)
|
||||||
return buildVideoEmbed(embedUrl)
|
return buildVideoOrPlaylistEmbed(embedUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
getPlaylistIframeCode () {
|
||||||
|
const options = this.getPlaylistOptions(this.playlist.embedUrl)
|
||||||
|
|
||||||
|
const embedUrl = buildPlaylistLink(options)
|
||||||
|
return buildVideoOrPlaylistEmbed(embedUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoUrl () {
|
getVideoUrl () {
|
||||||
const baseUrl = window.location.origin + '/videos/watch/' + this.video.uuid
|
const baseUrl = window.location.origin + '/videos/watch/' + this.video.uuid
|
||||||
const options = this.getOptions(baseUrl)
|
const options = this.getVideoOptions(baseUrl)
|
||||||
|
|
||||||
return buildVideoLink(options)
|
return buildVideoLink(options)
|
||||||
}
|
}
|
||||||
|
@ -99,15 +114,23 @@ export class VideoShareComponent {
|
||||||
return window.location.protocol === 'http:'
|
return window.location.protocol === 'http:'
|
||||||
}
|
}
|
||||||
|
|
||||||
isInEmbedTab () {
|
isVideoInEmbedTab () {
|
||||||
return this.activeId === 'embed'
|
return this.activeVideoId === 'embed'
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPlaylist () {
|
hasPlaylist () {
|
||||||
return !!this.playlist
|
return !!this.playlist
|
||||||
}
|
}
|
||||||
|
|
||||||
private getOptions (baseUrl?: string) {
|
private getPlaylistOptions (baseUrl?: string) {
|
||||||
|
return {
|
||||||
|
baseUrl,
|
||||||
|
|
||||||
|
playlistPosition: this.playlistPosition || undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getVideoOptions (baseUrl?: string) {
|
||||||
return {
|
return {
|
||||||
baseUrl,
|
baseUrl,
|
||||||
|
|
||||||
|
|
|
@ -244,7 +244,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
showShareModal () {
|
showShareModal () {
|
||||||
this.pausePlayer()
|
this.pausePlayer()
|
||||||
|
|
||||||
this.videoShareModal.show(this.currentTime)
|
this.videoShareModal.show(this.currentTime, this.videoWatchPlaylist.currentPlaylistPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
isUserLoggedIn () {
|
isUserLoggedIn () {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as debug from 'debug'
|
import * as debug from 'debug'
|
||||||
import truncate from 'lodash-es/truncate'
|
import truncate from 'lodash-es/truncate'
|
||||||
import { SortMeta } from 'primeng/api'
|
import { SortMeta } from 'primeng/api'
|
||||||
import { buildVideoEmbed, buildVideoLink } from 'src/assets/player/utils'
|
import { buildVideoOrPlaylistEmbed, buildVideoLink } from 'src/assets/player/utils'
|
||||||
import { environment } from 'src/environments/environment'
|
import { environment } from 'src/environments/environment'
|
||||||
import { AfterViewInit, Component, OnInit, ViewChild, Input } from '@angular/core'
|
import { AfterViewInit, Component, OnInit, ViewChild, Input } from '@angular/core'
|
||||||
import { DomSanitizer } from '@angular/platform-browser'
|
import { DomSanitizer } from '@angular/platform-browser'
|
||||||
|
@ -141,7 +141,7 @@ export class AbuseListTableComponent extends RestTable implements OnInit, AfterV
|
||||||
}
|
}
|
||||||
|
|
||||||
getVideoEmbed (abuse: AdminAbuse) {
|
getVideoEmbed (abuse: AdminAbuse) {
|
||||||
return buildVideoEmbed(
|
return buildVideoOrPlaylistEmbed(
|
||||||
buildVideoLink({
|
buildVideoLink({
|
||||||
baseUrl: `${environment.embedUrl}/videos/embed/${abuse.video.uuid}`,
|
baseUrl: `${environment.embedUrl}/videos/embed/${abuse.video.uuid}`,
|
||||||
title: false,
|
title: false,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { mapValues, pickBy } from 'lodash-es'
|
import { mapValues, pickBy } from 'lodash-es'
|
||||||
import { buildVideoEmbed, buildVideoLink } from 'src/assets/player/utils'
|
import { buildVideoOrPlaylistEmbed, buildVideoLink } from 'src/assets/player/utils'
|
||||||
import { Component, Input, OnInit, ViewChild } from '@angular/core'
|
import { Component, Input, OnInit, ViewChild } from '@angular/core'
|
||||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
|
||||||
import { Notifier } from '@app/core'
|
import { Notifier } from '@app/core'
|
||||||
|
@ -58,7 +58,7 @@ export class VideoReportComponent extends FormReactive implements OnInit {
|
||||||
|
|
||||||
getVideoEmbed () {
|
getVideoEmbed () {
|
||||||
return this.sanitizer.bypassSecurityTrustHtml(
|
return this.sanitizer.bypassSecurityTrustHtml(
|
||||||
buildVideoEmbed(
|
buildVideoOrPlaylistEmbed(
|
||||||
buildVideoLink({
|
buildVideoLink({
|
||||||
baseUrl: this.video.embedUrl,
|
baseUrl: this.video.embedUrl,
|
||||||
title: false,
|
title: false,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { getAbsoluteAPIUrl } from '@app/helpers'
|
import { getAbsoluteAPIUrl, getAbsoluteEmbedUrl } from '@app/helpers'
|
||||||
import { Actor } from '@app/shared/shared-main'
|
import { Actor } from '@app/shared/shared-main'
|
||||||
import { peertubeTranslate } from '@shared/core-utils/i18n'
|
import { peertubeTranslate } from '@shared/core-utils/i18n'
|
||||||
import {
|
import {
|
||||||
|
@ -33,6 +33,9 @@ export class VideoPlaylist implements ServerVideoPlaylist {
|
||||||
|
|
||||||
thumbnailUrl: string
|
thumbnailUrl: string
|
||||||
|
|
||||||
|
embedPath: string
|
||||||
|
embedUrl: string
|
||||||
|
|
||||||
ownerBy: string
|
ownerBy: string
|
||||||
ownerAvatarUrl: string
|
ownerAvatarUrl: string
|
||||||
|
|
||||||
|
@ -63,6 +66,9 @@ export class VideoPlaylist implements ServerVideoPlaylist {
|
||||||
this.thumbnailUrl = window.location.origin + '/client/assets/images/default-playlist.jpg'
|
this.thumbnailUrl = window.location.origin + '/client/assets/images/default-playlist.jpg'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.embedPath = hash.embedPath
|
||||||
|
this.embedUrl = getAbsoluteEmbedUrl() + hash.embedPath
|
||||||
|
|
||||||
this.videosLength = hash.videosLength
|
this.videosLength = hash.videosLength
|
||||||
|
|
||||||
this.type = hash.type
|
this.type = hash.type
|
||||||
|
|
|
@ -35,7 +35,7 @@ import {
|
||||||
VideoJSPluginOptions
|
VideoJSPluginOptions
|
||||||
} from './peertube-videojs-typings'
|
} from './peertube-videojs-typings'
|
||||||
import { TranslationsManager } from './translations-manager'
|
import { TranslationsManager } from './translations-manager'
|
||||||
import { buildVideoEmbed, buildVideoLink, copyToClipboard, getRtcConfig, isIOS, isSafari } from './utils'
|
import { buildVideoOrPlaylistEmbed, buildVideoLink, copyToClipboard, getRtcConfig, isIOS, isSafari } from './utils'
|
||||||
|
|
||||||
// Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
|
// Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
|
||||||
(videojs.getComponent('PlaybackRateMenuButton') as any).prototype.controlText_ = 'Speed'
|
(videojs.getComponent('PlaybackRateMenuButton') as any).prototype.controlText_ = 'Speed'
|
||||||
|
@ -492,7 +492,7 @@ export class PeertubePlayerManager {
|
||||||
{
|
{
|
||||||
label: player.localize('Copy embed code'),
|
label: player.localize('Copy embed code'),
|
||||||
listener: () => {
|
listener: () => {
|
||||||
copyToClipboard(buildVideoEmbed(videoEmbedUrl))
|
copyToClipboard(buildVideoOrPlaylistEmbed(videoEmbedUrl))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -43,20 +43,20 @@ function isMobile () {
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildVideoLink (options: {
|
function buildVideoLink (options: {
|
||||||
baseUrl?: string,
|
baseUrl?: string
|
||||||
|
|
||||||
startTime?: number,
|
startTime?: number
|
||||||
stopTime?: number,
|
stopTime?: number
|
||||||
|
|
||||||
subtitle?: string,
|
subtitle?: string
|
||||||
|
|
||||||
loop?: boolean,
|
loop?: boolean
|
||||||
autoplay?: boolean,
|
autoplay?: boolean
|
||||||
muted?: boolean,
|
muted?: boolean
|
||||||
|
|
||||||
// Embed options
|
// Embed options
|
||||||
title?: boolean,
|
title?: boolean
|
||||||
warningTitle?: boolean,
|
warningTitle?: boolean
|
||||||
controls?: boolean
|
controls?: boolean
|
||||||
peertubeLink?: boolean
|
peertubeLink?: boolean
|
||||||
} = {}) {
|
} = {}) {
|
||||||
|
@ -66,10 +66,7 @@ function buildVideoLink (options: {
|
||||||
? baseUrl
|
? baseUrl
|
||||||
: window.location.origin + window.location.pathname.replace('/embed/', '/watch/')
|
: window.location.origin + window.location.pathname.replace('/embed/', '/watch/')
|
||||||
|
|
||||||
const params = new URLSearchParams(window.location.search)
|
const params = generateParams(window.location.search)
|
||||||
// Remove these unused parameters when we are on a playlist page
|
|
||||||
params.delete('videoId')
|
|
||||||
params.delete('resume')
|
|
||||||
|
|
||||||
if (options.startTime) {
|
if (options.startTime) {
|
||||||
const startTimeInt = Math.floor(options.startTime)
|
const startTimeInt = Math.floor(options.startTime)
|
||||||
|
@ -91,6 +88,28 @@ function buildVideoLink (options: {
|
||||||
if (options.controls === false) params.set('controls', '0')
|
if (options.controls === false) params.set('controls', '0')
|
||||||
if (options.peertubeLink === false) params.set('peertubeLink', '0')
|
if (options.peertubeLink === false) params.set('peertubeLink', '0')
|
||||||
|
|
||||||
|
return buildUrl(url, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildPlaylistLink (options: {
|
||||||
|
baseUrl?: string
|
||||||
|
|
||||||
|
playlistPosition: number
|
||||||
|
}) {
|
||||||
|
const { baseUrl } = options
|
||||||
|
|
||||||
|
const url = baseUrl
|
||||||
|
? baseUrl
|
||||||
|
: window.location.origin + window.location.pathname.replace('/video-playlists/embed/', '/videos/watch/playlist/')
|
||||||
|
|
||||||
|
const params = generateParams(window.location.search)
|
||||||
|
|
||||||
|
if (options.playlistPosition) params.set('playlistPosition', '' + options.playlistPosition)
|
||||||
|
|
||||||
|
return buildUrl(url, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildUrl (url: string, params: URLSearchParams) {
|
||||||
let hasParams = false
|
let hasParams = false
|
||||||
params.forEach(() => hasParams = true)
|
params.forEach(() => hasParams = true)
|
||||||
|
|
||||||
|
@ -99,6 +118,15 @@ function buildVideoLink (options: {
|
||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateParams (url: string) {
|
||||||
|
const params = new URLSearchParams(window.location.search)
|
||||||
|
// Unused parameters in embed
|
||||||
|
params.delete('videoId')
|
||||||
|
params.delete('resume')
|
||||||
|
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
function timeToInt (time: number | string) {
|
function timeToInt (time: number | string) {
|
||||||
if (!time) return 0
|
if (!time) return 0
|
||||||
if (typeof time === 'number') return time
|
if (typeof time === 'number') return time
|
||||||
|
@ -140,7 +168,7 @@ function secondsToTime (seconds: number, full = false, symbol?: string) {
|
||||||
return time
|
return time
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildVideoEmbed (embedUrl: string) {
|
function buildVideoOrPlaylistEmbed (embedUrl: string) {
|
||||||
return '<iframe width="560" height="315" ' +
|
return '<iframe width="560" height="315" ' +
|
||||||
'sandbox="allow-same-origin allow-scripts allow-popups" ' +
|
'sandbox="allow-same-origin allow-scripts allow-popups" ' +
|
||||||
'src="' + embedUrl + '" ' +
|
'src="' + embedUrl + '" ' +
|
||||||
|
@ -203,8 +231,9 @@ export {
|
||||||
timeToInt,
|
timeToInt,
|
||||||
secondsToTime,
|
secondsToTime,
|
||||||
isWebRTCDisabled,
|
isWebRTCDisabled,
|
||||||
|
buildPlaylistLink,
|
||||||
buildVideoLink,
|
buildVideoLink,
|
||||||
buildVideoEmbed,
|
buildVideoOrPlaylistEmbed,
|
||||||
videoFileMaxByResolution,
|
videoFileMaxByResolution,
|
||||||
videoFileMinByResolution,
|
videoFileMinByResolution,
|
||||||
copyToClipboard,
|
copyToClipboard,
|
||||||
|
|
|
@ -528,6 +528,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
|
||||||
},
|
},
|
||||||
|
|
||||||
thumbnailPath: this.getThumbnailStaticPath(),
|
thumbnailPath: this.getThumbnailStaticPath(),
|
||||||
|
embedPath: this.getEmbedStaticPath(),
|
||||||
|
|
||||||
type: {
|
type: {
|
||||||
id: this.type,
|
id: this.type,
|
||||||
|
|
|
@ -236,7 +236,7 @@ describe('Test video playlists', function () {
|
||||||
const playlistFromList = res.body.data[0] as VideoPlaylist
|
const playlistFromList = res.body.data[0] as VideoPlaylist
|
||||||
|
|
||||||
const res2 = await getVideoPlaylist(server.url, playlistFromList.uuid)
|
const res2 = await getVideoPlaylist(server.url, playlistFromList.uuid)
|
||||||
const playlistFromGet = res2.body
|
const playlistFromGet = res2.body as VideoPlaylist
|
||||||
|
|
||||||
for (const playlist of [ playlistFromGet, playlistFromList ]) {
|
for (const playlist of [ playlistFromGet, playlistFromList ]) {
|
||||||
expect(playlist.id).to.be.a('number')
|
expect(playlist.id).to.be.a('number')
|
||||||
|
@ -250,6 +250,7 @@ describe('Test video playlists', function () {
|
||||||
expect(playlist.privacy.label).to.equal('Public')
|
expect(playlist.privacy.label).to.equal('Public')
|
||||||
expect(playlist.type.id).to.equal(VideoPlaylistType.REGULAR)
|
expect(playlist.type.id).to.equal(VideoPlaylistType.REGULAR)
|
||||||
expect(playlist.type.label).to.equal('Regular')
|
expect(playlist.type.label).to.equal('Regular')
|
||||||
|
expect(playlist.embedPath).to.equal('/video-playlists/embed/' + playlist.uuid)
|
||||||
|
|
||||||
expect(playlist.videosLength).to.equal(0)
|
expect(playlist.videosLength).to.equal(0)
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ export interface VideoPlaylist {
|
||||||
|
|
||||||
type: VideoConstant<VideoPlaylistType>
|
type: VideoConstant<VideoPlaylistType>
|
||||||
|
|
||||||
|
embedPath: string
|
||||||
|
|
||||||
createdAt: Date | string
|
createdAt: Date | string
|
||||||
updatedAt: Date | string
|
updatedAt: Date | string
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue