})
export class AppComponent {
- isLoggedIn: boolean;
- search_field: string = name;
choices = [];
+ isLoggedIn: boolean;
- constructor(private friendService: FriendService,
- private authService: AuthService,
- private router: Router
+ constructor(
+ private authService: AuthService,
+ private friendService: FriendService,
+ private router: Router
) {
this.isLoggedIn = this.authService.isLoggedIn();
onSearch(search: Search) {
if (search.value !== '') {
const params = {
- search: search.value,
- field: search.field
+ field: search.field,
+ search: search.value
};
this.router.navigate(['VideosList', params]);
} else {
quitFriends() {
this.friendService.quitFriends().subscribe(
status => {
- alert('Quit friends!');
+ alert('Quit friends!');
},
error => alert(error)
);
export class SearchComponent {
@Output() search = new EventEmitter<Search>();
- searchCriterias: Search = {
- field: 'name',
- value: ''
- };
-
fieldChoices = {
name: 'Name',
author: 'Author',
podUrl: 'Pod Url',
magnetUri: 'Magnet Uri'
};
+ searchCriterias: Search = {
+ field: 'name',
+ value: ''
+ };
get choiceKeys() {
return Object.keys(this.fieldChoices);
}
- getStringChoice(choiceKey: SearchField) {
- return this.fieldChoices[choiceKey];
- }
-
choose($event: MouseEvent, choice: SearchField) {
$event.preventDefault();
$event.stopPropagation();
this.search.emit(this.searchCriterias);
}
+ getStringChoice(choiceKey: SearchField) {
+ return this.fieldChoices[choiceKey];
+ }
}
})
export class UserLoginComponent {
- constructor(private authService: AuthService, private router: Router) {}
+ constructor(
+ private authService: AuthService,
+ private router: Router
+ ) {}
login(username: string, password: string) {
this.authService.login(username, password).subscribe(
@Injectable()
export class AuthService {
- private static BASE_LOGIN_URL = '/api/v1/users/token';
private static BASE_CLIENT_URL = '/api/v1/users/client';
+ private static BASE_LOGIN_URL = '/api/v1/users/token';
loginChangedSource: Observable<AuthStatus>;
- private loginChanged: Subject<AuthStatus>;
private clientId: string;
private clientSecret: string;
+ private loginChanged: Subject<AuthStatus>;
constructor(private http: Http) {
this.loginChanged = new Subject<AuthStatus>();
);
}
- login(username: string, password: string) {
- let body = new URLSearchParams();
- body.set('client_id', this.clientId);
- body.set('client_secret', this.clientSecret);
- body.set('response_type', 'code');
- body.set('grant_type', 'password');
- body.set('scope', 'upload');
- body.set('username', username);
- body.set('password', password);
-
- let headers = new Headers();
- headers.append('Content-Type', 'application/x-www-form-urlencoded');
-
- let options = {
- headers: headers
- };
-
- return this.http.post(AuthService.BASE_LOGIN_URL, body.toString(), options)
- .map(res => res.json())
- .catch(this.handleError);
- }
-
- logout() {
- // TODO make HTTP request
+ getAuthRequestOptions(): RequestOptions {
+ return new RequestOptions({ headers: this.getRequestHeader() });
}
getRequestHeader() {
return new Headers({ 'Authorization': `${this.getTokenType()} ${this.getToken()}` });
}
- getAuthRequestOptions(): RequestOptions {
- return new RequestOptions({ headers: this.getRequestHeader() });
- }
-
getToken() {
return localStorage.getItem('access_token');
}
}
}
+ login(username: string, password: string) {
+ let body = new URLSearchParams();
+ body.set('client_id', this.clientId);
+ body.set('client_secret', this.clientSecret);
+ body.set('response_type', 'code');
+ body.set('grant_type', 'password');
+ body.set('scope', 'upload');
+ body.set('username', username);
+ body.set('password', password);
+
+ let headers = new Headers();
+ headers.append('Content-Type', 'application/x-www-form-urlencoded');
+
+ let options = {
+ headers: headers
+ };
+
+ return this.http.post(AuthService.BASE_LOGIN_URL, body.toString(), options)
+ .map(res => res.json())
+ .catch(this.handleError);
+ }
+
+ logout() {
+ // TODO make HTTP request
+ }
+
setStatus(status: AuthStatus) {
this.loginChanged.next(status);
}
export class Video {
- id: string;
- name: string;
+ author: string;
+ by: string;
+ createdDate: Date;
description: string;
+ duration: string;
+ id: string;
+ isLocal: boolean;
magnetUri: string;
+ name: string;
podUrl: string;
- isLocal: boolean;
thumbnailPath: string;
- author: string;
- createdDate: Date;
- by: string;
- duration: string;
-
- private static createDurationString(duration: number) {
- const minutes = Math.floor(duration / 60);
- const seconds = duration % 60;
- const minutes_padding = minutes >= 10 ? '' : '0';
- const seconds_padding = seconds >= 10 ? '' : '0';
-
- return minutes_padding + minutes.toString() + ':' + seconds_padding + seconds.toString();
- }
private static createByString(author: string, podUrl: string) {
let [ host, port ] = podUrl.replace(/^https?:\/\//, '').split(':');
return author + '@' + host + port;
}
+ private static createDurationString(duration: number) {
+ const minutes = Math.floor(duration / 60);
+ const seconds = duration % 60;
+ const minutes_padding = minutes >= 10 ? '' : '0';
+ const seconds_padding = seconds >= 10 ? '' : '0';
+
+ return minutes_padding + minutes.toString() + ':' + seconds_padding + seconds.toString();
+ }
+
constructor(hash: {
- id: string,
- name: string,
- description: string,
- magnetUri: string,
- podUrl: string,
- isLocal: boolean,
- thumbnailPath: string,
author: string,
createdDate: string,
+ description: string,
duration: number;
+ id: string,
+ isLocal: boolean,
+ magnetUri: string,
+ name: string,
+ podUrl: string,
+ thumbnailPath: string
}) {
- this.id = hash.id;
- this.name = hash.name;
+ this.author = hash.author;
+ this.createdDate = new Date(hash.createdDate);
this.description = hash.description;
+ this.duration = Video.createDurationString(hash.duration);
+ this.id = hash.id;
+ this.isLocal = hash.isLocal;
this.magnetUri = hash.magnetUri;
+ this.name = hash.name;
this.podUrl = hash.podUrl;
- this.isLocal = hash.isLocal;
this.thumbnailPath = hash.thumbnailPath;
- this.author = hash.author;
- this.createdDate = new Date(hash.createdDate);
- this.duration = Video.createDurationString(hash.duration);
+
this.by = Video.createByString(hash.author, hash.podUrl);
}
export class VideoService {
private static BASE_VIDEO_URL = '/api/v1/videos/';
- constructor(private http: Http, private authService: AuthService) {}
+ constructor(
+ private authService: AuthService,
+ private http: Http
+ ) {}
+
+ getVideo(id: string) {
+ return this.http.get(VideoService.BASE_VIDEO_URL + id)
+ .map(res => <Video> res.json())
+ .catch(this.handleError);
+ }
getVideos(pagination: Pagination, sort: SortField) {
const params = this.createPaginationParams(pagination);
.catch(this.handleError);
}
- getVideo(id: string) {
- return this.http.get(VideoService.BASE_VIDEO_URL + id)
- .map(res => <Video> res.json())
- .catch(this.handleError);
- }
-
removeVideo(id: string) {
const options = this.authService.getAuthRequestOptions();
return this.http.delete(VideoService.BASE_VIDEO_URL + id, options)
.catch(this.handleError);
}
+ private createPaginationParams(pagination: Pagination) {
+ const params = new URLSearchParams();
+ const start: number = (pagination.currentPage - 1) * pagination.itemsPerPage;
+ const count: number = pagination.itemsPerPage;
+
+ params.set('start', start.toString());
+ params.set('count', count.toString());
+
+ return params;
+ }
+
private extractVideos(body: any) {
const videos_json = body.data;
const totalVideos = body.total;
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
-
- private createPaginationParams(pagination: Pagination) {
- const params = new URLSearchParams();
- const start: number = (pagination.currentPage - 1) * pagination.itemsPerPage;
- const count: number = pagination.itemsPerPage;
-
- params.set('start', start.toString());
- params.set('count', count.toString());
-
- return params;
- }
}
})
export class VideoAddComponent implements OnInit {
- user: User;
fileToUpload: any;
progressBar: { value: number; max: number; } = { value: 0, max: 0 };
+ user: User;
- private _form: any;
+ private form: any;
constructor(
- private _router: Router, private _elementRef: ElementRef,
- private _authService: AuthService
+ private router: Router,
+ private elementRef: ElementRef,
+ private authService: AuthService
) {}
ngOnInit() {
this.user = User.load();
- jQuery(this._elementRef.nativeElement).find('#videofile').fileupload({
+ jQuery(this.elementRef.nativeElement).find('#videofile').fileupload({
url: '/api/v1/videos',
dataType: 'json',
singleFileUploads: true,
autoupload: false,
add: (e, data) => {
- this._form = data;
+ this.form = data;
this.fileToUpload = data['files'][0];
},
console.log('Video uploaded.');
// Print all the videos once it's finished
- this._router.navigate(['VideosList']);
+ this.router.navigate(['VideosList']);
}
});
}
uploadFile() {
- this._form.headers = this._authService.getRequestHeader().toJSON();
- this._form.formData = jQuery(this._elementRef.nativeElement).find('form').serializeArray();
- this._form.submit();
+ this.form.headers = this.authService.getRequestHeader().toJSON();
+ this.form.formData = jQuery(this.elementRef.nativeElement).find('form').serializeArray();
+ this.form.submit();
}
}
})
export class VideoListComponent implements OnInit {
- user: User = null;
- videos: Video[] = [];
+ loading = false;
pagination: Pagination = {
currentPage: 1,
itemsPerPage: 9,
total: 0
};
sort: SortField;
- loading = false;
+ user: User = null;
+ videos: Video[] = [];
private search: Search;
constructor(
private authService: AuthService,
- private videoService: VideoService,
+ private router: Router,
private routeParams: RouteParams,
- private router: Router
+ private videoService: VideoService
) {
this.search = {
value: this.routeParams.get('search'),
({ videos, totalVideos }) => {
this.videos = videos;
this.pagination.total = totalVideos;
+
this.loading = false;
},
error => alert(error)
};
if (this.search.value) {
- params.search = this.search.value;
params.field = this.search.field;
+ params.search = this.search.value;
}
this.router.navigate(['VideosList', params]);
export class VideoMiniatureComponent {
@Output() removed = new EventEmitter<any>();
- @Input() video: Video;
@Input() user: User;
+ @Input() video: Video;
hovering = false;
constructor(private videoService: VideoService) {}
- onHover() {
- this.hovering = true;
+ displayRemoveIcon() {
+ return this.hovering && this.video.isRemovableBy(this.user);
}
onBlur() {
this.hovering = false;
}
- displayRemoveIcon() {
- return this.hovering && this.video.isRemovableBy(this.user);
+ onHover() {
+ this.hovering = true;
}
removeVideo(id: string) {
})
export class VideoWatchComponent implements OnInit, CanDeactivate {
- video: Video;
downloadSpeed: number;
- uploadSpeed: number;
- numPeers: number;
loading: boolean = false;
+ numPeers: number;
+ uploadSpeed: number;
+ video: Video;
- private interval: NodeJS.Timer;
private client: any;
+ private interval: NodeJS.Timer;
constructor(
- private videoService: VideoService,
+ private elementRef: ElementRef,
private routeParams: RouteParams,
- private elementRef: ElementRef
+ private videoService: VideoService
) {
// TODO: use a service
this.client = new WebTorrent({ dht: false });
}
- ngOnInit() {
- let id = this.routeParams.get('id');
- this.videoService.getVideo(id).subscribe(
- video => this.loadVideo(video),
- error => alert(error)
- );
- }
-
loadVideo(video: Video) {
this.loading = true;
this.video = video;
// Refresh each second
this.interval = setInterval(() => {
this.downloadSpeed = torrent.downloadSpeed;
- this.uploadSpeed = torrent.uploadSpeed;
this.numPeers = torrent.numPeers;
+ this.uploadSpeed = torrent.uploadSpeed;
}, 1000);
});
}
+ ngOnInit() {
+ let id = this.routeParams.get('id');
+ this.videoService.getVideo(id).subscribe(
+ video => this.loadVideo(video),
+ error => alert(error)
+ );
+ }
+
routerCanDeactivate(next: ComponentInstruction, prev: ComponentInstruction) {
console.log('Removing video from webtorrent.');
clearInterval(this.interval);