mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-13 11:21:46 +00:00
fix(music-together): typing
This commit is contained in:
@ -1,12 +1,51 @@
|
||||
import { getMusicQueueRenderer } from './song';
|
||||
import { mapQueueItem } from './utils';
|
||||
|
||||
import type { Profile, QueueAPI, VideoData } from '../types';
|
||||
import { ConnectionEventUnion } from '@/plugins/music-together/connection';
|
||||
import { t } from '@/i18n';
|
||||
|
||||
import type { Profile, QueueAPI, VideoData } from '../types';
|
||||
import type { QueueItem } from '@/types/datahost-get-state';
|
||||
|
||||
const getHeaderPayload = (() => {
|
||||
let payload: unknown = null;
|
||||
let payload: {
|
||||
items?: QueueItem[] | undefined;
|
||||
title: {
|
||||
runs: {
|
||||
text: string;
|
||||
}[];
|
||||
};
|
||||
subtitle: {
|
||||
runs: {
|
||||
text: string;
|
||||
}[];
|
||||
};
|
||||
buttons: {
|
||||
chipCloudChipRenderer: {
|
||||
style: {
|
||||
styleType: string;
|
||||
};
|
||||
text: {
|
||||
runs: {
|
||||
text: string;
|
||||
}[];
|
||||
};
|
||||
navigationEndpoint: {
|
||||
saveQueueToPlaylistCommand: unknown;
|
||||
};
|
||||
icon: {
|
||||
iconType: string;
|
||||
};
|
||||
accessibilityData: {
|
||||
accessibilityData: {
|
||||
label: string;
|
||||
};
|
||||
};
|
||||
isSelected: boolean;
|
||||
uniqueId: string;
|
||||
};
|
||||
}[];
|
||||
} | null = null;
|
||||
|
||||
return () => {
|
||||
if (!payload) {
|
||||
@ -58,7 +97,7 @@ const getHeaderPayload = (() => {
|
||||
}
|
||||
|
||||
return payload;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
export type QueueOptions = {
|
||||
@ -70,11 +109,11 @@ export type QueueOptions = {
|
||||
export type QueueEventListener = (event: ConnectionEventUnion) => void;
|
||||
|
||||
export class Queue {
|
||||
private queue: (HTMLElement & QueueAPI) | null = null;
|
||||
private originalDispatch: ((obj: {
|
||||
private queue: (HTMLElement & QueueAPI);
|
||||
private originalDispatch?: (obj: {
|
||||
type: string;
|
||||
payload?: unknown;
|
||||
}) => void) | null = null;
|
||||
payload?: { items?: QueueItem[] | undefined; };
|
||||
}) => void;
|
||||
private internalDispatch = false;
|
||||
private ignoreFlag = false;
|
||||
private listeners: QueueEventListener[] = [];
|
||||
@ -83,7 +122,7 @@ export class Queue {
|
||||
|
||||
constructor(options: QueueOptions) {
|
||||
this.getProfile = options.getProfile;
|
||||
this.queue = options.queue ?? document.querySelector<HTMLElement & QueueAPI>('#queue');
|
||||
this.queue = options.queue ?? document.querySelector<HTMLElement & QueueAPI>('#queue')!;
|
||||
this.owner = options.owner ?? null;
|
||||
this._videoList = options.videoList ?? [];
|
||||
}
|
||||
@ -96,7 +135,7 @@ export class Queue {
|
||||
}
|
||||
|
||||
get selectedIndex() {
|
||||
return mapQueueItem((it) => it?.selected, this.queue?.store.getState().queue.items).findIndex(Boolean) ?? 0;
|
||||
return mapQueueItem((it) => it?.selected, this.queue.store.getState().queue.items).findIndex(Boolean) ?? 0;
|
||||
}
|
||||
|
||||
get rawItems() {
|
||||
@ -146,7 +185,7 @@ export class Queue {
|
||||
return true;
|
||||
}
|
||||
|
||||
async removeVideo(index: number) {
|
||||
removeVideo(index: number) {
|
||||
this.internalDispatch = true;
|
||||
this._videoList.splice(index, 1);
|
||||
this.queue?.dispatch({
|
||||
@ -233,10 +272,10 @@ export class Queue {
|
||||
if (event.type === 'ADD_ITEMS') {
|
||||
if (this.ignoreFlag) {
|
||||
this.ignoreFlag = false;
|
||||
const videoList = mapQueueItem((it: any) => ({
|
||||
videoId: it.videoId,
|
||||
const videoList = mapQueueItem((it) => ({
|
||||
videoId: it!.videoId,
|
||||
ownerId: this.owner!.id
|
||||
} satisfies VideoData), (event.payload as any).items);
|
||||
} satisfies VideoData), event.payload!.items!);
|
||||
const index = this._videoList.length + videoList.length - 1;
|
||||
|
||||
if (videoList.length > 0) {
|
||||
@ -255,15 +294,17 @@ export class Queue {
|
||||
]
|
||||
});
|
||||
}
|
||||
} else if ((event.payload as any).items.length === 1) {
|
||||
} else if ((event.payload as {
|
||||
items: unknown[];
|
||||
}).items.length === 1) {
|
||||
this.broadcast({ // add playlist
|
||||
type: 'ADD_SONGS',
|
||||
payload: {
|
||||
// index: (event.payload as any).index,
|
||||
videoList: mapQueueItem((it: any) => ({
|
||||
videoId: it.videoId,
|
||||
videoList: mapQueueItem((it) => ({
|
||||
videoId: it!.videoId,
|
||||
ownerId: this.owner!.id
|
||||
} satisfies VideoData), (event.payload as any).items)
|
||||
} satisfies VideoData), event.payload!.items!)
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -275,8 +316,12 @@ export class Queue {
|
||||
this.broadcast({
|
||||
type: 'MOVE_SONG',
|
||||
payload: {
|
||||
fromIndex: (event.payload as any).fromIndex,
|
||||
toIndex: (event.payload as any).toIndex
|
||||
fromIndex: (event.payload as {
|
||||
fromIndex: number;
|
||||
}).fromIndex,
|
||||
toIndex: (event.payload as {
|
||||
toIndex: number;
|
||||
}).toIndex
|
||||
}
|
||||
});
|
||||
return;
|
||||
@ -306,7 +351,7 @@ export class Queue {
|
||||
event.payload = undefined;
|
||||
}
|
||||
if (event.type === 'SET_PLAYER_UI_STATE') {
|
||||
if (event.payload === 'INACTIVE' && this.videoList.length > 0) {
|
||||
if (event.payload as string === 'INACTIVE' && this.videoList.length > 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -321,12 +366,12 @@ export class Queue {
|
||||
dispatch: this.originalDispatch
|
||||
}
|
||||
};
|
||||
this.originalDispatch!.call(fakeContext, event);
|
||||
this.originalDispatch?.call(fakeContext, event);
|
||||
};
|
||||
}
|
||||
|
||||
/* sync */
|
||||
async initQueue() {
|
||||
initQueue() {
|
||||
if (!this.queue) return;
|
||||
|
||||
this.internalDispatch = true;
|
||||
@ -369,13 +414,13 @@ export class Queue {
|
||||
return true;
|
||||
}
|
||||
|
||||
async syncQueueOwner() {
|
||||
syncQueueOwner() {
|
||||
const allQueue = document.querySelectorAll('#queue');
|
||||
|
||||
allQueue.forEach((queue) => {
|
||||
const list = Array.from(queue?.querySelectorAll<HTMLElement>('ytmusic-player-queue-item') ?? []);
|
||||
|
||||
list.forEach((item, index) => {
|
||||
list.forEach((item, index: number | undefined) => {
|
||||
if (typeof index !== 'number') return;
|
||||
|
||||
const id = this._videoList[index]?.ownerId;
|
||||
|
||||
@ -12,14 +12,14 @@ export function SHA1Hash(): {
|
||||
}
|
||||
|
||||
function processBlock(block: number[]): void {
|
||||
let words: number[] = [];
|
||||
const words: number[] = [];
|
||||
for (let i = 0; i < 64; i += 4) {
|
||||
words[i / 4] = block[i] << 24 | block[i + 1] << 16 | block[i + 2] << 8 | block[i + 3];
|
||||
words[i / 4] = (block[i] << 24) | (block[i + 1] << 16) | (block[i + 2] << 8) | block[i + 3];
|
||||
}
|
||||
|
||||
for (let i = 16; i < 80; i++) {
|
||||
let temp = words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16];
|
||||
words[i] = (temp << 1 | temp >>> 31) & 4294967295;
|
||||
const temp = words[i - 3] ^ words[i - 8] ^ words[i - 14] ^ words[i - 16];
|
||||
words[i] = ((temp << 1) | (temp >>> 31)) & 4294967295;
|
||||
}
|
||||
|
||||
let a = hash[0],
|
||||
@ -30,22 +30,22 @@ export function SHA1Hash(): {
|
||||
for (let i = 0; i < 80; i++) {
|
||||
let f, k;
|
||||
if (i < 20) {
|
||||
f = d ^ b & (c ^ d);
|
||||
f = d ^ (b & (c ^ d));
|
||||
k = 1518500249;
|
||||
} else if (i < 40) {
|
||||
f = b ^ c ^ d;
|
||||
k = 1859775393;
|
||||
} else if (i < 60) {
|
||||
f = b & c | d & (b | c);
|
||||
f = (b & c) | (d & (b | c));
|
||||
k = 2400959708;
|
||||
} else {
|
||||
f = b ^ c ^ d;
|
||||
k = 3395469782;
|
||||
}
|
||||
let temp = ((a << 5 | a >>> 27) & 4294967295) + f + e + k + words[i] & 4294967295;
|
||||
const temp = (((a << 5) | (a >>> 27)) & 4294967295) + f + e + k + words[i] & 4294967295;
|
||||
e = d;
|
||||
d = c;
|
||||
c = (b << 30 | b >>> 2) & 4294967295;
|
||||
c = ((b << 30) | (b >>> 2)) & 4294967295;
|
||||
b = a;
|
||||
a = temp;
|
||||
}
|
||||
@ -58,8 +58,9 @@ export function SHA1Hash(): {
|
||||
|
||||
function update(message: string | number[], length?: number): void {
|
||||
if ('string' === typeof message) {
|
||||
// HACK: to decode UTF-8
|
||||
message = unescape(encodeURIComponent(message));
|
||||
let bytes: number[] = [];
|
||||
const bytes: number[] = [];
|
||||
for (let i = 0, len = message.length; i < len; ++i)
|
||||
bytes.push(message.charCodeAt(i));
|
||||
message = bytes;
|
||||
@ -67,48 +68,59 @@ export function SHA1Hash(): {
|
||||
length || (length = message.length);
|
||||
let i = 0;
|
||||
if (0 == currentLength)
|
||||
for (; i + 64 < length;)
|
||||
processBlock(message.slice(i, i + 64)),
|
||||
i += 64,
|
||||
for (; i + 64 < length;) {
|
||||
processBlock(message.slice(i, i + 64));
|
||||
i += 64;
|
||||
totalLength += 64;
|
||||
}
|
||||
for (; i < length;) {
|
||||
if (buffer[currentLength++] = message[i++], totalLength++, 64 == currentLength)
|
||||
for (currentLength = 0, processBlock(buffer); i + 64 < length;) {
|
||||
processBlock(message.slice(i, i + 64));
|
||||
i += 64;
|
||||
totalLength += 64;
|
||||
for (; i < length;)
|
||||
if (buffer[currentLength++] = message[i++],
|
||||
totalLength++,
|
||||
64 == currentLength)
|
||||
for (currentLength = 0,
|
||||
processBlock(buffer); i + 64 < length;)
|
||||
processBlock(message.slice(i, i + 64)),
|
||||
i += 64,
|
||||
totalLength += 64;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function finalize(): number[] {
|
||||
let result: number[] = []
|
||||
, bits = 8 * totalLength;
|
||||
if (currentLength < 56)
|
||||
const result: number[] = [];
|
||||
let bits = 8 * totalLength;
|
||||
if (currentLength < 56) {
|
||||
update(padding, 56 - currentLength);
|
||||
else
|
||||
} else {
|
||||
update(padding, 64 - (currentLength - 56));
|
||||
for (let i = 63; i >= 56; i--)
|
||||
buffer[i] = bits & 255,
|
||||
bits >>>= 8;
|
||||
}
|
||||
for (let i = 63; i >= 56; i--) {
|
||||
buffer[i] = bits & 255;
|
||||
bits >>>= 8;
|
||||
}
|
||||
processBlock(buffer);
|
||||
for (let i = 0; i < 5; i++)
|
||||
for (let j = 24; j >= 0; j -= 8)
|
||||
result.push(hash[i] >> j & 255);
|
||||
for (let i = 0; i < 5; i++) {
|
||||
for (let j = 24; j >= 0; j -= 8) {
|
||||
result.push((hash[i] >> j) & 255);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
let buffer: number[] = [], padding: number[] = [128], totalLength: number, currentLength: number;
|
||||
for (let i = 1; i < 64; ++i)
|
||||
const buffer: number[] = [];
|
||||
const padding: number[] = [128];
|
||||
let totalLength: number;
|
||||
let currentLength: number;
|
||||
|
||||
for (let i = 1; i < 64; ++i) {
|
||||
padding[i] = 0;
|
||||
}
|
||||
|
||||
initialize();
|
||||
return {
|
||||
reset: initialize,
|
||||
update: update,
|
||||
digest: finalize,
|
||||
digestString: function(): string {
|
||||
let hash = finalize(), hex = '';
|
||||
const hash = finalize();
|
||||
let hex = '';
|
||||
for (let i = 0; i < hash.length; i++)
|
||||
hex += '0123456789ABCDEF'.charAt(Math.floor(hash[i] / 16)) + '0123456789ABCDEF'.charAt(hash[i] % 16);
|
||||
return hex;
|
||||
|
||||
@ -1,15 +1,21 @@
|
||||
export const mapQueueItem = <T>(map: (item: any | null) => T, array: any[]): T[] => array
|
||||
import {
|
||||
ItemPlaylistPanelVideoRenderer,
|
||||
PlaylistPanelVideoWrapperRenderer,
|
||||
QueueItem
|
||||
} from '@/types/datahost-get-state';
|
||||
|
||||
export const mapQueueItem = <T>(map: (item?: ItemPlaylistPanelVideoRenderer) => T, array: QueueItem[]): T[] => array
|
||||
.map((item) => {
|
||||
if ('playlistPanelVideoWrapperRenderer' in item) {
|
||||
const keys = Object.keys(item.playlistPanelVideoWrapperRenderer.primaryRenderer);
|
||||
return item.playlistPanelVideoWrapperRenderer.primaryRenderer[keys[0]];
|
||||
const keys = Object.keys(item.playlistPanelVideoWrapperRenderer!.primaryRenderer) as (keyof PlaylistPanelVideoWrapperRenderer['primaryRenderer'])[];
|
||||
return item.playlistPanelVideoWrapperRenderer!.primaryRenderer[keys[0]];
|
||||
}
|
||||
if ('playlistPanelVideoRenderer' in item) {
|
||||
return item.playlistPanelVideoRenderer;
|
||||
}
|
||||
|
||||
console.error('Music Together: Unknown item', item);
|
||||
return null;
|
||||
return undefined;
|
||||
})
|
||||
.map(map);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user