Improving popup messages
This commit is contained in:
parent
dd4b741e4a
commit
97d390737e
|
@ -6,4 +6,5 @@ package-lock.json
|
|||
.vscode
|
||||
pnpm-lock.yaml
|
||||
src/pages/options/build
|
||||
src/pages/popup/build
|
||||
src/pages/popup/build
|
||||
src/pages/messages/build
|
|
@ -14,7 +14,7 @@
|
|||
"build": "web-ext build -i pages/options_src -i pages/popup_src pages/icons -i pages/popup_src -i pages/components",
|
||||
"build_chromium": "brave-browser --pack-extension=src/ --pack-extension-key=src.pem",
|
||||
"test": "web-ext lint",
|
||||
"html": "rollup -c --config-popup && rollup -c --config-options"
|
||||
"html": "rollup -c --config-popup && rollup -c --config-options && rollup -c --config-messages"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
@ -14,6 +14,10 @@ if (process.argv.includes("--config-options")) {
|
|||
input = "src/pages/popup_src/main.js"
|
||||
output = "src/pages/popup/build/bundle.js"
|
||||
}
|
||||
else if (process.argv.includes("--config-messages")) {
|
||||
input = "src/pages/messages_src/main.js"
|
||||
output = "src/pages/messages/build/bundle.js"
|
||||
}
|
||||
|
||||
export default {
|
||||
input,
|
||||
|
|
|
@ -610,18 +610,20 @@ function redirect(url, type, originUrl, documentUrl, incognito, forceRedirection
|
|||
}
|
||||
|
||||
let instanceList = options[frontend]
|
||||
if (instanceList === undefined) break
|
||||
if (instanceList.length === 0) return "https://libredirect.invalid"
|
||||
if (instanceList === undefined) break // should not happen if settings are correct
|
||||
|
||||
if (config.services[service].frontends[frontend].localhost && options[service].instance == "localhost") {
|
||||
randomInstance = `http://${frontend}.localhost:8080`
|
||||
} else if (instanceList.length === 0) {
|
||||
return `https://no-instance.libredirect.invalid?frontend=${encodeURIComponent(frontend)}&url=${encodeURIComponent(url.href)}`
|
||||
} else {
|
||||
randomInstance = utils.getRandomInstance(instanceList)
|
||||
}
|
||||
|
||||
if (originUrl && instanceList.includes(originUrl.origin)) {
|
||||
if (type == "main_frame") return "BYPASSTAB"
|
||||
else return null
|
||||
}
|
||||
|
||||
randomInstance = utils.getRandomInstance(instanceList)
|
||||
if (config.services[service].frontends[frontend].localhost && options[service].instance == "localhost") {
|
||||
randomInstance = `http://${frontend}.localhost:8080`
|
||||
}
|
||||
break
|
||||
}
|
||||
if (!frontend) return
|
||||
|
@ -636,7 +638,7 @@ function redirect(url, type, originUrl, documentUrl, incognito, forceRedirection
|
|||
* @param {URL} documentUrl
|
||||
* @param {boolean} incognito
|
||||
* @param {boolean} forceRedirection
|
||||
* @returns {string | undefined}
|
||||
* @returns {Promise<string | undefined>}
|
||||
*/
|
||||
async function redirectAsync(url, type, originUrl, documentUrl, incognito, forceRedirection) {
|
||||
await init()
|
||||
|
@ -645,9 +647,8 @@ async function redirectAsync(url, type, originUrl, documentUrl, incognito, force
|
|||
|
||||
/**
|
||||
* @param {URL} url
|
||||
* @param {*} returnFrontend
|
||||
*/
|
||||
function computeService(url, returnFrontend) {
|
||||
function computeService(url) {
|
||||
return new Promise(async resolve => {
|
||||
const config = await utils.getConfig()
|
||||
const options = await utils.getOptions()
|
||||
|
@ -658,9 +659,7 @@ function computeService(url, returnFrontend) {
|
|||
} else {
|
||||
for (const frontend in config.services[service].frontends) {
|
||||
if (all(service, frontend, options, config).includes(utils.protocolHost(url))) {
|
||||
if (returnFrontend) resolve([service, frontend, utils.protocolHost(url)])
|
||||
else resolve(service)
|
||||
return
|
||||
return resolve(service)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -768,7 +767,7 @@ async function reverse(url) {
|
|||
}
|
||||
|
||||
const defaultInstances = {
|
||||
invidious: ["https://inv.vern.cc"],
|
||||
// invidious: ["https://inv.vern.cc"],
|
||||
materialious: ["https://app.materialio.us"],
|
||||
viewtube: ["https://viewtube.io"],
|
||||
piped: ["https://pipedapi-libre.kavin.rocks"],
|
||||
|
|
|
@ -24,7 +24,7 @@ function getNextInstance(currentInstanceUrl, instances) {
|
|||
* @param {URL} url
|
||||
*/
|
||||
function protocolHost(url) {
|
||||
url.pathname = url.pathname.replace(/\/$/, '');
|
||||
url.pathname = url.pathname.replace(/\/$/, "")
|
||||
if (url.username && url.password) return `${url.protocol}//${url.username}:${url.password}@${url.host}${url.pathname}`
|
||||
|
||||
// workaround
|
||||
|
@ -211,6 +211,55 @@ function convertMapCentre(url) {
|
|||
return { zoom, lon, lat }
|
||||
}
|
||||
|
||||
export function randomInstances(clearnet, n) {
|
||||
let instances = []
|
||||
if (n > clearnet.length) n = clearnet.length
|
||||
for (let i = 0; i < n; i++) {
|
||||
const randomNumber = Math.floor(Math.random() * clearnet.length)
|
||||
const randomInstance = clearnet[randomNumber]
|
||||
instances.push(randomInstance)
|
||||
}
|
||||
return instances
|
||||
}
|
||||
export function style(options, window) {
|
||||
const vars = cssVariables(options, window)
|
||||
return `--text: ${vars.text};
|
||||
--bg-main: ${vars.bgMain};
|
||||
--bg-secondary: ${vars.bgSecondary};
|
||||
--active: ${vars.active};
|
||||
--danger: ${vars.danger};
|
||||
--light-grey: ${vars.lightGrey};`
|
||||
}
|
||||
|
||||
function cssVariables(options, window) {
|
||||
const dark = {
|
||||
text: "#fff",
|
||||
bgMain: "#121212",
|
||||
bgSecondary: "#202020",
|
||||
active: "#fbc117",
|
||||
danger: "#f04141",
|
||||
lightGrey: "#c3c3c3",
|
||||
}
|
||||
|
||||
const light = {
|
||||
text: "black",
|
||||
bgMain: "white",
|
||||
bgSecondary: "#e4e4e4",
|
||||
active: "#fb9817",
|
||||
danger: "#f04141",
|
||||
lightGrey: "#c3c3c3",
|
||||
}
|
||||
if (options.theme == "dark") {
|
||||
return dark
|
||||
} else if (options.theme == "light") {
|
||||
return light
|
||||
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
return dark
|
||||
} else {
|
||||
return light
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
getRandomInstance,
|
||||
getNextInstance,
|
||||
|
@ -225,4 +274,6 @@ export default {
|
|||
getQuery,
|
||||
prefsEncoded,
|
||||
convertMapCentre,
|
||||
randomInstances,
|
||||
style,
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@
|
|||
],
|
||||
"name": "YouTube",
|
||||
"options": {
|
||||
"enabled": false,
|
||||
"enabled": true,
|
||||
"redirectType": "main_frame",
|
||||
"frontend": "invidious",
|
||||
"embedFrontend": "invidious",
|
||||
|
|
|
@ -67,10 +67,25 @@ browser.webRequest.onBeforeRequest.addListener(
|
|||
tabIdRedirects[details.tabId]
|
||||
)
|
||||
|
||||
if (newUrl && newUrl.startsWith("https://no-instance.libredirect.invalid")) {
|
||||
const url = new URL(newUrl)
|
||||
const frontend = url.searchParams.get("frontend")
|
||||
const oldUrl = new URL(url.searchParams.get("url"))
|
||||
|
||||
browser.tabs.update({
|
||||
url: browser.runtime.getURL(
|
||||
`/pages/messages/index.html?message=no_instance&url=${encodeURIComponent(oldUrl)}&frontend=${encodeURIComponent(frontend)}`
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
if (!newUrl) {
|
||||
const match = url.href.match(/^https?:\/{2}(.*\.)?libredirect\.invalid.*/)
|
||||
if (match) {
|
||||
browser.tabs.update({ url: browser.runtime.getURL(`/pages/messages/no_instance.html`) })
|
||||
if (url.href.match(/^https?:\/{2}(.*\.)?libredirect\.invalid.*/)) {
|
||||
browser.tabs.update({
|
||||
url: browser.runtime.getURL(
|
||||
`/pages/messages/index.html?message=disabled&url=${encodeURIComponent(url.href)}`
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,11 +19,17 @@
|
|||
padding: 10px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
button:hover:enabled {
|
||||
color: var(--active);
|
||||
}
|
||||
|
||||
button:active {
|
||||
button:active:enabled {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="../../../assets/images/libredirect.svg" />
|
||||
<title>Settings</title>
|
||||
<link rel="stylesheet" href="build/bundle.css" />
|
||||
<link rel="stylesheet" href="../fonts/styles.css" />
|
||||
<script defer src="build/bundle.js"></script>
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
</html>
|
|
@ -1,24 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link href="../stylesheets/styles.css" rel="stylesheet" />
|
||||
<title>No instances found</title>
|
||||
<style>
|
||||
#body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="body">
|
||||
<h1>LibRedirect: You have no instance selected for this frontend</h1>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,132 @@
|
|||
<script>
|
||||
const browser = window.browser || window.chrome
|
||||
|
||||
import utils from "../../assets/javascripts/utils.js"
|
||||
import { onDestroy } from "svelte"
|
||||
import servicesHelper from "../../assets/javascripts/services.js"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
import { options, config, page } from "./stores"
|
||||
import Button from "../components/Button.svelte"
|
||||
import AutoPickIcon from "../icons/AutoPickIcon.svelte"
|
||||
|
||||
let _options
|
||||
const unsubscribeOptions = options.subscribe(val => {
|
||||
if (val) {
|
||||
_options = val
|
||||
browser.storage.local.set({ options: val })
|
||||
}
|
||||
})
|
||||
|
||||
let _config
|
||||
const unsubscribeConfig = config.subscribe(val => (_config = val))
|
||||
|
||||
onDestroy(() => {
|
||||
unsubscribeOptions()
|
||||
unsubscribeConfig()
|
||||
})
|
||||
|
||||
onMount(async () => {
|
||||
let opts = await utils.getOptions()
|
||||
if (!opts) {
|
||||
await servicesHelper.initDefaults()
|
||||
opts = await utils.getOptions()
|
||||
}
|
||||
redirects = await utils.getList(opts)
|
||||
options.set(opts)
|
||||
config.set(await utils.getConfig())
|
||||
})
|
||||
|
||||
let _page
|
||||
page.subscribe(val => (_page = val))
|
||||
|
||||
let style
|
||||
$: if (_options) style = utils.style(_options, window)
|
||||
|
||||
let autoPicking = false
|
||||
let redirects
|
||||
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
const oldUrl = new URL(params.get("url"))
|
||||
|
||||
async function autoPickInstance() {
|
||||
const frontend = params.get("frontend")
|
||||
autoPicking = true
|
||||
const instances = utils.randomInstances(redirects[frontend]["clearnet"], 5)
|
||||
const pings = await Promise.all([...instances.map(async instance => [instance, await utils.ping(instance)])])
|
||||
pings.sort((a, b) => a[1] - b[1])
|
||||
console.log(pings)
|
||||
_options[frontend].push(pings[0][0])
|
||||
options.set(_options)
|
||||
autoPicking = false
|
||||
await redirectUrl()
|
||||
}
|
||||
|
||||
async function enableService() {
|
||||
const service = await servicesHelper.computeService(oldUrl)
|
||||
_options[service].enabled = true
|
||||
options.set(_options)
|
||||
await redirectUrl()
|
||||
}
|
||||
|
||||
async function redirectUrl() {
|
||||
const newUrl = await servicesHelper.redirectAsync(oldUrl, "main_frame", null, null, false, true)
|
||||
browser.tabs.update({ url: newUrl })
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if _options && _config}
|
||||
<div class="main" dir="auto" {style}>
|
||||
{#if window.location.search.includes("message=disabled")}
|
||||
<div>
|
||||
<h1>You disabled redirections for this service</h1>
|
||||
<Button on:click={enableService}>
|
||||
{browser.i18n.getMessage("enable") || "Enable"}
|
||||
</Button>
|
||||
</div>
|
||||
{:else if window.location.search.includes("message=no_instance")}
|
||||
<div>
|
||||
<h1>You have no instance selected for this frontend</h1>
|
||||
<Button on:click={autoPickInstance} disabled={autoPicking}>
|
||||
<AutoPickIcon class="margin margin_{document.body.dir}" />
|
||||
{browser.i18n.getMessage("autoPickInstance") || "Auto Pick Instance"}
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<p>Loading...</p>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.main {
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 800px;
|
||||
margin: 0;
|
||||
padding-top: 50px;
|
||||
justify-content: center;
|
||||
font-family: "Inter", sans-serif;
|
||||
box-sizing: border-box;
|
||||
font-size: 16px;
|
||||
background-color: var(--bg-main);
|
||||
color: var(--text);
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
:global(.margin) {
|
||||
margin-right: 10px;
|
||||
margin-left: 0;
|
||||
}
|
||||
:global(.margin_rtl) {
|
||||
margin-right: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,7 @@
|
|||
import App from "./App.svelte"
|
||||
|
||||
const app = new App({
|
||||
target: document.body,
|
||||
})
|
||||
|
||||
export default app
|
|
@ -0,0 +1,5 @@
|
|||
import { writable } from "svelte/store"
|
||||
|
||||
export const options = writable(null)
|
||||
export const config = writable(null)
|
||||
export const page = writable("general")
|
|
@ -2,7 +2,7 @@
|
|||
const browser = window.browser || window.chrome
|
||||
|
||||
import General from "./General/General.svelte"
|
||||
import url from './url'
|
||||
import url from "./url"
|
||||
import utils from "../../assets/javascripts/utils.js"
|
||||
import { onDestroy } from "svelte"
|
||||
import servicesHelper from "../../assets/javascripts/services.js"
|
||||
|
@ -37,51 +37,15 @@
|
|||
config.set(await utils.getConfig())
|
||||
})
|
||||
|
||||
const dark = {
|
||||
text: "#fff",
|
||||
bgMain: "#121212",
|
||||
bgSecondary: "#202020",
|
||||
active: "#fbc117",
|
||||
danger: "#f04141",
|
||||
lightGrey: "#c3c3c3",
|
||||
}
|
||||
const light = {
|
||||
text: "black",
|
||||
bgMain: "white",
|
||||
bgSecondary: "#e4e4e4",
|
||||
active: "#fb9817",
|
||||
danger: "#f04141",
|
||||
lightGrey: "#c3c3c3",
|
||||
}
|
||||
let cssVariables
|
||||
$: if (_options) {
|
||||
if (_options.theme == "dark") {
|
||||
cssVariables = dark
|
||||
} else if (_options.theme == "light") {
|
||||
cssVariables = light
|
||||
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
cssVariables = dark
|
||||
} else {
|
||||
cssVariables = light
|
||||
}
|
||||
}
|
||||
let style
|
||||
$: if (_options) style = utils.style(_options, window)
|
||||
|
||||
const dir = ["ar", "iw", "ku", "fa", "ur"].includes(browser.i18n.getUILanguage()) ? "rtl" : "ltr"
|
||||
document.body.dir = dir
|
||||
</script>
|
||||
|
||||
{#if _options && _config}
|
||||
<div
|
||||
class={dir}
|
||||
{dir}
|
||||
style="
|
||||
--text: {cssVariables.text};
|
||||
--bg-main: {cssVariables.bgMain};
|
||||
--bg-secondary: {cssVariables.bgSecondary};
|
||||
--active: {cssVariables.active};
|
||||
--danger: {cssVariables.danger};
|
||||
--light-grey: {cssVariables.lightGrey};"
|
||||
>
|
||||
<div class={dir} {dir} {style}>
|
||||
<Sidebar />
|
||||
{#if !$url.hash || $url.hash == "#general"}
|
||||
<General />
|
||||
|
|
|
@ -64,16 +64,9 @@
|
|||
pingCache[instance] = colorTime(time)
|
||||
}
|
||||
}
|
||||
function randomInstances(n) {
|
||||
let instances = []
|
||||
for (let i = 0; i < n; i++) {
|
||||
instances.push(redirects[selectedFrontend]["clearnet"][Math.floor(Math.random() * allInstances.length)])
|
||||
}
|
||||
return instances
|
||||
}
|
||||
|
||||
async function autoPickInstance() {
|
||||
const instances = randomInstances(5)
|
||||
const instances = utils.randomInstances(redirects[selectedFrontend]["clearnet"], 5)
|
||||
const myInstancesCache = []
|
||||
for (const instance of instances) {
|
||||
pingCache[instance] = { color: "lightblue", value: "pinging..." }
|
||||
|
@ -81,9 +74,7 @@
|
|||
pingCache[instance] = colorTime(time)
|
||||
myInstancesCache.push([instance, time])
|
||||
}
|
||||
myInstancesCache.sort(function (a, b) {
|
||||
return a[1] - b[1]
|
||||
})
|
||||
myInstancesCache.sort((a, b) => a[1] - b[1])
|
||||
|
||||
_options[selectedFrontend].push(myInstancesCache[0][0])
|
||||
options.set(_options)
|
||||
|
|
|
@ -38,48 +38,12 @@
|
|||
let _page
|
||||
page.subscribe(val => (_page = val))
|
||||
|
||||
const dark = {
|
||||
text: "#fff",
|
||||
bgMain: "#121212",
|
||||
bgSecondary: "#202020",
|
||||
active: "#fbc117",
|
||||
danger: "#f04141",
|
||||
lightGrey: "#c3c3c3",
|
||||
}
|
||||
const light = {
|
||||
text: "black",
|
||||
bgMain: "white",
|
||||
bgSecondary: "#e4e4e4",
|
||||
active: "#fb9817",
|
||||
danger: "#f04141",
|
||||
lightGrey: "#c3c3c3",
|
||||
}
|
||||
let cssVariables
|
||||
$: if (_options) {
|
||||
if (_options.theme == "dark") {
|
||||
cssVariables = dark
|
||||
} else if (_options.theme == "light") {
|
||||
cssVariables = light
|
||||
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
cssVariables = dark
|
||||
} else {
|
||||
cssVariables = light
|
||||
}
|
||||
}
|
||||
let style
|
||||
$: if (_options) style = utils.style(_options, window)
|
||||
</script>
|
||||
|
||||
{#if _options && _config}
|
||||
<div
|
||||
class="main"
|
||||
dir="auto"
|
||||
style="
|
||||
--text: {cssVariables.text};
|
||||
--bg-main: {cssVariables.bgMain};
|
||||
--bg-secondary: {cssVariables.bgSecondary};
|
||||
--active: {cssVariables.active};
|
||||
--danger: {cssVariables.danger};
|
||||
--light-grey: {cssVariables.lightGrey};"
|
||||
>
|
||||
<div class="main" dir="auto" {style}>
|
||||
<Buttons />
|
||||
</div>
|
||||
{:else}
|
||||
|
|
Loading…
Reference in New Issue