A few updates for the watch video view (#181)
authorBenjamin Bouvier <public@benj.me>
Sun, 7 Jan 2018 13:48:10 +0000 (14:48 +0100)
committerChocobozzz <me@florianbigard.com>
Sun, 7 Jan 2018 13:48:10 +0000 (14:48 +0100)
* Fixes #156: Filter out the video being watched from the list of other videos of the same author;

* Fixes #167: in the video view, hide the author's domain when it's from the current host;

* Fixes #171: Allow undoing a like/dislike;

client/src/app/shared/video/video.model.ts
client/src/app/shared/video/video.service.ts
client/src/app/videos/+video-watch/video-watch.component.html
client/src/app/videos/+video-watch/video-watch.component.ts
server/controllers/api/videos/rate.ts
server/helpers/custom-validators/videos.ts
shared/models/videos/video-rate.type.ts

index 060bf933f316d4d9f16be62ba56e93dd42a03bcc..a4b90ad94f0ae924c4db3e596f2aaf95c40fe5a1 100644 (file)
@@ -35,7 +35,10 @@ export class Video implements VideoServerModel {
   nsfw: boolean
   account: Account
 
-  private static createByString (account: string, serverHost: string) {
+  private static createByString (account: string, serverHost: string, apiURL: string) {
+    const thisHost = new URL(apiURL).host
+    if (serverHost.trim() === thisHost)
+      return account
     return account + '@' + serverHost
   }
 
@@ -78,7 +81,7 @@ export class Video implements VideoServerModel {
     this.dislikes = hash.dislikes
     this.nsfw = hash.nsfw
 
-    this.by = Video.createByString(hash.accountName, hash.serverHost)
+    this.by = Video.createByString(hash.accountName, hash.serverHost, absoluteAPIUrl)
   }
 
   isVideoNSFWForUser (user: User) {
index 073acb2b63fcab063a45238bd54e501cc5f5ab21..50761ca0c106c71cb2c8f89de8adc1951f42837f 100644 (file)
@@ -136,6 +136,10 @@ export class VideoService {
     return this.setVideoRate(id, 'dislike')
   }
 
+  unsetVideoLike (id: number) {
+    return this.setVideoRate(id, 'none')
+  }
+
   getUserVideoRating (id: number): Observable<UserVideoRate> {
     const url = UserService.BASE_USERS_URL + 'me/videos/' + id + '/rating'
 
index 514a86e280cc2d801ea3f885fb2eb132c2a28c08..a5c387638906af7d24d3174490d166a30401abd6 100644 (file)
         Other videos
       </div>
 
-      <div *ngFor="let video of otherVideos">
+      <div *ngFor="let video of otherVideosDisplayed">
         <my-video-miniature [video]="video" [user]="user"></my-video-miniature>
       </div>
     </div>
index f1f19476483f29455b5f571e388cb21b289c6357..01e4bbf4af11c8b18445f5e7467d37888359f240 100644 (file)
@@ -29,6 +29,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
   @ViewChild('videoReportModal') videoReportModal: VideoReportComponent
 
   otherVideos: Video[] = []
+  otherVideosDisplayed: Video[] = []
 
   error = false
   loading = false
@@ -69,8 +70,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
     this.videoService.getVideos({ currentPage: 1, itemsPerPage: 5 }, '-createdAt')
       .subscribe(
         data => this.otherVideos = data.videos,
-
-    err => console.error(err)
+        err => console.error(err)
       )
 
     this.paramsSub = this.route.params.subscribe(routeParams => {
@@ -102,36 +102,22 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
 
   setLike () {
     if (this.isUserLoggedIn() === false) return
-    // Already liked this video
-    if (this.userRating === 'like') return
-
-    this.videoService.setVideoLike(this.video.id)
-                     .subscribe(
-                      () => {
-                        // Update the video like attribute
-                        this.updateVideoRating(this.userRating, 'like')
-                        this.userRating = 'like'
-                      },
-
-                      err => this.notificationsService.error('Error', err.message)
-                     )
+    if (this.userRating === 'like') {
+      // Already liked this video
+      this.setRating('none')
+    } else {
+      this.setRating('like')
+    }
   }
 
   setDislike () {
     if (this.isUserLoggedIn() === false) return
-    // Already disliked this video
-    if (this.userRating === 'dislike') return
-
-    this.videoService.setVideoDislike(this.video.id)
-                     .subscribe(
-                      () => {
-                        // Update the video dislike attribute
-                        this.updateVideoRating(this.userRating, 'dislike')
-                        this.userRating = 'dislike'
-                      },
-
-                      err => this.notificationsService.error('Error', err.message)
-                     )
+    if (this.userRating === 'dislike') {
+      // Already disliked this video
+      this.setRating('none')
+    } else {
+      this.setRating('dislike')
+    }
   }
 
   blacklistVideo (event: Event) {
@@ -303,6 +289,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
   private onVideoFetched (video: VideoDetails) {
     this.video = video
 
+    if (this.otherVideos.length > 0) {
+      this.otherVideosDisplayed = this.otherVideos.filter(v => v.uuid !== this.video.uuid)
+    }
+
     let observable
     if (this.video.isVideoNSFWForUser(this.user)) {
       observable = this.confirmService.confirm(
@@ -366,6 +356,31 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
     )
   }
 
+  private setRating (nextRating) {
+    let method
+    switch (nextRating) {
+      case 'like':
+        method = this.videoService.setVideoLike
+        break
+      case 'dislike':
+        method = this.videoService.setVideoDislike
+        break
+      case 'none':
+        method = this.videoService.unsetVideoLike
+        break
+    }
+
+    method.call(this.videoService, this.video.id)
+     .subscribe(
+      () => {
+        // Update the video like attribute
+        this.updateVideoRating(this.userRating, nextRating)
+        this.userRating = nextRating
+      },
+      err => this.notificationsService.error('Error', err.message)
+     )
+  }
+
   private updateVideoRating (oldRating: UserVideoRateType, newRating: VideoRateType) {
     let likesToIncrement = 0
     let dislikesToIncrement = 0
index b470f27f6e960fca192af0aba50af2dbf9a9d1e2..a7bd570eb71f9c22e979a500783e17efca157c16 100644 (file)
@@ -62,7 +62,6 @@ async function rateVideo (req: express.Request, res: express.Response) {
         await previousRate.destroy({ transaction: t })
       } else { // Update previous rate
         previousRate.type = rateType
-
         await previousRate.save({ transaction: t })
       }
     } else if (rateType !== 'none') { // There was not a previous rate, insert a new one if there is a rate
index 1a5fdb8871403add4089879ffd681c29bf86402e..0e8a2aab2db83d96fbfa79643badc4825009d2bc 100644 (file)
@@ -65,7 +65,7 @@ function isVideoViewsValid (value: string) {
 }
 
 function isVideoRatingTypeValid (value: string) {
-  return values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
+  return value === 'none' || values(VIDEO_RATE_TYPES).indexOf(value as VideoRateType) !== -1
 }
 
 function isVideoFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
index d48774a4b45ddc91d62efb26bebcd029442393a8..17aaba5a5e9326767ec5fabf0aec8d3233d5275d 100644 (file)
@@ -1 +1 @@
-export type VideoRateType = 'like' | 'dislike'
+export type VideoRateType = 'like' | 'dislike' | 'none'