diff options
-rw-r--r-- | client/package.json | 1 | ||||
-rw-r--r-- | client/src/app/core/auth/auth-user.model.ts | 2 | ||||
-rw-r--r-- | client/src/app/core/auth/auth.service.ts | 34 | ||||
-rw-r--r-- | client/src/app/videos/video-list/video-list.component.ts | 15 | ||||
-rw-r--r-- | client/src/app/videos/video-watch/video-watch.component.ts | 12 | ||||
-rw-r--r-- | client/src/app/videos/video-watch/webtorrent.service.ts | 12 | ||||
-rw-r--r-- | client/yarn.lock | 41 |
7 files changed, 88 insertions, 29 deletions
diff --git a/client/package.json b/client/package.json index a922fe107..b19a3e57d 100644 --- a/client/package.json +++ b/client/package.json | |||
@@ -93,6 +93,7 @@ | |||
93 | "zone.js": "~0.8.5" | 93 | "zone.js": "~0.8.5" |
94 | }, | 94 | }, |
95 | "devDependencies": { | 95 | "devDependencies": { |
96 | "@types/webtorrent": "^0.98.4", | ||
96 | "add-asset-html-webpack-plugin": "^2.0.1", | 97 | "add-asset-html-webpack-plugin": "^2.0.1", |
97 | "codelyzer": "^3.0.0-beta.4", | 98 | "codelyzer": "^3.0.0-beta.4", |
98 | "standard": "^10.0.0", | 99 | "standard": "^10.0.0", |
diff --git a/client/src/app/core/auth/auth-user.model.ts b/client/src/app/core/auth/auth-user.model.ts index 9cb201907..4155aea19 100644 --- a/client/src/app/core/auth/auth-user.model.ts +++ b/client/src/app/core/auth/auth-user.model.ts | |||
@@ -96,6 +96,7 @@ export class AuthUser extends User { | |||
96 | localStorage.removeItem(this.KEYS.ID) | 96 | localStorage.removeItem(this.KEYS.ID) |
97 | localStorage.removeItem(this.KEYS.ROLE) | 97 | localStorage.removeItem(this.KEYS.ROLE) |
98 | localStorage.removeItem(this.KEYS.DISPLAY_NSFW) | 98 | localStorage.removeItem(this.KEYS.DISPLAY_NSFW) |
99 | localStorage.removeItem(this.KEYS.EMAIL) | ||
99 | Tokens.flush() | 100 | Tokens.flush() |
100 | } | 101 | } |
101 | 102 | ||
@@ -130,6 +131,7 @@ export class AuthUser extends User { | |||
130 | save () { | 131 | save () { |
131 | localStorage.setItem(AuthUser.KEYS.ID, this.id.toString()) | 132 | localStorage.setItem(AuthUser.KEYS.ID, this.id.toString()) |
132 | localStorage.setItem(AuthUser.KEYS.USERNAME, this.username) | 133 | localStorage.setItem(AuthUser.KEYS.USERNAME, this.username) |
134 | localStorage.setItem(AuthUser.KEYS.EMAIL, this.email) | ||
133 | localStorage.setItem(AuthUser.KEYS.ROLE, this.role) | 135 | localStorage.setItem(AuthUser.KEYS.ROLE, this.role) |
134 | localStorage.setItem(AuthUser.KEYS.DISPLAY_NSFW, JSON.stringify(this.displayNSFW)) | 136 | localStorage.setItem(AuthUser.KEYS.DISPLAY_NSFW, JSON.stringify(this.displayNSFW)) |
135 | this.tokens.save() | 137 | this.tokens.save() |
diff --git a/client/src/app/core/auth/auth.service.ts b/client/src/app/core/auth/auth.service.ts index d5aa80512..de9e14b2d 100644 --- a/client/src/app/core/auth/auth.service.ts +++ b/client/src/app/core/auth/auth.service.ts | |||
@@ -11,7 +11,7 @@ import { NotificationsService } from 'angular2-notifications' | |||
11 | 11 | ||
12 | import { AuthStatus } from './auth-status.model' | 12 | import { AuthStatus } from './auth-status.model' |
13 | import { AuthUser } from './auth-user.model' | 13 | import { AuthUser } from './auth-user.model' |
14 | import { OAuthClientLocal } from '../../../../../shared' | 14 | import { OAuthClientLocal, UserRole } from '../../../../../shared' |
15 | // Do not use the barrel (dependency loop) | 15 | // Do not use the barrel (dependency loop) |
16 | import { RestExtractor } from '../../shared/rest' | 16 | import { RestExtractor } from '../../shared/rest' |
17 | 17 | ||
@@ -181,7 +181,10 @@ export class AuthService { | |||
181 | 181 | ||
182 | refreshUserInformations () { | 182 | refreshUserInformations () { |
183 | const obj = { | 183 | const obj = { |
184 | access_token: this.user.getAccessToken() | 184 | access_token: this.user.getAccessToken(), |
185 | refresh_token: null, | ||
186 | token_type: this.user.getTokenType(), | ||
187 | username: this.user.username | ||
185 | } | 188 | } |
186 | 189 | ||
187 | this.mergeUserInformations (obj) | 190 | this.mergeUserInformations (obj) |
@@ -195,7 +198,12 @@ export class AuthService { | |||
195 | ) | 198 | ) |
196 | } | 199 | } |
197 | 200 | ||
198 | private mergeUserInformations (obj: { access_token: string }) { | 201 | private mergeUserInformations (obj: { |
202 | access_token: string, | ||
203 | refresh_token: string, | ||
204 | token_type: string, | ||
205 | username: string | ||
206 | }) { | ||
199 | // Do not call authHttp here to avoid circular dependencies headaches | 207 | // Do not call authHttp here to avoid circular dependencies headaches |
200 | 208 | ||
201 | const headers = new Headers() | 209 | const headers = new Headers() |
@@ -205,9 +213,10 @@ export class AuthService { | |||
205 | .map(res => res.json()) | 213 | .map(res => res.json()) |
206 | .map(res => { | 214 | .map(res => { |
207 | const newProperties = { | 215 | const newProperties = { |
208 | id: res.id, | 216 | id: res.id as number, |
209 | role: res.role, | 217 | role: res.role as UserRole, |
210 | displayNSFW: res.displayNSFW | 218 | displayNSFW: res.displayNSFW as boolean, |
219 | email: res.email as string | ||
211 | } | 220 | } |
212 | 221 | ||
213 | return Object.assign(obj, newProperties) | 222 | return Object.assign(obj, newProperties) |
@@ -215,7 +224,16 @@ export class AuthService { | |||
215 | ) | 224 | ) |
216 | } | 225 | } |
217 | 226 | ||
218 | private handleLogin (obj: any) { | 227 | private handleLogin (obj: { |
228 | access_token: string, | ||
229 | refresh_token: string, | ||
230 | token_type: string, | ||
231 | id: number, | ||
232 | username: string, | ||
233 | email: string, | ||
234 | role: UserRole, | ||
235 | displayNSFW: boolean | ||
236 | }) { | ||
219 | const id = obj.id | 237 | const id = obj.id |
220 | const username = obj.username | 238 | const username = obj.username |
221 | const role = obj.role | 239 | const role = obj.role |
@@ -233,7 +251,7 @@ export class AuthService { | |||
233 | this.setStatus(AuthStatus.LoggedIn) | 251 | this.setStatus(AuthStatus.LoggedIn) |
234 | } | 252 | } |
235 | 253 | ||
236 | private handleRefreshToken (obj: any) { | 254 | private handleRefreshToken (obj: { access_token: string, refresh_token: string }) { |
237 | this.user.refreshTokens(obj.access_token, obj.refresh_token) | 255 | this.user.refreshTokens(obj.access_token, obj.refresh_token) |
238 | this.user.save() | 256 | this.user.save() |
239 | } | 257 | } |
diff --git a/client/src/app/videos/video-list/video-list.component.ts b/client/src/app/videos/video-list/video-list.component.ts index 0c36e5b08..4ac539960 100644 --- a/client/src/app/videos/video-list/video-list.component.ts +++ b/client/src/app/videos/video-list/video-list.component.ts | |||
@@ -1,5 +1,6 @@ | |||
1 | import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core' | 1 | import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core' |
2 | import { ActivatedRoute, Router } from '@angular/router' | 2 | import { ActivatedRoute, Router } from '@angular/router' |
3 | import { Subscription } from 'rxjs/Subscription' | ||
3 | import { BehaviorSubject } from 'rxjs/BehaviorSubject' | 4 | import { BehaviorSubject } from 'rxjs/BehaviorSubject' |
4 | 5 | ||
5 | import { NotificationsService } from 'angular2-notifications' | 6 | import { NotificationsService } from 'angular2-notifications' |
@@ -30,8 +31,8 @@ export class VideoListComponent implements OnInit, OnDestroy { | |||
30 | videos: Video[] = [] | 31 | videos: Video[] = [] |
31 | 32 | ||
32 | private search: Search | 33 | private search: Search |
33 | private subActivatedRoute: any | 34 | private subActivatedRoute: Subscription |
34 | private subSearch: any | 35 | private subSearch: Subscription |
35 | 36 | ||
36 | constructor ( | 37 | constructor ( |
37 | private notificationsService: NotificationsService, | 38 | private notificationsService: NotificationsService, |
@@ -98,7 +99,7 @@ export class VideoListComponent implements OnInit, OnDestroy { | |||
98 | return !this.loading.getValue() && this.videos.length === 0 | 99 | return !this.loading.getValue() && this.videos.length === 0 |
99 | } | 100 | } |
100 | 101 | ||
101 | onPageChanged (event: any) { | 102 | onPageChanged (event: { page: number }) { |
102 | // Be sure the current page is set | 103 | // Be sure the current page is set |
103 | this.pagination.currentPage = event.page | 104 | this.pagination.currentPage = event.page |
104 | 105 | ||
@@ -113,21 +114,21 @@ export class VideoListComponent implements OnInit, OnDestroy { | |||
113 | 114 | ||
114 | private buildRouteParams () { | 115 | private buildRouteParams () { |
115 | // There is always a sort and a current page | 116 | // There is always a sort and a current page |
116 | const params: any = { | 117 | const params = { |
117 | sort: this.sort, | 118 | sort: this.sort, |
118 | page: this.pagination.currentPage | 119 | page: this.pagination.currentPage |
119 | } | 120 | } |
120 | 121 | ||
121 | // Maybe there is a search | 122 | // Maybe there is a search |
122 | if (this.search.value) { | 123 | if (this.search.value) { |
123 | params.field = this.search.field | 124 | params['field'] = this.search.field |
124 | params.search = this.search.value | 125 | params['search'] = this.search.value |
125 | } | 126 | } |
126 | 127 | ||
127 | return params | 128 | return params |
128 | } | 129 | } |
129 | 130 | ||
130 | private loadRouteParams (routeParams) { | 131 | private loadRouteParams (routeParams: { [ key: string ]: any }) { |
131 | if (routeParams['search'] !== undefined) { | 132 | if (routeParams['search'] !== undefined) { |
132 | this.search = { | 133 | this.search = { |
133 | value: routeParams['search'], | 134 | value: routeParams['search'], |
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 12ddf3eef..6bd6c1f7e 100644 --- a/client/src/app/videos/video-watch/video-watch.component.ts +++ b/client/src/app/videos/video-watch/video-watch.component.ts | |||
@@ -32,7 +32,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
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: HTMLMediaElement |
36 | uploadSpeed: number | 36 | uploadSpeed: number |
37 | userRating: UserVideoRateType = null | 37 | userRating: UserVideoRateType = null |
38 | video: Video = null | 38 | video: Video = null |
@@ -41,7 +41,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
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 | ||
45 | private torrentInfosInterval: number | 44 | private torrentInfosInterval: number |
46 | 45 | ||
47 | constructor ( | 46 | constructor ( |
@@ -82,8 +81,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
82 | self.player = this | 81 | self.player = this |
83 | }) | 82 | }) |
84 | 83 | ||
85 | this.errorsSub = this.webTorrentService.errors.subscribe(err => this.notificationsService.error('Error', err.message)) | 84 | this.errorsSub = this.webTorrentService.errors.subscribe(err => { |
86 | this.warningsSub = this.webTorrentService.errors.subscribe(err => this.notificationsService.alert('Warning', err.message)) | 85 | const message = typeof err === 'string' ? err : err.message |
86 | this.notificationsService.error('Error', message) | ||
87 | }) | ||
87 | } | 88 | } |
88 | 89 | ||
89 | ngOnDestroy () { | 90 | ngOnDestroy () { |
@@ -102,7 +103,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
102 | // Unsubscribe subscriptions | 103 | // Unsubscribe subscriptions |
103 | this.paramsSub.unsubscribe() | 104 | this.paramsSub.unsubscribe() |
104 | this.errorsSub.unsubscribe() | 105 | this.errorsSub.unsubscribe() |
105 | this.warningsSub.unsubscribe() | ||
106 | } | 106 | } |
107 | 107 | ||
108 | loadVideo () { | 108 | loadVideo () { |
@@ -117,7 +117,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
117 | // 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 |
118 | this.errorTimer = window.setTimeout(() => this.loadTooLong(), VideoWatchComponent.LOADTIME_TOO_LONG) | 118 | this.errorTimer = window.setTimeout(() => this.loadTooLong(), VideoWatchComponent.LOADTIME_TOO_LONG) |
119 | 119 | ||
120 | this.webTorrentService.add(this.video.magnetUri, (torrent) => { | 120 | this.webTorrentService.add(this.video.magnetUri, torrent => { |
121 | // Clear the error timer | 121 | // Clear the error timer |
122 | window.clearTimeout(this.errorTimer) | 122 | window.clearTimeout(this.errorTimer) |
123 | // Maybe the error was fired by the timer, so reset it | 123 | // Maybe the error was fired by the timer, so reset it |
diff --git a/client/src/app/videos/video-watch/webtorrent.service.ts b/client/src/app/videos/video-watch/webtorrent.service.ts index 211894bfd..8819e17d4 100644 --- a/client/src/app/videos/video-watch/webtorrent.service.ts +++ b/client/src/app/videos/video-watch/webtorrent.service.ts | |||
@@ -5,21 +5,17 @@ import * as WebTorrent from 'webtorrent' | |||
5 | 5 | ||
6 | @Injectable() | 6 | @Injectable() |
7 | export class WebTorrentService { | 7 | export class WebTorrentService { |
8 | errors = new Subject<Error>() | 8 | errors = new Subject<string | Error>() |
9 | warnings = new Subject<Error>() | ||
10 | 9 | ||
11 | // TODO: use WebTorrent @type | 10 | private client: WebTorrent.Instance |
12 | // private client: WebTorrent.Client | ||
13 | private client: any | ||
14 | 11 | ||
15 | constructor () { | 12 | constructor () { |
16 | this.client = new WebTorrent({ dht: false }) | 13 | this.client = new WebTorrent({ dht: false }) |
17 | 14 | ||
18 | this.client.on('error', (err) => this.errors.next(err)) | 15 | this.client.on('error', err => this.errors.next(err)) |
19 | this.client.on('warning', (err) => this.warnings.next(err)) | ||
20 | } | 16 | } |
21 | 17 | ||
22 | add (magnetUri: string, callback: Function) { | 18 | add (magnetUri: string, callback: (torrent: WebTorrent.Torrent) => any) { |
23 | return this.client.add(magnetUri, callback) | 19 | return this.client.add(magnetUri, callback) |
24 | } | 20 | } |
25 | 21 | ||
diff --git a/client/yarn.lock b/client/yarn.lock index b953fcb21..9a6aff1b2 100644 --- a/client/yarn.lock +++ b/client/yarn.lock | |||
@@ -86,10 +86,22 @@ | |||
86 | dependencies: | 86 | dependencies: |
87 | tslib "^1.7.0" | 87 | tslib "^1.7.0" |
88 | 88 | ||
89 | "@types/bittorrent-protocol@*": | ||
90 | version "2.2.2" | ||
91 | resolved "https://registry.yarnpkg.com/@types/bittorrent-protocol/-/bittorrent-protocol-2.2.2.tgz#169e9633e1bd18e6b830d11cf42e611b1972cb83" | ||
92 | dependencies: | ||
93 | "@types/node" "*" | ||
94 | |||
89 | "@types/core-js@^0.9.28": | 95 | "@types/core-js@^0.9.28": |
90 | version "0.9.42" | 96 | version "0.9.42" |
91 | resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-0.9.42.tgz#dd6da92cd7d5ab5ca0b4477524537c3e633b6bce" | 97 | resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-0.9.42.tgz#dd6da92cd7d5ab5ca0b4477524537c3e633b6bce" |
92 | 98 | ||
99 | "@types/magnet-uri@*": | ||
100 | version "5.1.1" | ||
101 | resolved "https://registry.yarnpkg.com/@types/magnet-uri/-/magnet-uri-5.1.1.tgz#861aaf64c92a3137dd848fefc55cd352a8ea851a" | ||
102 | dependencies: | ||
103 | "@types/node" "*" | ||
104 | |||
93 | "@types/node@*": | 105 | "@types/node@*": |
94 | version "8.0.8" | 106 | version "8.0.8" |
95 | resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.8.tgz#0dc4ca2c6f6fc69baee16c5e928c4a627f517ada" | 107 | resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.8.tgz#0dc4ca2c6f6fc69baee16c5e928c4a627f517ada" |
@@ -98,6 +110,26 @@ | |||
98 | version "6.0.79" | 110 | version "6.0.79" |
99 | resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.79.tgz#5efe7d4a6d8c453c7e9eaf55d931f4a22fac5169" | 111 | resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.79.tgz#5efe7d4a6d8c453c7e9eaf55d931f4a22fac5169" |
100 | 112 | ||
113 | "@types/parse-torrent-file@*": | ||
114 | version "4.0.1" | ||
115 | resolved "https://registry.yarnpkg.com/@types/parse-torrent-file/-/parse-torrent-file-4.0.1.tgz#056a6c18f3fac0cd7c6c74540f00496a3225976b" | ||
116 | dependencies: | ||
117 | "@types/node" "*" | ||
118 | |||
119 | "@types/parse-torrent@*": | ||
120 | version "5.8.1" | ||
121 | resolved "https://registry.yarnpkg.com/@types/parse-torrent/-/parse-torrent-5.8.1.tgz#012fe6f50d12ed23d86f10ea831a4f0e1b0aacb6" | ||
122 | dependencies: | ||
123 | "@types/magnet-uri" "*" | ||
124 | "@types/node" "*" | ||
125 | "@types/parse-torrent-file" "*" | ||
126 | |||
127 | "@types/simple-peer@*": | ||
128 | version "6.1.1" | ||
129 | resolved "https://registry.yarnpkg.com/@types/simple-peer/-/simple-peer-6.1.1.tgz#5d0f65ea72a0125b1e92b3cb392be3cab14976ad" | ||
130 | dependencies: | ||
131 | "@types/node" "*" | ||
132 | |||
101 | "@types/source-map@*": | 133 | "@types/source-map@*": |
102 | version "0.5.0" | 134 | version "0.5.0" |
103 | resolved "https://registry.yarnpkg.com/@types/source-map/-/source-map-0.5.0.tgz#dd34bbd8e32fe4e74f2e3d8ac07f8aa5b45a47ac" | 135 | resolved "https://registry.yarnpkg.com/@types/source-map/-/source-map-0.5.0.tgz#dd34bbd8e32fe4e74f2e3d8ac07f8aa5b45a47ac" |
@@ -128,6 +160,15 @@ | |||
128 | "@types/tapable" "*" | 160 | "@types/tapable" "*" |
129 | "@types/uglify-js" "*" | 161 | "@types/uglify-js" "*" |
130 | 162 | ||
163 | "@types/webtorrent@^0.98.4": | ||
164 | version "0.98.4" | ||
165 | resolved "https://registry.yarnpkg.com/@types/webtorrent/-/webtorrent-0.98.4.tgz#cf8dbe22e3d5cf6915305f7f970b52bca01bf8b4" | ||
166 | dependencies: | ||
167 | "@types/bittorrent-protocol" "*" | ||
168 | "@types/node" "*" | ||
169 | "@types/parse-torrent" "*" | ||
170 | "@types/simple-peer" "*" | ||
171 | |||
131 | abbrev@1: | 172 | abbrev@1: |
132 | version "1.1.0" | 173 | version "1.1.0" |
133 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" | 174 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" |