diff --git a/src/app/services/models/mastodon.interfaces.ts b/src/app/services/models/mastodon.interfaces.ts index 8ba398a5..087b1494 100644 --- a/src/app/services/models/mastodon.interfaces.ts +++ b/src/app/services/models/mastodon.interfaces.ts @@ -116,11 +116,15 @@ export interface Instance { description: string; email: string; version: string; - urls: string[]; + urls: InstanceUrls; contact_account: Account; max_toot_chars: number; } +export interface InstanceUrls { + streaming_api: string; +} + export interface Mention { url: string; username: string; diff --git a/src/app/services/streaming.service.ts b/src/app/services/streaming.service.ts index 7076bb1c..9f54f496 100644 --- a/src/app/services/streaming.service.ts +++ b/src/app/services/streaming.service.ts @@ -6,6 +6,7 @@ import { ApiRoutes } from "./models/api.settings"; import { StreamTypeEnum, StreamElement } from "../states/streams.state"; import { MastodonWrapperService } from "./mastodon-wrapper.service"; import { AccountInfo } from "../states/accounts.state"; +import { InstanceInfo, ToolsService } from "./tools.service"; @Injectable() export class StreamingService { @@ -13,12 +14,13 @@ export class StreamingService { public readonly nbStatusPerIteration: number = 20; constructor( - private readonly mastodonService: MastodonWrapperService) { } + private readonly mastodonService: MastodonWrapperService, + private readonly toolsService: ToolsService) { } getStreaming(accountInfo: AccountInfo, stream: StreamElement, since_id: string = null): StreamingWrapper { //new EventSourceStreaminWrapper(accountInfo, stream); - return new StreamingWrapper(this.mastodonService, accountInfo, stream, this.nbStatusPerIteration); + return new StreamingWrapper(this.mastodonService, this.toolsService, accountInfo, stream, this.nbStatusPerIteration); } } @@ -33,6 +35,7 @@ export class StreamingWrapper { constructor( private readonly mastodonService: MastodonWrapperService, + private readonly toolsService: ToolsService, private readonly account: AccountInfo, private readonly stream: StreamElement, private readonly nbStatusPerIteration: number, @@ -53,7 +56,13 @@ export class StreamingWrapper { return account; }) .then((refreshedAccount: AccountInfo) => { - const route = this.getRoute(refreshedAccount, stream); + let getInstanceProms = this.toolsService.getInstanceInfo(refreshedAccount); + return getInstanceProms.then(inst => { + return new StreamingAccountInfo(inst, refreshedAccount); + }); + }) + .then((account: StreamingAccountInfo) => { + const route = this.getRoute(account.instanceInfo, account.refreshedAccount, stream); this.eventSource = new WebSocket(route); this.eventSource.onmessage = x => { if (x.data !== '') { @@ -62,7 +71,7 @@ export class StreamingWrapper { } this.eventSource.onerror = x => this.webSocketGotError(x); this.eventSource.onopen = x => { }; - this.eventSource.onclose = x => this.webSocketClosed(refreshedAccount, stream, x); + this.eventSource.onclose = x => this.webSocketClosed(account.refreshedAccount, stream, x); }); } @@ -162,9 +171,15 @@ export class StreamingWrapper { this.statusUpdateSubjet.next(newUpdate); } - private getRoute(account: AccountInfo, stream: StreamElement): string { + private getRoute(instanceInfo: InstanceInfo, account: AccountInfo, stream: StreamElement): string { + let streamingEndpoint = `wss://${account.instance}`; + + if(instanceInfo.major >= 4){ + streamingEndpoint = instanceInfo.streamingApi; + } + const streamingRouteType = this.getStreamingRouteType(stream.type); - let route = `wss://${account.instance}${this.apiRoutes.getStreaming}`.replace('{0}', account.token.access_token).replace('{1}', streamingRouteType); + let route = `${streamingEndpoint}${this.apiRoutes.getStreaming}`.replace('{0}', account.token.access_token).replace('{1}', streamingRouteType); if (stream.tag) route = `${route}&tag=${stream.tag}`; if (stream.list) route = `${route}&list=${stream.listId}`; @@ -274,6 +289,13 @@ class WebSocketEvent { payload: any; } +class StreamingAccountInfo { + constructor( + public instanceInfo: InstanceInfo, + public refreshedAccount: AccountInfo) { + } +} + export class StatusUpdate { type: EventEnum; status: Status; diff --git a/src/app/services/tools.service.ts b/src/app/services/tools.service.ts index a6eaa891..b48deabf 100644 --- a/src/app/services/tools.service.ts +++ b/src/app/services/tools.service.ts @@ -78,7 +78,7 @@ export class ToolsService { } else { return this.mastodonService.getInstance(acc.instance) .then(instance => { - var type = InstanceType.Mastodon; + let type = InstanceType.Mastodon; if (instance.version.toLowerCase().includes('pleroma')) { type = InstanceType.Pleroma; } else if (instance.version.toLowerCase().includes('+glitch')) { @@ -89,11 +89,14 @@ export class ToolsService { type = InstanceType.Pixelfed; } - var splittedVersion = instance.version.split('.'); - var major = +splittedVersion[0]; - var minor = +splittedVersion[1]; + const splittedVersion = instance.version.split('.'); + const major = +splittedVersion[0]; + const minor = +splittedVersion[1]; - var instanceInfo = new InstanceInfo(type, major, minor); + let streamingApi = ""; + if(instance.urls) streamingApi = instance.urls.streaming_api; + + let instanceInfo = new InstanceInfo(type, major, minor, streamingApi); this.instanceInfos[acc.instance] = instanceInfo; return instanceInfo; @@ -231,7 +234,8 @@ export class InstanceInfo { constructor( public readonly type: InstanceType, public readonly major: number, - public readonly minor: number) { + public readonly minor: number, + public readonly streamingApi: string) { } }