]>
Commit | Line | Data |
---|---|---|
6ea59f41 C |
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' | |
7 | ||
8 | @Component({ | |
9 | selector: 'my-video-rate', | |
10 | templateUrl: './video-rate.component.html', | |
11 | styleUrls: [ './video-rate.component.scss' ] | |
12 | }) | |
13 | export class VideoRateComponent implements OnInit, OnChanges, OnDestroy { | |
14 | @Input() video: VideoDetails | |
15 | @Input() isUserLoggedIn: boolean | |
16 | ||
17 | @Output() userRatingLoaded = new EventEmitter<UserVideoRateType>() | |
18 | @Output() rateUpdated = new EventEmitter<UserVideoRateType>() | |
19 | ||
20 | userRating: UserVideoRateType | |
21 | ||
22 | tooltipLike = '' | |
23 | tooltipDislike = '' | |
24 | ||
25 | private hotkeys: Hotkey[] | |
26 | ||
27 | constructor ( | |
28 | private videoService: VideoService, | |
29 | private notifier: Notifier, | |
30 | private hotkeysService: HotkeysService, | |
31 | private screenService: ScreenService | |
32 | ) { } | |
33 | ||
06a55579 | 34 | ngOnInit () { |
6ea59f41 C |
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` | |
39 | } | |
40 | ||
41 | if (this.isUserLoggedIn) { | |
42 | this.hotkeys = [ | |
43 | new Hotkey('shift+l', () => { | |
44 | this.setLike() | |
45 | return false | |
46 | }, undefined, $localize`Like the video`), | |
47 | ||
48 | new Hotkey('shift+d', () => { | |
49 | this.setDislike() | |
50 | return false | |
51 | }, undefined, $localize`Dislike the video`) | |
52 | ] | |
53 | ||
54 | this.hotkeysService.add(this.hotkeys) | |
55 | } | |
56 | } | |
57 | ||
58 | ngOnChanges () { | |
59 | this.checkUserRating() | |
60 | } | |
61 | ||
62 | ngOnDestroy () { | |
63 | this.hotkeysService.remove(this.hotkeys) | |
64 | } | |
65 | ||
66 | setLike () { | |
67 | if (this.isUserLoggedIn === false) return | |
68 | ||
69 | // Already liked this video | |
70 | if (this.userRating === 'like') this.setRating('none') | |
71 | else this.setRating('like') | |
72 | } | |
73 | ||
74 | setDislike () { | |
75 | if (this.isUserLoggedIn === false) return | |
76 | ||
77 | // Already disliked this video | |
78 | if (this.userRating === 'dislike') this.setRating('none') | |
79 | else this.setRating('dislike') | |
80 | } | |
81 | ||
82 | getRatePopoverText () { | |
83 | if (this.isUserLoggedIn) return undefined | |
84 | ||
85 | return $localize`You need to be <a href="/login">logged in</a> to rate this video.` | |
86 | } | |
87 | ||
88 | private checkUserRating () { | |
89 | // Unlogged users do not have ratings | |
90 | if (this.isUserLoggedIn === false) return | |
91 | ||
7c07259a | 92 | this.videoService.getUserVideoRating(this.video.uuid) |
1378c0d3 C |
93 | .subscribe({ |
94 | next: ratingObject => { | |
6ea59f41 C |
95 | if (!ratingObject) return |
96 | ||
97 | this.userRating = ratingObject.rating | |
98 | this.userRatingLoaded.emit(this.userRating) | |
99 | }, | |
100 | ||
1378c0d3 C |
101 | error: err => this.notifier.error(err.message) |
102 | }) | |
6ea59f41 C |
103 | } |
104 | ||
105 | private setRating (nextRating: UserVideoRateType) { | |
7c07259a | 106 | const ratingMethods: { [id in UserVideoRateType]: (id: string) => Observable<any> } = { |
6ea59f41 C |
107 | like: this.videoService.setVideoLike, |
108 | dislike: this.videoService.setVideoDislike, | |
109 | none: this.videoService.unsetVideoLike | |
110 | } | |
111 | ||
7c07259a | 112 | ratingMethods[nextRating].call(this.videoService, this.video.uuid) |
1378c0d3 C |
113 | .subscribe({ |
114 | next: () => { | |
6ea59f41 C |
115 | // Update the video like attribute |
116 | this.updateVideoRating(this.userRating, nextRating) | |
117 | this.userRating = nextRating | |
118 | this.rateUpdated.emit(this.userRating) | |
119 | }, | |
120 | ||
1378c0d3 C |
121 | error: err => this.notifier.error(err.message) |
122 | }) | |
6ea59f41 C |
123 | } |
124 | ||
125 | private updateVideoRating (oldRating: UserVideoRateType, newRating: UserVideoRateType) { | |
126 | let likesToIncrement = 0 | |
127 | let dislikesToIncrement = 0 | |
128 | ||
129 | if (oldRating) { | |
130 | if (oldRating === 'like') likesToIncrement-- | |
131 | if (oldRating === 'dislike') dislikesToIncrement-- | |
132 | } | |
133 | ||
134 | if (newRating === 'like') likesToIncrement++ | |
135 | if (newRating === 'dislike') dislikesToIncrement++ | |
136 | ||
137 | this.video.likes += likesToIncrement | |
138 | this.video.dislikes += dislikesToIncrement | |
139 | ||
140 | this.video.buildLikeAndDislikePercents() | |
141 | } | |
142 | } |