From 15f03b3bcca971781097ac4601e9482be8d32d41 Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Tue, 9 Aug 2022 17:06:41 +0000 Subject: [PATCH 01/10] =?UTF-8?q?=F0=9F=8D=99=20removed=20debug=20logs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scripts/ytContent.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/scripts/ytContent.tsx b/src/scripts/ytContent.tsx index 3e8cebc..b54cf43 100644 --- a/src/scripts/ytContent.tsx +++ b/src/scripts/ytContent.tsx @@ -256,7 +256,6 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa if (settings.redirect) { const target = (await getTargetsBySources(source))[source.id] if (!target) return - console.log(url.href, urlHrefCache) if (url.href === urlHrefCache) return const lbryURL = getLbryUrlByTarget(target) @@ -276,7 +275,6 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa location.replace(lbryURL) } else { - console.log('open', lbryURL.href) openNewTab(lbryURL, document.hasFocus()) if (window.history.length === 1) window.close() From 6af354de0c052a4890fec184379db4fd1a876b26 Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Tue, 9 Aug 2022 17:49:16 +0000 Subject: [PATCH 02/10] =?UTF-8?q?=F0=9F=8D=99=20more=20bug=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/dialogs.tsx | 1 + src/modules/yt/urlCache.ts | 42 +++++++++++++++++--------------------- src/scripts/background.ts | 2 +- src/scripts/ytContent.tsx | 36 +++++++++++++++++--------------- 4 files changed, 40 insertions(+), 41 deletions(-) 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 }) } } From a95b46bf0c5ddf87ab63e2585e5741484fdf1018 Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Tue, 9 Aug 2022 19:10:37 +0000 Subject: [PATCH 03/10] =?UTF-8?q?=F0=9F=8D=99=20made=20url=20resovler=20ti?= =?UTF-8?q?meout=20longer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/yt/urlResolve.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/yt/urlResolve.ts b/src/modules/yt/urlResolve.ts index be3807d..240cf7b 100644 --- a/src/modules/yt/urlResolve.ts +++ b/src/modules/yt/urlResolve.ts @@ -55,7 +55,7 @@ export async function resolveById(params: Paramaters, progressCallback?: (progre const controller = new AbortController() // 5 second timeout: - const timeoutId = setTimeout(() => controller.abort(), 5000) + const timeoutId = setTimeout(() => controller.abort(), 15000) const apiResponse = await fetch(url.toString(), { cache: 'no-store', signal: controller.signal }) clearTimeout(timeoutId) From 9c26d553f56317ae747f74dc8126a35199e8bebd Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Tue, 9 Aug 2022 21:16:05 +0000 Subject: [PATCH 04/10] =?UTF-8?q?=F0=9F=8D=A3=20major=20changes=20-=20mode?= =?UTF-8?q?s=20are=20removed=20-=20added=20more=20options=20for=20redirect?= =?UTF-8?q?=20-=20extension=20badge=20removed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/popup/main.tsx | 187 +++++++++++++++++---------------- src/pages/popup/style.css | 5 + src/scripts/ytContent.tsx | 210 ++++++++++++++++++++----------------- src/settings/background.ts | 6 +- src/settings/index.ts | 22 ++-- 5 files changed, 234 insertions(+), 196 deletions(-) diff --git a/src/pages/popup/main.tsx b/src/pages/popup/main.tsx index abd0562..f1e8197 100644 --- a/src/pages/popup/main.tsx +++ b/src/pages/popup/main.tsx @@ -12,9 +12,9 @@ const targetPlatforms = getTargetPlatfromSettingsEntiries() const ytUrlResolverOptions = getYtUrlResolversSettingsEntiries() function WatchOnLbryPopup(params: { profile: Awaited> | null }) { - const { redirect, targetPlatform, urlResolver, videoSubButton, channelSubButton, videoPlayerButton, privateKey, publicKey } = useExtensionSettings() + const { targetPlatform, urlResolver, redirectChannel, redirectVideo, redirectVideoPlaylist, buttonVideoSub, buttonChannelSub, buttonVideoPlayer, privateKey, publicKey } = useExtensionSettings() let [loading, updateLoading] = useState(() => false) - let [route, updateRoute] = useState(() => null) + let [route, updateRoute] = useState(() => '') const dialogManager = createDialogManager() const nickname = params.profile ? params.profile.nickname ?? 'No Nickname' : '...' @@ -35,29 +35,30 @@ function WatchOnLbryPopup(params: { profile: Awaited { - publicKey - ?
+ +
+ { + publicKey &&

{friendlyPublicKey(publicKey)}

Score: {params.profile?.score ?? '...'} - 🔗Leaderboard {urlResolver !== 'madiatorFinder' && You need to use Madiator Finder API for scoring to work}
-
- { - route === 'profile' - ? updateRoute('')} className="filled">⇐ Back - : updateRoute('profile')} href="#profile">Profile Settings - } -
-
- :
- { - route === 'profile' - ? updateRoute('')} className="filled">⇐ Back - : updateRoute('profile')} href="#profile">Profile Settings - } -
+ } + + { + route !== '' + ? +
+ updateRoute('')} className="filled">⇐ Back +
+ : +
+ updateRoute('profile')}>Profile Settings +
+ } +
} { route === 'profile' ? @@ -138,80 +139,88 @@ function WatchOnLbryPopup(params: { profile: Awaited : -
-
- - -
- { - !redirect && + route === 'advanced' ? +
- - Video + - - Channel -
- } -
- - -
-
- - - loads(lbryUrlCache.clearAll().then(() => dialogManager.alert("Cleared Cache!")))} className={`button active`}> - Clear Resolver Cache - -
-
- - - Subscription Converter - -
-
+
+ + + loads(lbryUrlCache.clearAll().then(() => dialogManager.alert("Cleared Cache!")))} className={`button active`}> + Clear Resolver Cache + +
+
+ : +
+
+ + +
+
+ + +
+
+ + + Subscription Converter + + updateRoute('advanced')}>Advanced Settings +
+
} {loading &&
Loading... diff --git a/src/pages/popup/style.css b/src/pages/popup/style.css index 3b0bd64..987f35b 100644 --- a/src/pages/popup/style.css +++ b/src/pages/popup/style.css @@ -54,4 +54,9 @@ section>* { justify-items: start; align-items: center; text-align: left; +} + +.toggle-option { + display: grid; + gap: .5em; } \ No newline at end of file diff --git a/src/scripts/ytContent.tsx b/src/scripts/ytContent.tsx index 23abe2a..67455e4 100644 --- a/src/scripts/ytContent.tsx +++ b/src/scripts/ytContent.tsx @@ -17,6 +17,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa platform: SourcePlatform id: string type: ResolveUrlTypes + url: URL time: number | null } @@ -26,7 +27,6 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa chrome.storage.onChanged.addListener(async (changes, areaName) => { if (areaName !== 'local') return Object.assign(settings, Object.fromEntries(Object.entries(changes).map(([key, change]) => [key, change.newValue]))) - if (settings.redirect) updateButton(null) }) const buttonMountPoint = document.createElement('div') @@ -112,7 +112,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa
} - function updateButton(params: { source: Source, target: Target } | null): void { + function updateButtons(params: { source: Source, target: Target } | null): void { if (!params) { render(, buttonMountPoint) render(, playerButtonMountPoint) @@ -120,7 +120,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa } { - const mountPlayerButtonBefore = settings.videoPlayerButton ? + const mountPlayerButtonBefore = settings.buttonVideoPlayer ? document.querySelector(params.source.platform.htmlQueries.mountPoints.mountPlayerButtonBefore) : null if (!mountPlayerButtonBefore) render(, playerButtonMountPoint) @@ -134,7 +134,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa } { - const mountButtonBefore = settings[(`${params.source.type}SubButton`) as 'videoSubButton' | 'channelSubButton'] ? + const mountButtonBefore = settings[(`button${params.source.type[0].toUpperCase() + params.source.type.substring(1)}Sub`) as 'buttonVideoSub' | 'buttonChannelSub'] ? document.querySelector(params.source.platform.htmlQueries.mountPoints.mountButtonBefore[params.source.type]) : null if (!mountButtonBefore) render(, buttonMountPoint) @@ -163,7 +163,8 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa id: url.searchParams.get('v')!, platform, time: url.searchParams.has('t') ? parseYouTubeURLTimeString(url.searchParams.get('t')!) : null, - type: 'video' + type: 'video', + url } } else if (url.pathname.startsWith('/channel/')) { @@ -171,7 +172,8 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa id: url.pathname.substring("/channel/".length), platform, time: null, - type: 'channel' + type: 'channel', + url } } else if (url.pathname.startsWith('/c/') || url.pathname.startsWith('/user/')) { @@ -187,7 +189,8 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa id, platform, time: null, - type: 'channel' + type: 'channel', + url } } @@ -233,9 +236,47 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa } // Request new tab - async function openNewTab(url: URL, active: boolean) { + async function openNewTab(url: URL) { if (!open(url.href, '_blank')) - chrome.runtime.sendMessage({ method: 'openTab', data: JSON.stringify({ href: url.href, active }) }) + chrome.runtime.sendMessage({ method: 'openTab', data: JSON.stringify({ href: url.href, active: document.hasFocus() }) }) + } + + function findTargetFromSourcePage(source: Source): Target | null { + 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 + lbryURL = new URL(url.searchParams.get('q')!) + } + // Just directly use the link itself on other platforms + else { + if (!targetPlatforms.some(([key, platform]) => url.href.startsWith(platform.domainPrefix))) continue + lbryURL = new URL(url.href) + } + + if (lbryURL) { + return { + lbryPathname: lbryURL.pathname.substring(1), + time: null, + type: lbryURL.pathname.substring(1).includes('/') ? 'video' : 'channel', + platform: targetPlatformSettings[settings.targetPlatform] + } + } + } + } + return null } function getLbryUrlByTarget(target: Target) { @@ -245,104 +286,83 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa return url } - let urlHrefCache: string | null = null - while (true) { + + // Master Loop + for ( + let url = new URL(location.href), + urlHrefCache: string | null = null; + ; + urlHrefCache = url.href, + url = new URL(location.href) + ) { await sleep(500) - const url: URL = new URL(location.href) - - await (async () => { + try { const source = await getSourceByUrl(new URL(location.href)) - if (!source) return + if (!source) { + updateButtons(null) + continue + } + const target = (await getTargetsBySources(source))[source.id] ?? findTargetFromSourcePage(source) + if (!target) { + updateButtons(null) + continue + } - try { - if (settings.redirect) { - const target = (await getTargetsBySources(source))[source.id] - if (!target) return - if (url.href === urlHrefCache) return + // Update Buttons + if (urlHrefCache !== url.href) updateButtons(null) + // If target is a video target add timestampt to it + if (target.type === 'video') { + const videoElement = document.querySelector(source.platform.htmlQueries.videoPlayer) + if (videoElement) target.time = videoElement.currentTime > 3 && videoElement.currentTime < videoElement.duration - 1 ? videoElement.currentTime : null + } + updateButtons({ target, source }) - const lbryURL = getLbryUrlByTarget(target) + // Redirect + if ( + source.type === target.type && + ( + ( + settings.redirectVideo && + source.type === 'video' && !source.url.searchParams.has('list') + ) || + ( + settings.redirectVideoPlaylist && + source.type === 'video' && source.url.searchParams.has('list') + ) || + ( + settings.redirectChannel && + source.type === 'channel' + ) + ) + ) { + if (url.href === urlHrefCache) continue - if (source.type === 'video') { - // As soon as video play is ready and start playing, pause it. - findVideoElementAwait(source).then((videoElement) => { - videoElement.addEventListener('play', () => videoElement.pause(), { once: true }) - videoElement.pause() - }) - } + const lbryURL = getLbryUrlByTarget(target) - 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 - // Its not gonna be able to replace anyway, since its a LBRY Uri - location.replace(lbryURL) - } - else { - openNewTab(lbryURL, document.hasFocus()) + if (source.type === 'video') { + // As soon as video play is ready and start playing, pause it. + findVideoElementAwait(source).then((videoElement) => { + videoElement.addEventListener('play', () => videoElement.pause(), { once: true }) + videoElement.pause() + }) + } - if (window.history.length === 1) window.close() - else window.history.back() - } + 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 + // Its not gonna be able to replace anyway, since its a LBRY Uri + location.replace(lbryURL) } else { - if (urlHrefCache !== url.href) updateButton(null) - let target = (await getTargetsBySources(source))[source.id] + openNewTab(lbryURL) - // 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 - lbryURL = new URL(url.searchParams.get('q')!) - } - // Just directly use the link itself on other platforms - else { - if (!targetPlatforms.some(([key, platform]) => url.href.startsWith(platform.domainPrefix))) continue - lbryURL = new URL(url.href) - } - - if (lbryURL) { - target = { - lbryPathname: lbryURL.pathname.substring(1), - time: null, - type: lbryURL.pathname.substring(1).includes('/') ? 'video' : 'channel', - platform: targetPlatformSettings[settings.targetPlatform] - } - break - } - } - } - } - - if (!target) updateButton(null) - else { - // If target is a video target add timestampt to it - if (target.type === 'video') { - 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 }) - } + if (window.history.length === 1) window.close() + else window.history.back() } - } catch (error) { - console.error(error) } - })() - - urlHrefCache = url.href + } catch (error) { + console.error(error) + } } })() \ No newline at end of file diff --git a/src/settings/background.ts b/src/settings/background.ts index 910c8ac..a522e1c 100644 --- a/src/settings/background.ts +++ b/src/settings/background.ts @@ -21,13 +21,13 @@ async function initSettings() { if (!Object.keys(targetPlatformSettings).includes(settings.targetPlatform)) setExtensionSetting('targetPlatform', DEFAULT_SETTINGS.targetPlatform) if (!Object.keys(ytUrlResolversSettings).includes(settings.urlResolver)) setExtensionSetting('urlResolver', DEFAULT_SETTINGS.urlResolver) - chromeAction.setBadgeText({ text: settings.redirect ? 'ON' : 'OFF' }) + // chromeAction.setBadgeText({ text: settings.redirect ? 'ON' : 'OFF' }) } -chrome.storage.onChanged.addListener((changes, areaName) => { +/* chrome.storage.onChanged.addListener((changes, areaName) => { if (areaName !== 'local' || !changes.redirect) return chromeAction.setBadgeText({ text: changes.redirect.newValue ? 'ON' : 'OFF' }) -}) +}) */ chrome.runtime.onStartup.addListener(initSettings) chrome.runtime.onInstalled.addListener(initSettings) \ No newline at end of file diff --git a/src/settings/index.ts b/src/settings/index.ts index e32e92c..69354ff 100644 --- a/src/settings/index.ts +++ b/src/settings/index.ts @@ -2,24 +2,28 @@ import type { JSX } from "preact" import { useEffect, useReducer } from "preact/hooks" import type { ResolveUrlTypes } from "../modules/yt/urlResolve" -export interface ExtensionSettings { - redirect: boolean +export interface ExtensionSettings extends Record{ targetPlatform: TargetPlatformName urlResolver: YTUrlResolverName, - videoSubButton: boolean - videoPlayerButton: boolean - channelSubButton: boolean + redirectVideo: boolean, + redirectChannel: boolean, + redirectVideoPlaylist: boolean, + buttonVideoSub: boolean + buttonVideoPlayer: boolean + buttonChannelSub: boolean publicKey: string | null, privateKey: string | null } export const DEFAULT_SETTINGS: ExtensionSettings = { - redirect: true, targetPlatform: 'odysee', urlResolver: 'odyseeApi', - videoSubButton: true, - videoPlayerButton: true, - channelSubButton: true, + redirectVideo: false, + redirectChannel: false, + redirectVideoPlaylist: false, + buttonVideoSub: true, + buttonVideoPlayer: true, + buttonChannelSub: true, privateKey: null, publicKey: null } From 59a5e0dee23dcaf662a9754d15645c258ee72f1b Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Tue, 9 Aug 2022 22:22:25 +0000 Subject: [PATCH 05/10] =?UTF-8?q?=F0=9F=8D=99=20on=20redirect=20use=20repl?= =?UTF-8?q?ace=20if=20tab=20has=20no=20history?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scripts/ytContent.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/scripts/ytContent.tsx b/src/scripts/ytContent.tsx index 67455e4..5c2148c 100644 --- a/src/scripts/ytContent.tsx +++ b/src/scripts/ytContent.tsx @@ -354,10 +354,15 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa location.replace(lbryURL) } else { - openNewTab(lbryURL) - - if (window.history.length === 1) window.close() - else window.history.back() + if (window.history.length === 1) + { + location.replace(lbryURL) + } + else + { + openNewTab(lbryURL) + window.history.back() + } } } } catch (error) { From a41b51e454a3325b6921343aac5045b95cc1ba54 Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Tue, 9 Aug 2022 22:44:40 +0000 Subject: [PATCH 06/10] =?UTF-8?q?=F0=9F=8D=A3=20handle=20unexpected=20loca?= =?UTF-8?q?tion.replace=20behavior?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scripts/ytContent.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/scripts/ytContent.tsx b/src/scripts/ytContent.tsx index 5c2148c..21e1d20 100644 --- a/src/scripts/ytContent.tsx +++ b/src/scripts/ytContent.tsx @@ -357,6 +357,11 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa if (window.history.length === 1) { location.replace(lbryURL) + + // Some extensions such as Firefox Multi-Account Containers, opens new tab for Odysee even though we say replace + // In those cases if the window is still active after 2 seconds we close it manually + await sleep(2000) + window.close() } else { From 28ef256c4067cbad67e3ad2d432c5de47461ea43 Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Wed, 10 Aug 2022 07:56:24 +0000 Subject: [PATCH 07/10] =?UTF-8?q?=F0=9F=8D=99=20on=20redirect=20pause=20th?= =?UTF-8?q?e=20video=20directly=20only?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scripts/ytContent.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/scripts/ytContent.tsx b/src/scripts/ytContent.tsx index 21e1d20..824e8e4 100644 --- a/src/scripts/ytContent.tsx +++ b/src/scripts/ytContent.tsx @@ -340,11 +340,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa const lbryURL = getLbryUrlByTarget(target) if (source.type === 'video') { - // As soon as video play is ready and start playing, pause it. - findVideoElementAwait(source).then((videoElement) => { - videoElement.addEventListener('play', () => videoElement.pause(), { once: true }) - videoElement.pause() - }) + findVideoElementAwait(source).then((videoElement) => videoElement.pause()) } if (target.platform === targetPlatformSettings.app) { From 1ee722b6ff6eebd3765db92d1255c369d67443c7 Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Wed, 10 Aug 2022 08:12:04 +0000 Subject: [PATCH 08/10] =?UTF-8?q?=F0=9F=8D=A3=20improved=20logic=20of=20re?= =?UTF-8?q?drect=20and=20opening=20a=20new=20tab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/scripts/background.ts | 4 ++-- src/scripts/ytContent.tsx | 14 ++------------ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/scripts/background.ts b/src/scripts/background.ts index 051762d..3996ccf 100644 --- a/src/scripts/background.ts +++ b/src/scripts/background.ts @@ -11,8 +11,8 @@ chrome.runtime.onMessage.addListener(({ method, data }, sender, sendResponse) => switch (method) { case 'openTab': { - const { href, active }: { href: string, active: boolean } = JSON.parse(data) - chrome.tabs.create({ url: href, active }) + const { href }: { href: string } = JSON.parse(data) + chrome.tabs.create({ url: href, active: sender.tab?.active, index: sender.tab ? sender.tab.index + 1 : undefined }) } break case 'resolveUrl': diff --git a/src/scripts/ytContent.tsx b/src/scripts/ytContent.tsx index 824e8e4..f4c69c2 100644 --- a/src/scripts/ytContent.tsx +++ b/src/scripts/ytContent.tsx @@ -237,8 +237,7 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa // Request new tab async function openNewTab(url: URL) { - if (!open(url.href, '_blank')) - chrome.runtime.sendMessage({ method: 'openTab', data: JSON.stringify({ href: url.href, active: document.hasFocus() }) }) + chrome.runtime.sendMessage({ method: 'openTab', data: JSON.stringify({ href: url.href }) }) } function findTargetFromSourcePage(source: Source): Target | null { @@ -350,20 +349,11 @@ import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, getTa location.replace(lbryURL) } else { + openNewTab(lbryURL) if (window.history.length === 1) - { - location.replace(lbryURL) - - // Some extensions such as Firefox Multi-Account Containers, opens new tab for Odysee even though we say replace - // In those cases if the window is still active after 2 seconds we close it manually - await sleep(2000) window.close() - } else - { - openNewTab(lbryURL) window.history.back() - } } } } catch (error) { From 21f6ffc85b516182fd458cdb8b791592721c7e23 Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Wed, 10 Aug 2022 08:17:55 +0000 Subject: [PATCH 09/10] =?UTF-8?q?=F0=9F=8D=A4=20popup=20width=20made=20lar?= =?UTF-8?q?ger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/popup/style.css | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pages/popup/style.css b/src/pages/popup/style.css index 987f35b..f492c52 100644 --- a/src/pages/popup/style.css +++ b/src/pages/popup/style.css @@ -1,3 +1,10 @@ +#popup { + width: 40em; + max-width: 100%; + overflow: hidden; + margin: auto; +} + header { display: grid; gap: .5em; @@ -37,13 +44,6 @@ section>* { padding: 0 1rem; } -#popup { - width: 35em; - max-width: 100%; - overflow: hidden; - margin: auto; -} - .center { display: grid; place-items: center; From 7fa57b9e880742a1826fbc3f8a7e6abbe8c639a6 Mon Sep 17 00:00:00 2001 From: Shiba <44804845+DeepDoge@users.noreply.github.com> Date: Wed, 10 Aug 2022 09:38:57 +0000 Subject: [PATCH 10/10] =?UTF-8?q?=F0=9F=8D=99=20updated=20YTtoLBRY=20video?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/YTtoLBRY/README.md | 6 ------ src/pages/YTtoLBRY/main.tsx | 12 +++++++++--- 2 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 src/pages/YTtoLBRY/README.md diff --git a/src/pages/YTtoLBRY/README.md b/src/pages/YTtoLBRY/README.md deleted file mode 100644 index 04a15ce..0000000 --- a/src/pages/YTtoLBRY/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Getting your subscription data - -1. Go to https://takeout.google.com/settings/takeout -2. Deselect everything except `YouTube and YouTube Music` and within that only select `subscriptions` -3. Go through the process and create the export -4. Once it's exported, open the archive and find `YouTube and YouTube Music/subscriptions/subscriptions.json` and upload it to the extension \ No newline at end of file diff --git a/src/pages/YTtoLBRY/main.tsx b/src/pages/YTtoLBRY/main.tsx index 0294ce3..8ab79b1 100644 --- a/src/pages/YTtoLBRY/main.tsx +++ b/src/pages/YTtoLBRY/main.tsx @@ -4,7 +4,6 @@ import { getFileContent } from '../../modules/file' import { getSubsFromCsv, getSubsFromJson, getSubsFromOpml } from '../../modules/yt' import { resolveById } from '../../modules/yt/urlResolve' import { targetPlatformSettings, useExtensionSettings } from '../../settings' -import readme from './README.md' async function getSubscribedChannelIdsFromFile(file: File) { const ext = file.name.split('.').pop()?.toLowerCase() @@ -71,8 +70,15 @@ function YTtoLBRY() {