1 import { Hotkey, HotkeysService } from 'angular2-hotkeys'
2 import { Observable } from 'rxjs'
3 import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output } from '@angular/core'
4 import { Notifier, ScreenService } from '@app/core'
5 import { VideoDetails, VideoService } from '@app/shared/shared-main'
6 import { UserVideoRateType } from '@shared/models'
9 selector: 'my-video-rate',
10 templateUrl: './video-rate.component.html',
11 styleUrls: [ './video-rate.component.scss' ]
13 export class VideoRateComponent implements OnInit, OnChanges, OnDestroy {
14 @Input() video: VideoDetails
15 @Input() isUserLoggedIn: boolean
17 @Output() userRatingLoaded = new EventEmitter<UserVideoRateType>()
18 @Output() rateUpdated = new EventEmitter<UserVideoRateType>()
20 userRating: UserVideoRateType
25 private hotkeys: Hotkey[]
28 private videoService: VideoService,
29 private notifier: Notifier,
30 private hotkeysService: HotkeysService,
31 private screenService: ScreenService
35 // Hide the tooltips for unlogged users in mobile view, this adds confusion with the popover
36 if (this.isUserLoggedIn || !this.screenService.isInMobileView()) {
37 this.tooltipLike = $localize`Like this video`
38 this.tooltipDislike = $localize`Dislike this video`
41 if (this.isUserLoggedIn) {
43 new Hotkey('shift+l', () => {
46 }, undefined, $localize`Like the video`),
48 new Hotkey('shift+d', () => {
51 }, undefined, $localize`Dislike the video`)
54 this.hotkeysService.add(this.hotkeys)
59 this.checkUserRating()
63 this.hotkeysService.remove(this.hotkeys)
67 if (this.isUserLoggedIn === false) return
69 // Already liked this video
70 if (this.userRating === 'like') this.setRating('none')
71 else this.setRating('like')
75 if (this.isUserLoggedIn === false) return
77 // Already disliked this video
78 if (this.userRating === 'dislike') this.setRating('none')
79 else this.setRating('dislike')
82 getRatePopoverText () {
83 if (this.isUserLoggedIn) return undefined
85 return $localize`You need to be logged in to rate this video.`
88 private checkUserRating () {
89 // Unlogged users do not have ratings
90 if (this.isUserLoggedIn === false) return
92 this.videoService.getUserVideoRating(this.video.uuid)
94 next: ratingObject => {
95 if (!ratingObject) return
97 this.userRating = ratingObject.rating
98 this.userRatingLoaded.emit(this.userRating)
101 error: err => this.notifier.error(err.message)
105 private setRating (nextRating: UserVideoRateType) {
106 const ratingMethods: { [id in UserVideoRateType]: (id: string) => Observable<any> } = {
107 like: this.videoService.setVideoLike,
108 dislike: this.videoService.setVideoDislike,
109 none: this.videoService.unsetVideoLike
112 ratingMethods[nextRating].call(this.videoService, this.video.uuid)
115 // Update the video like attribute
116 this.updateVideoRating(this.userRating, nextRating)
117 this.userRating = nextRating
118 this.rateUpdated.emit(this.userRating)
121 error: err => this.notifier.error(err.message)
125 private updateVideoRating (oldRating: UserVideoRateType, newRating: UserVideoRateType) {
126 let likesToIncrement = 0
127 let dislikesToIncrement = 0
130 if (oldRating === 'like') likesToIncrement--
131 if (oldRating === 'dislike') dislikesToIncrement--
134 if (newRating === 'like') likesToIncrement++
135 if (newRating === 'dislike') dislikesToIncrement++
137 this.video.likes += likesToIncrement
138 this.video.dislikes += dislikesToIncrement
140 this.video.buildLikeAndDislikePercents()