diff --git a/CHANGELOG-nightly.md b/CHANGELOG-nightly.md index bfabf710..6043099e 100644 --- a/CHANGELOG-nightly.md +++ b/CHANGELOG-nightly.md @@ -1,3 +1,7 @@ +### 3.1.4.1000 + +- Fixed an issue with avatars not loading + ### 3.1.3.1000 - Added option hide shared chat diff --git a/package.json b/package.json index 14f64def..2a4a23b3 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "7TV", "description": "Improve your viewing experience on Twitch & YouTube with new features, emotes, vanity and performance.", "private": true, - "version": "3.1.3", + "version": "3.1.4", "dev_version": "1.0", "scripts": { "start": "NODE_ENV=dev yarn build:dev && NODE_ENV=dev vite --mode dev", diff --git a/src/worker/index.ts b/src/worker/index.ts index 7f795e89..5d9554b0 100644 --- a/src/worker/index.ts +++ b/src/worker/index.ts @@ -115,7 +115,6 @@ export enum EventAPIOpCode { RESUME = 34, SUBSCRIBE = 35, UNSUBSCRIBE = 36, - BRIDGE = 38, UNKNOWN = 1001, } diff --git a/src/worker/worker.driver.ts b/src/worker/worker.driver.ts index 1b5d7f4a..b4c29737 100644 --- a/src/worker/worker.driver.ts +++ b/src/worker/worker.driver.ts @@ -143,6 +143,7 @@ type WorkerEventName = | "set_channel_presence" | "identity_updated" | "user_updated" + | "request_user_cosmetics" | "imageformat_updated"; type WorkerTypedEvent = { @@ -155,6 +156,7 @@ type WorkerTypedEvent = { channel_data_fetched: CurrentChannel; identity_updated: TwitchIdentity | YouTubeIdentity; user_updated: SevenTV.User; + request_user_cosmetics: ["id" | "username", string][]; imageformat_updated: string; }[EVN]; diff --git a/src/worker/worker.events.ts b/src/worker/worker.events.ts index bd13b144..b33eab8e 100644 --- a/src/worker/worker.events.ts +++ b/src/worker/worker.events.ts @@ -16,6 +16,7 @@ export class EventAPI { subscriptions: Record = {}; url = import.meta.env.VITE_APP_API_EVENTS; + version = import.meta.env.VITE_APP_VERSION; private socket: WebSocket | null = null; private eventSource: EventSource | null = null; private shouldResume = false; @@ -40,10 +41,15 @@ export class EventAPI { connect(transport: EventAPITransport): void { if (this.eventSource || this.socket || !this.url) return; + const url = new URL(this.url); + + url.searchParams.append("app", "7tv-extension"); + url.searchParams.append("version", this.version); + this.transport = transport; if (this.transport === "WebSocket") { - this.socket = new WebSocket(this.url); + this.socket = new WebSocket(url); this.socket.onopen = () => this.onOpen(); this.socket.onclose = () => this.onClose(); this.socket.onmessage = (ev) => { @@ -116,7 +122,7 @@ export class EventAPI { ); } - private onDispatch(msg: EventAPIMessage<"DISPATCH">): void { + onDispatch(msg: EventAPIMessage<"DISPATCH">): void { handleDispatchedEvent(this.getContext(), msg.data.type, msg.data.body); log.debugWithObjects(["", "Dispatch received"], [msg.data]); diff --git a/src/worker/worker.http.ts b/src/worker/worker.http.ts index ee2a8ade..8d49a0a9 100644 --- a/src/worker/worker.http.ts +++ b/src/worker/worker.http.ts @@ -7,6 +7,7 @@ import { convertBttvEmoteSet, convertFFZEmoteSet, convertFfzBadges } from "@/com import { db } from "@/db/idb"; import type { WorkerDriver } from "./worker.driver"; import type { WorkerPort } from "./worker.port"; +import { EventAPIMessage } from "."; namespace API_BASE { export const SEVENTV = import.meta.env.VITE_APP_API; @@ -66,6 +67,21 @@ export class WorkerHttp { if (!ev.port) return; WorkerHttp.imageFormat = ev.port.imageFormat!; }); + driver.addEventListener("request_user_cosmetics", async (ev) => { + if (!ev.port) return; + + const cosmeticEvents = await this.API() + .seventv.loadUserCosmetics(ev.detail) + .catch(() => void 0); + + if (!cosmeticEvents) { + return; + } + + for (const cosmeticEvent of cosmeticEvents) { + this.driver.eventAPI.onDispatch(cosmeticEvent); + } + }); } public async fetchConfig(): Promise { @@ -300,6 +316,23 @@ export const seventv = { return Promise.resolve(userConn.user); }, + + async loadUserCosmetics(identifiers: ["id" | "username", string][]): Promise[]> { + const body = { + identifiers: identifiers.map(([idType, id]) => `${idType}:${id}`), + }; + + const resp = await doRequest(API_BASE.SEVENTV, "bridge/event-api", "POST", body).catch((err) => + Promise.reject(err), + ); + + if (!resp || resp.status !== 200) { + return Promise.reject(resp); + } + + const cosmetics = (await resp.json()) as EventAPIMessage<"DISPATCH">[]; + return Promise.resolve(cosmetics); + }, }; export const frankerfacez = { diff --git a/src/worker/worker.port.ts b/src/worker/worker.port.ts index 2267f715..78f18026 100644 --- a/src/worker/worker.port.ts +++ b/src/worker/worker.port.ts @@ -96,17 +96,7 @@ export class WorkerPort { if (!Array.isArray(identifiers) || !this.platform || !kinds.length) break; log.debugWithObjects(["Requesting cosmetics"], [identifiers, kinds]); - this.driver.eventAPI.sendMessage({ - op: "BRIDGE", - data: { - command: "userstate", - body: { - identifiers: identifiers.map(([idType, id]) => `${idType}:${id}`), - platform: this.platform, - kinds, - }, - }, - }); + this.driver.emit("request_user_cosmetics", identifiers, this); break; } case "CLOSE":