Type webtorrent
This commit is contained in:
parent
4771e0008d
commit
33c4972d5b
7 changed files with 88 additions and 29 deletions
|
@ -93,6 +93,7 @@
|
||||||
"zone.js": "~0.8.5"
|
"zone.js": "~0.8.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/webtorrent": "^0.98.4",
|
||||||
"add-asset-html-webpack-plugin": "^2.0.1",
|
"add-asset-html-webpack-plugin": "^2.0.1",
|
||||||
"codelyzer": "^3.0.0-beta.4",
|
"codelyzer": "^3.0.0-beta.4",
|
||||||
"standard": "^10.0.0",
|
"standard": "^10.0.0",
|
||||||
|
|
|
@ -96,6 +96,7 @@ export class AuthUser extends User {
|
||||||
localStorage.removeItem(this.KEYS.ID)
|
localStorage.removeItem(this.KEYS.ID)
|
||||||
localStorage.removeItem(this.KEYS.ROLE)
|
localStorage.removeItem(this.KEYS.ROLE)
|
||||||
localStorage.removeItem(this.KEYS.DISPLAY_NSFW)
|
localStorage.removeItem(this.KEYS.DISPLAY_NSFW)
|
||||||
|
localStorage.removeItem(this.KEYS.EMAIL)
|
||||||
Tokens.flush()
|
Tokens.flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +131,7 @@ export class AuthUser extends User {
|
||||||
save () {
|
save () {
|
||||||
localStorage.setItem(AuthUser.KEYS.ID, this.id.toString())
|
localStorage.setItem(AuthUser.KEYS.ID, this.id.toString())
|
||||||
localStorage.setItem(AuthUser.KEYS.USERNAME, this.username)
|
localStorage.setItem(AuthUser.KEYS.USERNAME, this.username)
|
||||||
|
localStorage.setItem(AuthUser.KEYS.EMAIL, this.email)
|
||||||
localStorage.setItem(AuthUser.KEYS.ROLE, this.role)
|
localStorage.setItem(AuthUser.KEYS.ROLE, this.role)
|
||||||
localStorage.setItem(AuthUser.KEYS.DISPLAY_NSFW, JSON.stringify(this.displayNSFW))
|
localStorage.setItem(AuthUser.KEYS.DISPLAY_NSFW, JSON.stringify(this.displayNSFW))
|
||||||
this.tokens.save()
|
this.tokens.save()
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { NotificationsService } from 'angular2-notifications'
|
||||||
|
|
||||||
import { AuthStatus } from './auth-status.model'
|
import { AuthStatus } from './auth-status.model'
|
||||||
import { AuthUser } from './auth-user.model'
|
import { AuthUser } from './auth-user.model'
|
||||||
import { OAuthClientLocal } from '../../../../../shared'
|
import { OAuthClientLocal, UserRole } from '../../../../../shared'
|
||||||
// Do not use the barrel (dependency loop)
|
// Do not use the barrel (dependency loop)
|
||||||
import { RestExtractor } from '../../shared/rest'
|
import { RestExtractor } from '../../shared/rest'
|
||||||
|
|
||||||
|
@ -181,7 +181,10 @@ export class AuthService {
|
||||||
|
|
||||||
refreshUserInformations () {
|
refreshUserInformations () {
|
||||||
const obj = {
|
const obj = {
|
||||||
access_token: this.user.getAccessToken()
|
access_token: this.user.getAccessToken(),
|
||||||
|
refresh_token: null,
|
||||||
|
token_type: this.user.getTokenType(),
|
||||||
|
username: this.user.username
|
||||||
}
|
}
|
||||||
|
|
||||||
this.mergeUserInformations (obj)
|
this.mergeUserInformations (obj)
|
||||||
|
@ -195,7 +198,12 @@ export class AuthService {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private mergeUserInformations (obj: { access_token: string }) {
|
private mergeUserInformations (obj: {
|
||||||
|
access_token: string,
|
||||||
|
refresh_token: string,
|
||||||
|
token_type: string,
|
||||||
|
username: string
|
||||||
|
}) {
|
||||||
// Do not call authHttp here to avoid circular dependencies headaches
|
// Do not call authHttp here to avoid circular dependencies headaches
|
||||||
|
|
||||||
const headers = new Headers()
|
const headers = new Headers()
|
||||||
|
@ -205,9 +213,10 @@ export class AuthService {
|
||||||
.map(res => res.json())
|
.map(res => res.json())
|
||||||
.map(res => {
|
.map(res => {
|
||||||
const newProperties = {
|
const newProperties = {
|
||||||
id: res.id,
|
id: res.id as number,
|
||||||
role: res.role,
|
role: res.role as UserRole,
|
||||||
displayNSFW: res.displayNSFW
|
displayNSFW: res.displayNSFW as boolean,
|
||||||
|
email: res.email as string
|
||||||
}
|
}
|
||||||
|
|
||||||
return Object.assign(obj, newProperties)
|
return Object.assign(obj, newProperties)
|
||||||
|
@ -215,7 +224,16 @@ export class AuthService {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleLogin (obj: any) {
|
private handleLogin (obj: {
|
||||||
|
access_token: string,
|
||||||
|
refresh_token: string,
|
||||||
|
token_type: string,
|
||||||
|
id: number,
|
||||||
|
username: string,
|
||||||
|
email: string,
|
||||||
|
role: UserRole,
|
||||||
|
displayNSFW: boolean
|
||||||
|
}) {
|
||||||
const id = obj.id
|
const id = obj.id
|
||||||
const username = obj.username
|
const username = obj.username
|
||||||
const role = obj.role
|
const role = obj.role
|
||||||
|
@ -233,7 +251,7 @@ export class AuthService {
|
||||||
this.setStatus(AuthStatus.LoggedIn)
|
this.setStatus(AuthStatus.LoggedIn)
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleRefreshToken (obj: any) {
|
private handleRefreshToken (obj: { access_token: string, refresh_token: string }) {
|
||||||
this.user.refreshTokens(obj.access_token, obj.refresh_token)
|
this.user.refreshTokens(obj.access_token, obj.refresh_token)
|
||||||
this.user.save()
|
this.user.save()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'
|
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'
|
||||||
import { ActivatedRoute, Router } from '@angular/router'
|
import { ActivatedRoute, Router } from '@angular/router'
|
||||||
|
import { Subscription } from 'rxjs/Subscription'
|
||||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject'
|
import { BehaviorSubject } from 'rxjs/BehaviorSubject'
|
||||||
|
|
||||||
import { NotificationsService } from 'angular2-notifications'
|
import { NotificationsService } from 'angular2-notifications'
|
||||||
|
@ -30,8 +31,8 @@ export class VideoListComponent implements OnInit, OnDestroy {
|
||||||
videos: Video[] = []
|
videos: Video[] = []
|
||||||
|
|
||||||
private search: Search
|
private search: Search
|
||||||
private subActivatedRoute: any
|
private subActivatedRoute: Subscription
|
||||||
private subSearch: any
|
private subSearch: Subscription
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private notificationsService: NotificationsService,
|
private notificationsService: NotificationsService,
|
||||||
|
@ -98,7 +99,7 @@ export class VideoListComponent implements OnInit, OnDestroy {
|
||||||
return !this.loading.getValue() && this.videos.length === 0
|
return !this.loading.getValue() && this.videos.length === 0
|
||||||
}
|
}
|
||||||
|
|
||||||
onPageChanged (event: any) {
|
onPageChanged (event: { page: number }) {
|
||||||
// Be sure the current page is set
|
// Be sure the current page is set
|
||||||
this.pagination.currentPage = event.page
|
this.pagination.currentPage = event.page
|
||||||
|
|
||||||
|
@ -113,21 +114,21 @@ export class VideoListComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
private buildRouteParams () {
|
private buildRouteParams () {
|
||||||
// There is always a sort and a current page
|
// There is always a sort and a current page
|
||||||
const params: any = {
|
const params = {
|
||||||
sort: this.sort,
|
sort: this.sort,
|
||||||
page: this.pagination.currentPage
|
page: this.pagination.currentPage
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maybe there is a search
|
// Maybe there is a search
|
||||||
if (this.search.value) {
|
if (this.search.value) {
|
||||||
params.field = this.search.field
|
params['field'] = this.search.field
|
||||||
params.search = this.search.value
|
params['search'] = this.search.value
|
||||||
}
|
}
|
||||||
|
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadRouteParams (routeParams) {
|
private loadRouteParams (routeParams: { [ key: string ]: any }) {
|
||||||
if (routeParams['search'] !== undefined) {
|
if (routeParams['search'] !== undefined) {
|
||||||
this.search = {
|
this.search = {
|
||||||
value: routeParams['search'],
|
value: routeParams['search'],
|
||||||
|
|
|
@ -32,7 +32,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
loading = false
|
loading = false
|
||||||
numPeers: number
|
numPeers: number
|
||||||
player: videojs.Player
|
player: videojs.Player
|
||||||
playerElement: Element
|
playerElement: HTMLMediaElement
|
||||||
uploadSpeed: number
|
uploadSpeed: number
|
||||||
userRating: UserVideoRateType = null
|
userRating: UserVideoRateType = null
|
||||||
video: Video = null
|
video: Video = null
|
||||||
|
@ -41,7 +41,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
private errorTimer: number
|
private errorTimer: number
|
||||||
private paramsSub: Subscription
|
private paramsSub: Subscription
|
||||||
private errorsSub: Subscription
|
private errorsSub: Subscription
|
||||||
private warningsSub: Subscription
|
|
||||||
private torrentInfosInterval: number
|
private torrentInfosInterval: number
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
|
@ -82,8 +81,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
self.player = this
|
self.player = this
|
||||||
})
|
})
|
||||||
|
|
||||||
this.errorsSub = this.webTorrentService.errors.subscribe(err => this.notificationsService.error('Error', err.message))
|
this.errorsSub = this.webTorrentService.errors.subscribe(err => {
|
||||||
this.warningsSub = this.webTorrentService.errors.subscribe(err => this.notificationsService.alert('Warning', err.message))
|
const message = typeof err === 'string' ? err : err.message
|
||||||
|
this.notificationsService.error('Error', message)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy () {
|
ngOnDestroy () {
|
||||||
|
@ -102,7 +103,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
// Unsubscribe subscriptions
|
// Unsubscribe subscriptions
|
||||||
this.paramsSub.unsubscribe()
|
this.paramsSub.unsubscribe()
|
||||||
this.errorsSub.unsubscribe()
|
this.errorsSub.unsubscribe()
|
||||||
this.warningsSub.unsubscribe()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadVideo () {
|
loadVideo () {
|
||||||
|
@ -117,7 +117,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
// So we create a timer to inform the user the load is abnormally long
|
// So we create a timer to inform the user the load is abnormally long
|
||||||
this.errorTimer = window.setTimeout(() => this.loadTooLong(), VideoWatchComponent.LOADTIME_TOO_LONG)
|
this.errorTimer = window.setTimeout(() => this.loadTooLong(), VideoWatchComponent.LOADTIME_TOO_LONG)
|
||||||
|
|
||||||
this.webTorrentService.add(this.video.magnetUri, (torrent) => {
|
this.webTorrentService.add(this.video.magnetUri, torrent => {
|
||||||
// Clear the error timer
|
// Clear the error timer
|
||||||
window.clearTimeout(this.errorTimer)
|
window.clearTimeout(this.errorTimer)
|
||||||
// Maybe the error was fired by the timer, so reset it
|
// Maybe the error was fired by the timer, so reset it
|
||||||
|
|
|
@ -5,21 +5,17 @@ import * as WebTorrent from 'webtorrent'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WebTorrentService {
|
export class WebTorrentService {
|
||||||
errors = new Subject<Error>()
|
errors = new Subject<string | Error>()
|
||||||
warnings = new Subject<Error>()
|
|
||||||
|
|
||||||
// TODO: use WebTorrent @type
|
private client: WebTorrent.Instance
|
||||||
// private client: WebTorrent.Client
|
|
||||||
private client: any
|
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
this.client = new WebTorrent({ dht: false })
|
this.client = new WebTorrent({ dht: false })
|
||||||
|
|
||||||
this.client.on('error', (err) => this.errors.next(err))
|
this.client.on('error', err => this.errors.next(err))
|
||||||
this.client.on('warning', (err) => this.warnings.next(err))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add (magnetUri: string, callback: Function) {
|
add (magnetUri: string, callback: (torrent: WebTorrent.Torrent) => any) {
|
||||||
return this.client.add(magnetUri, callback)
|
return this.client.add(magnetUri, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,10 +86,22 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.7.0"
|
tslib "^1.7.0"
|
||||||
|
|
||||||
|
"@types/bittorrent-protocol@*":
|
||||||
|
version "2.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/bittorrent-protocol/-/bittorrent-protocol-2.2.2.tgz#169e9633e1bd18e6b830d11cf42e611b1972cb83"
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/core-js@^0.9.28":
|
"@types/core-js@^0.9.28":
|
||||||
version "0.9.42"
|
version "0.9.42"
|
||||||
resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-0.9.42.tgz#dd6da92cd7d5ab5ca0b4477524537c3e633b6bce"
|
resolved "https://registry.yarnpkg.com/@types/core-js/-/core-js-0.9.42.tgz#dd6da92cd7d5ab5ca0b4477524537c3e633b6bce"
|
||||||
|
|
||||||
|
"@types/magnet-uri@*":
|
||||||
|
version "5.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/magnet-uri/-/magnet-uri-5.1.1.tgz#861aaf64c92a3137dd848fefc55cd352a8ea851a"
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/node@*":
|
"@types/node@*":
|
||||||
version "8.0.8"
|
version "8.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.8.tgz#0dc4ca2c6f6fc69baee16c5e928c4a627f517ada"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.8.tgz#0dc4ca2c6f6fc69baee16c5e928c4a627f517ada"
|
||||||
|
@ -98,6 +110,26 @@
|
||||||
version "6.0.79"
|
version "6.0.79"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.79.tgz#5efe7d4a6d8c453c7e9eaf55d931f4a22fac5169"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.79.tgz#5efe7d4a6d8c453c7e9eaf55d931f4a22fac5169"
|
||||||
|
|
||||||
|
"@types/parse-torrent-file@*":
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/parse-torrent-file/-/parse-torrent-file-4.0.1.tgz#056a6c18f3fac0cd7c6c74540f00496a3225976b"
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/parse-torrent@*":
|
||||||
|
version "5.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/parse-torrent/-/parse-torrent-5.8.1.tgz#012fe6f50d12ed23d86f10ea831a4f0e1b0aacb6"
|
||||||
|
dependencies:
|
||||||
|
"@types/magnet-uri" "*"
|
||||||
|
"@types/node" "*"
|
||||||
|
"@types/parse-torrent-file" "*"
|
||||||
|
|
||||||
|
"@types/simple-peer@*":
|
||||||
|
version "6.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/simple-peer/-/simple-peer-6.1.1.tgz#5d0f65ea72a0125b1e92b3cb392be3cab14976ad"
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/source-map@*":
|
"@types/source-map@*":
|
||||||
version "0.5.0"
|
version "0.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/source-map/-/source-map-0.5.0.tgz#dd34bbd8e32fe4e74f2e3d8ac07f8aa5b45a47ac"
|
resolved "https://registry.yarnpkg.com/@types/source-map/-/source-map-0.5.0.tgz#dd34bbd8e32fe4e74f2e3d8ac07f8aa5b45a47ac"
|
||||||
|
@ -128,6 +160,15 @@
|
||||||
"@types/tapable" "*"
|
"@types/tapable" "*"
|
||||||
"@types/uglify-js" "*"
|
"@types/uglify-js" "*"
|
||||||
|
|
||||||
|
"@types/webtorrent@^0.98.4":
|
||||||
|
version "0.98.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/webtorrent/-/webtorrent-0.98.4.tgz#cf8dbe22e3d5cf6915305f7f970b52bca01bf8b4"
|
||||||
|
dependencies:
|
||||||
|
"@types/bittorrent-protocol" "*"
|
||||||
|
"@types/node" "*"
|
||||||
|
"@types/parse-torrent" "*"
|
||||||
|
"@types/simple-peer" "*"
|
||||||
|
|
||||||
abbrev@1:
|
abbrev@1:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
|
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
|
||||||
|
|
Loading…
Reference in a new issue