diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e5c7e8a0..962b4adb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,9 @@ name: Build YouTube Music on: - - push + push: + branches: [ master ] + pull_request: env: NODE_VERSION: "16.x" diff --git a/menu.js b/menu.js index 0f127124..a741cd5d 100644 --- a/menu.js +++ b/menu.js @@ -131,7 +131,7 @@ const mainMenuTemplate = (win) => { ], }, { - label: "Release single instance lock", + label: "Single instance lock", type: "checkbox", checked: false, click: (item) => { diff --git a/package.json b/package.json index fef4f42f..328e0f16 100644 --- a/package.json +++ b/package.json @@ -87,11 +87,11 @@ "generate:package": "node utils/generate-package-json.js", "postinstall": "yarn run icon && yarn run plugins", "clean": "del-cli dist", - "build": "yarn run clean && electron-builder --win --mac --linux", - "build:linux": "yarn run clean && electron-builder --linux", - "build:mac": "yarn run clean && electron-builder --mac dmg:x64", - "build:mac:arm64": "yarn run clean && electron-builder --mac dmg:arm64", - "build:win": "yarn run clean && electron-builder --win", + "build": "yarn run clean && electron-builder --win --mac --linux -p never", + "build:linux": "yarn run clean && electron-builder --linux -p never", + "build:mac": "yarn run clean && electron-builder --mac dmg:x64 -p never", + "build:mac:arm64": "yarn run clean && electron-builder --mac dmg:arm64 -p never", + "build:win": "yarn run clean && electron-builder --win -p never", "lint": "xo", "changelog": "auto-changelog", "plugins": "yarn run plugin:adblocker && yarn run plugin:bypass-age-restrictions", diff --git a/plugins/in-app-menu/style.css b/plugins/in-app-menu/style.css index a5de9cf0..0148b38a 100644 --- a/plugins/in-app-menu/style.css +++ b/plugins/in-app-menu/style.css @@ -12,11 +12,17 @@ height: 75px !important; } -/* fixes top gap between nav-bar and browse-page */ +/* fix top gap between nav-bar and browse-page */ #browse-page { padding-top: 0 !important; } +/* fix navbar hiding library items */ +ytmusic-section-list-renderer[page-type="MUSIC_PAGE_TYPE_LIBRARY_CONTENT_LANDING_PAGE"] { + top: 50px; + position: relative; +} + /* remove window dragging for nav bar (conflict with titlebar drag) */ ytmusic-nav-bar, .tab-titleiron-icon, diff --git a/plugins/lyrics-genius/back.js b/plugins/lyrics-genius/back.js index 21e91811..ad626d14 100644 --- a/plugins/lyrics-genius/back.js +++ b/plugins/lyrics-genius/back.js @@ -7,8 +7,13 @@ const fetch = require("node-fetch"); const { cleanupName } = require("../../providers/song-info"); const { injectCSS } = require("../utils"); +let eastAsianChars = new RegExp("[\u{3040}-\u{30ff}\u{3400}-\u{4dbf}\u{4e00}-\u{9fff}\u{f900}-\u{faff}\u{ff66}-\u{ff9f}]"); +let revRomanized = false; -module.exports = async (win) => { +module.exports = async (win, options) => { + if(options.romanizedLyrics) { + revRomanized = true; + } injectCSS(win.webContents, join(__dirname, "style.css")); ipcMain.on("search-genius-lyrics", async (event, extractedSongInfo) => { @@ -17,10 +22,41 @@ module.exports = async (win) => { }); }; +const toggleRomanized = () => { + revRomanized = !revRomanized; +}; + const fetchFromGenius = async (metadata) => { - const queryString = `${cleanupName(metadata.artist)} ${cleanupName( - metadata.title - )}`; + const songTitle = `${cleanupName(metadata.title)}`; + const songArtist = `${cleanupName(metadata.artist)}`; + let lyrics; + + /* Uses Regex to test the title and artist first for said characters if romanization is enabled. Otherwise normal + Genius Lyrics behavior is observed. + */ + let hasAsianChars = false; + if (revRomanized && (eastAsianChars.test(songTitle) || eastAsianChars.test(songArtist))) { + lyrics = await getLyricsList(`${songArtist} ${songTitle} Romanized`); + hasAsianChars = true; + } else { + lyrics = await getLyricsList(`${songArtist} ${songTitle}`); + } + + /* If the romanization toggle is on, and we did not detect any characters in the title or artist, we do a check + for characters in the lyrics themselves. If this check proves true, we search for Romanized lyrics. + */ + if(revRomanized && !hasAsianChars && eastAsianChars.test(lyrics)) { + lyrics = await getLyricsList(`${songArtist} ${songTitle} Romanized`); + } + return lyrics; +}; + +/** + * Fetches a JSON of songs which is then parsed and passed into getLyrics to get the lyrical content of the first song + * @param {*} queryString + * @returns The lyrics of the first song found using the Genius-Lyrics API + */ +const getLyricsList = async (queryString) => { let response = await fetch( `https://genius.com/api/search/multi?per_page=5&q=${encodeURIComponent(queryString)}` ); @@ -28,6 +64,9 @@ const fetchFromGenius = async (metadata) => { return null; } + /* Fetch the first URL with the api, giving a collection of song results. + Pick the first song, parsing the json given by the API. + */ const info = await response.json(); let url = ""; try { @@ -36,16 +75,23 @@ const fetchFromGenius = async (metadata) => { } catch { return null; } + let lyrics = await getLyrics(url); + return lyrics; +} - if (is.dev()) { - console.log("Fetching lyrics from Genius:", url); - } - +/** + * + * @param {*} url + * @returns The lyrics of the song URL provided, null if none + */ +const getLyrics = async (url) => { response = await fetch(url); if (!response.ok) { return null; } - + if (is.dev()) { + console.log("Fetching lyrics from Genius:", url); + } const html = await response.text(); const lyrics = convert(html, { baseElements: { @@ -64,8 +110,8 @@ const fetchFromGenius = async (metadata) => { }, }, }); - return lyrics; }; -module.exports.fetchFromGenius = fetchFromGenius; +module.exports.toggleRomanized = toggleRomanized; +module.exports.fetchFromGenius = fetchFromGenius; \ No newline at end of file diff --git a/plugins/lyrics-genius/menu.js b/plugins/lyrics-genius/menu.js new file mode 100644 index 00000000..5d8c390e --- /dev/null +++ b/plugins/lyrics-genius/menu.js @@ -0,0 +1,17 @@ +const { setOptions } = require("../../config/plugins"); +const { toggleRomanized } = require("./back"); + +module.exports = (win, options, refreshMenu) => { + return [ + { + label: "Romanized Lyrics", + type: "checkbox", + checked: options.romanizedLyrics, + click: (item) => { + options.romanizedLyrics = item.checked; + setOptions('lyrics-genius', options); + toggleRomanized(); + }, + }, + ]; +}; \ No newline at end of file diff --git a/providers/song-info-front.js b/providers/song-info-front.js index 829b31cf..f033847c 100644 --- a/providers/song-info-front.js +++ b/providers/song-info-front.js @@ -76,7 +76,7 @@ module.exports = () => { apiEvent.detail.addEventListener('videodatachange', (name, _dataEvent) => { if (name !== 'dataloaded') return; video.dispatchEvent(srcChangedEvent); - sendSongInfo(); + setTimeout(sendSongInfo()); }) for (const status of ['playing', 'pause']) { @@ -95,7 +95,10 @@ module.exports = () => { data.videoDetails.album = $$( ".byline.ytmusic-player-bar > .yt-simple-endpoint" - ).find(e => e.href?.includes("browse"))?.textContent; + ).find(e => + e.href?.includes("browse/FEmusic_library_privately_owned_release") + || e.href?.includes("browse/MPREb") + )?.textContent; data.videoDetails.elapsedSeconds = Math.floor(video.currentTime); data.videoDetails.isPaused = false; diff --git a/youtube-music.css b/youtube-music.css index ee48dc3a..c0d3cc4e 100644 --- a/youtube-music.css +++ b/youtube-music.css @@ -44,3 +44,9 @@ ytmusic-cast-button { .ytp-chrome-top-buttons { display: none !important; } + +/* Make youtube-music logo un-draggable */ +ytmusic-nav-bar>div.left-content>a, +ytmusic-nav-bar>div.left-content>a>picture>img { + -webkit-user-drag: none; +}