mirror of
https://github.com/LBRYFoundation/Watch-on-LBRY.git
synced 2025-08-23 17:47:26 +00:00
🍙 refactoring and fixes
This commit is contained in:
parent
fe5c38bfed
commit
e8d7a349f4
6 changed files with 95 additions and 151 deletions
|
@ -10,6 +10,7 @@
|
|||
}
|
||||
|
||||
:root {
|
||||
font-family: Arial, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Open Sans, Helvetica Neue, sans-serif;
|
||||
letter-spacing: .2ch;
|
||||
}
|
||||
|
||||
|
@ -21,6 +22,13 @@ body {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
body::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(19, 19, 19, 0.75);
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
|
@ -28,19 +36,28 @@ body {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
.button {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
place-items: center;
|
||||
place-content: center;
|
||||
text-align: center;
|
||||
padding: .5em 1em;
|
||||
|
||||
background: var(--color-dark);
|
||||
color: var(--color-light);
|
||||
|
||||
cursor: pointer;
|
||||
border-radius: .5em;
|
||||
}
|
||||
|
||||
.filled {
|
||||
background: var(--color-gradient-0);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
font-weight: bold;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.button.active {
|
||||
background: var(--color-gradient-0);
|
||||
}
|
||||
|
@ -58,4 +75,30 @@ body {
|
|||
.button.disabled {
|
||||
filter: saturate(0);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.options {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
grid-template-columns: repeat(auto-fit, minmax(3em, 1fr));
|
||||
justify-content: center;
|
||||
gap: .25em;
|
||||
padding: 0 1.5em;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.overlay::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-color: #0e1117;
|
||||
opacity: .75;
|
||||
}
|
|
@ -54,7 +54,7 @@ export async function resolveById(params: Paramaters, progressCallback?: (progre
|
|||
const response: ApiResponse = await apiResponse.json()
|
||||
for (const item of params)
|
||||
{
|
||||
const lbryUrl = ((item.type === 'channel' ? response.channels : response.videos) ?? {})[item.id] ?? null
|
||||
const lbryUrl = ((item.type === 'channel' ? response.channels : response.videos) ?? {})[item.id]?.replaceAll('#', ':') ?? null
|
||||
// we cache it no matter if its null or not
|
||||
await LbryPathnameCache.put(lbryUrl, item.id)
|
||||
|
||||
|
|
|
@ -1,40 +1,3 @@
|
|||
:root {
|
||||
--color-master: #499375;
|
||||
--color-slave: #43889d;
|
||||
--color-error: rgb(245, 81, 69);
|
||||
--color-gradient-0: linear-gradient(130deg, var(--color-master), var(--color-slave));
|
||||
--color-gradient-1: linear-gradient(130deg, #ff7a18, #af002d 41.07%, #319197 76.05%);
|
||||
--color-dark: #0e1117;
|
||||
--color-light: rgb(235, 237, 241);
|
||||
--gradient-animation: gradient-animation 5s linear infinite alternate;
|
||||
}
|
||||
|
||||
:root {
|
||||
letter-spacing: .2ch;
|
||||
}
|
||||
|
||||
body {
|
||||
background: linear-gradient(to left top, var(--color-master), var(--color-slave));
|
||||
background-attachment: fixed;
|
||||
color: var(--color-light);
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(19, 19, 19, 0.75);
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 1.75em;
|
||||
font-weight: bold;
|
||||
|
@ -75,76 +38,4 @@ section {
|
|||
width: 35em;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-flex;
|
||||
place-items: center;
|
||||
text-align: center;
|
||||
padding: .5em 1em;
|
||||
|
||||
background: var(--color-dark);
|
||||
color: var(--color-light);
|
||||
|
||||
cursor: pointer;
|
||||
border-radius: .5em;
|
||||
}
|
||||
|
||||
.filled {
|
||||
background: var(--color-gradient-0);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
font-weight: bold;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.button.active {
|
||||
background: var(--color-gradient-0);
|
||||
}
|
||||
|
||||
.button.active::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: var(--color-gradient-0);
|
||||
filter: blur(.5em);
|
||||
z-index: -1;
|
||||
border-radius: .5em;
|
||||
}
|
||||
|
||||
.button.disabled {
|
||||
filter: saturate(0);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.go-back {
|
||||
color: currentColor;
|
||||
text-decoration: none;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.options {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
grid-template-columns: repeat(auto-fit, minmax(3em, 1fr));
|
||||
justify-content: center;
|
||||
gap: .25em;
|
||||
padding: 0 1.5em;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.overlay::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-color: #0e1117;
|
||||
opacity: .75;
|
||||
}
|
|
@ -82,7 +82,7 @@ function WatchOnLbryPopup(params: { profile: Awaited<ReturnType<typeof getProfil
|
|||
<label>Purge your profile and data!</label>
|
||||
<p>Purge your profile data online and offline.</p>
|
||||
<div className='options'>
|
||||
<a className="button filled">(╯°□°)╯︵ ┻━┻</a>
|
||||
<span className="filled button">(╯°□°)╯︵ ┻━┻</span>
|
||||
<a onClick={() => startAsyncOperation(purgeProfile()).then(() => renderPopup())} className={`button`}>
|
||||
Purge Everything!!
|
||||
</a>
|
||||
|
|
|
@ -1,34 +1,27 @@
|
|||
import { resolveById, YtUrlResolveItem } from '../common/yt/urlResolve'
|
||||
import { resolveById } from '../common/yt/urlResolve'
|
||||
|
||||
async function resolveYT(item: YtUrlResolveItem) {
|
||||
const lbryProtocolUrl: string | null = (await resolveById([item]).then((items) => items[item.id]))?.id ?? null
|
||||
if (!lbryProtocolUrl) return null
|
||||
return lbryProtocolUrl.replaceAll('#', ':')
|
||||
/* const segments = parseProtocolUrl(lbryProtocolUrl || '', { encode: true })
|
||||
if (segments.length === 0) throw new Error()
|
||||
return segments.join('/') */
|
||||
}
|
||||
const onGoingLbryPathnameRequest: Record<string, ReturnType<typeof resolveById>> = {}
|
||||
|
||||
const onGoingLbryPathnameRequest: Record<string, Promise<string | null>> = {}
|
||||
async function lbryPathnameFromVideoId(videoId: string): Promise<string | null> {
|
||||
// Don't create a new Promise for same ID until on going one is over.
|
||||
try {
|
||||
const promise = onGoingLbryPathnameRequest[videoId] ?? (onGoingLbryPathnameRequest[videoId] = resolveYT({ id: videoId, type: 'video' }))
|
||||
console.log('lbrypathname request', videoId, await promise)
|
||||
return await promise
|
||||
} catch (error) {
|
||||
throw error
|
||||
chrome.runtime.onMessage.addListener(({ json }, sender, sendResponse) => {
|
||||
function resolve(result: Awaited<ReturnType<typeof resolveById>>) {
|
||||
sendResponse(JSON.stringify(result))
|
||||
}
|
||||
finally {
|
||||
delete onGoingLbryPathnameRequest[videoId]
|
||||
}
|
||||
}
|
||||
(async () => {
|
||||
try {
|
||||
const params: Parameters<typeof resolveById> = JSON.parse(json)
|
||||
// Don't create a new Promise for same ID until on going one is over.
|
||||
const promise = onGoingLbryPathnameRequest[json] ?? (onGoingLbryPathnameRequest[json] = resolveById(...params))
|
||||
console.log('lbrypathname request', params, await promise)
|
||||
resolve(await promise)
|
||||
} catch (error) {
|
||||
sendResponse('error')
|
||||
console.error(error)
|
||||
}
|
||||
finally {
|
||||
delete onGoingLbryPathnameRequest[json]
|
||||
}
|
||||
})()
|
||||
|
||||
chrome.runtime.onMessage.addListener(({ videoId }: { videoId: string }, sender, sendResponse) => {
|
||||
lbryPathnameFromVideoId(videoId).then((lbryPathname) => sendResponse(lbryPathname)).catch((err) => {
|
||||
sendResponse('error')
|
||||
console.error(err)
|
||||
})
|
||||
return true
|
||||
})
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { h, render } from 'preact'
|
||||
import { getExtensionSettingsAsync, getSourcePlatfromSettingsFromHostname, TargetPlatform, targetPlatformSettings } from '../common/settings'
|
||||
import { parseYouTubeURLTimeString } from '../common/yt'
|
||||
import { resolveById } from '../common/yt/urlResolve'
|
||||
|
||||
const sleep = (t: number) => new Promise(resolve => setTimeout(resolve, t))
|
||||
|
||||
|
@ -79,10 +80,10 @@ async function findVideoElement() {
|
|||
}
|
||||
|
||||
// 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) {
|
||||
const response = await new Promise<string | null | 'error'>((resolve) => chrome.runtime.sendMessage({ videoId }, resolve))
|
||||
if (response === 'error') throw new Error("Background error.")
|
||||
return response
|
||||
async function requestResolveById(...params: Parameters<typeof resolveById>): ReturnType<typeof resolveById> {
|
||||
const json = await new Promise<string | null | 'error'>((resolve) => chrome.runtime.sendMessage({ json: JSON.stringify(params) }, resolve))
|
||||
if (json === 'error') throw new Error("Background error.")
|
||||
return json ? JSON.parse(json) : null
|
||||
}
|
||||
|
||||
// Start
|
||||
|
@ -106,13 +107,29 @@ async function requestLbryPathname(videoId: string) {
|
|||
chrome.runtime.onMessage.addListener(() => updater())
|
||||
|
||||
async function getTargetByURL(url: URL) {
|
||||
if (url.pathname !== '/watch') return null
|
||||
if (url.pathname === '/watch' && url.searchParams.has('v')) {
|
||||
const videoId = url.searchParams.get('v')!
|
||||
const result = await requestResolveById([{ id: videoId, type: 'video' }])
|
||||
const target: Target | null = result?.[videoId] ? { lbryPathname: result[videoId].id, platfrom: targetPlatformSettings[settings.targetPlatform], time: null } : null
|
||||
|
||||
return target
|
||||
}
|
||||
else if (url.pathname.startsWith('/channel/')) {
|
||||
await requestResolveById([{ id: url.pathname.substring("/channel/".length), type: 'channel' }])
|
||||
}
|
||||
else if (url.pathname.startsWith('/c/') || url.pathname.startsWith('/user/'))
|
||||
{
|
||||
// We have to download the page content again because these parts of the page are not responsive
|
||||
// yt front end sucks anyway
|
||||
const content = await (await fetch(location.href)).text()
|
||||
const prefix = `https://www.youtube.com/feeds/videos.xml?channel_id=`
|
||||
const suffix = `"`
|
||||
const startsAt = content.indexOf(prefix) + prefix.length
|
||||
const endsAt = content.indexOf(suffix, startsAt)
|
||||
await requestResolveById([{ id: content.substring(startsAt, endsAt), type: 'channel' }])
|
||||
}
|
||||
|
||||
const videoId = url.searchParams.get('v')
|
||||
const lbryPathname = videoId && await requestLbryPathname(videoId)
|
||||
const target: Target | null = lbryPathname ? { lbryPathname, platfrom: targetPlatformSettings[settings.targetPlatform], time: null } : null
|
||||
|
||||
return target
|
||||
return null
|
||||
}
|
||||
|
||||
async function redirectTo({ lbryPathname, platfrom, time }: Target) {
|
||||
|
|
Loading…
Add table
Reference in a new issue