diff --git a/src/background.js b/src/background.js index 0ef24cde..673499f6 100644 --- a/src/background.js +++ b/src/background.js @@ -68,12 +68,7 @@ chrome.storage.onChanged.addListener(async changes => { }) async function getActiveTab() { - const result = await chrome.tabs.query({ currentWindow: true, url: ['*://open.spotify.com/*'] }) - return result?.at(0) -} - -async function getAllSpotifyTabs() { - const result = await chrome.tabs.query({ url: '*://*.spotify.com/*' }) + const result = await chrome.tabs.query({ url: ['*://open.spotify.com/*'] }) return result?.at(0) } @@ -93,10 +88,6 @@ async function sendMessage({ message }) { return await messenger({ tabId: activeTab.id, message }) } -function handleButtonClick(selector) { - document.querySelector(selector).click() -} - chrome.webRequest.onBeforeRequest.addListener(details => { const rawBody = details?.requestBody?.raw?.at(0)?.bytes if (!rawBody) return @@ -118,15 +109,15 @@ chrome.webRequest.onBeforeSendHeaders.addListener(details => { }, { urls: [ - 'https://guc3-spclient.spotify.com/track-playback/v1/devices', - 'https://api.spotify.com/*' + 'https://api.spotify.com/*', + 'https://guc3-spclient.spotify.com/track-playback/v1/devices' ] }, ['requestHeaders'] ) chrome.commands.onCommand.addListener(async command => { - const tab = await getAllSpotifyTabs() + const tab = await getActiveTab() if (!tab) return const chorusMap = { @@ -159,7 +150,7 @@ chrome.commands.onCommand.addListener(async command => { await chrome.scripting.executeScript({ args: [selector], - func: handleButtonClick, target: { tabId: tab.id }, + func: selector => document.querySelector(selector)?.click(), }) }) diff --git a/src/models/now-playing-icons.js b/src/models/now-playing-icons.js index 897f0c4b..1d54831b 100644 --- a/src/models/now-playing-icons.js +++ b/src/models/now-playing-icons.js @@ -5,6 +5,7 @@ import { SETTINGS_ICON, NOW_PLAYING_SKIP_ICON, createIcon } from '../components/ import { currentSongInfo } from '../utils/song.js' import { parseNodeString } from '../utils/parser.js' +import { highlightElement } from '../utils/higlight.js' export default class NowPlayingIcons { constructor({ snip, chorus }) { @@ -63,19 +64,42 @@ export default class NowPlayingIcons { }) const skipIcon = document.getElementById('chorus-skip') - skipIcon.addEventListener('click', () => this.#handleSkipTrack()) + skipIcon.addEventListener('click', async () => this.#handleSkipTrack()) + } + + #hightlightTrackListBlock(songStateData) { + if (!this.#trackRows) return + + const title = currentSongInfo()?.id?.split(' by ')?.at(0) || '' + const context = this.#trackRows.find(row => + row.querySelector('[data-testid="internal-track-link"] div')?.textContent == title + ) + if (!context) return + + highlightElement({ songStateData, context, property: 'fill', selector: 'svg[role="skip"]' }) + + const icon = context.querySelector('svg[role="skip"]') + if (!icon) return + + icon.style.visibility = 'visible' + } + + get #trackRows() { + const trackRows = document.querySelectorAll('[data-testid="tracklist-row"]') + return trackRows?.length > 0 ? Array.from(trackRows) : undefined } async #handleSkipTrack() { const songInfo = await currentData.readTrack() if (!songInfo) return - await store.saveTrack({ + const updatedValues = await store.saveTrack({ id: currentSongInfo().id, value: { ...songInfo, isSkipped: !songInfo.isSkipped }, }) - if (!songInfo.isSkipped) { + if (updatedValues.isSkipped) { + this.#hightlightTrackListBlock(updatedValues) document.querySelector('[data-testid="control-button-skip-forward"]')?.click() } } diff --git a/src/utils/higlight.js b/src/utils/higlight.js index f5c6d1ae..e7ab7f4d 100644 --- a/src/utils/higlight.js +++ b/src/utils/higlight.js @@ -1,9 +1,10 @@ const isHighlightable = ({ isSnip, + isSkipped, playbackRate = '1', preservesPitch = true, }) => ( - isSnip || !preservesPitch || playbackRate !== '1' + isSnip || isSkipped || !preservesPitch || playbackRate !== '1' ) export const highlightElement = ({