🥡 Refactor

This commit is contained in:
Shiba 2022-01-10 12:32:32 +00:00
parent 5bcd33890d
commit 8f75c67601

View file

@ -18,7 +18,7 @@ interface Target
time: number | null time: number | null
} }
export function WatchOnLbryButton({ targetPlatform, lbryPathname, time }: WatchOnLbryButtonParameters) function WatchOnLbryButton({ targetPlatform, lbryPathname, time }: WatchOnLbryButtonParameters)
{ {
if (!lbryPathname || !targetPlatform) return null if (!lbryPathname || !targetPlatform) return null
@ -61,7 +61,8 @@ async function redirectTo({ lbryPathname, platfrom, time }: Target)
if (time) url.searchParams.set('t', time.toFixed(0)) if (time) url.searchParams.set('t', time.toFixed(0))
findVideoElement().then((videoElement) => { findVideoElement().then((videoElement) =>
{
videoElement.addEventListener('play', () => videoElement.pause(), { once: true }) videoElement.addEventListener('play', () => videoElement.pause(), { once: true })
videoElement.pause() videoElement.pause()
}) })
@ -70,7 +71,7 @@ async function redirectTo({ lbryPathname, platfrom, time }: Target)
{ {
if (document.hidden) await new Promise((resolve) => document.addEventListener('visibilitychange', resolve, { once: true })) if (document.hidden) await new Promise((resolve) => document.addEventListener('visibilitychange', resolve, { once: true }))
open(url, '_blank') open(url, '_blank')
if (window.history.length === 1) window.close(); if (window.history.length === 1) window.close()
else window.history.back() else window.history.back()
} }
location.replace(url.toString()) location.replace(url.toString())
@ -79,15 +80,16 @@ async function redirectTo({ lbryPathname, platfrom, time }: Target)
/** Returns a mount point for the button */ /** Returns a mount point for the button */
async function findButtonMountPoint(): Promise<HTMLDivElement> async function findButtonMountPoint(): Promise<HTMLDivElement>
{ {
const id = 'watch-on-lbry-button-container'
let mountBefore: HTMLDivElement | null = null let mountBefore: HTMLDivElement | null = null
const sourcePlatform = getSourcePlatfromSettingsFromHostname(new URL(location.href).hostname) const sourcePlatform = getSourcePlatfromSettingsFromHostname(new URL(location.href).hostname)
if (!sourcePlatform) throw new Error(`Unknown source of: ${location.href}`) if (!sourcePlatform) throw new Error(`Unknown source of: ${location.href}`)
const exits: HTMLDivElement | null = document.querySelector('#watch-on-yt-button-container') const exits: HTMLDivElement | null = document.querySelector(`#${id}`)
if (exits) return exits; if (exits) return exits
while (!(mountBefore = document.querySelector(sourcePlatform.htmlQueries.mountButtonBefore))) await sleep(200) while (!(mountBefore = document.querySelector(sourcePlatform.htmlQueries.mountButtonBefore))) await sleep(200)
const div = document.createElement('div') const div = document.createElement('div')
div.id = 'watch-on-yt-button-container' div.id = id
div.style.display = 'flex' div.style.display = 'flex'
div.style.alignItems = 'center' div.style.alignItems = 'center'
mountBefore.parentElement?.insertBefore(div, mountBefore) mountBefore.parentElement?.insertBefore(div, mountBefore)
@ -100,25 +102,28 @@ async function findVideoElement()
const sourcePlatform = getSourcePlatfromSettingsFromHostname(new URL(location.href).hostname) const sourcePlatform = getSourcePlatfromSettingsFromHostname(new URL(location.href).hostname)
if (!sourcePlatform) throw new Error(`Unknown source of: ${location.href}`) if (!sourcePlatform) throw new Error(`Unknown source of: ${location.href}`)
let videoElement: HTMLVideoElement | null = null let videoElement: HTMLVideoElement | null = null
while (!(videoElement = document.querySelector(sourcePlatform.htmlQueries.videoPlayer))) await sleep(200) while (!(videoElement = document.querySelector(sourcePlatform.htmlQueries.videoPlayer))) await sleep(200)
return videoElement return videoElement
} }
window.addEventListener('load', async () => // We should get this from background, so the caching works and we don't get errors in the future if yt decides to impliment CORS
async function requestLbryPathname(videoId: string)
{
return await new Promise<string | null>((resolve) => chrome.runtime.sendMessage({ videoId }, resolve))
}
// Start
(async () =>
{ {
const settings = await getExtensionSettingsAsync() const settings = await getExtensionSettingsAsync()
let target: Target | null = null let updater: (() => Promise<void>)
const [buttonMountPoint, videoElement] = await Promise.all([findButtonMountPoint(), findVideoElement()])
// Listen Settings Change // Listen Settings Change
chrome.storage.onChanged.addListener(async (changes, areaName) => chrome.storage.onChanged.addListener(async (changes, areaName) =>
{ {
if (areaName !== 'local') return if (areaName !== 'local') return
Object.assign(settings, Object.fromEntries(Object.entries(changes).map(([key, change]) => [key, change.newValue]))) Object.assign(settings, Object.fromEntries(Object.entries(changes).map(([key, change]) => [key, change.newValue])))
await updateByURL(new URL(location.href)) if (changes.redirect) await onModeChange()
}) })
/* /*
@ -126,41 +131,55 @@ window.addEventListener('load', async () =>
* history.pushState changes from a content script * history.pushState changes from a content script
*/ */
// Listen URL Change // Listen URL Change
chrome.runtime.onMessage.addListener(onUrlChange) chrome.runtime.onMessage.addListener(() => updater())
// We should get this from background, so the caching works and we don't get errors in the future if yt decides to impliment CORS async function getTargetByURL(url: URL)
async function requestLbryPathname(videoId: string)
{ {
return await new Promise<string | null>((resolve) => chrome.runtime.sendMessage({ videoId }, resolve)) if (url.pathname !== '/watch') return null
}
function getVideoTime(url: URL)
{
return settings.redirect ?
(url.searchParams.has('t') ? parseYouTubeURLTimeString(url.searchParams.get('t')!) : null) :
(videoElement.currentTime > 3 && videoElement.currentTime < videoElement.duration - 1 ? videoElement.currentTime : null)
}
async function updateByURL(url: URL)
{
if (url.pathname !== '/watch') return
const videoId = url.searchParams.get('v') const videoId = url.searchParams.get('v')
const lbryPathname = videoId && await requestLbryPathname(videoId) const lbryPathname = videoId && await requestLbryPathname(videoId)
if (lbryPathname) target = { lbryPathname, platfrom: targetPlatformSettings[settings.targetPlatform], time: getVideoTime(url) } const target: Target | null = lbryPathname ? { lbryPathname, platfrom: targetPlatformSettings[settings.targetPlatform], time: null } : null
else target = null
if (settings.redirect) target && redirectTo(target) return target
else updateButton(buttonMountPoint, target)
} }
videoElement.addEventListener('timeupdate', let removeVideoTimeUpdateListener: (() => void) | null = null
() => target && updateButton(buttonMountPoint, Object.assign(target, { time: getVideoTime(new URL(location.href)) }))) async function onModeChange()
async function onUrlChange()
{ {
await updateByURL(new URL(location.href)) let target: Target | null = null
if (settings.redirect)
updater = async () =>
{
const url = new URL(location.href)
target = await getTargetByURL(url)
if (!target) return
target.time = url.searchParams.has('t') ? parseYouTubeURLTimeString(url.searchParams.get('t')!) : null
redirectTo(target)
}
else
{
const mountPoint = await findButtonMountPoint()
const videoElement = await findVideoElement()
const getTime = () => videoElement.currentTime > 3 && videoElement.currentTime < videoElement.duration - 1 ? videoElement.currentTime : null
const onTimeUpdate = () => target && updateButton(mountPoint, Object.assign(target, { time: getTime() }))
removeVideoTimeUpdateListener?.call(null)
videoElement.addEventListener('timeupdate', onTimeUpdate)
removeVideoTimeUpdateListener = () => videoElement.removeEventListener('timeupdate', onTimeUpdate)
updater = async () =>
{
const url = new URL(location.href)
target = await getTargetByURL(url)
if (target) target.time = getTime()
updateButton(mountPoint, target)
}
}
await updater()
} }
await updateByURL(new URL(location.href)) await onModeChange()
}) })()