mirror of
https://github.com/LBRYFoundation/Watch-on-LBRY.git
synced 2025-09-02 18:25:17 +00:00
Common settings module
* settings module as single source of truth and provides utilities, defaults, constants, and typing * runtimeOnStartup and storageOnChanged were merged into storageSetup * storageSetup reworked to use settings for seamless additions * tabOnUpdated and YTtoLBRY updated to use settings for URL prefixes
This commit is contained in:
parent
468c04ba62
commit
48f88da6aa
8 changed files with 132 additions and 107 deletions
15
src/common/settings.ts
Normal file
15
src/common/settings.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
export interface LbrySettings {
|
||||
enabled: boolean
|
||||
redirect: keyof typeof redirectDomains
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: LbrySettings = { enabled: true, redirect: 'lbry.tv' };
|
||||
|
||||
export const redirectDomains = {
|
||||
'lbry.tv': { prefix: 'https://lbry.tv/', display: 'lbry.tv' },
|
||||
app: { prefix: 'lbry://', display: 'App' },
|
||||
};
|
||||
|
||||
export function getSettingsAsync<K extends Array<keyof LbrySettings>>(...keys: K): Promise<Pick<LbrySettings, K[number]>> {
|
||||
return new Promise(resolve => chrome.storage.local.get(keys, o => resolve(o as any)));
|
||||
}
|
|
@ -13,8 +13,7 @@
|
|||
],
|
||||
"background": {
|
||||
"scripts": [
|
||||
"scripts/runtimeOnStartup.js",
|
||||
"scripts/storageOnChanged.js",
|
||||
"scripts/storageSetup.js",
|
||||
"scripts/tabOnUpdated.js"
|
||||
],
|
||||
"persistent": false
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
const func = () => {
|
||||
chrome.storage.local.get(['enabled', 'redirect'], ({ enabled, redirect }) => {
|
||||
if (enabled === null || enabled === undefined) enabled = true;
|
||||
if (!redirect) redirect = 'lbry.tv';
|
||||
chrome.storage.local.set({ enabled, redirect });
|
||||
// have to set this manually as the trigger doesn't work for `onInstalled`
|
||||
chrome.browserAction.setBadgeText({ text: enabled ? 'ON' : 'OFF' });
|
||||
});
|
||||
};
|
||||
|
||||
chrome.runtime.onStartup.addListener(func);
|
||||
chrome.runtime.onInstalled.addListener(func);
|
|
@ -1,7 +0,0 @@
|
|||
chrome.storage.onChanged.addListener((changes, areaName) => {
|
||||
if (areaName !== "local") return;
|
||||
if (!changes.enabled) return;
|
||||
const { newValue } = changes.enabled;
|
||||
console.log(newValue);
|
||||
chrome.browserAction.setBadgeText({ text: newValue ? "ON" : "OFF" });
|
||||
});
|
28
src/scripts/storageSetup.ts
Normal file
28
src/scripts/storageSetup.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
import { DEFAULT_SETTINGS, LbrySettings, getSettingsAsync } from '../common/settings';
|
||||
|
||||
/** Reset settings to default value and update the browser badge text */
|
||||
async function initSettings() {
|
||||
const settings = await getSettingsAsync(...Object.keys(DEFAULT_SETTINGS) as Array<keyof LbrySettings>);
|
||||
|
||||
// get all the values that aren't set and use them as a change set
|
||||
const invalidEntries = (Object.entries(DEFAULT_SETTINGS) as Array<[keyof LbrySettings, LbrySettings[keyof LbrySettings]]>)
|
||||
.filter(([k]) => settings[k] === null || settings[k] === undefined);
|
||||
|
||||
// fix our local var and set it in storage for later
|
||||
if (invalidEntries.length > 0) {
|
||||
const changeSet = Object.fromEntries(invalidEntries);
|
||||
Object.assign(settings, changeSet);
|
||||
chrome.storage.local.set(changeSet);
|
||||
}
|
||||
|
||||
chrome.browserAction.setBadgeText({ text: settings.enabled ? 'ON' : 'OFF' });
|
||||
}
|
||||
|
||||
chrome.storage.onChanged.addListener((changes, areaName) => {
|
||||
if (areaName !== 'local' || !changes.enabled) return;
|
||||
chrome.browserAction.setBadgeText({ text: changes.enabled.newValue ? 'ON' : 'OFF' });
|
||||
});
|
||||
|
||||
|
||||
chrome.runtime.onStartup.addListener(initSettings);
|
||||
chrome.runtime.onInstalled.addListener(initSettings);
|
|
@ -1,83 +0,0 @@
|
|||
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
||||
chrome.storage.local.get(async ({ enabled }) => {
|
||||
if (!enabled) return;
|
||||
if (!changeInfo.url) return;
|
||||
if (tab.url.match(/\b(https:\/\/lbry.tv|lbry:\/\/)/g)) {
|
||||
chrome.storage.local.get('redirect', ({redirect}) => {
|
||||
var redirectTo;
|
||||
if (redirect === "app") {
|
||||
let isChannel = tab.url.match(/^(https|http):\/\/lbry.tv\/@([^?:$#@;/"<>%{}|^~[\]`])+?:[a-z0-9]{1,40}($|(?=\?))/g);
|
||||
let isClaim = tab.url.match(/^(https|http):\/\/lbry.tv\/@([^?:$#@;/"<>%{}|^~[\]`])+?:[a-z0-9]{1,40}\/([^?:$#@;/"<>%{}|^~[\]`])+?:[a-z0-9]{1,40}($|(?=\?))/g);
|
||||
|
||||
if (isChannel) {
|
||||
redirectTo = `lbry://${tab.url.match(/@([^$#@;/"<>%{}|^~[\]`])+?(?=[#:])/g)[0]}#${tab.url.match(/#([a-z0-9]{40})|:[a-z0-9]($|(?=\?))/g)[0].substr(1)}`;
|
||||
} else if (isClaim) {
|
||||
redirectTo = `lbry://${tab.url.match(/@([^$#@;/"<>%{}|^~[\]`])+?(?=[#:])/g)}#${tab.url.match(/(#([a-z0-9]{40})|:[a-z0-9])(?=\/([^$#@;/"<>%{}|^~[\]`])+?(#([a-z0-9]{40})|:[a-z0-9])($|(?=\?)))/g)[0].substr(1)}${tab.url.match(/\/([^$#@;/"<>%{}|^~[\]`])+?(?=[#:])/g)[0]}#${tab.url.match(/(#([a-z0-9]{40})|:[a-z0-9])($|(?=\?))/g)[0].substr(1)}`;
|
||||
}
|
||||
}
|
||||
|
||||
if (redirectTo) {
|
||||
chrome.tabs.update(tabId, { url: redirectTo + "?src=watch-on-lbry" });
|
||||
if (redirect === "app") {
|
||||
alert("Opened link in LBRY App!"); // Better for UX since sometimes LBRY App doesn't take focus, if that is fixed, this can be removed
|
||||
|
||||
// Close tab if it lacks history and go back if it does
|
||||
chrome.tabs.executeScript(tabId, {
|
||||
code: `
|
||||
if (window.history.length === 1) {
|
||||
window.close();
|
||||
} else {
|
||||
window.history.back();
|
||||
}`
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
const { id, type } = getId(tab.url);
|
||||
if (!id) return;
|
||||
|
||||
const url = `https://api.lbry.com/yt/resolve?${type}_ids=${id}`;
|
||||
const response = await fetch(url, { headers: { 'Content-Type': 'application/json' } });
|
||||
const json = await response.json();
|
||||
console.log(json);
|
||||
const title = json.data[`${type}s`][id];
|
||||
if (!title) return;
|
||||
console.log(title);
|
||||
|
||||
chrome.storage.local.get('redirect', ({ redirect }) => {
|
||||
console.log(redirect);
|
||||
let newUrl;
|
||||
if (redirect === "lbry.tv") {
|
||||
newUrl = `https://lbry.tv/${title.replace(/^lbry:\/\//, "").replace(/#/g, ":")}?src=watch-on-lbry`;
|
||||
} else if (redirect === "app") {
|
||||
newUrl = `lbry://${title.replace(/^lbry:\/\//, "")}`;
|
||||
}
|
||||
chrome.tabs.update(tabId, { url: newUrl });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getId(url) {
|
||||
const videoId = getVideoId(url);
|
||||
if (videoId) return { id: videoId, type: "video" };
|
||||
const channelId = getChannelId(url);
|
||||
if (channelId) return { id: channelId, type: "channel" };
|
||||
return {}; // Equivalent of returning null
|
||||
}
|
||||
|
||||
function getVideoId(url) {
|
||||
const regex = /watch\/?\?.*v=([^\s&]*)/;
|
||||
const match = url.match(regex);
|
||||
return match ? match[1] : null; // match[1] is the videoId
|
||||
}
|
||||
|
||||
function getChannelId(url) {
|
||||
const regex = /channel\/([^\s?]*)/;
|
||||
const match = url.match(regex);
|
||||
return match ? match[1] : null; // match[1] is the channelId
|
||||
}
|
||||
|
||||
function getNewUrl(title) {
|
||||
}
|
83
src/scripts/tabOnUpdated.ts
Normal file
83
src/scripts/tabOnUpdated.ts
Normal file
|
@ -0,0 +1,83 @@
|
|||
import { getSettingsAsync, redirectDomains } from "../common/settings";
|
||||
|
||||
chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, { url: tabUrl }) => {
|
||||
const { enabled, redirect } = await getSettingsAsync('enabled', 'redirect');
|
||||
const urlPrefix = redirectDomains[redirect].prefix;
|
||||
|
||||
if (!enabled || !changeInfo.url || !tabUrl) return;
|
||||
if (tabUrl.match(/\b(https:\/\/lbry.tv|lbry:\/\/)/g)) {
|
||||
|
||||
var redirectTo;
|
||||
if (redirect === "app") {
|
||||
let isChannel = tabUrl.match(/^(https|http):\/\/lbry.tv\/@([^?:$#@;/"<>%{}|^~[\]`])+?:[a-z0-9]{1,40}($|(?=\?))/g);
|
||||
let isClaim = tabUrl.match(/^(https|http):\/\/lbry.tv\/@([^?:$#@;/"<>%{}|^~[\]`])+?:[a-z0-9]{1,40}\/([^?:$#@;/"<>%{}|^~[\]`])+?:[a-z0-9]{1,40}($|(?=\?))/g);
|
||||
|
||||
if (isChannel) {
|
||||
redirectTo = `lbry://${tabUrl.match(/@([^$#@;/"<>%{}|^~[\]`])+?(?=[#:])/g)![0]}#${tabUrl.match(/#([a-z0-9]{40})|:[a-z0-9]($|(?=\?))/g)![0].substr(1)}`;
|
||||
} else if (isClaim) {
|
||||
redirectTo = `lbry://${tabUrl.match(/@([^$#@;/"<>%{}|^~[\]`])+?(?=[#:])/g)}#${tabUrl.match(/(#([a-z0-9]{40})|:[a-z0-9])(?=\/([^$#@;/"<>%{}|^~[\]`])+?(#([a-z0-9]{40})|:[a-z0-9])($|(?=\?)))/g)![0].substr(1)}${tabUrl.match(/\/([^$#@;/"<>%{}|^~[\]`])+?(?=[#:])/g)![0]}#${tabUrl.match(/(#([a-z0-9]{40})|:[a-z0-9])($|(?=\?))/g)![0].substr(1)}`;
|
||||
}
|
||||
}
|
||||
|
||||
if (redirectTo) {
|
||||
chrome.tabs.update(tabId, { url: redirectTo + "?src=watch-on-lbry" });
|
||||
if (redirect === "app") {
|
||||
alert("Opened link in LBRY App!"); // Better for UX since sometimes LBRY App doesn't take focus, if that is fixed, this can be removed
|
||||
|
||||
// Close tab if it lacks history and go back if it does
|
||||
chrome.tabs.executeScript(tabId, {
|
||||
code: `
|
||||
if (window.history.length === 1) {
|
||||
window.close();
|
||||
} else {
|
||||
window.history.back();
|
||||
}`
|
||||
});
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
const { id, type } = getId(tabUrl);
|
||||
if (!id) return;
|
||||
|
||||
const url = `https://api.lbry.com/yt/resolve?${type}_ids=${id}`;
|
||||
const response = await fetch(url, { headers: { 'Content-Type': 'application/json' } });
|
||||
const json = await response.json();
|
||||
console.log(json);
|
||||
const title = json.data[`${type}s`][id];
|
||||
if (!title) return;
|
||||
console.log(title);
|
||||
|
||||
|
||||
console.log(redirect);
|
||||
let newUrl;
|
||||
if (redirect === "lbry.tv") {
|
||||
newUrl = `${urlPrefix}${title.replace(/^lbry:\/\//, "").replace(/#/g, ":")}?src=watch-on-lbry`;
|
||||
} else if (redirect === "app") {
|
||||
newUrl = `lbry://${title.replace(/^lbry:\/\//, "")}`;
|
||||
}
|
||||
chrome.tabs.update(tabId, { url: newUrl });
|
||||
});
|
||||
|
||||
function getId(url) {
|
||||
const videoId = getVideoId(url);
|
||||
if (videoId) return { id: videoId, type: "video" };
|
||||
const channelId = getChannelId(url);
|
||||
if (channelId) return { id: channelId, type: "channel" };
|
||||
return {}; // Equivalent of returning null
|
||||
}
|
||||
|
||||
function getVideoId(url) {
|
||||
const regex = /watch\/?\?.*v=([^\s&]*)/;
|
||||
const match = url.match(regex);
|
||||
return match ? match[1] : null; // match[1] is the videoId
|
||||
}
|
||||
|
||||
function getChannelId(url) {
|
||||
const regex = /channel\/([^\s?]*)/;
|
||||
const match = url.match(regex);
|
||||
return match ? match[1] : null; // match[1] is the channelId
|
||||
}
|
||||
|
||||
function getNewUrl(title) {
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import { redirectDomains } from '../common/settings'
|
||||
|
||||
console.log("YouTube To LBRY finder!");
|
||||
var ytChannelsString = "";
|
||||
var lbryChannelsString = "";
|
||||
|
@ -48,7 +50,7 @@ function lbryAPIrequest() {
|
|||
while (lbryChannelList.lastElementChild) {
|
||||
lbryChannelList.removeChild(lbryChannelList.lastElementChild);
|
||||
}
|
||||
|
||||
|
||||
chrome.storage.local.get('redirect', redirect => {
|
||||
validateChannels(toCheck, redirect.redirect, []);
|
||||
});
|
||||
|
@ -60,7 +62,7 @@ function validateChannels(channels, redirect, validatedChannels) {
|
|||
for (let i = 0; i < channels.length && i < requestSize; i++) {
|
||||
channelsString += `${channelsString.length > 0 ? ',' : ''}${channels[i]}`
|
||||
}
|
||||
request = new XMLHttpRequest();
|
||||
request = new XMLHttpRequest();
|
||||
request.open("GET", `https://api.lbry.com/yt/resolve?channel_ids={${channelsString}}`);
|
||||
request.send();
|
||||
request.onload = () => {
|
||||
|
@ -69,7 +71,7 @@ function validateChannels(channels, redirect, validatedChannels) {
|
|||
Object.keys(testChannels).map((testChannelKey) => {
|
||||
let testChannel = testChannels[testChannelKey];
|
||||
if (testChannel != null) {
|
||||
let link = `${redirect === "lbry.tv" ? "https://lbry.tv/" : "lbry://"}${testChannel}`;
|
||||
let link = redirectDomains[redirect].prefix + testChannel;
|
||||
validatedChannels.push(link);
|
||||
let li = document.createElement('li');
|
||||
let a = document.createElement('a');
|
||||
|
|
Loading…
Add table
Reference in a new issue