Adapt client with video channels
authorChocobozzz <florian.bigard@gmail.com>
Wed, 25 Oct 2017 14:43:19 +0000 (16:43 +0200)
committerChocobozzz <florian.bigard@gmail.com>
Thu, 26 Oct 2017 07:11:38 +0000 (09:11 +0200)
13 files changed:
client/src/app/shared/users/user.model.ts
client/src/app/videos/+video-edit/video-update.component.ts
client/src/app/videos/+video-watch/video-download.component.ts
client/src/app/videos/+video-watch/video-report.component.ts
client/src/app/videos/+video-watch/video-share.component.ts
client/src/app/videos/+video-watch/video-watch.component.ts
client/src/app/videos/shared/index.ts
client/src/app/videos/shared/video-details.model.ts [new file with mode: 0644]
client/src/app/videos/shared/video-edit.model.ts [new file with mode: 0644]
client/src/app/videos/shared/video.model.ts
client/src/app/videos/shared/video.service.ts
client/src/standalone/videos/embed.ts
server/helpers/utils.ts

index bf12876c70c7cd6cf2f7139f370a7d855937c1fe..7beea5910958aa9638715bdb465350420e830413 100644 (file)
@@ -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
index 6d45265e790ad7ed457c89286485a36427473674..70cb334fddde57e1192e0b89160d7e9cf8e97a55 100644 (file)
@@ -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
index 22149aa6be6622c973abf2be3e15782a5520a8e7..c32f8d586b162dde50453142e26c4aafbb6bafdc 100644 (file)
@@ -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
 
index d9c83a640bb45a154c37d9b48cd5294fe24fa398..fc9b5a9d4b6cab7420fe4256d25f06dfbe88494f 100644 (file)
@@ -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
 
index 414ed28c6a79325f8592fb24454779214a545a24..aeef65ecfbd5a87b8b6c8083926a569dc3c3aeae 100644 (file)
@@ -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
 
index f45ffd82f3cf633ae3b6c7c72d1b77ec7dab1f6e..529e2e84f5d1ce3e6f1d3d2d9efcffe9705bb2ae 100644 (file)
@@ -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
index 8168e3bfdc859e61067ec3de7ce95684b4b222b0..dcaa4e0903a5f471a1fe6f2b6b754c4f922b72ed 100644 (file)
@@ -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'
diff --git a/client/src/app/videos/shared/video-details.model.ts b/client/src/app/videos/shared/video-details.model.ts
new file mode 100644 (file)
index 0000000..e99a5ce
--- /dev/null
@@ -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
+  }
+}
diff --git a/client/src/app/videos/shared/video-edit.model.ts b/client/src/app/videos/shared/video-edit.model.ts
new file mode 100644 (file)
index 0000000..f30d8fe
--- /dev/null
@@ -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
+    }
+  }
+}
index 6e8dfaa6f4c9ef94a8297c2c0ff428b7bba2384b..7f28710328daceeb661d29aa4f08840a6dc64043 100644 (file)
@@ -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
-    }
-  }
 }
index fc552f2b524cfb9020bb837f8dc0938201e0256e..06fb3313ea7d52127b8a1cfedff649ba8036bfee 100644 (file)
@@ -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 = {
index f2f339bcca0899f7de1efd53b7d0c917f6ff752e..f696df9680dfef25a413f04bd28a1df113f469b0 100644 (file)
@@ -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) {
index 8b81a61e173046d41a48c5067a52eeb68999476d..0ebbf48a866eaafe33c89b0fbe3c05edfee7ccc8 100644 (file)
@@ -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'