aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/videos/video-watch
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/videos/video-watch')
-rw-r--r--client/src/app/videos/video-watch/index.ts10
-rw-r--r--client/src/app/videos/video-watch/video-magnet.component.ts20
-rw-r--r--client/src/app/videos/video-watch/video-report.component.ts56
-rw-r--r--client/src/app/videos/video-watch/video-share.component.ts32
-rw-r--r--client/src/app/videos/video-watch/video-watch.component.ts323
-rw-r--r--client/src/app/videos/video-watch/webtorrent.service.ts34
6 files changed, 239 insertions, 236 deletions
diff --git a/client/src/app/videos/video-watch/index.ts b/client/src/app/videos/video-watch/index.ts
index ed0ed2fc0..6e35262d3 100644
--- a/client/src/app/videos/video-watch/index.ts
+++ b/client/src/app/videos/video-watch/index.ts
@@ -1,5 +1,5 @@
1export * from './video-magnet.component'; 1export * from './video-magnet.component'
2export * from './video-share.component'; 2export * from './video-share.component'
3export * from './video-report.component'; 3export * from './video-report.component'
4export * from './video-watch.component'; 4export * from './video-watch.component'
5export * from './webtorrent.service'; 5export * from './webtorrent.service'
diff --git a/client/src/app/videos/video-watch/video-magnet.component.ts b/client/src/app/videos/video-watch/video-magnet.component.ts
index 894fa45fc..f9432e92c 100644
--- a/client/src/app/videos/video-watch/video-magnet.component.ts
+++ b/client/src/app/videos/video-watch/video-magnet.component.ts
@@ -1,27 +1,27 @@
1import { Component, Input, ViewChild } from '@angular/core'; 1import { Component, Input, ViewChild } from '@angular/core'
2 2
3import { ModalDirective } from 'ngx-bootstrap/modal'; 3import { ModalDirective } from 'ngx-bootstrap/modal'
4 4
5import { Video } from '../shared'; 5import { Video } from '../shared'
6 6
7@Component({ 7@Component({
8 selector: 'my-video-magnet', 8 selector: 'my-video-magnet',
9 templateUrl: './video-magnet.component.html' 9 templateUrl: './video-magnet.component.html'
10}) 10})
11export class VideoMagnetComponent { 11export class VideoMagnetComponent {
12 @Input() video: Video = null; 12 @Input() video: Video = null
13 13
14 @ViewChild('modal') modal: ModalDirective; 14 @ViewChild('modal') modal: ModalDirective
15 15
16 constructor() { 16 constructor () {
17 // empty 17 // empty
18 } 18 }
19 19
20 show() { 20 show () {
21 this.modal.show(); 21 this.modal.show()
22 } 22 }
23 23
24 hide() { 24 hide () {
25 this.modal.hide(); 25 this.modal.hide()
26 } 26 }
27} 27}
diff --git a/client/src/app/videos/video-watch/video-report.component.ts b/client/src/app/videos/video-watch/video-report.component.ts
index 528005b84..61213cd68 100644
--- a/client/src/app/videos/video-watch/video-report.component.ts
+++ b/client/src/app/videos/video-watch/video-report.component.ts
@@ -1,69 +1,69 @@
1import { Component, Input, OnInit, ViewChild } from '@angular/core'; 1import { Component, Input, OnInit, ViewChild } from '@angular/core'
2import { FormBuilder, FormGroup } from '@angular/forms'; 2import { FormBuilder, FormGroup } from '@angular/forms'
3 3
4import { ModalDirective } from 'ngx-bootstrap/modal'; 4import { ModalDirective } from 'ngx-bootstrap/modal'
5import { NotificationsService } from 'angular2-notifications'; 5import { NotificationsService } from 'angular2-notifications'
6 6
7import { FormReactive, VideoAbuseService, VIDEO_ABUSE_REASON } from '../../shared'; 7import { FormReactive, VideoAbuseService, VIDEO_ABUSE_REASON } from '../../shared'
8import { Video, VideoService } from '../shared'; 8import { Video, VideoService } from '../shared'
9 9
10@Component({ 10@Component({
11 selector: 'my-video-report', 11 selector: 'my-video-report',
12 templateUrl: './video-report.component.html' 12 templateUrl: './video-report.component.html'
13}) 13})
14export class VideoReportComponent extends FormReactive implements OnInit { 14export class VideoReportComponent extends FormReactive implements OnInit {
15 @Input() video: Video = null; 15 @Input() video: Video = null
16 16
17 @ViewChild('modal') modal: ModalDirective; 17 @ViewChild('modal') modal: ModalDirective
18 18
19 error: string = null; 19 error: string = null
20 form: FormGroup; 20 form: FormGroup
21 formErrors = { 21 formErrors = {
22 reason: '' 22 reason: ''
23 }; 23 }
24 validationMessages = { 24 validationMessages = {
25 reason: VIDEO_ABUSE_REASON.MESSAGES 25 reason: VIDEO_ABUSE_REASON.MESSAGES
26 }; 26 }
27 27
28 constructor( 28 constructor (
29 private formBuilder: FormBuilder, 29 private formBuilder: FormBuilder,
30 private videoAbuseService: VideoAbuseService, 30 private videoAbuseService: VideoAbuseService,
31 private notificationsService: NotificationsService 31 private notificationsService: NotificationsService
32 ) { 32 ) {
33 super(); 33 super()
34 } 34 }
35 35
36 ngOnInit() { 36 ngOnInit () {
37 this.buildForm(); 37 this.buildForm()
38 } 38 }
39 39
40 buildForm() { 40 buildForm () {
41 this.form = this.formBuilder.group({ 41 this.form = this.formBuilder.group({
42 reason: [ '', VIDEO_ABUSE_REASON.VALIDATORS ] 42 reason: [ '', VIDEO_ABUSE_REASON.VALIDATORS ]
43 }); 43 })
44 44
45 this.form.valueChanges.subscribe(data => this.onValueChanged(data)); 45 this.form.valueChanges.subscribe(data => this.onValueChanged(data))
46 } 46 }
47 47
48 show() { 48 show () {
49 this.modal.show(); 49 this.modal.show()
50 } 50 }
51 51
52 hide() { 52 hide () {
53 this.modal.hide(); 53 this.modal.hide()
54 } 54 }
55 55
56 report() { 56 report () {
57 const reason = this.form.value['reason']; 57 const reason = this.form.value['reason']
58 58
59 this.videoAbuseService.reportVideo(this.video.id, reason) 59 this.videoAbuseService.reportVideo(this.video.id, reason)
60 .subscribe( 60 .subscribe(
61 () => { 61 () => {
62 this.notificationsService.success('Success', 'Video reported.'); 62 this.notificationsService.success('Success', 'Video reported.')
63 this.hide(); 63 this.hide()
64 }, 64 },
65 65
66 err => this.notificationsService.error('Error', err.text) 66 err => this.notificationsService.error('Error', err.text)
67 ); 67 )
68 } 68 }
69} 69}
diff --git a/client/src/app/videos/video-watch/video-share.component.ts b/client/src/app/videos/video-watch/video-share.component.ts
index aa921afc2..bbd25f5ef 100644
--- a/client/src/app/videos/video-watch/video-share.component.ts
+++ b/client/src/app/videos/video-watch/video-share.component.ts
@@ -1,42 +1,42 @@
1import { Component, Input, ViewChild } from '@angular/core'; 1import { Component, Input, ViewChild } from '@angular/core'
2 2
3import { ModalDirective } from 'ngx-bootstrap/modal'; 3import { ModalDirective } from 'ngx-bootstrap/modal'
4 4
5import { Video } from '../shared'; 5import { Video } from '../shared'
6 6
7@Component({ 7@Component({
8 selector: 'my-video-share', 8 selector: 'my-video-share',
9 templateUrl: './video-share.component.html' 9 templateUrl: './video-share.component.html'
10}) 10})
11export class VideoShareComponent { 11export class VideoShareComponent {
12 @Input() video: Video = null; 12 @Input() video: Video = null
13 13
14 @ViewChild('modal') modal: ModalDirective; 14 @ViewChild('modal') modal: ModalDirective
15 15
16 constructor() { 16 constructor () {
17 // empty 17 // empty
18 } 18 }
19 19
20 show() { 20 show () {
21 this.modal.show(); 21 this.modal.show()
22 } 22 }
23 23
24 hide() { 24 hide () {
25 this.modal.hide(); 25 this.modal.hide()
26 } 26 }
27 27
28 getVideoIframeCode() { 28 getVideoIframeCode () {
29 return '<iframe width="560" height="315" ' + 29 return '<iframe width="560" height="315" ' +
30 'src="' + window.location.origin + '/videos/embed/' + this.video.id + '" ' + 30 'src="' + window.location.origin + '/videos/embed/' + this.video.id + '" ' +
31 'frameborder="0" allowfullscreen>' + 31 'frameborder="0" allowfullscreen>' +
32 '</iframe>'; 32 '</iframe>'
33 } 33 }
34 34
35 getVideoUrl() { 35 getVideoUrl () {
36 return window.location.href; 36 return window.location.href
37 } 37 }
38 38
39 notSecure() { 39 notSecure () {
40 return window.location.protocol === 'http:'; 40 return window.location.protocol === 'http:'
41 } 41 }
42} 42}
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 bcfebf2fd..4a547f7e4 100644
--- a/client/src/app/videos/video-watch/video-watch.component.ts
+++ b/client/src/app/videos/video-watch/video-watch.component.ts
@@ -1,18 +1,18 @@
1import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core'; 1import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router'; 2import { ActivatedRoute, Router } from '@angular/router'
3import { Observable } from 'rxjs/Observable'; 3import { Observable } from 'rxjs/Observable'
4import { Subscription } from 'rxjs/Subscription'; 4import { Subscription } from 'rxjs/Subscription'
5 5
6import * as videojs from 'video.js'; 6import * as videojs from 'video.js'
7import { MetaService } from '@nglibs/meta'; 7import { MetaService } from '@nglibs/meta'
8import { NotificationsService } from 'angular2-notifications'; 8import { NotificationsService } from 'angular2-notifications'
9 9
10import { AuthService, ConfirmService } from '../../core'; 10import { AuthService, ConfirmService } from '../../core'
11import { VideoMagnetComponent } from './video-magnet.component'; 11import { VideoMagnetComponent } from './video-magnet.component'
12import { VideoShareComponent } from './video-share.component'; 12import { VideoShareComponent } from './video-share.component'
13import { VideoReportComponent } from './video-report.component'; 13import { VideoReportComponent } from './video-report.component'
14import { RateType, Video, VideoService } from '../shared'; 14import { RateType, Video, VideoService } from '../shared'
15import { WebTorrentService } from './webtorrent.service'; 15import { WebTorrentService } from './webtorrent.service'
16 16
17@Component({ 17@Component({
18 selector: 'my-video-watch', 18 selector: 'my-video-watch',
@@ -21,30 +21,30 @@ import { WebTorrentService } from './webtorrent.service';
21}) 21})
22 22
23export class VideoWatchComponent implements OnInit, OnDestroy { 23export class VideoWatchComponent implements OnInit, OnDestroy {
24 private static LOADTIME_TOO_LONG = 20000; 24 private static LOADTIME_TOO_LONG = 20000
25 25
26 @ViewChild('videoMagnetModal') videoMagnetModal: VideoMagnetComponent; 26 @ViewChild('videoMagnetModal') videoMagnetModal: VideoMagnetComponent
27 @ViewChild('videoShareModal') videoShareModal: VideoShareComponent; 27 @ViewChild('videoShareModal') videoShareModal: VideoShareComponent
28 @ViewChild('videoReportModal') videoReportModal: VideoReportComponent; 28 @ViewChild('videoReportModal') videoReportModal: VideoReportComponent
29 29
30 downloadSpeed: number; 30 downloadSpeed: number
31 error = false; 31 error = false
32 loading = false; 32 loading = false
33 numPeers: number; 33 numPeers: number
34 player: videojs.Player; 34 player: videojs.Player
35 playerElement: Element; 35 playerElement: Element
36 uploadSpeed: number; 36 uploadSpeed: number
37 userRating: RateType = null; 37 userRating: RateType = null
38 video: Video = null; 38 video: Video = null
39 videoNotFound = false; 39 videoNotFound = false
40 40
41 private errorTimer: number; 41 private errorTimer: number
42 private paramsSub: Subscription; 42 private paramsSub: Subscription
43 private errorsSub: Subscription; 43 private errorsSub: Subscription
44 private warningsSub: Subscription; 44 private warningsSub: Subscription
45 private torrentInfosInterval: number; 45 private torrentInfosInterval: number
46 46
47 constructor( 47 constructor (
48 private elementRef: ElementRef, 48 private elementRef: ElementRef,
49 private ngZone: NgZone, 49 private ngZone: NgZone,
50 private route: ActivatedRoute, 50 private route: ActivatedRoute,
@@ -57,278 +57,281 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
57 private notificationsService: NotificationsService 57 private notificationsService: NotificationsService
58 ) {} 58 ) {}
59 59
60 ngOnInit() { 60 ngOnInit () {
61 this.paramsSub = this.route.params.subscribe(routeParams => { 61 this.paramsSub = this.route.params.subscribe(routeParams => {
62 let id = routeParams['id']; 62 let id = routeParams['id']
63 this.videoService.getVideo(id).subscribe( 63 this.videoService.getVideo(id).subscribe(
64 video => this.onVideoFetched(video), 64 video => this.onVideoFetched(video),
65 65
66 error => this.videoNotFound = true 66 error => {
67 ); 67 console.error(error)
68 }); 68 this.videoNotFound = true
69 }
70 )
71 })
69 72
70 this.playerElement = this.elementRef.nativeElement.querySelector('#video-container'); 73 this.playerElement = this.elementRef.nativeElement.querySelector('#video-container')
71 74
72 const videojsOptions = { 75 const videojsOptions = {
73 controls: true, 76 controls: true,
74 autoplay: false 77 autoplay: false
75 }; 78 }
76 79
77 const self = this; 80 const self = this
78 videojs(this.playerElement, videojsOptions, function () { 81 videojs(this.playerElement, videojsOptions, function () {
79 self.player = this; 82 self.player = this
80 }); 83 })
81 84
82 this.errorsSub = this.webTorrentService.errors.subscribe(err => this.notificationsService.error('Error', err.message)); 85 this.errorsSub = this.webTorrentService.errors.subscribe(err => this.notificationsService.error('Error', err.message))
83 this.warningsSub = this.webTorrentService.errors.subscribe(err => this.notificationsService.alert('Warning', err.message)); 86 this.warningsSub = this.webTorrentService.errors.subscribe(err => this.notificationsService.alert('Warning', err.message))
84 } 87 }
85 88
86 ngOnDestroy() { 89 ngOnDestroy () {
87 // Remove WebTorrent stuff 90 // Remove WebTorrent stuff
88 console.log('Removing video from webtorrent.'); 91 console.log('Removing video from webtorrent.')
89 window.clearInterval(this.torrentInfosInterval); 92 window.clearInterval(this.torrentInfosInterval)
90 window.clearTimeout(this.errorTimer); 93 window.clearTimeout(this.errorTimer)
91 94
92 if (this.video !== null && this.webTorrentService.has(this.video.magnetUri)) { 95 if (this.video !== null && this.webTorrentService.has(this.video.magnetUri)) {
93 this.webTorrentService.remove(this.video.magnetUri); 96 this.webTorrentService.remove(this.video.magnetUri)
94 } 97 }
95 98
96 // Remove player 99 // Remove player
97 videojs(this.playerElement).dispose(); 100 videojs(this.playerElement).dispose()
98 101
99 // Unsubscribe subscriptions 102 // Unsubscribe subscriptions
100 this.paramsSub.unsubscribe(); 103 this.paramsSub.unsubscribe()
101 this.errorsSub.unsubscribe(); 104 this.errorsSub.unsubscribe()
102 this.warningsSub.unsubscribe(); 105 this.warningsSub.unsubscribe()
103 } 106 }
104 107
105 loadVideo() { 108 loadVideo () {
106 // Reset the error 109 // Reset the error
107 this.error = false; 110 this.error = false
108 // We are loading the video 111 // We are loading the video
109 this.loading = true; 112 this.loading = true
110 113
111 console.log('Adding ' + this.video.magnetUri + '.'); 114 console.log('Adding ' + this.video.magnetUri + '.')
112 115
113 // The callback might never return if there are network issues 116 // The callback might never return if there are network issues
114 // So we create a timer to inform the user the load is abnormally long 117 // So we create a timer to inform the user the load is abnormally long
115 this.errorTimer = window.setTimeout(() => this.loadTooLong(), VideoWatchComponent.LOADTIME_TOO_LONG); 118 this.errorTimer = window.setTimeout(() => this.loadTooLong(), VideoWatchComponent.LOADTIME_TOO_LONG)
116 119
117 this.webTorrentService.add(this.video.magnetUri, (torrent) => { 120 this.webTorrentService.add(this.video.magnetUri, (torrent) => {
118 // Clear the error timer 121 // Clear the error timer
119 window.clearTimeout(this.errorTimer); 122 window.clearTimeout(this.errorTimer)
120 // Maybe the error was fired by the timer, so reset it 123 // Maybe the error was fired by the timer, so reset it
121 this.error = false; 124 this.error = false
122 125
123 // We are not loading the video anymore 126 // We are not loading the video anymore
124 this.loading = false; 127 this.loading = false
125 128
126 console.log('Added ' + this.video.magnetUri + '.'); 129 console.log('Added ' + this.video.magnetUri + '.')
127 torrent.files[0].renderTo(this.playerElement, { autoplay: true }, (err) => { 130 torrent.files[0].renderTo(this.playerElement, { autoplay: true }, (err) => {
128 if (err) { 131 if (err) {
129 this.notificationsService.error('Error', 'Cannot append the file in the video element.'); 132 this.notificationsService.error('Error', 'Cannot append the file in the video element.')
130 console.error(err); 133 console.error(err)
131 } 134 }
132 }); 135 })
133 136
134 this.runInProgress(torrent); 137 this.runInProgress(torrent)
135 }); 138 })
136 } 139 }
137 140
138 setLike() { 141 setLike () {
139 if (this.isUserLoggedIn() === false) return; 142 if (this.isUserLoggedIn() === false) return
140 // Already liked this video 143 // Already liked this video
141 if (this.userRating === 'like') return; 144 if (this.userRating === 'like') return
142 145
143 this.videoService.setVideoLike(this.video.id) 146 this.videoService.setVideoLike(this.video.id)
144 .subscribe( 147 .subscribe(
145 () => { 148 () => {
146 // Update the video like attribute 149 // Update the video like attribute
147 this.updateVideoRating(this.userRating, 'like'); 150 this.updateVideoRating(this.userRating, 'like')
148 this.userRating = 'like'; 151 this.userRating = 'like'
149 }, 152 },
150 153
151 err => this.notificationsService.error('Error', err.text) 154 err => this.notificationsService.error('Error', err.text)
152 ); 155 )
153 } 156 }
154 157
155 setDislike() { 158 setDislike () {
156 if (this.isUserLoggedIn() === false) return; 159 if (this.isUserLoggedIn() === false) return
157 // Already disliked this video 160 // Already disliked this video
158 if (this.userRating === 'dislike') return; 161 if (this.userRating === 'dislike') return
159 162
160 this.videoService.setVideoDislike(this.video.id) 163 this.videoService.setVideoDislike(this.video.id)
161 .subscribe( 164 .subscribe(
162 () => { 165 () => {
163 // Update the video dislike attribute 166 // Update the video dislike attribute
164 this.updateVideoRating(this.userRating, 'dislike'); 167 this.updateVideoRating(this.userRating, 'dislike')
165 this.userRating = 'dislike'; 168 this.userRating = 'dislike'
166 }, 169 },
167 170
168 err => this.notificationsService.error('Error', err.text) 171 err => this.notificationsService.error('Error', err.text)
169 ); 172 )
170 } 173 }
171 174
172 removeVideo(event: Event) { 175 removeVideo (event: Event) {
173 event.preventDefault(); 176 event.preventDefault()
174 177
175 this.confirmService.confirm('Do you really want to delete this video?', 'Delete').subscribe( 178 this.confirmService.confirm('Do you really want to delete this video?', 'Delete').subscribe(
176 res => { 179 res => {
177 if (res === false) return; 180 if (res === false) return
178 181
179 this.videoService.removeVideo(this.video.id) 182 this.videoService.removeVideo(this.video.id)
180 .subscribe( 183 .subscribe(
181 status => { 184 status => {
182 this.notificationsService.success('Success', `Video ${this.video.name} deleted.`); 185 this.notificationsService.success('Success', `Video ${this.video.name} deleted.`)
183 // Go back to the video-list. 186 // Go back to the video-list.
184 this.router.navigate(['/videos/list']); 187 this.router.navigate(['/videos/list'])
185 }, 188 },
186 189
187 error => this.notificationsService.error('Error', error.text) 190 error => this.notificationsService.error('Error', error.text)
188 ); 191 )
189 } 192 }
190 ); 193 )
191 } 194 }
192 195
193 blacklistVideo(event: Event) { 196 blacklistVideo (event: Event) {
194 event.preventDefault(); 197 event.preventDefault()
195 198
196 this.confirmService.confirm('Do you really want to blacklist this video ?', 'Blacklist').subscribe( 199 this.confirmService.confirm('Do you really want to blacklist this video ?', 'Blacklist').subscribe(
197 res => { 200 res => {
198 if (res === false) return; 201 if (res === false) return
199 202
200 this.videoService.blacklistVideo(this.video.id) 203 this.videoService.blacklistVideo(this.video.id)
201 .subscribe( 204 .subscribe(
202 status => { 205 status => {
203 this.notificationsService.success('Success', `Video ${this.video.name} had been blacklisted.`); 206 this.notificationsService.success('Success', `Video ${this.video.name} had been blacklisted.`)
204 this.router.navigate(['/videos/list']); 207 this.router.navigate(['/videos/list'])
205 }, 208 },
206 209
207 error => this.notificationsService.error('Error', error.text) 210 error => this.notificationsService.error('Error', error.text)
208 ); 211 )
209 } 212 }
210 ); 213 )
211 } 214 }
212 215
213 showReportModal(event: Event) { 216 showReportModal (event: Event) {
214 event.preventDefault(); 217 event.preventDefault()
215 this.videoReportModal.show(); 218 this.videoReportModal.show()
216 } 219 }
217 220
218 showShareModal() { 221 showShareModal () {
219 this.videoShareModal.show(); 222 this.videoShareModal.show()
220 } 223 }
221 224
222 showMagnetUriModal(event: Event) { 225 showMagnetUriModal (event: Event) {
223 event.preventDefault(); 226 event.preventDefault()
224 this.videoMagnetModal.show(); 227 this.videoMagnetModal.show()
225 } 228 }
226 229
227 isUserLoggedIn() { 230 isUserLoggedIn () {
228 return this.authService.isLoggedIn(); 231 return this.authService.isLoggedIn()
229 } 232 }
230 233
231 canUserUpdateVideo() { 234 canUserUpdateVideo () {
232 return this.video.isUpdatableBy(this.authService.getUser()); 235 return this.video.isUpdatableBy(this.authService.getUser())
233 } 236 }
234 237
235 isVideoRemovable() { 238 isVideoRemovable () {
236 return this.video.isRemovableBy(this.authService.getUser()); 239 return this.video.isRemovableBy(this.authService.getUser())
237 } 240 }
238 241
239 isVideoBlacklistable() { 242 isVideoBlacklistable () {
240 return this.video.isBlackistableBy(this.authService.getUser()); 243 return this.video.isBlackistableBy(this.authService.getUser())
241 } 244 }
242 245
243 private checkUserRating() { 246 private checkUserRating () {
244 // Unlogged users do not have ratings 247 // Unlogged users do not have ratings
245 if (this.isUserLoggedIn() === false) return; 248 if (this.isUserLoggedIn() === false) return
246 249
247 this.videoService.getUserVideoRating(this.video.id) 250 this.videoService.getUserVideoRating(this.video.id)
248 .subscribe( 251 .subscribe(
249 ratingObject => { 252 ratingObject => {
250 if (ratingObject) { 253 if (ratingObject) {
251 this.userRating = ratingObject.rating; 254 this.userRating = ratingObject.rating
252 } 255 }
253 }, 256 },
254 257
255 err => this.notificationsService.error('Error', err.text) 258 err => this.notificationsService.error('Error', err.text)
256 ); 259 )
257 } 260 }
258 261
259 private onVideoFetched(video: Video) { 262 private onVideoFetched (video: Video) {
260 this.video = video; 263 this.video = video
261 264
262 let observable; 265 let observable
263 if (this.video.isVideoNSFWForUser(this.authService.getUser())) { 266 if (this.video.isVideoNSFWForUser(this.authService.getUser())) {
264 observable = this.confirmService.confirm('This video is not safe for work. Are you sure you want to watch it?', 'NSFW'); 267 observable = this.confirmService.confirm('This video is not safe for work. Are you sure you want to watch it?', 'NSFW')
265 } else { 268 } else {
266 observable = Observable.of(true); 269 observable = Observable.of(true)
267 } 270 }
268 271
269 observable.subscribe( 272 observable.subscribe(
270 res => { 273 res => {
271 if (res === false) { 274 if (res === false) {
272 return this.router.navigate([ '/videos/list' ]); 275 return this.router.navigate([ '/videos/list' ])
273 } 276 }
274 277
275 this.setOpenGraphTags(); 278 this.setOpenGraphTags()
276 this.loadVideo(); 279 this.loadVideo()
277 this.checkUserRating(); 280 this.checkUserRating()
278 } 281 }
279 ); 282 )
280 } 283 }
281 284
282 private updateVideoRating(oldRating: RateType, newRating: RateType) { 285 private updateVideoRating (oldRating: RateType, newRating: RateType) {
283 let likesToIncrement = 0; 286 let likesToIncrement = 0
284 let dislikesToIncrement = 0; 287 let dislikesToIncrement = 0
285 288
286 if (oldRating) { 289 if (oldRating) {
287 if (oldRating === 'like') likesToIncrement--; 290 if (oldRating === 'like') likesToIncrement--
288 if (oldRating === 'dislike') dislikesToIncrement--; 291 if (oldRating === 'dislike') dislikesToIncrement--
289 } 292 }
290 293
291 if (newRating === 'like') likesToIncrement++; 294 if (newRating === 'like') likesToIncrement++
292 if (newRating === 'dislike') dislikesToIncrement++; 295 if (newRating === 'dislike') dislikesToIncrement++
293 296
294 this.video.likes += likesToIncrement; 297 this.video.likes += likesToIncrement
295 this.video.dislikes += dislikesToIncrement; 298 this.video.dislikes += dislikesToIncrement
296 } 299 }
297 300
298 private loadTooLong() { 301 private loadTooLong () {
299 this.error = true; 302 this.error = true
300 console.error('The video load seems to be abnormally long.'); 303 console.error('The video load seems to be abnormally long.')
301 } 304 }
302 305
303 private setOpenGraphTags() { 306 private setOpenGraphTags () {
304 this.metaService.setTitle(this.video.name); 307 this.metaService.setTitle(this.video.name)
305 308
306 this.metaService.setTag('og:type', 'video'); 309 this.metaService.setTag('og:type', 'video')
307 310
308 this.metaService.setTag('og:title', this.video.name); 311 this.metaService.setTag('og:title', this.video.name)
309 this.metaService.setTag('name', this.video.name); 312 this.metaService.setTag('name', this.video.name)
310 313
311 this.metaService.setTag('og:description', this.video.description); 314 this.metaService.setTag('og:description', this.video.description)
312 this.metaService.setTag('description', this.video.description); 315 this.metaService.setTag('description', this.video.description)
313 316
314 this.metaService.setTag('og:image', this.video.thumbnailPath); 317 this.metaService.setTag('og:image', this.video.thumbnailPath)
315 318
316 this.metaService.setTag('og:duration', this.video.duration.toString()); 319 this.metaService.setTag('og:duration', this.video.duration.toString())
317 320
318 this.metaService.setTag('og:site_name', 'PeerTube'); 321 this.metaService.setTag('og:site_name', 'PeerTube')
319 322
320 this.metaService.setTag('og:url', window.location.href); 323 this.metaService.setTag('og:url', window.location.href)
321 this.metaService.setTag('url', window.location.href); 324 this.metaService.setTag('url', window.location.href)
322 } 325 }
323 326
324 private runInProgress(torrent: any) { 327 private runInProgress (torrent: any) {
325 // Refresh each second 328 // Refresh each second
326 this.torrentInfosInterval = window.setInterval(() => { 329 this.torrentInfosInterval = window.setInterval(() => {
327 this.ngZone.run(() => { 330 this.ngZone.run(() => {
328 this.downloadSpeed = torrent.downloadSpeed; 331 this.downloadSpeed = torrent.downloadSpeed
329 this.numPeers = torrent.numPeers; 332 this.numPeers = torrent.numPeers
330 this.uploadSpeed = torrent.uploadSpeed; 333 this.uploadSpeed = torrent.uploadSpeed
331 }); 334 })
332 }, 1000); 335 }, 1000)
333 } 336 }
334} 337}
diff --git a/client/src/app/videos/video-watch/webtorrent.service.ts b/client/src/app/videos/video-watch/webtorrent.service.ts
index 8936e7992..211894bfd 100644
--- a/client/src/app/videos/video-watch/webtorrent.service.ts
+++ b/client/src/app/videos/video-watch/webtorrent.service.ts
@@ -1,33 +1,33 @@
1import { Injectable } from '@angular/core'; 1import { Injectable } from '@angular/core'
2import { Subject } from 'rxjs/Subject'; 2import { Subject } from 'rxjs/Subject'
3 3
4import * as WebTorrent from 'webtorrent'; 4import * as WebTorrent from 'webtorrent'
5 5
6@Injectable() 6@Injectable()
7export class WebTorrentService { 7export class WebTorrentService {
8 errors = new Subject<Error>(); 8 errors = new Subject<Error>()
9 warnings = new Subject<Error>(); 9 warnings = new Subject<Error>()
10 10
11 // TODO: use WebTorrent @type 11 // TODO: use WebTorrent @type
12 // private client: WebTorrent.Client; 12 // private client: WebTorrent.Client
13 private client: any; 13 private client: any
14 14
15 constructor() { 15 constructor () {
16 this.client = new WebTorrent({ dht: false }); 16 this.client = new WebTorrent({ dht: false })
17 17
18 this.client.on('error', (err) => this.errors.next(err)); 18 this.client.on('error', (err) => this.errors.next(err))
19 this.client.on('warning', (err) => this.warnings.next(err)); 19 this.client.on('warning', (err) => this.warnings.next(err))
20 } 20 }
21 21
22 add(magnetUri: string, callback: Function) { 22 add (magnetUri: string, callback: Function) {
23 return this.client.add(magnetUri, callback); 23 return this.client.add(magnetUri, callback)
24 } 24 }
25 25
26 remove(magnetUri: string) { 26 remove (magnetUri: string) {
27 return this.client.remove(magnetUri); 27 return this.client.remove(magnetUri)
28 } 28 }
29 29
30 has(magnetUri: string) { 30 has (magnetUri: string) {
31 return this.client.get(magnetUri) !== null; 31 return this.client.get(magnetUri) !== null
32 } 32 }
33} 33}