feat: rename IPC

This commit is contained in:
JellyBrick
2024-01-06 10:17:40 +09:00
parent 5d5cc58f59
commit 6b7c43925a
26 changed files with 88 additions and 73 deletions

View File

@ -114,18 +114,18 @@ function onClosed() {
mainWindow = null; mainWindow = null;
} }
ipcMain.handle('get-main-plugin-names', () => Object.keys(mainPlugins)); ipcMain.handle('ytmd:get-main-plugin-names', () => Object.keys(mainPlugins));
const initHook = (win: BrowserWindow) => { const initHook = (win: BrowserWindow) => {
ipcMain.handle( ipcMain.handle(
'get-config', 'ytmd:get-config',
(_, id: string) => (_, id: string) =>
deepmerge( deepmerge(
allPlugins[id].config ?? { enabled: false }, allPlugins[id].config ?? { enabled: false },
config.get(`plugins.${id}`) ?? {}, config.get(`plugins.${id}`) ?? {},
) as PluginConfig, ) as PluginConfig,
); );
ipcMain.handle('set-config', (_, name: string, obj: object) => ipcMain.handle('ytmd:set-config', (_, name: string, obj: object) =>
config.setPartial(`plugins.${name}`, obj, allPlugins[name].config), config.setPartial(`plugins.${name}`, obj, allPlugins[name].config),
); );

View File

@ -18,9 +18,9 @@ const loadedPluginMap: Record<
export const createContext = <Config extends PluginConfig>( export const createContext = <Config extends PluginConfig>(
id: string, id: string,
): RendererContext<Config> => ({ ): RendererContext<Config> => ({
getConfig: async () => window.ipcRenderer.invoke('get-config', id), getConfig: async () => window.ipcRenderer.invoke('ytmd:get-config', id),
setConfig: async (newConfig) => { setConfig: async (newConfig) => {
await window.ipcRenderer.invoke('set-config', id, newConfig); await window.ipcRenderer.invoke('ytmd:set-config', id, newConfig);
}, },
ipc: { ipc: {
send: (event: string, ...args: unknown[]) => { send: (event: string, ...args: unknown[]) => {

View File

@ -9,7 +9,25 @@ import { t } from '@/i18n';
const COLOR_KEY = '--ytmusic-album-color'; const COLOR_KEY = '--ytmusic-album-color';
const DARK_COLOR_KEY = '--ytmusic-album-color-dark'; const DARK_COLOR_KEY = '--ytmusic-album-color-dark';
export default createPlugin({ export default createPlugin<
unknown,
unknown,
{
color?: Color;
darkColor?: Color;
playerPage: HTMLElement | null;
navBarBackground: HTMLElement | null;
ytmusicPlayerBar: HTMLElement | null;
playerBarBackground: HTMLElement | null;
sidebarBig: HTMLElement | null;
sidebarSmall: HTMLElement | null;
ytmusicAppLayout: HTMLElement | null;
getColor(key: string, alpha?: number): string;
updateColor(): void;
}
>({
name: () => t('plugins.album-color-theme.name'), name: () => t('plugins.album-color-theme.name'),
description: () => t('plugins.album-color-theme.description'), description: () => t('plugins.album-color-theme.description'),
restartNeeded: true, restartNeeded: true,
@ -18,16 +36,13 @@ export default createPlugin({
}, },
stylesheets: [style], stylesheets: [style],
renderer: { renderer: {
color: null as Color | null, playerPage: null,
darkColor: null as Color | null, navBarBackground: null,
ytmusicPlayerBar: null,
playerPage: null as HTMLElement | null, playerBarBackground: null,
navBarBackground: null as HTMLElement | null, sidebarBig: null,
ytmusicPlayerBar: null as HTMLElement | null, sidebarSmall: null,
playerBarBackground: null as HTMLElement | null, ytmusicAppLayout: null,
sidebarBig: null as HTMLElement | null,
sidebarSmall: null as HTMLElement | null,
ytmusicAppLayout: null as HTMLElement | null,
start() { start() {
this.playerPage = document.querySelector<HTMLElement>('#player-page'); this.playerPage = document.querySelector<HTMLElement>('#player-page');

View File

@ -7,7 +7,7 @@ export default createPlugin({
renderer() { renderer() {
document.addEventListener( document.addEventListener(
'audioCanPlay', 'ytmd:audio-can-play',
({ detail: { audioSource, audioContext } }) => { ({ detail: { audioSource, audioContext } }) => {
const compressor = audioContext.createDynamicsCompressor(); const compressor = audioContext.createDynamicsCompressor();

View File

@ -121,7 +121,7 @@ export default createRenderer<
?.unloadModule('captions'); ?.unloadModule('captions');
document document
.querySelector('video') .querySelector('video')
?.removeEventListener('srcChanged', this.videoChangeListener); ?.removeEventListener('ytmd:src-changed', this.videoChangeListener);
this.captionsSettingsButton.removeEventListener( this.captionsSettingsButton.removeEventListener(
'click', 'click',
this.captionsButtonClickListener, this.captionsButtonClickListener,
@ -139,7 +139,7 @@ export default createRenderer<
document document
.querySelector('video') .querySelector('video')
?.addEventListener('srcChanged', this.videoChangeListener); ?.addEventListener('ytmd:src-changed', this.videoChangeListener);
this.captionsSettingsButton.addEventListener( this.captionsSettingsButton.addEventListener(
'click', 'click',
this.captionsButtonClickListener, this.captionsButtonClickListener,

View File

@ -244,7 +244,7 @@ export const backend = createBackend<
}); });
connect(); connect();
let lastSent = Date.now(); let lastSent = Date.now();
ipcMain.on('timeChanged', (_, t: number) => { ipcMain.on('ytmd:time-changed', (_, t: number) => {
const currentTime = Date.now(); const currentTime = Date.now();
// if lastSent is more than 5 seconds ago, send the new time // if lastSent is more than 5 seconds ago, send the new time
if (currentTime - lastSent > 5000) { if (currentTime - lastSent > 5000) {

View File

@ -110,7 +110,7 @@ export const onMainLoad = async ({
fetch: getNetFetchAsFetch(), fetch: getNetFetchAsFetch(),
}); });
ipc.handle('download-song', (url: string) => downloadSong(url)); ipc.handle('download-song', (url: string) => downloadSong(url));
ipc.on('video-src-changed', (data: GetPlayerResponse) => { ipc.on('ytmd:video-src-changed', (data: GetPlayerResponse) => {
playingUrl = data.microformat.microformatDataRenderer.urlCanonical; playingUrl = data.microformat.microformatDataRenderer.urlCanonical;
}); });
ipc.handle('download-playlist-request', async (url: string) => ipc.handle('download-playlist-request', async (url: string) =>

View File

@ -47,7 +47,7 @@ export const onMainLoad = ({
return target; return target;
}; };
ipcMain.handle('menu-event', (event, commandId: number) => { ipcMain.handle('ytmd:menu-event', (event, commandId: number) => {
const target = getMenuItemById(commandId); const target = getMenuItemById(commandId);
if (target) if (target)
target.click( target.click(

View File

@ -76,7 +76,7 @@ export const createPanel = (
} }
menu.addEventListener('click', async () => { menu.addEventListener('click', async () => {
await window.ipcRenderer.invoke('menu-event', item.commandId); await window.ipcRenderer.invoke('ytmd:menu-event', item.commandId);
const menuItem = (await window.ipcRenderer.invoke( const menuItem = (await window.ipcRenderer.invoke(
'get-menu-by-id', 'get-menu-by-id',
item.commandId, item.commandId,

View File

@ -253,9 +253,9 @@ export default (
songControls = getSongControls(win); songControls = getSongControls(win);
let currentSeconds = 0; let currentSeconds = 0;
on('ytmd:player-api-loaded', () => send('setupTimeChangedListener')); on('ytmd:player-api-loaded', () => send('ytmd:setup-time-changed-listener'));
on('timeChanged', (t: number) => { on('ytmd:time-changed', (t: number) => {
currentSeconds = t; currentSeconds = t;
}); });

View File

@ -101,7 +101,7 @@ export const onMainLoad = async ({
config ??= await getConfig(); config ??= await getConfig();
setConfig({ isInPiP }); setConfig({ isInPiP });
on('picture-in-picture', () => { on('plugin:toggle-picture-in-picture', () => {
togglePiP(); togglePiP();
}); });

View File

@ -90,7 +90,7 @@ const togglePictureInPicture = async () => {
} catch {} } catch {}
} }
window.ipcRenderer.send('picture-in-picture'); window.ipcRenderer.send('plugin:toggle-picture-in-picture');
return false; return false;
}; };
// For UI (HTML) // For UI (HTML)

View File

@ -78,7 +78,7 @@ const observeVideo = () => {
const video = document.querySelector<HTMLVideoElement>('video'); const video = document.querySelector<HTMLVideoElement>('video');
if (video) { if (video) {
video.addEventListener('ratechange', forcePlaybackRate); video.addEventListener('ratechange', forcePlaybackRate);
video.addEventListener('srcChanged', forcePlaybackRate); video.addEventListener('ytmd:src-changed', forcePlaybackRate);
} }
}; };
@ -128,7 +128,7 @@ export const onUnload = () => {
const video = document.querySelector<HTMLVideoElement>('video'); const video = document.querySelector<HTMLVideoElement>('video');
if (video) { if (video) {
video.removeEventListener('ratechange', forcePlaybackRate); video.removeEventListener('ratechange', forcePlaybackRate);
video.removeEventListener('srcChanged', forcePlaybackRate); video.removeEventListener('ytmd:src-changed', forcePlaybackRate);
} }
slider.removeEventListener('wheel', wheelEventListener); slider.removeEventListener('wheel', wheelEventListener);
getSongMenu()?.removeChild(slider); getSongMenu()?.removeChild(slider);

View File

@ -71,7 +71,7 @@ export const onPlayerApiReady = async (
const videoMode = () => const videoMode = () =>
api.getPlayerResponse().videoDetails?.musicVideoType !== api.getPlayerResponse().videoDetails?.musicVideoType !==
'MUSIC_VIDEO_TYPE_ATV'; 'MUSIC_VIDEO_TYPE_ATV';
$('video')?.addEventListener('srcChanged', () => $('video')?.addEventListener('ytmd:src-changed', () =>
moveVolumeHud(videoMode()), moveVolumeHud(videoMode()),
); );
} }

View File

@ -29,25 +29,25 @@ function registerMPRIS(win: BrowserWindow) {
const microToSec = (n: unknown) => Math.round(Number(n) / 1e6); const microToSec = (n: unknown) => Math.round(Number(n) / 1e6);
const seekTo = (e: { position: unknown }) => const seekTo = (e: { position: unknown }) =>
win.webContents.send('seekTo', microToSec(e.position)); win.webContents.send('ytmd:seek-to', microToSec(e.position));
const seekBy = (o: unknown) => const seekBy = (o: unknown) =>
win.webContents.send('seekBy', microToSec(o)); win.webContents.send('ytmd:seek-by', microToSec(o));
const player = setupMPRIS(); const player = setupMPRIS();
ipcMain.on('ytmd:player-api-loaded', () => { ipcMain.on('ytmd:player-api-loaded', () => {
win.webContents.send('setupSeekedListener', 'mpris'); win.webContents.send('ytmd:setup-seeked-listener', 'mpris');
win.webContents.send('setupTimeChangedListener', 'mpris'); win.webContents.send('ytmd:setup-time-changed-listener', 'mpris');
win.webContents.send('setupRepeatChangedListener', 'mpris'); win.webContents.send('ytmd:setup-repeat-changed-listener', 'mpris');
win.webContents.send('setupVolumeChangedListener', 'mpris'); win.webContents.send('ytmd:setup-volume-changed-listener', 'mpris');
}); });
ipcMain.on('seeked', (_, t: number) => player.seeked(secToMicro(t))); ipcMain.on('ytmd:seeked', (_, t: number) => player.seeked(secToMicro(t)));
let currentSeconds = 0; let currentSeconds = 0;
ipcMain.on('timeChanged', (_, t: number) => (currentSeconds = t)); ipcMain.on('ytmd:time-changed', (_, t: number) => (currentSeconds = t));
ipcMain.on('repeatChanged', (_, mode: string) => { ipcMain.on('ytmd:repeat-changed', (_, mode: string) => {
switch (mode) { switch (mode) {
case 'NONE': { case 'NONE': {
player.loopStatus = mpris.LOOP_STATUS_NONE; player.loopStatus = mpris.LOOP_STATUS_NONE;
@ -122,7 +122,7 @@ function registerMPRIS(win: BrowserWindow) {
let mprisVolNewer = false; let mprisVolNewer = false;
let autoUpdate = false; let autoUpdate = false;
ipcMain.on('volumeChanged', (_, newVol) => { ipcMain.on('ytmd:volume-changed', (_, newVol) => {
if (~~(player.volume * 100) !== newVol) { if (~~(player.volume * 100) !== newVol) {
if (mprisVolNewer) { if (mprisVolNewer) {
mprisVolNewer = false; mprisVolNewer = false;

View File

@ -115,13 +115,13 @@ export const onRendererLoad = async ({
}: RendererContext<SkipSilencesPluginConfig>) => { }: RendererContext<SkipSilencesPluginConfig>) => {
config = await getConfig(); config = await getConfig();
document.addEventListener('audioCanPlay', audioCanPlayListener, { document.addEventListener('ytmd:audio-can-play', audioCanPlayListener, {
passive: true, passive: true,
}); });
}; };
export const onRendererUnload = () => { export const onRendererUnload = () => {
document.removeEventListener('audioCanPlay', audioCanPlayListener); document.removeEventListener('ytmd:audio-can-play', audioCanPlayListener);
if (playOrSeekHandler) { if (playOrSeekHandler) {
const video = document.querySelector('video'); const video = document.querySelector('video');

View File

@ -76,7 +76,7 @@ export default createPlugin({
const { apiURL, categories } = config; const { apiURL, categories } = config;
ipc.on('video-src-changed', async (data: GetPlayerResponse) => { ipc.on('ytmd:video-src-changed', async (data: GetPlayerResponse) => {
const segments = await fetchSegments( const segments = await fetchSegments(
apiURL, apiURL,
categories, categories,

View File

@ -68,9 +68,9 @@ export default createPlugin({
}; };
ipc.on('ytmd:player-api-loaded', () => ipc.on('ytmd:player-api-loaded', () =>
ipc.send('setupTimeChangedListener'), ipc.send('ytmd:setup-time-changed-listener'),
); );
ipc.on('timeChanged', (t: number) => { ipc.on('ytmd:time-changed', (t: number) => {
if (!this.data.title) { if (!this.data.title) {
return; return;
} }

View File

@ -305,7 +305,7 @@ export default createPlugin({
setVideoState(target.checked); setVideoState(target.checked);
}); });
video?.addEventListener('srcChanged', videoStarted); video?.addEventListener('ytmd:src-changed', videoStarted);
observeThumbnail(); observeThumbnail();

View File

@ -161,7 +161,7 @@ export default createPlugin({
} }
document.addEventListener( document.addEventListener(
'audioCanPlay', 'ytmd:audio-can-play',
(e) => { (e) => {
const video = document.querySelector< const video = document.querySelector<
HTMLVideoElement & { captureStream(): MediaStream } HTMLVideoElement & { captureStream(): MediaStream }

View File

@ -48,7 +48,7 @@ contextBridge.exposeInMainWorld('ipcRenderer', {
sendToHost: (channel: string, ...args: unknown[]) => sendToHost: (channel: string, ...args: unknown[]) =>
ipcRenderer.sendToHost(channel, ...args), ipcRenderer.sendToHost(channel, ...args),
}); });
contextBridge.exposeInMainWorld('reload', () => ipcRenderer.send('reload')); contextBridge.exposeInMainWorld('reload', () => ipcRenderer.send('ytmd:reload'));
contextBridge.exposeInMainWorld( contextBridge.exposeInMainWorld(
'ELECTRON_RENDERER_URL', 'ELECTRON_RENDERER_URL',
process.env.ELECTRON_RENDERER_URL, process.env.ELECTRON_RENDERER_URL,

View File

@ -7,14 +7,14 @@ import config from '@/config';
export const restart = () => restartInternal(); export const restart = () => restartInternal();
export const setupAppControls = () => { export const setupAppControls = () => {
ipcMain.on('restart', restart); ipcMain.on('ytmd:restart', restart);
ipcMain.handle('getDownloadsFolder', () => app.getPath('downloads')); ipcMain.handle('ytmd:get-downloads-folder', () => app.getPath('downloads'));
ipcMain.on( ipcMain.on(
'reload', 'ytmd:reload',
() => () =>
BrowserWindow.getFocusedWindow()?.webContents.loadURL(config.get('url')), BrowserWindow.getFocusedWindow()?.webContents.loadURL(config.get('url')),
); );
ipcMain.handle('getPath', (_, ...args: string[]) => path.join(...args)); ipcMain.handle('ytmd:get-path', (_, ...args: string[]) => path.join(...args));
}; };
function restartInternal() { function restartInternal() {

View File

@ -18,12 +18,12 @@ window.ipcRenderer.on('update-song-info', (_, extractedSongInfo: SongInfo) => {
}); });
// Used because 'loadeddata' or 'loadedmetadata' weren't firing on song start for some users (https://github.com/th-ch/youtube-music/issues/473) // Used because 'loadeddata' or 'loadedmetadata' weren't firing on song start for some users (https://github.com/th-ch/youtube-music/issues/473)
const srcChangedEvent = new CustomEvent('srcChanged'); const srcChangedEvent = new CustomEvent('ytmd:src-changed');
export const setupSeekedListener = singleton(() => { export const setupSeekedListener = singleton(() => {
$('video')?.addEventListener('seeked', (v) => { $('video')?.addEventListener('seeked', (v) => {
if (v.target instanceof HTMLVideoElement) { if (v.target instanceof HTMLVideoElement) {
window.ipcRenderer.send('seeked', v.target.currentTime); window.ipcRenderer.send('ytmd:seeked', v.target.currentTime);
} }
}); });
}); });
@ -32,7 +32,7 @@ export const setupTimeChangedListener = singleton(() => {
const progressObserver = new MutationObserver((mutations) => { const progressObserver = new MutationObserver((mutations) => {
for (const mutation of mutations) { for (const mutation of mutations) {
const target = mutation.target as Node & { value: string }; const target = mutation.target as Node & { value: string };
window.ipcRenderer.send('timeChanged', target.value); window.ipcRenderer.send('ytmd:time-changed', target.value);
songInfo.elapsedSeconds = Number(target.value); songInfo.elapsedSeconds = Number(target.value);
} }
}); });
@ -46,7 +46,7 @@ export const setupRepeatChangedListener = singleton(() => {
const repeatObserver = new MutationObserver((mutations) => { const repeatObserver = new MutationObserver((mutations) => {
// provided by YouTube Music // provided by YouTube Music
window.ipcRenderer.send( window.ipcRenderer.send(
'repeatChanged', 'ytmd:repeat-changed',
( (
mutations[0].target as Node & { mutations[0].target as Node & {
__dataHost: { __dataHost: {
@ -63,7 +63,7 @@ export const setupRepeatChangedListener = singleton(() => {
// Emit the initial value as well; as it's persistent between launches. // Emit the initial value as well; as it's persistent between launches.
// provided by YouTube Music // provided by YouTube Music
window.ipcRenderer.send( window.ipcRenderer.send(
'repeatChanged', 'ytmd:repeat-changed',
$< $<
HTMLElement & { HTMLElement & {
getState: () => GetState; getState: () => GetState;
@ -74,26 +74,26 @@ export const setupRepeatChangedListener = singleton(() => {
export const setupVolumeChangedListener = singleton((api: YoutubePlayer) => { export const setupVolumeChangedListener = singleton((api: YoutubePlayer) => {
$('video')?.addEventListener('volumechange', () => { $('video')?.addEventListener('volumechange', () => {
window.ipcRenderer.send('volumeChanged', api.getVolume()); window.ipcRenderer.send('ytmd:volume-changed', api.getVolume());
}); });
// Emit the initial value as well; as it's persistent between launches. // Emit the initial value as well; as it's persistent between launches.
window.ipcRenderer.send('volumeChanged', api.getVolume()); window.ipcRenderer.send('ytmd:volume-changed', api.getVolume());
}); });
export default (api: YoutubePlayer) => { export default (api: YoutubePlayer) => {
window.ipcRenderer.on('setupTimeChangedListener', () => { window.ipcRenderer.on('ytmd:setup-time-changed-listener', () => {
setupTimeChangedListener(); setupTimeChangedListener();
}); });
window.ipcRenderer.on('setupRepeatChangedListener', () => { window.ipcRenderer.on('ytmd:setup-repeat-changed-listener', () => {
setupRepeatChangedListener(); setupRepeatChangedListener();
}); });
window.ipcRenderer.on('setupVolumeChangedListener', () => { window.ipcRenderer.on('ytmd:setup-volume-changed-listener', () => {
setupVolumeChangedListener(api); setupVolumeChangedListener(api);
}); });
window.ipcRenderer.on('setupSeekedListener', () => { window.ipcRenderer.on('ytmd:setup-seeked-listener', () => {
setupSeekedListener(); setupSeekedListener();
}); });
@ -102,7 +102,7 @@ export default (api: YoutubePlayer) => {
e.target instanceof HTMLVideoElement && e.target instanceof HTMLVideoElement &&
Math.round(e.target.currentTime) > 0 Math.round(e.target.currentTime) > 0
) { ) {
window.ipcRenderer.send('playPaused', { window.ipcRenderer.send('ytmd:play-or-paused', {
isPaused: status === 'pause', isPaused: status === 'pause',
elapsedSeconds: Math.floor(e.target.currentTime), elapsedSeconds: Math.floor(e.target.currentTime),
}); });
@ -170,6 +170,6 @@ export default (api: YoutubePlayer) => {
data.microformat.microformatDataRenderer.pageOwnerDetails.name; data.microformat.microformatDataRenderer.pageOwnerDetails.name;
} }
window.ipcRenderer.send('video-src-changed', data); window.ipcRenderer.send('ytmd:video-src-changed', data);
} }
}; };

View File

@ -104,16 +104,16 @@ let handlingData = false;
const registerProvider = (win: BrowserWindow) => { const registerProvider = (win: BrowserWindow) => {
// This will be called when the song-info-front finds a new request with song data // This will be called when the song-info-front finds a new request with song data
ipcMain.on('video-src-changed', async (_, data: GetPlayerResponse) => { ipcMain.on('ytmd:video-src-changed', async (_, data: GetPlayerResponse) => {
handlingData = true; handlingData = true;
await handleData(data, win); await handleData(data, win);
handlingData = false; handlingData = false;
for (const c of callbacks) { for (const c of callbacks) {
c(songInfo, 'video-src-changed'); c(songInfo, 'ytmd:video-src-changed');
} }
}); });
ipcMain.on( ipcMain.on(
'playPaused', 'ytmd:play-or-paused',
( (
_, _,
{ {
@ -128,7 +128,7 @@ const registerProvider = (win: BrowserWindow) => {
} }
for (const c of callbacks) { for (const c of callbacks) {
c(songInfo, 'playPaused'); c(songInfo, 'ytmd:play-or-paused');
} }
}, },
); );

View File

@ -37,8 +37,8 @@ interface YouTubeMusicAppElement extends HTMLElement {
} }
async function onApiLoaded() { async function onApiLoaded() {
window.ipcRenderer.on('seekTo', (_, t: number) => api!.seekTo(t)); window.ipcRenderer.on('ytmd:seek-to', (_, t: number) => api!.seekTo(t));
window.ipcRenderer.on('seekBy', (_, t: number) => api!.seekBy(t)); window.ipcRenderer.on('ytmd:seek-by', (_, t: number) => api!.seekBy(t));
const video = document.querySelector('video')!; const video = document.querySelector('video')!;
const audioContext = new AudioContext(); const audioContext = new AudioContext();
@ -65,7 +65,7 @@ async function onApiLoaded() {
const audioCanPlayEventDispatcher = () => { const audioCanPlayEventDispatcher = () => {
document.dispatchEvent( document.dispatchEvent(
new CustomEvent('audioCanPlay', { new CustomEvent('ytmd:audio-can-play', {
detail: { detail: {
audioContext, audioContext,
audioSource, audioSource,

2
src/reset.d.ts vendored
View File

@ -14,7 +14,7 @@ declare global {
} }
interface DocumentEventMap { interface DocumentEventMap {
audioCanPlay: CustomEvent<Compressor>; 'ytmd:audio-can-play': CustomEvent<Compressor>;
videodatachange: CustomEvent<VideoDataChanged>; videodatachange: CustomEvent<VideoDataChanged>;
} }