mirror of
https://github.com/LBRYFoundation/Watch-on-LBRY.git
synced 2025-09-04 04:45:13 +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": {
|
"background": {
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"scripts/runtimeOnStartup.js",
|
"scripts/storageSetup.js",
|
||||||
"scripts/storageOnChanged.js",
|
|
||||||
"scripts/tabOnUpdated.js"
|
"scripts/tabOnUpdated.js"
|
||||||
],
|
],
|
||||||
"persistent": false
|
"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!");
|
console.log("YouTube To LBRY finder!");
|
||||||
var ytChannelsString = "";
|
var ytChannelsString = "";
|
||||||
var lbryChannelsString = "";
|
var lbryChannelsString = "";
|
||||||
|
@ -48,7 +50,7 @@ function lbryAPIrequest() {
|
||||||
while (lbryChannelList.lastElementChild) {
|
while (lbryChannelList.lastElementChild) {
|
||||||
lbryChannelList.removeChild(lbryChannelList.lastElementChild);
|
lbryChannelList.removeChild(lbryChannelList.lastElementChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.storage.local.get('redirect', redirect => {
|
chrome.storage.local.get('redirect', redirect => {
|
||||||
validateChannels(toCheck, 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++) {
|
for (let i = 0; i < channels.length && i < requestSize; i++) {
|
||||||
channelsString += `${channelsString.length > 0 ? ',' : ''}${channels[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.open("GET", `https://api.lbry.com/yt/resolve?channel_ids={${channelsString}}`);
|
||||||
request.send();
|
request.send();
|
||||||
request.onload = () => {
|
request.onload = () => {
|
||||||
|
@ -69,7 +71,7 @@ function validateChannels(channels, redirect, validatedChannels) {
|
||||||
Object.keys(testChannels).map((testChannelKey) => {
|
Object.keys(testChannels).map((testChannelKey) => {
|
||||||
let testChannel = testChannels[testChannelKey];
|
let testChannel = testChannels[testChannelKey];
|
||||||
if (testChannel != null) {
|
if (testChannel != null) {
|
||||||
let link = `${redirect === "lbry.tv" ? "https://lbry.tv/" : "lbry://"}${testChannel}`;
|
let link = redirectDomains[redirect].prefix + testChannel;
|
||||||
validatedChannels.push(link);
|
validatedChannels.push(link);
|
||||||
let li = document.createElement('li');
|
let li = document.createElement('li');
|
||||||
let a = document.createElement('a');
|
let a = document.createElement('a');
|
||||||
|
|
Loading…
Add table
Reference in a new issue