Adapt client with video channels
This commit is contained in:
parent
f5028693a8
commit
404b54e14f
|
@ -1,5 +1,23 @@
|
|||
import { User as UserServerModel, UserRole } from '../../../../../shared'
|
||||
import {
|
||||
User as UserServerModel,
|
||||
UserRole,
|
||||
VideoChannel
|
||||
} from '../../../../../shared'
|
||||
|
||||
export type UserConstructorHash = {
|
||||
id: number,
|
||||
username: string,
|
||||
email: string,
|
||||
role: UserRole,
|
||||
videoQuota?: number,
|
||||
displayNSFW?: boolean,
|
||||
createdAt?: Date,
|
||||
author?: {
|
||||
id: number
|
||||
uuid: string
|
||||
},
|
||||
videoChannels?: VideoChannel[]
|
||||
}
|
||||
export class User implements UserServerModel {
|
||||
id: number
|
||||
username: string
|
||||
|
@ -7,21 +25,23 @@ export class User implements UserServerModel {
|
|||
role: UserRole
|
||||
displayNSFW: boolean
|
||||
videoQuota: number
|
||||
author: {
|
||||
id: number
|
||||
uuid: string
|
||||
}
|
||||
videoChannels: VideoChannel[]
|
||||
createdAt: Date
|
||||
|
||||
constructor (hash: {
|
||||
id: number,
|
||||
username: string,
|
||||
email: string,
|
||||
role: UserRole,
|
||||
videoQuota?: number,
|
||||
displayNSFW?: boolean,
|
||||
createdAt?: Date
|
||||
}) {
|
||||
constructor (hash: UserConstructorHash) {
|
||||
this.id = hash.id
|
||||
this.username = hash.username
|
||||
this.email = hash.email
|
||||
this.role = hash.role
|
||||
this.author = hash.author
|
||||
|
||||
if (hash.videoChannels !== undefined) {
|
||||
this.videoChannels = hash.videoChannels
|
||||
}
|
||||
|
||||
if (hash.videoQuota !== undefined) {
|
||||
this.videoQuota = hash.videoQuota
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
VIDEO_DESCRIPTION,
|
||||
VIDEO_TAGS
|
||||
} from '../../shared'
|
||||
import { Video, VideoService } from '../shared'
|
||||
import { VideoEdit, VideoService } from '../shared'
|
||||
|
||||
@Component({
|
||||
selector: 'my-videos-update',
|
||||
|
@ -27,7 +27,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
|||
videoCategories = []
|
||||
videoLicences = []
|
||||
videoLanguages = []
|
||||
video: Video
|
||||
video: VideoEdit
|
||||
|
||||
tagValidators = VIDEO_TAGS.VALIDATORS
|
||||
tagValidatorsMessages = VIDEO_TAGS.MESSAGES
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Component, Input, ViewChild } from '@angular/core'
|
|||
|
||||
import { ModalDirective } from 'ngx-bootstrap/modal'
|
||||
|
||||
import { Video } from '../shared'
|
||||
import { VideoDetails } from '../shared'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-download',
|
||||
|
@ -10,7 +10,7 @@ import { Video } from '../shared'
|
|||
styles: [ '.resolution-block { margin-top: 20px; }' ]
|
||||
})
|
||||
export class VideoDownloadComponent {
|
||||
@Input() video: Video = null
|
||||
@Input() video: VideoDetails = null
|
||||
|
||||
@ViewChild('modal') modal: ModalDirective
|
||||
|
||||
|
|
|
@ -5,14 +5,14 @@ import { ModalDirective } from 'ngx-bootstrap/modal'
|
|||
import { NotificationsService } from 'angular2-notifications'
|
||||
|
||||
import { FormReactive, VideoAbuseService, VIDEO_ABUSE_REASON } from '../../shared'
|
||||
import { Video, VideoService } from '../shared'
|
||||
import { VideoDetails, VideoService } from '../shared'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-report',
|
||||
templateUrl: './video-report.component.html'
|
||||
})
|
||||
export class VideoReportComponent extends FormReactive implements OnInit {
|
||||
@Input() video: Video = null
|
||||
@Input() video: VideoDetails = null
|
||||
|
||||
@ViewChild('modal') modal: ModalDirective
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@ import { Component, Input, ViewChild } from '@angular/core'
|
|||
|
||||
import { ModalDirective } from 'ngx-bootstrap/modal'
|
||||
|
||||
import { Video } from '../shared'
|
||||
import { VideoDetails } from '../shared'
|
||||
|
||||
@Component({
|
||||
selector: 'my-video-share',
|
||||
templateUrl: './video-share.component.html'
|
||||
})
|
||||
export class VideoShareComponent {
|
||||
@Input() video: Video = null
|
||||
@Input() video: VideoDetails = null
|
||||
|
||||
@ViewChild('modal') modal: ModalDirective
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import { AuthService, ConfirmService } from '../../core'
|
|||
import { VideoDownloadComponent } from './video-download.component'
|
||||
import { VideoShareComponent } from './video-share.component'
|
||||
import { VideoReportComponent } from './video-report.component'
|
||||
import { Video, VideoService } from '../shared'
|
||||
import { VideoDetails, VideoService } from '../shared'
|
||||
import { VideoBlacklistService } from '../../shared'
|
||||
import { UserVideoRateType, VideoRateType } from '../../../../../shared'
|
||||
|
||||
|
@ -35,7 +35,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
playerElement: HTMLMediaElement
|
||||
uploadSpeed: number
|
||||
userRating: UserVideoRateType = null
|
||||
video: Video = null
|
||||
video: VideoDetails = null
|
||||
videoPlayerLoaded = false
|
||||
videoNotFound = false
|
||||
|
||||
|
@ -211,7 +211,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
)
|
||||
}
|
||||
|
||||
private onVideoFetched (video: Video) {
|
||||
private onVideoFetched (video: VideoDetails) {
|
||||
this.video = video
|
||||
|
||||
let observable
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export * from './sort-field.type'
|
||||
export * from './video.model'
|
||||
export * from './video-details.model'
|
||||
export * from './video-edit.model'
|
||||
export * from './video.service'
|
||||
export * from './video-pagination.model'
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
import { Video } from './video.model'
|
||||
import {
|
||||
VideoDetails as VideoDetailsServerModel,
|
||||
VideoFile,
|
||||
VideoChannel,
|
||||
VideoResolution
|
||||
} from '../../../../../shared'
|
||||
|
||||
export class VideoDetails extends Video implements VideoDetailsServerModel {
|
||||
author: string
|
||||
by: string
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
categoryLabel: string
|
||||
category: number
|
||||
licenceLabel: string
|
||||
licence: number
|
||||
languageLabel: string
|
||||
language: number
|
||||
description: string
|
||||
duration: number
|
||||
durationLabel: string
|
||||
id: number
|
||||
uuid: string
|
||||
isLocal: boolean
|
||||
name: string
|
||||
podHost: string
|
||||
tags: string[]
|
||||
thumbnailPath: string
|
||||
thumbnailUrl: string
|
||||
previewPath: string
|
||||
previewUrl: string
|
||||
embedPath: string
|
||||
embedUrl: string
|
||||
views: number
|
||||
likes: number
|
||||
dislikes: number
|
||||
nsfw: boolean
|
||||
files: VideoFile[]
|
||||
channel: VideoChannel
|
||||
|
||||
constructor (hash: VideoDetailsServerModel) {
|
||||
super(hash)
|
||||
|
||||
this.files = hash.files
|
||||
this.channel = hash.channel
|
||||
}
|
||||
|
||||
getAppropriateMagnetUri (actualDownloadSpeed = 0) {
|
||||
if (this.files === undefined || this.files.length === 0) return ''
|
||||
if (this.files.length === 1) return this.files[0].magnetUri
|
||||
|
||||
// Find first video that is good for our download speed (remember they are sorted)
|
||||
let betterResolutionFile = this.files.find(f => actualDownloadSpeed > (f.size / this.duration))
|
||||
|
||||
// If the download speed is too bad, return the lowest resolution we have
|
||||
if (betterResolutionFile === undefined) {
|
||||
betterResolutionFile = this.files.find(f => f.resolution === VideoResolution.H_240P)
|
||||
}
|
||||
|
||||
return betterResolutionFile.magnetUri
|
||||
}
|
||||
|
||||
isRemovableBy (user) {
|
||||
return user && this.isLocal === true && (this.author === user.username || user.isAdmin() === true)
|
||||
}
|
||||
|
||||
isBlackistableBy (user) {
|
||||
return user && user.isAdmin() === true && this.isLocal === false
|
||||
}
|
||||
|
||||
isUpdatableBy (user) {
|
||||
return user && this.isLocal === true && user.username === this.author
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
export class VideoEdit {
|
||||
category: number
|
||||
licence: number
|
||||
language: number
|
||||
description: string
|
||||
name: string
|
||||
tags: string[]
|
||||
nsfw: boolean
|
||||
channel: number
|
||||
uuid?: string
|
||||
id?: number
|
||||
|
||||
patch (values: Object) {
|
||||
Object.keys(values).forEach((key) => {
|
||||
this[key] = values[key]
|
||||
})
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return {
|
||||
category: this.category,
|
||||
licence: this.licence,
|
||||
language: this.language,
|
||||
description: this.description,
|
||||
name: this.name,
|
||||
tags: this.tags,
|
||||
nsfw: this.nsfw,
|
||||
channel: this.channel
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import { Video as VideoServerModel, VideoFile } from '../../../../../shared'
|
||||
import { Video as VideoServerModel } from '../../../../../shared'
|
||||
import { User } from '../../shared'
|
||||
import { VideoResolution } from '../../../../../shared/models/videos/video-resolution.enum'
|
||||
|
||||
export class Video implements VideoServerModel {
|
||||
author: string
|
||||
|
@ -32,7 +31,6 @@ export class Video implements VideoServerModel {
|
|||
likes: number
|
||||
dislikes: number
|
||||
nsfw: boolean
|
||||
files: VideoFile[]
|
||||
|
||||
private static createByString (author: string, podHost: string) {
|
||||
return author + '@' + podHost
|
||||
|
@ -47,32 +45,7 @@ export class Video implements VideoServerModel {
|
|||
return minutesPadding + minutes.toString() + ':' + secondsPadding + seconds.toString()
|
||||
}
|
||||
|
||||
constructor (hash: {
|
||||
author: string,
|
||||
createdAt: Date | string,
|
||||
categoryLabel: string,
|
||||
category: number,
|
||||
licenceLabel: string,
|
||||
licence: number,
|
||||
languageLabel: string
|
||||
language: number
|
||||
description: string,
|
||||
duration: number
|
||||
id: number,
|
||||
uuid: string,
|
||||
isLocal: boolean,
|
||||
name: string,
|
||||
podHost: string,
|
||||
tags: string[],
|
||||
thumbnailPath: string,
|
||||
previewPath: string,
|
||||
embedPath: string,
|
||||
views: number,
|
||||
likes: number,
|
||||
dislikes: number,
|
||||
nsfw: boolean,
|
||||
files: VideoFile[]
|
||||
}) {
|
||||
constructor (hash: VideoServerModel) {
|
||||
let absoluteAPIUrl = API_URL
|
||||
if (!absoluteAPIUrl) {
|
||||
// The API is on the same domain
|
||||
|
@ -106,69 +79,12 @@ export class Video implements VideoServerModel {
|
|||
this.likes = hash.likes
|
||||
this.dislikes = hash.dislikes
|
||||
this.nsfw = hash.nsfw
|
||||
this.files = hash.files
|
||||
|
||||
this.by = Video.createByString(hash.author, hash.podHost)
|
||||
}
|
||||
|
||||
isRemovableBy (user) {
|
||||
return user && this.isLocal === true && (this.author === user.username || user.isAdmin() === true)
|
||||
}
|
||||
|
||||
isBlackistableBy (user) {
|
||||
return user && user.isAdmin() === true && this.isLocal === false
|
||||
}
|
||||
|
||||
isUpdatableBy (user) {
|
||||
return user && this.isLocal === true && user.username === this.author
|
||||
}
|
||||
|
||||
isVideoNSFWForUser (user: User) {
|
||||
// If the video is NSFW and the user is not logged in, or the user does not want to display NSFW videos...
|
||||
return (this.nsfw && (!user || user.displayNSFW === false))
|
||||
}
|
||||
|
||||
getAppropriateMagnetUri (actualDownloadSpeed = 0) {
|
||||
if (this.files === undefined || this.files.length === 0) return ''
|
||||
if (this.files.length === 1) return this.files[0].magnetUri
|
||||
|
||||
// Find first video that is good for our download speed (remember they are sorted)
|
||||
let betterResolutionFile = this.files.find(f => actualDownloadSpeed > (f.size / this.duration))
|
||||
|
||||
// If the download speed is too bad, return the lowest resolution we have
|
||||
if (betterResolutionFile === undefined) {
|
||||
betterResolutionFile = this.files.find(f => f.resolution === VideoResolution.H_240P)
|
||||
}
|
||||
|
||||
return betterResolutionFile.magnetUri
|
||||
}
|
||||
|
||||
patch (values: Object) {
|
||||
Object.keys(values).forEach((key) => {
|
||||
this[key] = values[key]
|
||||
})
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return {
|
||||
author: this.author,
|
||||
createdAt: this.createdAt,
|
||||
category: this.category,
|
||||
licence: this.licence,
|
||||
language: this.language,
|
||||
description: this.description,
|
||||
duration: this.duration,
|
||||
id: this.id,
|
||||
isLocal: this.isLocal,
|
||||
name: this.name,
|
||||
podHost: this.podHost,
|
||||
tags: this.tags,
|
||||
thumbnailPath: this.thumbnailPath,
|
||||
views: this.views,
|
||||
likes: this.likes,
|
||||
dislikes: this.dislikes,
|
||||
nsfw: this.nsfw,
|
||||
files: this.files
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import {
|
|||
UserService
|
||||
} from '../../shared'
|
||||
import { Video } from './video.model'
|
||||
import { VideoDetails } from './video-details.model'
|
||||
import { VideoEdit } from './video-edit.model'
|
||||
import { VideoPagination } from './video-pagination.model'
|
||||
import {
|
||||
UserVideoRate,
|
||||
|
@ -20,6 +22,7 @@ import {
|
|||
VideoAbuseCreate,
|
||||
UserVideoRateUpdate,
|
||||
Video as VideoServerModel,
|
||||
VideoDetails as VideoDetailsServerModel,
|
||||
ResultList
|
||||
} from '../../../../../shared'
|
||||
|
||||
|
@ -34,12 +37,12 @@ export class VideoService {
|
|||
) {}
|
||||
|
||||
getVideo (uuid: string) {
|
||||
return this.authHttp.get<VideoServerModel>(VideoService.BASE_VIDEO_URL + uuid)
|
||||
.map(videoHash => new Video(videoHash))
|
||||
return this.authHttp.get<VideoDetailsServerModel>(VideoService.BASE_VIDEO_URL + uuid)
|
||||
.map(videoHash => new VideoDetails(videoHash))
|
||||
.catch((res) => this.restExtractor.handleError(res))
|
||||
}
|
||||
|
||||
updateVideo (video: Video) {
|
||||
updateVideo (video: VideoEdit) {
|
||||
const language = video.language ? video.language : null
|
||||
|
||||
const body: VideoUpdate = {
|
||||
|
|
|
@ -3,9 +3,9 @@ import './embed.scss'
|
|||
import videojs from 'video.js'
|
||||
import '../../assets/player/peertube-videojs-plugin'
|
||||
import 'videojs-dock/dist/videojs-dock.es.js'
|
||||
import { Video } from '../../../../shared'
|
||||
import { VideoDetails } from '../../../../shared'
|
||||
|
||||
function loadVideoInfo (videoId: string, callback: (err: Error, res?: Video) => void) {
|
||||
function loadVideoInfo (videoId: string, callback: (err: Error, res?: VideoDetails) => void) {
|
||||
const xhttp = new XMLHttpRequest()
|
||||
xhttp.onreadystatechange = function () {
|
||||
if (this.readyState === 4 && this.status === 200) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import * as express from 'express'
|
||||
import * as Sequelize from 'sequelize'
|
||||
import * as Promise from 'bluebird'
|
||||
|
||||
import { pseudoRandomBytesPromise } from './core-utils'
|
||||
import { CONFIG, database as db } from '../initializers'
|
||||
|
|
Loading…
Reference in New Issue