Skip to content

Commit acbe0ac

Browse files
committed
Add Genius lyrics plugin
1 parent c66ff2b commit acbe0ac

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

plugins/lyrics-genius/back.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const { join } = require("path");
2+
3+
const { ipcMain } = require("electron");
4+
const is = require("electron-is");
5+
const fetch = require("node-fetch");
6+
7+
const { cleanupName } = require("../../providers/song-info");
8+
const { injectCSS } = require("../utils");
9+
10+
module.exports = async (win) => {
11+
injectCSS(win.webContents, join(__dirname, "style.css"));
12+
13+
ipcMain.on("search-genius-lyrics", async (event, extractedSongInfo) => {
14+
const metadata = JSON.parse(extractedSongInfo);
15+
const queryString = `${cleanupName(metadata.artist)} ${cleanupName(
16+
metadata.title
17+
)}`;
18+
19+
let response = await fetch(
20+
`https://genius.com/api/search/multi?per_page=5&q=${encodeURI(
21+
queryString
22+
)}`
23+
);
24+
if (!response.ok) {
25+
event.returnValue = null;
26+
return;
27+
}
28+
29+
const info = await response.json();
30+
let url = "";
31+
try {
32+
url = info.response.sections.filter(
33+
(section) => section.type === "song"
34+
)[0].hits[0].result.url;
35+
} catch {
36+
event.returnValue = null;
37+
return;
38+
}
39+
40+
if (is.dev()) {
41+
console.log("Fetching lyrics from Genius:", url);
42+
}
43+
44+
response = await fetch(url);
45+
if (!response.ok) {
46+
event.returnValue = null;
47+
return;
48+
}
49+
50+
event.returnValue = await response.text();
51+
});
52+
};

plugins/lyrics-genius/front.js

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
const { ipcRenderer } = require("electron");
2+
3+
module.exports = () => {
4+
ipcRenderer.on("update-song-info", (_, extractedSongInfo) => {
5+
const lyricsTab = document.querySelector('tp-yt-paper-tab[tabindex="-1"]');
6+
7+
// Check if disabled
8+
if (!lyricsTab || !lyricsTab.hasAttribute("disabled")) {
9+
return;
10+
}
11+
12+
const html = ipcRenderer.sendSync(
13+
"search-genius-lyrics",
14+
extractedSongInfo
15+
);
16+
if (!html) {
17+
return;
18+
}
19+
20+
const wrapper = document.createElement("div");
21+
wrapper.innerHTML = html;
22+
const lyricsSelector1 = wrapper.querySelector(".lyrics");
23+
const lyricsSelector2 = wrapper.querySelector(
24+
'[class^="Lyrics__Container"]'
25+
);
26+
const lyrics = lyricsSelector1
27+
? lyricsSelector1.innerHTML
28+
: lyricsSelector2
29+
? lyricsSelector2.innerHTML
30+
: null;
31+
if (!lyrics) {
32+
return;
33+
}
34+
35+
lyricsTab.removeAttribute("disabled");
36+
lyricsTab.removeAttribute("aria-disabled");
37+
document.querySelector("tp-yt-paper-tab").onclick = () => {
38+
lyricsTab.removeAttribute("disabled");
39+
lyricsTab.removeAttribute("aria-disabled");
40+
};
41+
42+
lyricsTab.onclick = () => {
43+
const tabContainer = document.querySelector("ytmusic-tab-renderer");
44+
console.log("tabContainer", tabContainer);
45+
const observer = new MutationObserver((_, observer) => {
46+
const lyricsContainer = document.querySelector(
47+
'[page-type="MUSIC_PAGE_TYPE_TRACK_LYRICS"] > ytmusic-message-renderer'
48+
);
49+
if (lyricsContainer) {
50+
lyricsContainer.innerHTML = `<div id="contents" class="style-scope ytmusic-section-list-renderer genius-lyrics">
51+
${lyrics}
52+
53+
<yt-formatted-string class="footer style-scope ytmusic-description-shelf-renderer">Source&nbsp;: Genius</yt-formatted-string>
54+
</div>`;
55+
observer.disconnect();
56+
}
57+
});
58+
observer.observe(tabContainer, {
59+
attributes: true,
60+
childList: true,
61+
subtree: true,
62+
});
63+
};
64+
});
65+
};

plugins/lyrics-genius/style.css

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/* Disable links in Genius lyrics */
2+
.genius-lyrics a {
3+
color: var(--ytmusic-text-primary);
4+
display: inline-block;
5+
pointer-events: none;
6+
text-decoration: none;
7+
}

0 commit comments

Comments
 (0)