🍙 refactoring and fixes

This commit is contained in:
Shiba 2022-04-30 16:14:52 +00:00
parent fe5c38bfed
commit e8d7a349f4
6 changed files with 95 additions and 151 deletions

View file

@ -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;
}

View file

@ -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)

View file

@ -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;
}

View file

@ -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>

View file

@ -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
})

View file

@ -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) {