feat: run prettier

This commit is contained in:
JellyBrick
2023-11-30 11:59:27 +09:00
parent 44c42310f1
commit a3104fda4b
116 changed files with 2928 additions and 1254 deletions

View File

@ -9,7 +9,11 @@ export const restart = () => restartInternal();
export const setupAppControls = () => {
ipcMain.on('restart', restart);
ipcMain.handle('getDownloadsFolder', () => app.getPath('downloads'));
ipcMain.on('reload', () => BrowserWindow.getFocusedWindow()?.webContents.loadURL(config.get('url')));
ipcMain.on(
'reload',
() =>
BrowserWindow.getFocusedWindow()?.webContents.loadURL(config.get('url')),
);
ipcMain.handle('getPath', (_, ...args: string[]) => path.join(...args));
};
@ -25,9 +29,9 @@ function sendToFrontInternal(channel: string, ...args: unknown[]) {
}
}
export const sendToFront
= process.type === 'browser'
? sendToFrontInternal
: () => {
console.error('sendToFront called from renderer');
};
export const sendToFront =
process.type === 'browser'
? sendToFrontInternal
: () => {
console.error('sendToFront called from renderer');
};

View File

@ -11,7 +11,10 @@ export function singleton<T extends (...params: never[]) => unknown>(fn: T): T {
}) as T;
}
export function debounce<T extends (...params: never[]) => unknown>(fn: T, delay: number): T {
export function debounce<T extends (...params: never[]) => unknown>(
fn: T,
delay: number,
): T {
let timeout: NodeJS.Timeout;
return ((...args) => {
clearTimeout(timeout);
@ -19,13 +22,15 @@ export function debounce<T extends (...params: never[]) => unknown>(fn: T, delay
}) as T;
}
export function cache<T extends (...params: P) => R, P extends never[], R>(fn: T): T {
export function cache<T extends (...params: P) => R, P extends never[], R>(
fn: T,
): T {
let lastArgs: P;
let lastResult: R;
return ((...args: P) => {
if (
args.length !== lastArgs?.length
|| args.some((arg, i) => arg !== lastArgs[i])
args.length !== lastArgs?.length ||
args.some((arg, i) => arg !== lastArgs[i])
) {
lastArgs = args;
lastResult = fn(...args);
@ -39,7 +44,10 @@ export function cache<T extends (...params: P) => R, P extends never[], R>(fn: T
The following are currently unused, but potentially useful in the future
*/
export function throttle<T extends (...params: unknown[]) => unknown>(fn: T, delay: number): T {
export function throttle<T extends (...params: unknown[]) => unknown>(
fn: T,
delay: number,
): T {
let timeout: NodeJS.Timeout | undefined;
return ((...args) => {
if (timeout) {
@ -66,7 +74,10 @@ function memoize<T extends (...params: unknown[]) => unknown>(fn: T): T {
}) as T;
}
function retry<T extends (...params: unknown[]) => unknown>(fn: T, { retries = 3, delay = 1000 } = {}): T {
function retry<T extends (...params: unknown[]) => unknown>(
fn: T,
{ retries = 3, delay = 1000 } = {},
): T {
return ((...args) => {
try {
return fn(...args);

View File

@ -10,11 +10,9 @@ let protocolHandler: ((cmd: string) => void) | undefined;
export function setupProtocolHandler(win: BrowserWindow) {
if (process.defaultApp && process.argv.length >= 2) {
app.setAsDefaultProtocolClient(
APP_PROTOCOL,
process.execPath,
[path.resolve(process.argv[1])],
);
app.setAsDefaultProtocolClient(APP_PROTOCOL, process.execPath, [
path.resolve(process.argv[1]),
]);
} else {
app.setAsDefaultProtocolClient(APP_PROTOCOL);
}
@ -42,4 +40,3 @@ export default {
handleProtocol,
changeProtocolHandler,
};

View File

@ -1,8 +1,16 @@
// This is used for to control the songs
import { BrowserWindow } from 'electron';
type Modifiers = (Electron.MouseInputEvent | Electron.MouseWheelInputEvent | Electron.KeyboardInputEvent)['modifiers'];
export const pressKey = (window: BrowserWindow, key: string, modifiers: Modifiers = []) => {
type Modifiers = (
| Electron.MouseInputEvent
| Electron.MouseWheelInputEvent
| Electron.KeyboardInputEvent
)['modifiers'];
export const pressKey = (
window: BrowserWindow,
key: string,
modifiers: Modifiers = [],
) => {
window.webContents.sendInputEvent({
type: 'keyDown',
modifiers,

View File

@ -10,7 +10,8 @@ import type { VideoDataChanged } from '@/types/video-data-changed';
let songInfo: SongInfo = {} as SongInfo;
export const getSongInfo = () => songInfo;
const $ = <E extends Element = Element>(s: string): E | null => document.querySelector<E>(s);
const $ = <E extends Element = Element>(s: string): E | null =>
document.querySelector<E>(s);
window.ipcRenderer.on('update-song-info', (_, extractedSongInfo: SongInfo) => {
songInfo = extractedSongInfo;
@ -43,26 +44,31 @@ export const setupTimeChangedListener = singleton(() => {
export const setupRepeatChangedListener = singleton(() => {
const repeatObserver = new MutationObserver((mutations) => {
// provided by YouTube Music
window.ipcRenderer.send(
'repeatChanged',
(mutations[0].target as Node & {
__dataHost: {
getState: () => GetState;
(
mutations[0].target as Node & {
__dataHost: {
getState: () => GetState;
};
}
}).__dataHost.getState().queue.repeatMode,
).__dataHost.getState().queue.repeatMode,
);
});
repeatObserver.observe($('#right-controls .repeat')!, { attributeFilter: ['title'] });
repeatObserver.observe($('#right-controls .repeat')!, {
attributeFilter: ['title'],
});
// Emit the initial value as well; as it's persistent between launches.
// provided by YouTube Music
window.ipcRenderer.send(
'repeatChanged',
$<HTMLElement & {
getState: () => GetState;
}>('ytmusic-player-bar')?.getState().queue.repeatMode,
$<
HTMLElement & {
getState: () => GetState;
}
>('ytmusic-player-bar')?.getState().queue.repeatMode,
);
});
@ -92,7 +98,10 @@ export default (api: YoutubePlayer) => {
});
const playPausedHandler = (e: Event, status: string) => {
if (e.target instanceof HTMLVideoElement && Math.round(e.target.currentTime) > 0) {
if (
e.target instanceof HTMLVideoElement &&
Math.round(e.target.currentTime) > 0
) {
window.ipcRenderer.send('playPaused', {
isPaused: status === 'pause',
elapsedSeconds: Math.floor(e.target.currentTime),
@ -108,7 +117,11 @@ export default (api: YoutubePlayer) => {
const waitingEvent = new Set<string>();
// Name = "dataloaded" and abit later "dataupdated"
api.addEventListener('videodatachange', (name: string, videoData) => {
document.dispatchEvent(new CustomEvent<VideoDataChanged>('videodatachange', { detail: { name, videoData } }));
document.dispatchEvent(
new CustomEvent<VideoDataChanged>('videodatachange', {
detail: { name, videoData },
}),
);
if (name === 'dataupdated' && waitingEvent.has(videoData.videoId)) {
waitingEvent.delete(videoData.videoId);
@ -117,7 +130,8 @@ export default (api: YoutubePlayer) => {
const video = $<HTMLVideoElement>('video');
video?.dispatchEvent(srcChangedEvent);
for (const status of ['playing', 'pause'] as const) { // for fix issue that pause event not fired
for (const status of ['playing', 'pause'] as const) {
// for fix issue that pause event not fired
video?.addEventListener(status, playPausedHandlers[status]);
}
@ -133,13 +147,17 @@ export default (api: YoutubePlayer) => {
function sendSongInfo(videoData: VideoDataChangeValue) {
const data = api.getPlayerResponse();
data.videoDetails.album = videoData?.Hd?.playerOverlays?.playerOverlayRenderer?.browserMediaSession?.browserMediaSessionRenderer?.album.runs?.at(0)?.text;
data.videoDetails.album =
videoData?.Hd?.playerOverlays?.playerOverlayRenderer?.browserMediaSession?.browserMediaSessionRenderer?.album.runs?.at(
0,
)?.text;
data.videoDetails.elapsedSeconds = 0;
data.videoDetails.isPaused = false;
// HACK: This is a workaround for "podcast" type video. GREAT JOB GOOGLE.
if (data.playabilityStatus.transportControlsConfig) {
data.videoDetails.author = data.microformat.microformatDataRenderer.pageOwnerDetails.name;
data.videoDetails.author =
data.microformat.microformatDataRenderer.pageOwnerDetails.name;
}
window.ipcRenderer.send('video-src-changed', data);

View File

@ -42,11 +42,11 @@ export const songInfo: SongInfo = {
// Grab the native image using the src
export const getImage = cache(
async (src: string): Promise<Electron.NativeImage> => {
const result = await net.fetch(src);
const buffer = await result.arrayBuffer();
const output = nativeImage.createFromBuffer(Buffer.from(buffer));
if (output.isEmpty() && !src.endsWith('.jpg') && src.includes('.jpg')) { // Fix hidden webp files (https://github.com/th-ch/youtube-music/issues/315)
if (output.isEmpty() && !src.endsWith('.jpg') && src.includes('.jpg')) {
// Fix hidden webp files (https://github.com/th-ch/youtube-music/issues/315)
return getImage(src.slice(0, src.lastIndexOf('.jpg') + 4));
}
@ -54,7 +54,10 @@ export const getImage = cache(
},
);
const handleData = async (data: GetPlayerResponse, win: Electron.BrowserWindow) => {
const handleData = async (
data: GetPlayerResponse,
win: Electron.BrowserWindow,
) => {
if (!data) {
return;
}
@ -63,7 +66,8 @@ const handleData = async (data: GetPlayerResponse, win: Electron.BrowserWindow)
if (microformat) {
songInfo.uploadDate = microformat.uploadDate;
songInfo.url = microformat.urlCanonical?.split('&')[0];
songInfo.playlistId = new URL(microformat.urlCanonical).searchParams.get('list') ?? '';
songInfo.playlistId =
new URL(microformat.urlCanonical).searchParams.get('list') ?? '';
// Used for options.resumeOnStart
config.set('url', microformat.urlCanonical);
}
@ -108,17 +112,26 @@ const registerProvider = (win: BrowserWindow) => {
c(songInfo, 'video-src-changed');
}
});
ipcMain.on('playPaused', (_, { isPaused, elapsedSeconds }: { isPaused: boolean, elapsedSeconds: number }) => {
songInfo.isPaused = isPaused;
songInfo.elapsedSeconds = elapsedSeconds;
if (handlingData) {
return;
}
ipcMain.on(
'playPaused',
(
_,
{
isPaused,
elapsedSeconds,
}: { isPaused: boolean; elapsedSeconds: number },
) => {
songInfo.isPaused = isPaused;
songInfo.elapsedSeconds = elapsedSeconds;
if (handlingData) {
return;
}
for (const c of callbacks) {
c(songInfo, 'playPaused');
}
});
for (const c of callbacks) {
c(songInfo, 'playPaused');
}
},
);
};
const suffixesToRemove = [
@ -133,7 +146,10 @@ export function cleanupName(name: string): string {
return name;
}
name = name.replace(/\((?:official)? ?(?:music)? ?(?:lyrics?)? ?(?:video)?\)$/i, '');
name = name.replace(
/\((?:official)? ?(?:music)? ?(?:lyrics?)? ?(?:video)?\)$/i,
'',
);
const lowCaseName = name.toLowerCase();
for (const suffix of suffixesToRemove) {
if (lowCaseName.endsWith(suffix)) {