Skip to content

Commit

Permalink
fix issues with info init
Browse files Browse the repository at this point in the history
  • Loading branch information
KentoNishi committed Aug 22, 2023
1 parent f3ced76 commit 43c7406
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 107 deletions.
18 changes: 9 additions & 9 deletions src/components/Hyperchat.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
UNDONE_MSG
} from '../ts/chat-constants';
import '../ts/resize-tracker';
import { isAllEmoji, isChatMessage, isPrivileged, responseIsAction, createPopup, getRandomString, getFrameInfoAsync } from '../ts/chat-utils';
import { isAllEmoji, isChatMessage, isPrivileged, responseIsAction, createPopup, getRandomString } from '../ts/chat-utils';
import Button from 'smelte/src/components/Button';
import {
theme,
Expand Down Expand Up @@ -155,20 +155,20 @@
chatFilterPresets.ready(),
defaultFilterPresetId.ready(),
new Promise(resolve => {
const unsub = initialized.subscribe((v) => {
if (v) {
unsub();
const interval = setInterval(() => {
if ($initialized) {
clearInterval(interval);
resolve(null);
}
});
}, 10);
}),
new Promise(resolve => {
const unsub = videoInfo.subscribe((v) => {
if (v !== undefined) {
unsub();
const interval = setInterval(() => {
if ($videoInfo !== undefined) {
clearInterval(interval);
resolve(null);
}
});
}, 10);
})
]);
await tick();
Expand Down
16 changes: 5 additions & 11 deletions src/scripts/chat-injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,10 @@ const chatLoaded = async (): Promise<void> => {
window.addEventListener('messageSent', (d) => {
processSentMessage((d as CustomEvent).detail);
});
let videoInfoResolver = (_info: string): void => {};
const videoInfoPromise = new Promise<string>((resolve) => {
videoInfoResolver = resolve;
});
window.addEventListener('videoInfo', d => {
videoInfoResolver((d as CustomEvent).detail);
let json = '{}';
window.addEventListener('videoInfoYtcFilter', d => {
console.log('calling setInitialData', json, JSON.parse((d as CustomEvent).detail));
setInitialData(json, JSON.parse((d as CustomEvent).detail));
});
const script = document.createElement('script');
script.src = chrome.runtime.getURL('scripts/chat-interceptor.js');
Expand All @@ -73,11 +71,7 @@ const chatLoaded = async (): Promise<void> => {
if (!text || !text.startsWith(start)) {
continue;
}
const json = text.replace(start, '').slice(0, -1);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
videoInfoPromise.then((info) => {
setInitialData(json, JSON.parse(info));
});
json = text.replace(start, '').slice(0, -1);
break;
}

Expand Down
140 changes: 71 additions & 69 deletions src/scripts/chat-interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,76 +2,78 @@ import { stringifyRuns } from '../ts/ytcf-utils';
import { fixLeaks } from '../ts/ytc-fix-memleaks';
import { parseMessageRuns } from '../ts/chat-parser';

for (const eventName of ['visibilitychange', 'webkitvisibilitychange', 'blur']) {
window.addEventListener(eventName, event => {
event.stopImmediatePropagation();
}, true);
}
const fetchFallback = window.fetch;
(window as any).fetchFallback = fetchFallback;
window.fetch = async (...args) => {
const request = args[0] as Request;
const url = request.url;
const result = await fetchFallback(...args);

const currentDomain = (location.protocol + '//' + location.host);
const ytApi = (end: string): string => `${currentDomain}/youtubei/v1/live_chat${end}`;
const isReceiving = url.startsWith(ytApi('/get_live_chat'));
const isSending = url.startsWith(ytApi('/send_message'));
const action = isReceiving ? 'messageReceive' : 'messageSent';
if (isReceiving || isSending) {
const response = JSON.stringify(await (result.clone()).json());
window.dispatchEvent(new CustomEvent(action, { detail: response }));
if (!window.location.href.includes('v=Lq9eqHDKJPE&ytcfilter=1')) {
for (const eventName of ['visibilitychange', 'webkitvisibilitychange', 'blur']) {
window.addEventListener(eventName, event => {
event.stopImmediatePropagation();
}, true);
}
return result;
};
// window.dispatchEvent(new CustomEvent('chatLoaded', {
// detail: JSON.stringify(window.ytcfg)
// }));
// eslint-disable-next-line @typescript-eslint/no-misused-promises
window.addEventListener('proxyFetchRequest', async (event) => {
const args = JSON.parse((event as any).detail as string) as [string, any];
const request = await fetchFallback(...args);
const response = await request.json();
window.dispatchEvent(new CustomEvent('proxyFetchResponse', {
detail: JSON.stringify(response)
}));
});
const fetchFallback = window.fetch;
(window as any).fetchFallback = fetchFallback;
window.fetch = async (...args) => {
const request = args[0] as Request;
const url = request.url;
const result = await fetchFallback(...args);

const currentDomain = (location.protocol + '//' + location.host);
const ytApi = (end: string): string => `${currentDomain}/youtubei/v1/live_chat${end}`;
const isReceiving = url.startsWith(ytApi('/get_live_chat'));
const isSending = url.startsWith(ytApi('/send_message'));
const action = isReceiving ? 'messageReceive' : 'messageSent';
if (isReceiving || isSending) {
const response = JSON.stringify(await (result.clone()).json());
window.dispatchEvent(new CustomEvent(action, { detail: response }));
}
return result;
};
// window.dispatchEvent(new CustomEvent('chatLoaded', {
// detail: JSON.stringify(window.ytcfg)
// }));
// eslint-disable-next-line @typescript-eslint/no-misused-promises
window.addEventListener('proxyFetchRequest', async (event) => {
const args = JSON.parse((event as any).detail as string) as [string, any];
const request = await fetchFallback(...args);
const response = await request.json();
window.dispatchEvent(new CustomEvent('proxyFetchResponse', {
detail: JSON.stringify(response)
}));
});

try {
const video = (window as any)
.parent.yt.config_.SBOX_SETTINGS.SEARCHBOX_COMPONENT.__dataHost.parentComponent
.__data.data.response.contents.twoColumnWatchNextResults.results.results.contents[0]
.videoPrimaryInfoRenderer;
const channel = (window as any).parent.yt.config_.SBOX_SETTINGS.SEARCHBOX_COMPONENT.__dataHost
.parentComponent.__data.data.response.contents.twoColumnWatchNextResults.results.results
.contents[1].videoSecondaryInfoRenderer.owner.videoOwnerRenderer;
const params = new URLSearchParams(window.parent.location.search);
window.dispatchEvent(new CustomEvent('videoInfo', {
detail: JSON.stringify({
video: {
title: stringifyRuns(parseMessageRuns(video.title.runs)),
videoId: video.updatedMetadataEndpoint?.updatedMetadataEndpoint?.videoId || params.get('v')
},
channel: {
channelId: channel.navigationEndpoint.browseEndpoint.browseId,
handle: channel.navigationEndpoint.browseEndpoint.canonicalBaseUrl.split('/@')[1],
name: stringifyRuns(parseMessageRuns(channel.title.runs))
}
})
}));
} catch (e) {
const videoId = new URLSearchParams(window.location.search).get('v');
window.dispatchEvent(new CustomEvent('videoInfo', {
detail: JSON.stringify(
videoId !== null
? {
video: {
videoId
try {
const video = (window as any)
.parent.yt.config_.SBOX_SETTINGS.SEARCHBOX_COMPONENT.__dataHost.parentComponent
.__data.data.response.contents.twoColumnWatchNextResults.results.results.contents[0]
.videoPrimaryInfoRenderer;
const channel = (window as any).parent.yt.config_.SBOX_SETTINGS.SEARCHBOX_COMPONENT.__dataHost
.parentComponent.__data.data.response.contents.twoColumnWatchNextResults.results.results
.contents[1].videoSecondaryInfoRenderer.owner.videoOwnerRenderer;
const params = new URLSearchParams(window.parent.location.search);
window.dispatchEvent(new CustomEvent('videoInfoYtcFilter', {
detail: JSON.stringify({
video: {
title: stringifyRuns(parseMessageRuns(video.title.runs)),
videoId: video.updatedMetadataEndpoint?.updatedMetadataEndpoint?.videoId || params.get('v')
},
channel: {
channelId: channel.navigationEndpoint.browseEndpoint.browseId,
handle: channel.navigationEndpoint.browseEndpoint.canonicalBaseUrl.split('/@')[1],
name: stringifyRuns(parseMessageRuns(channel.title.runs))
}
})
}));
} catch (e) {
const videoId = new URLSearchParams(window.location.search).get('v');
window.dispatchEvent(new CustomEvent('videoInfoYtcFilter', {
detail: JSON.stringify(
videoId !== null
? {
video: {
videoId
}
}
}
: null)
}));
}
: null)
}));
}

fixLeaks();
fixLeaks();
}
42 changes: 26 additions & 16 deletions src/ts/messaging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,30 @@ const registerClient = (
}
);

if (getInitialData && isYtcInterceptor(interceptor)) {
const selfChannel = interceptor.queue.selfChannel.get();
const videoInfo = interceptor.queue.videoInfo.get();
const payload: Chat.InitialData = {
type: 'initialData',
initialData: interceptor.queue.getInitialData(),
selfChannel: selfChannel != null
? {
name: selfChannel.authorName?.simpleText ?? '',
channelId: selfChannel.authorExternalChannelId ?? ''
}
: null,
videoInfo
if (getInitialData) {
const callback = (): void => {
if (isYtcInterceptor(interceptor) && interceptor.queue.initialDataReady.get()) {
const selfChannel = interceptor.queue.selfChannel.get();
const videoInfo = interceptor.queue.videoInfo.get();
if (!videoInfo) console.debug('Video info not ready', { port, interceptor });
const payload: Chat.InitialData = {
type: 'initialData',
initialData: interceptor.queue.getInitialData(),
selfChannel: selfChannel != null
? {
name: selfChannel.authorName?.simpleText ?? '',
channelId: selfChannel.authorExternalChannelId ?? ''
}
: null,
videoInfo
};
port.postMessage(payload);
console.debug('Sent initial data', { port, interceptor, payload });
unsubber();
}
};
port.postMessage(payload);
console.debug('Sent initial data', { port, interceptor, payload });
const unsubber = (interceptor as Chat.YtcInterceptor).queue.initialDataReady.subscribe(() => setTimeout(callback, 0));
callback();
}
};

Expand Down Expand Up @@ -140,12 +148,14 @@ export const setInitialData = (json: string, info: SimpleVideoInfo | null): void
?.addLiveChatTextMessageFromTemplateAction?.template
?.liveChatTextMessageRenderer ?? {
authorName: {
simpleText: parsedJson.continuationContents.liveChatContinuation.viewerName
simpleText: parsedJson?.continuationContents?.liveChatContinuation?.viewerName
}
};

interceptor.queue.selfChannel.set(user);
interceptor.queue.videoInfo.set(info);
interceptor.queue.initialDataReady.set(true);
console.log('initialDataReady', interceptor.queue.initialDataReady.get());
};

/** Updates the player progress of the queue of the interceptor. */
Expand Down
6 changes: 5 additions & 1 deletion src/ts/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export interface YtcQueue {
cleanUp: () => void;
selfChannel: Subscribable<Ytc.TextMessageRenderer | null | undefined>;
videoInfo: Subscribable<SimpleVideoInfo | null>;
initialDataReady: Subscribable<boolean>;
}

export function ytcQueue(isReplay = false): YtcQueue {
Expand All @@ -108,6 +109,8 @@ export function ytcQueue(isReplay = false): YtcQueue {
let initialData: Chat.Actions[] = [];
const selfChannel = subscribable<Ytc.TextMessageRenderer | null | undefined>();
const videoInfo = subscribable<SimpleVideoInfo | null>();
const initialDataReady = subscribable<boolean>();
initialDataReady.set(false);

/**
* Continuously pushes queue messages to store until queue is empty or until
Expand Down Expand Up @@ -302,6 +305,7 @@ export function ytcQueue(isReplay = false): YtcQueue {
updatePlayerProgress,
cleanUp,
selfChannel,
videoInfo
videoInfo,
initialDataReady
};
}
1 change: 0 additions & 1 deletion src/ts/ytcf-logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,6 @@ export const saveMessageActions = async (
nickname: lastObj.nickname || '',
size: actions.length
};
console.log(obj);
await saveMessageDumpInfo(key, obj);
// const actionsStore = stores.addSyncStore(keyGen(key, 'actions'), actions, false);
// await actionsStore.ready();
Expand Down

0 comments on commit 43c7406

Please sign in to comment.