diff --git a/src/components/dialogs.tsx b/src/components/dialogs.tsx index d62caaa..5ff8c53 100644 --- a/src/components/dialogs.tsx +++ b/src/components/dialogs.tsx @@ -68,6 +68,7 @@ export function Dialogs(params: { manager: ReturnType openRequest.result.createObjectStore("store").createIndex("expireAt", "expireAt")) - - // Delete Expired - openRequest.addEventListener('success', () => { - db = openRequest.result - clearExpired() - }) -} -else console.warn(`IndexedDB not supported`) +let db = new Promise((resolve, reject) => { + if (typeof self.indexedDB !== 'undefined') { + const openRequest = indexedDB.open("yt-url-resolver-cache") + openRequest.addEventListener('upgradeneeded', () => openRequest.result.createObjectStore("store").createIndex("expireAt", "expireAt")) + openRequest.addEventListener('success', () => { + resolve(openRequest.result) + clearExpired() + }, { once: true }) + } + else reject(`IndexedDB not supported`) +}) async function clearExpired() { - return new Promise((resolve, reject) => { - if (!db) throw new Error(`IDBDatabase not defined.`) - const transaction = db.transaction("store", "readwrite") + return new Promise(async (resolve, reject) => { + const transaction = (await db).transaction("store", "readwrite") const range = IDBKeyRange.upperBound(new Date()) const expireAtCursorRequest = transaction.objectStore("store").index("expireAt").openCursor(range) @@ -40,8 +36,8 @@ async function clearExpired() { } async function clearAll() { - return await new Promise((resolve, reject) => { - const store = db?.transaction("store", "readwrite").objectStore("store") + return await new Promise(async (resolve, reject) => { + const store = (await db).transaction("store", "readwrite").objectStore("store") if (!store) return resolve() const request = store.clear() request.addEventListener('success', () => resolve()) @@ -50,8 +46,8 @@ async function clearAll() { } async function put(url: string | null, id: string): Promise { - return await new Promise((resolve, reject) => { - const store = db?.transaction("store", "readwrite").objectStore("store") + return await new Promise(async (resolve, reject) => { + const store = (await db).transaction("store", "readwrite").objectStore("store") if (!store) return resolve() const expireAt = !url ? new Date(Date.now() + 1 * 60 * 60 * 1000) : new Date(Date.now() + 15 * 24 * 60 * 60 * 1000) const request = store.put({ value: url, expireAt }, id) @@ -65,8 +61,8 @@ async function put(url: string | null, id: string): Promise { // null means there is cache of that id has no lbrypathname // undefined means there is no cache async function get(id: string): Promise { - const response = (await new Promise((resolve, reject) => { - const store = db?.transaction("store", "readonly").objectStore("store") + const response = (await new Promise(async (resolve, reject) => { + const store = (await db).transaction("store", "readonly").objectStore("store") if (!store) return reject(`Can't find object store.`) const request = store.get(id) diff --git a/src/scripts/background.ts b/src/scripts/background.ts index 139b5b4..051762d 100644 --- a/src/scripts/background.ts +++ b/src/scripts/background.ts @@ -23,7 +23,7 @@ chrome.runtime.onMessage.addListener(({ method, data }, sender, sendResponse) => console.log('lbrypathname request', params, await promise) resolve(await promise) } catch (error) { - sendResponse(`error:${(error as any).toString()}`) + sendResponse(`error: ${(error as any).toString()}`) console.error(error) } finally { diff --git a/src/scripts/ytContent.tsx b/src/scripts/ytContent.tsx index b54cf43..23abe2a 100644 --- a/src/scripts/ytContent.tsx +++ b/src/scripts/ytContent.tsx @@ -226,14 +226,16 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa const response = await new Promise((resolve) => chrome.runtime.sendMessage({ method: 'resolveUrl', data: JSON.stringify(params) }, resolve)) if (response?.startsWith('error:')) { console.error("Background error on:", params) - throw new Error(`Background error.${response ?? ''}`) + throw new Error(`Background error. ${response ?? ''}`) } + console.log(response) return response ? JSON.parse(response) : null } // Request new tab async function openNewTab(url: URL, active: boolean) { - chrome.runtime.sendMessage({ method: 'openTab', data: JSON.stringify({ href: url.href, active }) }) + if (!open(url.href, '_blank')) + chrome.runtime.sendMessage({ method: 'openTab', data: JSON.stringify({ href: url.href, active }) }) } function getLbryUrlByTarget(target: Target) { @@ -246,20 +248,20 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa let urlHrefCache: string | null = null while (true) { await sleep(500) - const url: URL = new URL(location.href); - - await (async () => { + const url: URL = new URL(location.href) + + await (async () => { const source = await getSourceByUrl(new URL(location.href)) if (!source) return - + try { if (settings.redirect) { const target = (await getTargetsBySources(source))[source.id] if (!target) return if (url.href === urlHrefCache) return - + const lbryURL = getLbryUrlByTarget(target) - + if (source.type === 'video') { // As soon as video play is ready and start playing, pause it. findVideoElementAwait(source).then((videoElement) => { @@ -267,7 +269,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa videoElement.pause() }) } - + if (target.platform === targetPlatformSettings.app) { if (document.hidden) await new Promise((resolve) => document.addEventListener('visibilitychange', resolve, { once: true })) // Replace is being used so browser doesnt start an empty window @@ -276,7 +278,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa } else { openNewTab(lbryURL, document.hasFocus()) - + if (window.history.length === 1) window.close() else window.history.back() } @@ -284,22 +286,22 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa else { if (urlHrefCache !== url.href) updateButton(null) let target = (await getTargetsBySources(source))[source.id] - + // There is no target found via API try to check Video Description for LBRY links. if (!target) { const linksContainer = source.type === 'video' ? document.querySelector(source.platform.htmlQueries.videoDescription) : source.platform.htmlQueries.channelLinks ? document.querySelector(source.platform.htmlQueries.channelLinks) : null - + if (linksContainer) { const anchors = Array.from(linksContainer.querySelectorAll('a')) - + for (const anchor of anchors) { if (!anchor.href) continue const url = new URL(anchor.href) let lbryURL: URL | null = null - + // Extract real link from youtube's redirect link if (source.platform === sourcePlatfromSettings['youtube.com']) { if (!targetPlatforms.some(([key, platform]) => url.searchParams.get('q')?.startsWith(platform.domainPrefix))) continue @@ -310,7 +312,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa if (!targetPlatforms.some(([key, platform]) => url.href.startsWith(platform.domainPrefix))) continue lbryURL = new URL(url.href) } - + if (lbryURL) { target = { lbryPathname: lbryURL.pathname.substring(1), @@ -323,7 +325,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa } } } - + if (!target) updateButton(null) else { // If target is a video target add timestampt to it @@ -331,7 +333,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa const videoElement = document.querySelector(source.platform.htmlQueries.videoPlayer) if (videoElement) target.time = videoElement.currentTime > 3 && videoElement.currentTime < videoElement.duration - 1 ? videoElement.currentTime : null } - + updateButton({ target, source }) } }