mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-16 12:42:06 +00:00
fix(music-together): fix duplicate queue listener
This commit is contained in:
@ -14,6 +14,7 @@ export type ConnectionEventMap = {
|
|||||||
| { progress?: number; state?: number; index?: number }
|
| { progress?: number; state?: number; index?: number }
|
||||||
| undefined;
|
| undefined;
|
||||||
PERMISSION: Permission | undefined;
|
PERMISSION: Permission | undefined;
|
||||||
|
CONNECTION_CLOSED: null;
|
||||||
};
|
};
|
||||||
export type ConnectionEventUnion = {
|
export type ConnectionEventUnion = {
|
||||||
[Event in keyof ConnectionEventMap]: {
|
[Event in keyof ConnectionEventMap]: {
|
||||||
@ -31,7 +32,7 @@ type PromiseUtil<T> = {
|
|||||||
|
|
||||||
export type ConnectionListener = (
|
export type ConnectionListener = (
|
||||||
event: ConnectionEventUnion,
|
event: ConnectionEventUnion,
|
||||||
conn: DataConnection,
|
conn: DataConnection | null,
|
||||||
) => void;
|
) => void;
|
||||||
export type ConnectionMode = 'host' | 'guest' | 'disconnected';
|
export type ConnectionMode = 'host' | 'guest' | 'disconnected';
|
||||||
export class Connection {
|
export class Connection {
|
||||||
@ -59,6 +60,16 @@ export class Connection {
|
|||||||
this._mode = 'host';
|
this._mode = 'host';
|
||||||
await this.registerConnection(conn);
|
await this.registerConnection(conn);
|
||||||
});
|
});
|
||||||
|
this.peer.on('close', () => {
|
||||||
|
for (const listener of this.listeners) {
|
||||||
|
listener({ type: 'CONNECTION_CLOSED', payload: null }, null);
|
||||||
|
}
|
||||||
|
this.listeners = [];
|
||||||
|
this.connectionListeners = [];
|
||||||
|
this.connections = {};
|
||||||
|
this.peer.disconnect();
|
||||||
|
this.peer.destroy();
|
||||||
|
});
|
||||||
this.peer.on('error', async (err) => {
|
this.peer.on('error', async (err) => {
|
||||||
if (err.type === PeerErrorType.Network) {
|
if (err.type === PeerErrorType.Network) {
|
||||||
// retrying after 10 seconds
|
// retrying after 10 seconds
|
||||||
@ -99,6 +110,10 @@ export class Connection {
|
|||||||
this._mode = 'disconnected';
|
this._mode = 'disconnected';
|
||||||
this.connections = {};
|
this.connections = {};
|
||||||
this.connectionListeners = [];
|
this.connectionListeners = [];
|
||||||
|
for (const listener of this.listeners) {
|
||||||
|
listener({ type: 'CONNECTION_CLOSED', payload: null }, null);
|
||||||
|
}
|
||||||
|
this.listeners = [];
|
||||||
this.peer.disconnect();
|
this.peer.disconnect();
|
||||||
this.peer.destroy();
|
this.peer.destroy();
|
||||||
}
|
}
|
||||||
@ -126,7 +141,9 @@ export class Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public on(listener: ConnectionListener) {
|
public on(listener: ConnectionListener) {
|
||||||
this.listeners.push(listener);
|
if (!this.listeners.includes(listener)) {
|
||||||
|
this.listeners.push(listener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public onConnections(listener: (connections?: DataConnection) => void) {
|
public onConnections(listener: (connections?: DataConnection) => void) {
|
||||||
@ -172,7 +189,6 @@ export class Connection {
|
|||||||
delete this.connections[conn.connectionId];
|
delete this.connections[conn.connectionId];
|
||||||
|
|
||||||
this.connectionListeners.forEach((listener) => listener(conn));
|
this.connectionListeners.forEach((listener) => listener(conn));
|
||||||
this.connectionListeners = [];
|
|
||||||
|
|
||||||
if (conn.open) {
|
if (conn.open) {
|
||||||
conn.close({
|
conn.close({
|
||||||
|
|||||||
@ -208,7 +208,7 @@ export default createPlugin<
|
|||||||
|
|
||||||
const listener = async (
|
const listener = async (
|
||||||
event: ConnectionEventUnion,
|
event: ConnectionEventUnion,
|
||||||
conn?: DataConnection,
|
conn?: DataConnection | null,
|
||||||
) => {
|
) => {
|
||||||
this.ignoreChange = true;
|
this.ignoreChange = true;
|
||||||
|
|
||||||
@ -311,6 +311,10 @@ export default createPlugin<
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'CONNECTION_CLOSED': {
|
||||||
|
this.queue?.off(listener);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
console.warn('Music Together [Host]: Unknown Event', event);
|
console.warn('Music Together [Host]: Unknown Event', event);
|
||||||
break;
|
break;
|
||||||
@ -359,6 +363,37 @@ export default createPlugin<
|
|||||||
});
|
});
|
||||||
|
|
||||||
let resolveIgnore: number | null = null;
|
let resolveIgnore: number | null = null;
|
||||||
|
const queueListener = async (event: ConnectionEventUnion) => {
|
||||||
|
this.ignoreChange = true;
|
||||||
|
switch (event.type) {
|
||||||
|
case 'ADD_SONGS': {
|
||||||
|
await this.connection?.broadcast('ADD_SONGS', event.payload);
|
||||||
|
await this.connection?.broadcast('SYNC_QUEUE', undefined);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'REMOVE_SONG': {
|
||||||
|
await this.connection?.broadcast('REMOVE_SONG', event.payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'MOVE_SONG': {
|
||||||
|
await this.connection?.broadcast('MOVE_SONG', event.payload);
|
||||||
|
await this.connection?.broadcast('SYNC_QUEUE', undefined);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'SYNC_PROGRESS': {
|
||||||
|
if (this.permission === 'host-only')
|
||||||
|
await this.connection?.broadcast('SYNC_QUEUE', undefined);
|
||||||
|
else
|
||||||
|
await this.connection?.broadcast('SYNC_PROGRESS', event.payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof resolveIgnore === 'number') clearTimeout(resolveIgnore);
|
||||||
|
resolveIgnore = window.setTimeout(() => {
|
||||||
|
this.ignoreChange = false;
|
||||||
|
}, 16); // wait 1 frame
|
||||||
|
};
|
||||||
const listener = async (event: ConnectionEventUnion) => {
|
const listener = async (event: ConnectionEventUnion) => {
|
||||||
this.ignoreChange = true;
|
this.ignoreChange = true;
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
@ -448,6 +483,10 @@ export default createPlugin<
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'CONNECTION_CLOSED': {
|
||||||
|
this.queue?.off(queueListener);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
console.warn('Music Together [Guest]: Unknown Event', event);
|
console.warn('Music Together [Guest]: Unknown Event', event);
|
||||||
break;
|
break;
|
||||||
@ -461,37 +500,7 @@ export default createPlugin<
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.connection.on(listener);
|
this.connection.on(listener);
|
||||||
this.queue?.on(async (event: ConnectionEventUnion) => {
|
this.queue?.on(queueListener);
|
||||||
this.ignoreChange = true;
|
|
||||||
switch (event.type) {
|
|
||||||
case 'ADD_SONGS': {
|
|
||||||
await this.connection?.broadcast('ADD_SONGS', event.payload);
|
|
||||||
await this.connection?.broadcast('SYNC_QUEUE', undefined);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'REMOVE_SONG': {
|
|
||||||
await this.connection?.broadcast('REMOVE_SONG', event.payload);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'MOVE_SONG': {
|
|
||||||
await this.connection?.broadcast('MOVE_SONG', event.payload);
|
|
||||||
await this.connection?.broadcast('SYNC_QUEUE', undefined);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'SYNC_PROGRESS': {
|
|
||||||
if (this.permission === 'host-only')
|
|
||||||
await this.connection?.broadcast('SYNC_QUEUE', undefined);
|
|
||||||
else
|
|
||||||
await this.connection?.broadcast('SYNC_PROGRESS', event.payload);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof resolveIgnore === 'number') clearTimeout(resolveIgnore);
|
|
||||||
resolveIgnore = window.setTimeout(() => {
|
|
||||||
this.ignoreChange = false;
|
|
||||||
}, 16); // wait 1 frame
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!this.me) this.me = getDefaultProfile(this.connection.id);
|
if (!this.me) this.me = getDefaultProfile(this.connection.id);
|
||||||
this.queue?.injection();
|
this.queue?.injection();
|
||||||
|
|||||||
@ -252,7 +252,9 @@ export class Queue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
on(listener: QueueEventListener) {
|
on(listener: QueueEventListener) {
|
||||||
this.listeners.push(listener);
|
if (!this.listeners.includes(listener)) {
|
||||||
|
this.listeners.push(listener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
off(listener: QueueEventListener) {
|
off(listener: QueueEventListener) {
|
||||||
|
|||||||
Reference in New Issue
Block a user