-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
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
VIDEO_DESCRIPTION,
VIDEO_TAGS
} from '../../shared'
-import { Video, VideoService } from '../shared'
+import { VideoEdit, VideoService } from '../shared'
@Component({
selector: 'my-videos-update',
videoCategories = []
videoLicences = []
videoLanguages = []
- video: Video
+ video: VideoEdit
tagValidators = VIDEO_TAGS.VALIDATORS
tagValidatorsMessages = VIDEO_TAGS.MESSAGES
import { ModalDirective } from 'ngx-bootstrap/modal'
-import { Video } from '../shared'
+import { VideoDetails } from '../shared'
@Component({
selector: 'my-video-download',
styles: [ '.resolution-block { margin-top: 20px; }' ]
})
export class VideoDownloadComponent {
- @Input() video: Video = null
+ @Input() video: VideoDetails = null
@ViewChild('modal') modal: ModalDirective
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
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
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'
playerElement: HTMLMediaElement
uploadSpeed: number
userRating: UserVideoRateType = null
- video: Video = null
+ video: VideoDetails = null
videoPlayerLoaded = false
videoNotFound = false
)
}
- private onVideoFetched (video: Video) {
+ private onVideoFetched (video: VideoDetails) {
this.video = video
let observable
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'
--- /dev/null
+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
+ }
+}
--- /dev/null
+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
+ }
+ }
+}
-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
likes: number
dislikes: number
nsfw: boolean
- files: VideoFile[]
private static createByString (author: string, podHost: string) {
return author + '@' + podHost
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
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
- }
- }
}
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,
VideoAbuseCreate,
UserVideoRateUpdate,
Video as VideoServerModel,
+ VideoDetails as VideoDetailsServerModel,
ResultList
} from '../../../../../shared'
) {}
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 = {
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) {
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'