2018-03-22 05:31:34 +01:00
|
|
|
import { Injectable } from "@angular/core";
|
2018-09-13 08:02:24 +02:00
|
|
|
import { Status } from "./models/mastodon.interfaces";
|
2018-09-14 02:01:25 +02:00
|
|
|
import { BehaviorSubject } from "rxjs";
|
|
|
|
import { ApiRoutes } from "./models/api.settings";
|
2018-09-16 08:09:48 +02:00
|
|
|
import { StreamTypeEnum } from "../states/streams.state";
|
2018-03-22 05:31:34 +01:00
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
export class StreamingService {
|
2018-09-14 02:01:25 +02:00
|
|
|
private apiRoutes = new ApiRoutes();
|
2018-03-22 05:31:34 +01:00
|
|
|
|
2018-09-14 02:01:25 +02:00
|
|
|
constructor() { }
|
2018-03-22 05:31:34 +01:00
|
|
|
|
2018-09-16 08:09:48 +02:00
|
|
|
getStreaming(instance: string, accessToken: string, streamType: StreamTypeEnum): StreamingWrapper {
|
|
|
|
const request = this.getRequest(streamType);
|
|
|
|
const route = `wss://${instance}/api/v1/streaming?access_token=${accessToken}&stream=${request}`
|
2018-09-14 02:01:25 +02:00
|
|
|
return new StreamingWrapper(route);
|
|
|
|
}
|
2018-03-22 05:31:34 +01:00
|
|
|
|
2018-09-16 08:09:48 +02:00
|
|
|
private getRequest(type: StreamTypeEnum): string {
|
|
|
|
switch (type) {
|
|
|
|
case StreamTypeEnum.global:
|
|
|
|
return 'public';
|
|
|
|
case StreamTypeEnum.local:
|
|
|
|
return 'public:local';
|
|
|
|
case StreamTypeEnum.personnal:
|
|
|
|
return 'user';
|
|
|
|
}
|
|
|
|
}
|
2018-03-22 05:31:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export class StreamingWrapper {
|
2018-09-14 02:01:25 +02:00
|
|
|
statusUpdateSubjet = new BehaviorSubject<StatusUpdate>(null);
|
|
|
|
eventSource: WebSocket;
|
2018-03-22 05:31:34 +01:00
|
|
|
|
2018-09-14 02:01:25 +02:00
|
|
|
constructor(private readonly domain: string) {
|
2018-09-16 08:09:48 +02:00
|
|
|
this.start(domain);
|
2018-09-14 02:01:25 +02:00
|
|
|
}
|
2018-09-13 08:02:24 +02:00
|
|
|
|
2018-09-14 02:01:25 +02:00
|
|
|
private start(domain: string) {
|
|
|
|
this.eventSource = new WebSocket(domain);
|
2018-09-16 08:09:48 +02:00
|
|
|
this.eventSource.onmessage = x => this.statusParsing(<WebSocketEvent>JSON.parse(x.data));
|
|
|
|
this.eventSource.onerror = x => this.webSocketGotError(x);
|
2018-09-14 02:01:25 +02:00
|
|
|
this.eventSource.onopen = x => console.log(x);
|
2018-09-16 08:09:48 +02:00
|
|
|
this.eventSource.onclose = x => this.webSocketClosed(domain, x);
|
|
|
|
}
|
|
|
|
|
|
|
|
private errorClosing: boolean;
|
|
|
|
private webSocketGotError(x: Event) {
|
|
|
|
console.error(x);
|
|
|
|
this.errorClosing = true;
|
|
|
|
// this.eventSource.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
private webSocketClosed(domain, x: Event) {
|
|
|
|
console.log(x);
|
|
|
|
|
|
|
|
if(this.errorClosing){
|
|
|
|
|
|
|
|
|
|
|
|
this.errorClosing = false;
|
|
|
|
} else {
|
|
|
|
setTimeout(() => { this.start(domain) }, 3000);
|
|
|
|
}
|
2018-09-14 02:01:25 +02:00
|
|
|
}
|
2018-09-13 08:02:24 +02:00
|
|
|
|
2018-09-16 08:09:48 +02:00
|
|
|
private statusParsing(event: WebSocketEvent) {
|
2018-09-14 02:01:25 +02:00
|
|
|
const newUpdate = new StatusUpdate();
|
|
|
|
|
|
|
|
switch (event.event) {
|
|
|
|
case 'update':
|
|
|
|
newUpdate.type = EventEnum.update;
|
|
|
|
newUpdate.status = <Status>JSON.parse(event.payload);
|
|
|
|
break;
|
|
|
|
case 'delete':
|
|
|
|
newUpdate.type = EventEnum.delete;
|
|
|
|
newUpdate.messageId = event.payload;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
newUpdate.type = EventEnum.unknow;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.statusUpdateSubjet.next(newUpdate);
|
|
|
|
}
|
2018-09-16 08:09:48 +02:00
|
|
|
|
|
|
|
|
2018-09-13 08:02:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class WebSocketEvent {
|
2018-09-14 02:01:25 +02:00
|
|
|
event: string;
|
|
|
|
payload: any;
|
2018-09-13 08:02:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class StatusUpdate {
|
2018-09-14 02:01:25 +02:00
|
|
|
type: EventEnum;
|
|
|
|
status: Status;
|
|
|
|
messageId: number;
|
2018-09-13 08:02:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export enum EventEnum {
|
2018-09-14 02:01:25 +02:00
|
|
|
unknow = 0,
|
|
|
|
update = 1,
|
|
|
|
delete = 2
|
2018-03-22 05:31:34 +01:00
|
|
|
}
|