From 610b47d1e41fd256a0dedf6b212f5824f5c22aee Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Sun, 9 Jan 2022 22:03:31 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=8D=98=20Refactor=20bugfix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/yt/index.ts | 6 +-- src/scripts/background.ts | 4 +- src/scripts/ytContent.tsx | 92 ++++++++++++++++++++++----------------- 3 files changed, 57 insertions(+), 45 deletions(-) diff --git a/src/common/yt/index.ts b/src/common/yt/index.ts index 58a7859..30f0099 100644 --- a/src/common/yt/index.ts +++ b/src/common/yt/index.ts @@ -92,7 +92,7 @@ export function getChannelId(channelURL: string) export function parseYouTubeURLTimeString(timeString: string) { const signs = timeString.replace(/[0-9]/g, '') - if (signs.length === 0) return timeString + if (signs.length === 0) return 0 const numbers = timeString.replace(/[^0-9]/g, '-').split('-') let total = 0 for (let i = 0; i < signs.length; i++) @@ -104,9 +104,9 @@ export function parseYouTubeURLTimeString(timeString: string) case 'h': t *= 60 case 'm': t *= 60 case 's': break - default: return '0' + default: return 0 } total += t } - return total.toString() + return total } \ No newline at end of file diff --git a/src/scripts/background.ts b/src/scripts/background.ts index 591c7e2..95ad564 100644 --- a/src/scripts/background.ts +++ b/src/scripts/background.ts @@ -19,4 +19,6 @@ async function lbryPathnameFromVideoId(videoId: string): Promise chrome.runtime.onMessage.addListener(({ videoId }: { videoId: string }, sender, sendResponse) => { lbryPathnameFromVideoId(videoId).then((lbryPathname) => sendResponse(lbryPathname)) return true; -}) \ No newline at end of file +}) + +chrome.tabs.onUpdated.addListener((tabId, changeInfo) => changeInfo.url && chrome.tabs.sendMessage(tabId, { })); \ No newline at end of file diff --git a/src/scripts/ytContent.tsx b/src/scripts/ytContent.tsx index d5bcffa..f7b5493 100644 --- a/src/scripts/ytContent.tsx +++ b/src/scripts/ytContent.tsx @@ -2,9 +2,9 @@ import { h, render } from 'preact' import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, TargetPlatform, targetPlatformSettings } from '../common/settings' import { parseYouTubeURLTimeString } from '../common/yt' -const sleep = (t: number) => new Promise(resolve => setTimeout(resolve, t)); +const sleep = (t: number) => new Promise(resolve => setTimeout(resolve, t)) -function pauseAllVideos() { document.querySelectorAll('video').forEach(v => v.pause()); } +function pauseAllVideos() { document.querySelectorAll('video').forEach(v => v.pause()) } interface WatchOnLbryButtonParameters { @@ -20,8 +20,9 @@ interface Target time: number | null } -export function WatchOnLbryButton({ targetPlatform, lbryPathname, time }: WatchOnLbryButtonParameters) { - if (!lbryPathname || !targetPlatform) return null; +export function WatchOnLbryButton({ targetPlatform, lbryPathname, time }: WatchOnLbryButtonParameters) +{ + if (!lbryPathname || !targetPlatform) return null const url = new URL(`${targetPlatform.domainPrefix}${lbryPathname}`) if (time) url.searchParams.set('t', time.toFixed(0)) @@ -43,56 +44,59 @@ export function WatchOnLbryButton({ targetPlatform, lbryPathname, time }: WatchO textDecoration: 'none', ...targetPlatform.button.style?.button, }}> - - {targetPlatform.button.text} - - ; + + {targetPlatform.button.text} + + } -function updateButton(mountPoint: HTMLDivElement, target: Target | null): void { +function updateButton(mountPoint: HTMLDivElement, target: Target | null): void +{ if (!target) return render(, mountPoint) - render(, mountPoint) + const time = target.time && target.time > 3 ? target.time : null + render(, mountPoint) } -function redirectTo({ lbryPathname, platfrom }: Target) +function redirectTo({ lbryPathname, platfrom, time }: Target) { const url = new URL(`${platfrom.domainPrefix}${lbryPathname}`) - const time = new URL(location.href).searchParams.get('t') - - if (time) url.searchParams.set('t', parseYouTubeURLTimeString(time)) + + if (time) url.searchParams.set('t', time.toFixed(0)) if (platfrom === targetPlatformSettings.app) { - pauseAllVideos(); - location.assign(url); + pauseAllVideos() + location.assign(url) return } - location.replace(url.toString()); + location.replace(url.toString()) } /** Returns a mount point for the button */ -async function findButtonMountPoint(): Promise { +async function findButtonMountPoint(): Promise +{ let mountBefore: HTMLDivElement | null = null const sourcePlatform = getSourcePlatfromSettingsFromHostname(new URL(location.href).hostname) if (!sourcePlatform) throw new Error(`Unknown source of: ${location.href}`) - 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'); - div.style.display = 'flex'; + const div = document.createElement('div') + div.style.display = 'flex' div.style.alignItems = 'center' mountBefore.parentElement?.insertBefore(div, mountBefore) - + return div } -async function findVideoElement() { +async function findVideoElement() +{ const sourcePlatform = getSourcePlatfromSettingsFromHostname(new URL(location.href).hostname) 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 } @@ -100,19 +104,24 @@ async function findVideoElement() { window.addEventListener('load', async () => { const settings = await getExtensionSettingsAsync() - const [buttonMountPoint, videoElement] = await Promise.all([findButtonMountPoint(), findVideoElement()]) - - // Listen Settings Change - chrome.storage.onChanged.addListener(async (changes, areaName) => { - if (areaName !== 'local') return; - Object.assign(settings, changes) - }); + if (settings.redirect) return await updateByURL(new URL(location.href)) - // Listen History.pushState + const [buttonMountPoint, videoElement] = await Promise.all([findButtonMountPoint(), findVideoElement()]) + + // Listen Settings Change + chrome.storage.onChanged.addListener(async (changes, areaName) => { - const originalPushState = history.pushState - history.pushState = function(...params) { originalPushState(...params); afterPushState(); } - } + if (areaName !== 'local') return + Object.assign(settings, changes) + updateByURL(new URL(location.href)) + }) + + /* + * Gets messages from background script which relays tab update events. This is because there's no sensible way to detect + * history.pushState changes from a content script + */ + chrome.runtime.onMessage.addListener(onUrlChange) + // Request Lbry pathname from background // We should get this from background, so the caching works and we don't get erros in the future if yt decides to impliment CORS @@ -127,16 +136,17 @@ window.addEventListener('load', async () => if (!videoId) return const lbryPathname = await requestLbryPathname(videoId) if (!lbryPathname) return - const time = videoElement.currentTime > 3 && videoElement.currentTime < videoElement.duration - 1 ? videoElement.currentTime : null + const time = settings.redirect ? parseYouTubeURLTimeString(url.searchParams.get('t') ?? '0') : videoElement.currentTime target = { lbryPathname, platfrom: targetPlatformSettings[settings.targetPlatform], time } - if (settings.redirect) redirectTo(target) + if (settings.redirect) redirectTo(target) else updateButton(buttonMountPoint, target) } - videoElement.addEventListener('timeupdate', () => updateButton(buttonMountPoint, target)) + videoElement.addEventListener('timeupdate', () => target && updateButton(buttonMountPoint, Object.assign(target, { time: videoElement.currentTime }))) + videoElement.addEventListener('ended', () => target && updateButton(buttonMountPoint, Object.assign(target, { time: null }))) - async function afterPushState() + async function onUrlChange() { await updateByURL(new URL(location.href)) }