diff --git a/src/common/components/ButtonRadio.sass b/src/common/components/ButtonRadio.sass index f8d28e5..3109995 100644 --- a/src/common/components/ButtonRadio.sass +++ b/src/common/components/ButtonRadio.sass @@ -5,6 +5,10 @@ justify-content: center flex-wrap: wrap gap: .25em + cursor: pointer + + * + cursor: pointer .radio-button @extend .button diff --git a/src/common/yt/urlCache.ts b/src/common/yt/urlCache.ts index 1a47c8d..2e360c1 100644 --- a/src/common/yt/urlCache.ts +++ b/src/common/yt/urlCache.ts @@ -9,20 +9,44 @@ if (typeof self.indexedDB !== 'undefined') { // Delete Expired openRequest.addEventListener('success', () => { db = openRequest.result - const transaction = db.transaction("store", "readwrite") - const range = IDBKeyRange.upperBound(new Date()) - - const expireAtCursorRequest = transaction.objectStore("store").index("expireAt").openCursor(range) - expireAtCursorRequest.addEventListener('success', () => { - const expireCursor = expireAtCursorRequest.result - if (!expireCursor) return - expireCursor.delete() - expireCursor.continue() - }) + clearExpired() }) } else console.warn(`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") + const range = IDBKeyRange.upperBound(new Date()) + + const expireAtCursorRequest = transaction.objectStore("store").index("expireAt").openCursor(range) + expireAtCursorRequest.addEventListener('error', () => reject(expireAtCursorRequest.error)) + expireAtCursorRequest.addEventListener('success', () => { + try { + const expireCursor = expireAtCursorRequest.result + if (!expireCursor) return + expireCursor.delete() + expireCursor.continue() + resolve() + } + catch (ex) { + reject(ex) + } + }) + }) +} + +async function clearAll() +{ + return await new Promise((resolve, reject) => { + const store = db?.transaction("store", "readwrite").objectStore("store") + if (!store) return resolve() + const request = store.clear() + request.addEventListener('success', () => resolve()) + request.addEventListener('error', () => reject(request.error)) + }) +} async function put(url: string | null, id: string): Promise { return await new Promise((resolve, reject) => { @@ -34,15 +58,26 @@ async function put(url: string | null, id: string): Promise { }) } -async function get(id: string): Promise { - return (await new Promise((resolve, reject) => { +// string means there is cache of lbrypathname +// 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") - if (!store) return resolve(null) + if (!store) return reject(`Can't find object store.`) + const request = store.get(id) request.addEventListener('success', () => resolve(request.result)) request.addEventListener('error', () => reject(request.error)) - }) as any)?.value + }) as { value: string | null, expireAt: Date } | undefined) + + if (response === undefined) return undefined + if (response.expireAt <= new Date()) { + await clearExpired() + return undefined + } + return response.value } -export const LbryPathnameCache = { put, get } +export const LbryPathnameCache = { put, get, clearAll } diff --git a/src/popup/popup.sass b/src/popup/popup.sass index 3cbb7e0..ed3c5bd 100644 --- a/src/popup/popup.sass +++ b/src/popup/popup.sass @@ -10,4 +10,7 @@ .container > section display: grid grid-auto-flow: row - gap: 1em \ No newline at end of file + gap: 1em + +button + cursor: pointer \ No newline at end of file diff --git a/src/popup/popup.tsx b/src/popup/popup.tsx index b804a72..b9e506d 100644 --- a/src/popup/popup.tsx +++ b/src/popup/popup.tsx @@ -1,7 +1,9 @@ import { h, render } from 'preact' +import { useState } from 'preact/hooks' import ButtonRadio, { SelectionOption } from '../common/components/ButtonRadio' import { ExtensionSettings, getTargetPlatfromSettingsEntiries, getYtUrlResolversSettingsEntiries, TargetPlatformName, YTUrlResolverName } from '../common/settings' import { useLbrySettings } from '../common/useSettings' +import { LbryPathnameCache } from '../common/yt/urlCache' import './popup.sass' /** Utilty to set a setting in the browser */ @@ -16,6 +18,7 @@ const ytUrlResolverOptions: SelectionOption[] = getYtUrlResolversSettingsEntirie function WatchOnLbryPopup() { const { redirect, targetPlatform, urlResolver } = useLbrySettings() + let [clearingCache, updateClearingCache] = useState(() => false) return
@@ -33,6 +36,14 @@ function WatchOnLbryPopup() { setSetting('urlResolver', urlResolver)} />
+
+ { + await LbryPathnameCache.clearAll() + alert('Cleared Cache.') + }}> + + +