72 строки
2.4 KiB
JavaScript
72 строки
2.4 KiB
JavaScript
const uiLocale = chrome.i18n.getMessage('@@ui_locale')
|
|
const defaultServerURL = chrome.i18n.getMessage('default_server_url')
|
|
|
|
const getURL = () => {
|
|
return new Promise(resolve => {
|
|
chrome.storage.local.get([
|
|
'server_url',
|
|
]).then((data) => {
|
|
const serverURL = data.server_url || defaultServerURL
|
|
const url = new URL(serverURL)
|
|
url.pathname = '/ws/v1/server'
|
|
resolve(url)
|
|
})
|
|
})
|
|
}
|
|
|
|
const mutationObserverConfig = {
|
|
attributes: true,
|
|
childList: false,
|
|
characterData: false,
|
|
}
|
|
|
|
const connectWebSocket = async () => {
|
|
const url = await getURL()
|
|
const ws = new WebSocket(url)
|
|
const progressElement = document.querySelector('#progress-bar')
|
|
const mutationObserver = new MutationObserver(() => {
|
|
const promise = new Promise(resolve => {
|
|
const playerBarElement = document.querySelector('ytmusic-player-bar')
|
|
const metadataElement = playerBarElement.querySelector('.middle-controls > .content-info-wrapper')
|
|
const titleElement = metadataElement.querySelector(`yt-formatted-string.title`)
|
|
const subtitleElement = metadataElement.querySelector('span.subtitle > yt-formatted-string.byline')
|
|
const imageElement = playerBarElement.querySelector('img')
|
|
if (titleElement.textContent === '' || subtitleElement.length === 0) return
|
|
const data = {
|
|
type: 'music',
|
|
attributes: {
|
|
locale: uiLocale,
|
|
title: titleElement.textContent,
|
|
artists: subtitleElement.title.split('•')[0].trim(),
|
|
progress: progressElement.ariaValueNow / progressElement.ariaValueMax,
|
|
image: imageElement.src,
|
|
},
|
|
}
|
|
ws.send(JSON.stringify(data))
|
|
resolve()
|
|
})
|
|
promise.then()
|
|
})
|
|
|
|
ws.onopen = () => mutationObserver.observe(progressElement, mutationObserverConfig)
|
|
|
|
ws.onclose = () => {
|
|
mutationObserver.disconnect()
|
|
wsPromise = connectWebSocket()
|
|
}
|
|
|
|
return ws
|
|
}
|
|
|
|
chrome.storage.onChanged.addListener((changes) => {
|
|
const settings = {}
|
|
for (let [key, { oldValue, newValue }] of Object.entries(changes)) {
|
|
settings[key] = newValue || oldValue
|
|
}
|
|
chrome.storage.local.set(settings).then(() => {
|
|
wsPromise.then(ws => ws.close())
|
|
})
|
|
})
|
|
|
|
let wsPromise = connectWebSocket()
|