diff --git a/src/main/features/core/lyrics/genius.ts b/src/main/features/core/lyrics/genius.ts index 12bad30c..648547ed 100644 --- a/src/main/features/core/lyrics/genius.ts +++ b/src/main/features/core/lyrics/genius.ts @@ -5,7 +5,7 @@ import type { InternetProviderLyricSearchResponse, LyricSearchQuery, } from '/@/renderer/api/types'; -import { LyricSource } from '../../../../renderer/types'; +import { LyricSource } from '../../../../renderer/api/types'; const SEARCH_URL = 'https://genius.com/api/search/song'; @@ -117,7 +117,7 @@ async function getSongURL(params: LyricSearchQuery): Promise { +export async function getLyricsByURL(url: string): Promise { let result: AxiosResponse; try { result = await axios.get(url, { responseType: 'text' }); @@ -147,7 +147,7 @@ export async function query( return null; } - const lyrics = await getLyricsFromGenius(response.url); + const lyrics = await getLyricsByURL(response.url); if (!lyrics) { console.error('Could not get lyrics on Genius!'); return null; diff --git a/src/main/features/core/lyrics/index.ts b/src/main/features/core/lyrics/index.ts index 28e4d74a..943f9851 100644 --- a/src/main/features/core/lyrics/index.ts +++ b/src/main/features/core/lyrics/index.ts @@ -3,10 +3,19 @@ import { InternetProviderLyricSearchResponse, LyricSearchQuery, QueueSong, + LyricGetQuery, + LyricSource, } from '/@/renderer/api/types'; -import { query as queryGenius, getSearchResults as searchGenius } from './genius'; -import { query as queryNetease, getSearchResults as searchNetease } from './netease'; -import { LyricSource } from '../../../../renderer/types'; +import { + query as queryGenius, + getSearchResults as searchGenius, + getLyricsByURL as getGenius, +} from './genius'; +import { + query as queryNetease, + getSearchResults as searchNetease, + getLyricsBySongId as getNetease, +} from './netease'; import { ipcMain } from 'electron'; import { store } from '../settings/index'; @@ -14,6 +23,7 @@ type SongFetcher = (params: LyricSearchQuery) => Promise Promise; +type GetFetcher = (id: string) => Promise; type CachedLyrics = Record; @@ -27,6 +37,11 @@ const SEARCH_FETCHERS: Record = { [LyricSource.NETEASE]: searchNetease, }; +const GET_FETCHERS: Record = { + [LyricSource.GENIUS]: getGenius, + [LyricSource.NETEASE]: getNetease, +}; + const MAX_CACHED_ITEMS = 10; const lyricCache = new Map(); @@ -93,7 +108,18 @@ const searchRemoteLyrics = async (params: LyricSearchQuery) => { return results; }; -ipcMain.handle('lyric-fetch-manual', async (_event, song: QueueSong) => { +const getRemoteLyricsById = async (params: LyricGetQuery): Promise => { + const { remoteSongId, remoteSource } = params; + const response = await GET_FETCHERS[remoteSource](remoteSongId); + + if (!response) { + return null; + } + + return response; +}; + +ipcMain.handle('lyric-by-song', async (_event, song: QueueSong) => { const lyric = await getRemoteLyrics(song); return lyric; }); @@ -102,3 +128,8 @@ ipcMain.handle('lyric-search', async (_event, params: LyricSearchQuery) => { const lyricResults = await searchRemoteLyrics(params); return lyricResults; }); + +ipcMain.handle('lyric-by-remote-id', async (_event, params: LyricGetQuery) => { + const lyricResults = await getRemoteLyricsById(params); + return lyricResults; +}); diff --git a/src/main/features/core/lyrics/netease.ts b/src/main/features/core/lyrics/netease.ts index bba00c10..aa39cc57 100644 --- a/src/main/features/core/lyrics/netease.ts +++ b/src/main/features/core/lyrics/netease.ts @@ -1,5 +1,5 @@ import axios, { AxiosResponse } from 'axios'; -import { LyricSource } from '../../../../renderer/types'; +import { LyricSource } from '../../../../renderer/api/types'; import type { InternetProviderLyricResponse, InternetProviderLyricSearchResponse, @@ -64,7 +64,7 @@ async function getSongId(params: LyricSearchQuery): Promise { +export async function getLyricsBySongId(songId: string): Promise { let result: AxiosResponse; try { result = await axios.get(LYRICS_URL, { @@ -76,7 +76,7 @@ async function getLyricsFromSongId(songId: string): Promise }); } catch (e) { console.error('NetEase lyrics request got an error!', e); - return undefined; + return null; } return result.data.klyric?.lyric || result.data.lrc?.lyric; @@ -91,7 +91,7 @@ export async function query( return null; } - const lyrics = await getLyricsFromSongId(response.id); + const lyrics = await getLyricsBySongId(response.id); if (!lyrics) { console.error('Could not get lyrics on NetEase!'); return null; diff --git a/src/main/preload/lyrics.ts b/src/main/preload/lyrics.ts index 6bafaf81..27df51ed 100644 --- a/src/main/preload/lyrics.ts +++ b/src/main/preload/lyrics.ts @@ -1,8 +1,8 @@ -import { IpcRendererEvent, ipcRenderer } from 'electron'; -import { InternetProviderLyricResponse, LyricSearchQuery, QueueSong } from '/@/renderer/api/types'; +import { ipcRenderer } from 'electron'; +import { LyricSearchQuery, QueueSong } from '/@/renderer/api/types'; -const fetchRemoteLyrics = (song: QueueSong) => { - const result = ipcRenderer.invoke('lyric-fetch-manual', song); +const getRemoteLyricsBySong = (song: QueueSong) => { + const result = ipcRenderer.invoke('lyric-by-song', song); return result; }; @@ -11,19 +11,13 @@ const searchRemoteLyrics = (params: LyricSearchQuery) => { return result; }; -const remoteLyricsListener = ( - cb: ( - event: IpcRendererEvent, - songName: string, - source: string, - lyric: InternetProviderLyricResponse, - ) => void, -) => { - ipcRenderer.on('lyric-get', cb); +const getRemoteLyricsByRemoteId = (id: string) => { + const result = ipcRenderer.invoke('lyric-by-remote-id', id); + return result; }; export const lyrics = { - fetchRemoteLyrics, - remoteLyricsListener, + getRemoteLyricsByRemoteId, + getRemoteLyricsBySong, searchRemoteLyrics, }; diff --git a/src/renderer/api/types.ts b/src/renderer/api/types.ts index 65ed4f59..1a354c34 100644 --- a/src/renderer/api/types.ts +++ b/src/renderer/api/types.ts @@ -1033,14 +1033,14 @@ export type InternetProviderLyricResponse = { artist: string; lyrics: string; name: string; - source: string; + source: LyricSource; }; export type InternetProviderLyricSearchResponse = { artist: string; id: string; name: string; - source: string; + source: LyricSource; }; export type SynchronizedLyricMetadata = { @@ -1048,12 +1048,12 @@ export type SynchronizedLyricMetadata = { remote: boolean; } & Omit; -export type UnsyhchronizedLyricMetadata = { +export type UnsynchronizedLyricMetadata = { lyrics: string; remote: boolean; } & Omit; -export type FullLyricsMetadata = SynchronizedLyricMetadata | UnsyhchronizedLyricMetadata; +export type FullLyricsMetadata = SynchronizedLyricMetadata | UnsynchronizedLyricMetadata; export type LyricOverride = Omit; @@ -1065,3 +1065,15 @@ export type LyricSearchQuery = { artist: string; name: string; }; + +export type LyricGetQuery = { + remoteSongId: string; + remoteSource: LyricSource; +}; + +export enum LyricSource { + GENIUS = 'Genius', + NETEASE = 'NetEase', +} + +export type LyricsOverride = Omit & { id: string }; diff --git a/src/renderer/features/settings/components/playback/lyric-settings.tsx b/src/renderer/features/settings/components/playback/lyric-settings.tsx index fd6139b5..84f6949a 100644 --- a/src/renderer/features/settings/components/playback/lyric-settings.tsx +++ b/src/renderer/features/settings/components/playback/lyric-settings.tsx @@ -6,7 +6,7 @@ import { useLyricsSettings, useSettingsStoreActions } from '/@/renderer/store'; import { MultiSelect, MultiSelectProps, NumberInput, Switch } from '/@/renderer/components'; import isElectron from 'is-electron'; import styled from 'styled-components'; -import { LyricSource } from '/@/renderer/types'; +import { LyricSource } from '/@/renderer/api/types'; const localSettings = isElectron() ? window.electron.localSettings : null; diff --git a/src/renderer/store/settings.store.ts b/src/renderer/store/settings.store.ts index 1ab0cbe6..bea6f2b5 100644 --- a/src/renderer/store/settings.store.ts +++ b/src/renderer/store/settings.store.ts @@ -8,7 +8,7 @@ import { create } from 'zustand'; import { devtools, persist } from 'zustand/middleware'; import { immer } from 'zustand/middleware/immer'; import { shallow } from 'zustand/shallow'; -import { LibraryItem } from '/@/renderer/api/types'; +import { LibraryItem, LyricSource } from '/@/renderer/api/types'; import { AppRoute } from '/@/renderer/router/routes'; import { AppTheme } from '/@/renderer/themes/types'; import { @@ -19,7 +19,6 @@ import { PlaybackType, TableType, Platform, - LyricSource, } from '/@/renderer/types'; export type SidebarItemType = { diff --git a/src/renderer/types.ts b/src/renderer/types.ts index f0acf829..cb09d6fe 100644 --- a/src/renderer/types.ts +++ b/src/renderer/types.ts @@ -176,8 +176,3 @@ export type GridCardData = { playButtonBehavior: Play; route: CardRoute; }; - -export enum LyricSource { - GENIUS = 'Genius', - NETEASE = 'NetEase', -}