aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-06-29 17:00:30 +0200
committerChocobozzz <me@florianbigard.com>2021-06-29 17:00:30 +0200
commit6ea59f415461c27eea840ed204986eaefb538afc (patch)
tree39ce95e125cbf515720dcc014a279b34864877d6
parentc17ee0903ec33283351c206bc5fd7edc0af0fb12 (diff)
downloadPeerTube-6ea59f415461c27eea840ed204986eaefb538afc.tar.gz
PeerTube-6ea59f415461c27eea840ed204986eaefb538afc.tar.zst
PeerTube-6ea59f415461c27eea840ed204986eaefb538afc.zip
Create a dedicated component for video rating
-rw-r--r--client/src/app/+videos/+video-watch/video-rate.component.html23
-rw-r--r--client/src/app/+videos/+video-watch/video-rate.component.scss15
-rw-r--r--client/src/app/+videos/+video-watch/video-rate.component.ts142
-rw-r--r--client/src/app/+videos/+video-watch/video-watch.component.html27
-rw-r--r--client/src/app/+videos/+video-watch/video-watch.component.scss30
-rw-r--r--client/src/app/+videos/+video-watch/video-watch.component.ts106
-rw-r--r--client/src/app/+videos/+video-watch/video-watch.module.ts6
7 files changed, 198 insertions, 151 deletions
diff --git a/client/src/app/+videos/+video-watch/video-rate.component.html b/client/src/app/+videos/+video-watch/video-rate.component.html
new file mode 100644
index 000000000..7dd9b3678
--- /dev/null
+++ b/client/src/app/+videos/+video-watch/video-rate.component.html
@@ -0,0 +1,23 @@
1<ng-template #ratePopoverText>
2 <span [innerHTML]="getRatePopoverText()"></span>
3</ng-template>
4
5<button
6 [ngbPopover]="getRatePopoverText() && ratePopoverText" [ngClass]="{ 'activated': userRating === 'like' }" (click)="setLike()" (keyup.enter)="setLike()"
7 class="action-button action-button-like" [attr.aria-pressed]="userRating === 'like'" [attr.aria-label]="tooltipLike"
8 [ngbTooltip]="tooltipLike"
9 placement="bottom auto"
10>
11 <my-global-icon iconName="like"></my-global-icon>
12 <span *ngIf="video.likes" class="count">{{ video.likes }}</span>
13</button>
14
15<button
16 [ngbPopover]="getRatePopoverText() && ratePopoverText" [ngClass]="{ 'activated': userRating === 'dislike' }" (click)="setDislike()" (keyup.enter)="setDislike()"
17 class="action-button action-button-dislike" [attr.aria-pressed]="userRating === 'dislike'" [attr.aria-label]="tooltipDislike"
18 [ngbTooltip]="tooltipDislike"
19 placement="bottom auto"
20>
21 <my-global-icon iconName="dislike"></my-global-icon>
22 <span *ngIf="video.dislikes" class="count">{{ video.dislikes }}</span>
23</button>
diff --git a/client/src/app/+videos/+video-watch/video-rate.component.scss b/client/src/app/+videos/+video-watch/video-rate.component.scss
new file mode 100644
index 000000000..f4f696f33
--- /dev/null
+++ b/client/src/app/+videos/+video-watch/video-rate.component.scss
@@ -0,0 +1,15 @@
1@use '_variables' as *;
2@use '_mixins' as *;
3
4.action-button-like,
5.action-button-dislike {
6 filter: brightness(120%);
7
8 .count {
9 margin: 0 5px;
10 }
11}
12
13.activated {
14 color: pvar(--activatedActionButtonColor) !important;
15}
diff --git a/client/src/app/+videos/+video-watch/video-rate.component.ts b/client/src/app/+videos/+video-watch/video-rate.component.ts
new file mode 100644
index 000000000..89a666a62
--- /dev/null
+++ b/client/src/app/+videos/+video-watch/video-rate.component.ts
@@ -0,0 +1,142 @@
1import { Hotkey, HotkeysService } from 'angular2-hotkeys'
2import { Observable } from 'rxjs'
3import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output } from '@angular/core'
4import { Notifier, ScreenService } from '@app/core'
5import { VideoDetails, VideoService } from '@app/shared/shared-main'
6import { 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})
13export 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
34 async ngOnInit () {
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
92 this.videoService.getUserVideoRating(this.video.id)
93 .subscribe(
94 ratingObject => {
95 if (!ratingObject) return
96
97 this.userRating = ratingObject.rating
98 this.userRatingLoaded.emit(this.userRating)
99 },
100
101 err => this.notifier.error(err.message)
102 )
103 }
104
105 private setRating (nextRating: UserVideoRateType) {
106 const ratingMethods: { [id in UserVideoRateType]: (id: number) => Observable<any> } = {
107 like: this.videoService.setVideoLike,
108 dislike: this.videoService.setVideoDislike,
109 none: this.videoService.unsetVideoLike
110 }
111
112 ratingMethods[nextRating].call(this.videoService, this.video.id)
113 .subscribe(
114 () => {
115 // Update the video like attribute
116 this.updateVideoRating(this.userRating, nextRating)
117 this.userRating = nextRating
118 this.rateUpdated.emit(this.userRating)
119 },
120
121 (err: { message: string }) => this.notifier.error(err.message)
122 )
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}
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.html b/client/src/app/+videos/+video-watch/video-watch.component.html
index 4e424d95d..a659a7db1 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.html
+++ b/client/src/app/+videos/+video-watch/video-watch.component.html
@@ -75,30 +75,11 @@
75 </div> 75 </div>
76 76
77 <div class="video-actions-rates"> 77 <div class="video-actions-rates">
78 <ng-template #ratePopoverText>
79 <span [innerHTML]="getRatePopoverText()"></span>
80 </ng-template>
81
82 <div class="video-actions full-width justify-content-end"> 78 <div class="video-actions full-width justify-content-end">
83 <button 79 <my-video-rate
84 [ngbPopover]="getRatePopoverText() && ratePopoverText" [ngClass]="{ 'activated': userRating === 'like' }" (click)="setLike()" (keyup.enter)="setLike()" 80 [video]="video" [isUserLoggedIn]="isUserLoggedIn()"
85 class="action-button action-button-like" [attr.aria-pressed]="userRating === 'like'" [attr.aria-label]="tooltipLike" 81 (rateUpdated)="onRateUpdated($event)" (userRatingLoaded)="onRateUpdated($event)"
86 [ngbTooltip]="tooltipLike" 82 ></my-video-rate>
87 placement="bottom auto"
88 >
89 <my-global-icon iconName="like"></my-global-icon>
90 <span *ngIf="video.likes" class="count">{{ video.likes }}</span>
91 </button>
92
93 <button
94 [ngbPopover]="getRatePopoverText() && ratePopoverText" [ngClass]="{ 'activated': userRating === 'dislike' }" (click)="setDislike()" (keyup.enter)="setDislike()"
95 class="action-button action-button-dislike" [attr.aria-pressed]="userRating === 'dislike'" [attr.aria-label]="tooltipDislike"
96 [ngbTooltip]="tooltipDislike"
97 placement="bottom auto"
98 >
99 <my-global-icon iconName="dislike"></my-global-icon>
100 <span *ngIf="video.dislikes" class="count">{{ video.dislikes }}</span>
101 </button>
102 83
103 <button *ngIf="video.support" (click)="showSupportModal()" (keyup.enter)="showSupportModal()" class="action-button action-button-support" [attr.aria-label]="tooltipSupport" 84 <button *ngIf="video.support" (click)="showSupportModal()" (keyup.enter)="showSupportModal()" class="action-button action-button-support" [attr.aria-label]="tooltipSupport"
104 [ngbTooltip]="tooltipSupport" 85 [ngbTooltip]="tooltipSupport"
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.scss b/client/src/app/+videos/+video-watch/video-watch.component.scss
index 7b7934456..4d68504f5 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.scss
+++ b/client/src/app/+videos/+video-watch/video-watch.component.scss
@@ -239,7 +239,6 @@ $video-info-margin-left: 44px;
239 ::ng-deep.action-button { 239 ::ng-deep.action-button {
240 @include peertube-button; 240 @include peertube-button;
241 @include button-with-icon(21px, 0, -1px); 241 @include button-with-icon(21px, 0, -1px);
242 @include apply-svg-color(pvar(--actionButtonColor));
243 242
244 font-size: 100%; 243 font-size: 100%;
245 font-weight: $font-semibold; 244 font-weight: $font-semibold;
@@ -258,35 +257,6 @@ $video-info-margin-left: 44px;
258 opacity: 0.9; 257 opacity: 0.9;
259 } 258 }
260 259
261 &.action-button-like,
262 &.action-button-dislike {
263 filter: brightness(120%);
264
265 .count {
266 margin: 0 5px;
267 }
268 }
269
270 &.action-button-like.activated {
271 .count {
272 color: pvar(--activatedActionButtonColor);
273 }
274
275 my-global-icon {
276 @include apply-svg-color(pvar(--activatedActionButtonColor));
277 }
278 }
279
280 &.action-button-dislike.activated {
281 .count {
282 color: pvar(--activatedActionButtonColor);
283 }
284
285 my-global-icon {
286 @include apply-svg-color(pvar(--activatedActionButtonColor));
287 }
288 }
289
290 &.action-button-support { 260 &.action-button-support {
291 color: pvar(--supportButtonColor); 261 color: pvar(--supportButtonColor);
292 262
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.ts b/client/src/app/+videos/+video-watch/video-watch.component.ts
index 12b0baebe..e2fbf7524 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/+videos/+video-watch/video-watch.component.ts
@@ -1,5 +1,5 @@
1import { Hotkey, HotkeysService } from 'angular2-hotkeys' 1import { Hotkey, HotkeysService } from 'angular2-hotkeys'
2import { forkJoin, Observable, Subscription } from 'rxjs' 2import { forkJoin, Subscription } from 'rxjs'
3import { catchError } from 'rxjs/operators' 3import { catchError } from 'rxjs/operators'
4import { PlatformLocation } from '@angular/common' 4import { PlatformLocation } from '@angular/common'
5import { ChangeDetectorRef, Component, ElementRef, Inject, LOCALE_ID, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core' 5import { ChangeDetectorRef, Component, ElementRef, Inject, LOCALE_ID, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core'
@@ -77,8 +77,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
77 77
78 theaterEnabled = false 78 theaterEnabled = false
79 79
80 userRating: UserVideoRateType = null
81
82 playerPlaceholderImgSrc: string 80 playerPlaceholderImgSrc: string
83 81
84 video: VideoDetails = null 82 video: VideoDetails = null
@@ -98,10 +96,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
98 hasAlreadyAcceptedPrivacyConcern = false 96 hasAlreadyAcceptedPrivacyConcern = false
99 remoteServerDown = false 97 remoteServerDown = false
100 98
101 hotkeys: Hotkey[] = []
102
103 tooltipLike = ''
104 tooltipDislike = ''
105 tooltipSupport = '' 99 tooltipSupport = ''
106 tooltipSaveToPlaylist = '' 100 tooltipSaveToPlaylist = ''
107 101
@@ -117,6 +111,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
117 liveInfo: true 111 liveInfo: true
118 } 112 }
119 113
114 userRating: UserVideoRateType
115
120 private nextVideoUuid = '' 116 private nextVideoUuid = ''
121 private nextVideoTitle = '' 117 private nextVideoTitle = ''
122 private currentTime: number 118 private currentTime: number
@@ -127,6 +123,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
127 123
128 private serverConfig: HTMLServerConfig 124 private serverConfig: HTMLServerConfig
129 125
126 private hotkeys: Hotkey[] = []
127
130 constructor ( 128 constructor (
131 private elementRef: ElementRef, 129 private elementRef: ElementRef,
132 private changeDetector: ChangeDetectorRef, 130 private changeDetector: ChangeDetectorRef,
@@ -165,8 +163,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
165 async ngOnInit () { 163 async ngOnInit () {
166 // Hide the tooltips for unlogged users in mobile view, this adds confusion with the popover 164 // Hide the tooltips for unlogged users in mobile view, this adds confusion with the popover
167 if (this.user || !this.screenService.isInMobileView()) { 165 if (this.user || !this.screenService.isInMobileView()) {
168 this.tooltipLike = $localize`Like this video`
169 this.tooltipDislike = $localize`Dislike this video`
170 this.tooltipSupport = $localize`Support options for this video` 166 this.tooltipSupport = $localize`Support options for this video`
171 this.tooltipSaveToPlaylist = $localize`Save to playlist` 167 this.tooltipSaveToPlaylist = $localize`Save to playlist`
172 } 168 }
@@ -232,28 +228,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
232 this.hotkeysService.remove(this.hotkeys) 228 this.hotkeysService.remove(this.hotkeys)
233 } 229 }
234 230
235 setLike () {
236 if (this.isUserLoggedIn() === false) return
237
238 // Already liked this video
239 if (this.userRating === 'like') this.setRating('none')
240 else this.setRating('like')
241 }
242
243 setDislike () {
244 if (this.isUserLoggedIn() === false) return
245
246 // Already disliked this video
247 if (this.userRating === 'dislike') this.setRating('none')
248 else this.setRating('dislike')
249 }
250
251 getRatePopoverText () {
252 if (this.isUserLoggedIn()) return undefined
253
254 return $localize`You need to be <a href="/login">logged in</a> to rate this video.`
255 }
256
257 showMoreDescription () { 231 showMoreDescription () {
258 if (this.completeVideoDescription === undefined) { 232 if (this.completeVideoDescription === undefined) {
259 return this.loadCompleteDescription() 233 return this.loadCompleteDescription()
@@ -408,6 +382,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
408 this.loadVideo(videoId) 382 this.loadVideo(videoId)
409 } 383 }
410 384
385 onRateUpdated (userRating: UserVideoRateType) {
386 this.userRating = userRating
387 this.setVideoLikesBarTooltipText()
388 }
389
411 displayOtherVideosAsRow () { 390 displayOtherVideosAsRow () {
412 // Use the same value as in the SASS file 391 // Use the same value as in the SASS file
413 return this.screenService.getWindowInnerWidth() <= 1100 392 return this.screenService.getWindowInnerWidth() <= 1100
@@ -544,22 +523,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
544 this.notifier.error(errorMessage) 523 this.notifier.error(errorMessage)
545 } 524 }
546 525
547 private checkUserRating () {
548 // Unlogged users do not have ratings
549 if (this.isUserLoggedIn() === false) return
550
551 this.videoService.getUserVideoRating(this.video.id)
552 .subscribe(
553 ratingObject => {
554 if (ratingObject) {
555 this.userRating = ratingObject.rating
556 }
557 },
558
559 err => this.notifier.error(err.message)
560 )
561 }
562
563 private async onVideoFetched ( 526 private async onVideoFetched (
564 video: VideoDetails, 527 video: VideoDetails,
565 videoCaptions: VideoCaption[], 528 videoCaptions: VideoCaption[],
@@ -593,7 +556,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
593 this.setVideoLikesBarTooltipText() 556 this.setVideoLikesBarTooltipText()
594 557
595 this.setOpenGraphTags() 558 this.setOpenGraphTags()
596 this.checkUserRating()
597 559
598 const hookOptions = { 560 const hookOptions = {
599 videojs, 561 videojs,
@@ -706,44 +668,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
706 } 668 }
707 } 669 }
708 670
709 private setRating (nextRating: UserVideoRateType) {
710 const ratingMethods: { [id in UserVideoRateType]: (id: number) => Observable<any> } = {
711 like: this.videoService.setVideoLike,
712 dislike: this.videoService.setVideoDislike,
713 none: this.videoService.unsetVideoLike
714 }
715
716 ratingMethods[nextRating].call(this.videoService, this.video.id)
717 .subscribe(
718 () => {
719 // Update the video like attribute
720 this.updateVideoRating(this.userRating, nextRating)
721 this.userRating = nextRating
722 },
723
724 (err: { message: string }) => this.notifier.error(err.message)
725 )
726 }
727
728 private updateVideoRating (oldRating: UserVideoRateType, newRating: UserVideoRateType) {
729 let likesToIncrement = 0
730 let dislikesToIncrement = 0
731
732 if (oldRating) {
733 if (oldRating === 'like') likesToIncrement--
734 if (oldRating === 'dislike') dislikesToIncrement--
735 }
736
737 if (newRating === 'like') likesToIncrement++
738 if (newRating === 'dislike') dislikesToIncrement++
739
740 this.video.likes += likesToIncrement
741 this.video.dislikes += dislikesToIncrement
742
743 this.video.buildLikeAndDislikePercents()
744 this.setVideoLikesBarTooltipText()
745 }
746
747 private setOpenGraphTags () { 671 private setOpenGraphTags () {
748 this.metaService.setTitle(this.video.name) 672 this.metaService.setTitle(this.video.name)
749 673
@@ -982,16 +906,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
982 906
983 if (this.isUserLoggedIn()) { 907 if (this.isUserLoggedIn()) {
984 this.hotkeys = this.hotkeys.concat([ 908 this.hotkeys = this.hotkeys.concat([
985 new Hotkey('shift+l', () => {
986 this.setLike()
987 return false
988 }, undefined, $localize`Like the video`),
989
990 new Hotkey('shift+d', () => {
991 this.setDislike()
992 return false
993 }, undefined, $localize`Dislike the video`),
994
995 new Hotkey('shift+s', () => { 909 new Hotkey('shift+s', () => {
996 this.subscribeButton.subscribed ? this.subscribeButton.unsubscribe() : this.subscribeButton.subscribe() 910 this.subscribeButton.subscribed ? this.subscribeButton.unsubscribe() : this.subscribeButton.subscribe()
997 return false 911 return false
diff --git a/client/src/app/+videos/+video-watch/video-watch.module.ts b/client/src/app/+videos/+video-watch/video-watch.module.ts
index 62ce7be2d..57f36c723 100644
--- a/client/src/app/+videos/+video-watch/video-watch.module.ts
+++ b/client/src/app/+videos/+video-watch/video-watch.module.ts
@@ -10,6 +10,7 @@ import { SharedVideoModule } from '@app/shared/shared-video'
10import { SharedVideoCommentModule } from '@app/shared/shared-video-comment' 10import { SharedVideoCommentModule } from '@app/shared/shared-video-comment'
11import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature' 11import { SharedVideoMiniatureModule } from '@app/shared/shared-video-miniature'
12import { SharedVideoPlaylistModule } from '@app/shared/shared-video-playlist' 12import { SharedVideoPlaylistModule } from '@app/shared/shared-video-playlist'
13import { SharedActorImageModule } from '../../shared/shared-actor-image/shared-actor-image.module'
13import { VideoCommentService } from '../../shared/shared-video-comment/video-comment.service' 14import { VideoCommentService } from '../../shared/shared-video-comment/video-comment.service'
14import { VideoCommentAddComponent } from './comment/video-comment-add.component' 15import { VideoCommentAddComponent } from './comment/video-comment-add.component'
15import { VideoCommentComponent } from './comment/video-comment.component' 16import { VideoCommentComponent } from './comment/video-comment.component'
@@ -17,11 +18,11 @@ import { VideoCommentsComponent } from './comment/video-comments.component'
17import { PlayerStylesComponent } from './player-styles.component' 18import { PlayerStylesComponent } from './player-styles.component'
18import { RecommendationsModule } from './recommendations/recommendations.module' 19import { RecommendationsModule } from './recommendations/recommendations.module'
19import { TimestampRouteTransformerDirective } from './timestamp-route-transformer.directive' 20import { TimestampRouteTransformerDirective } from './timestamp-route-transformer.directive'
21import { VideoAvatarChannelComponent } from './video-avatar-channel.component'
22import { VideoRateComponent } from './video-rate.component'
20import { VideoWatchPlaylistComponent } from './video-watch-playlist.component' 23import { VideoWatchPlaylistComponent } from './video-watch-playlist.component'
21import { VideoWatchRoutingModule } from './video-watch-routing.module' 24import { VideoWatchRoutingModule } from './video-watch-routing.module'
22import { VideoWatchComponent } from './video-watch.component' 25import { VideoWatchComponent } from './video-watch.component'
23import { SharedActorImageModule } from '../../shared/shared-actor-image/shared-actor-image.module'
24import { VideoAvatarChannelComponent } from './video-avatar-channel.component'
25 26
26@NgModule({ 27@NgModule({
27 imports: [ 28 imports: [
@@ -45,6 +46,7 @@ import { VideoAvatarChannelComponent } from './video-avatar-channel.component'
45 declarations: [ 46 declarations: [
46 VideoWatchComponent, 47 VideoWatchComponent,
47 VideoWatchPlaylistComponent, 48 VideoWatchPlaylistComponent,
49 VideoRateComponent,
48 50
49 VideoCommentsComponent, 51 VideoCommentsComponent,
50 VideoCommentAddComponent, 52 VideoCommentAddComponent,