Compare commits

...

21 Commits

Author SHA1 Message Date
Milo Ivir 9270cb1a21
Translated using Weblate (Croatian)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/hr/
2023-10-05 14:10:39 +02:00
Flavio F. M f964060cd1
Translated using Weblate (Portuguese (Brazil))
Currently translated at 89.6% (26 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/pt_BR/
2023-09-29 20:02:03 +02:00
Fjuro b091d18ed2
Translated using Weblate (Czech)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/cs/
2023-09-24 11:00:00 +02:00
0que 6596556684
Translated using Weblate (Russian)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/ru/
2023-09-24 11:00:00 +02:00
jonnysemon 9c9897e528
Translated using Weblate (Arabic)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/ar/
2023-09-24 11:00:00 +02:00
ManeraKai e7d2217439 Merge branch 'master' of https://github.com/libredirect/browser_extension 2023-09-24 10:05:16 +03:00
ManeraKai f497e3d6fe
Added music.youtube.com to YouTube redirections https://github.com/libredirect/browser_extension/issues/823 2023-09-24 10:04:56 +03:00
mere 1ad221863e
Translated using Weblate (Romanian)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/ro/
2023-09-20 20:43:54 +02:00
Ihor Hordiichuk 5ef35f058f
Translated using Weblate (Ukrainian)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/uk/
2023-09-20 18:01:34 +02:00
Raymond Nee 6e4ec213e4
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/zh_Hans/
2023-09-20 18:01:34 +02:00
Heimen Stoffels 8a74756de3
Translated using Weblate (Dutch)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/nl/
2023-09-20 18:01:34 +02:00
gallegonovato ae261ff004
Translated using Weblate (Spanish)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/es/
2023-09-20 18:01:34 +02:00
josé m b01e9d3f3c
Translated using Weblate (Galician)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/gl/
2023-09-20 18:01:34 +02:00
Linerly 383b053cf8
Translated using Weblate (Indonesian)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/id/
2023-09-20 18:01:34 +02:00
Oğuz Ersen 66d74bc8b0
Translated using Weblate (Turkish)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/tr/
2023-09-20 18:01:34 +02:00
Matthaiks a8a58261ad
Translated using Weblate (Polish)
Currently translated at 100.0% (29 of 29 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/pl/
2023-09-20 18:01:34 +02:00
ManeraKai 29408760c6 Merge branch 'master' of https://github.com/libredirect/browser_extension 2023-09-19 10:39:44 +03:00
ManeraKai 98210bf264
Removed LingvaTranslate 2023-09-19 10:39:32 +03:00
xXx 6069dfc257
Translated using Weblate (Russian)
Currently translated at 100.0% (26 of 26 strings)

Translation: LibRedirect/extension
Translate-URL: https://hosted.weblate.org/projects/libredirect/extension/ru/
2023-09-18 14:02:15 +02:00
ManeraKai 2e1de247ee Add "Redirect (frontend) to Prefferred" https://github.com/libredirect/browser_extension/issues/767 2023-09-18 13:12:09 +03:00
ManeraKai f586207c43
Added cache for ping https://github.com/libredirect/browser_extension/issues/773 2023-09-17 22:49:27 +03:00
24 changed files with 267 additions and 111 deletions

View File

@ -101,5 +101,14 @@
},
"about": {
"message": "عن"
},
"unsupportedIframesHandling": {
"message": "التعامل مع إطارات iframe غير المدعومة"
},
"fetchPublicInstances": {
"message": "جلب الخوادم العامة"
},
"disable": {
"message": "عطّل"
}
}

View File

@ -99,5 +99,14 @@
},
"about": {
"message": "O rozšíření"
},
"unsupportedIframesHandling": {
"message": "Nepodporovaná manipulace s iframe"
},
"fetchPublicInstances": {
"message": "Načíst veřejné instance"
},
"disable": {
"message": "Zakázat"
}
}

View File

@ -60,7 +60,7 @@
"description": "used in the settings page"
},
"frontend": {
"message": "Frontend",
"message": "Interfaz",
"description": "used in the settings page"
},
"redirectType": {
@ -99,5 +99,14 @@
},
"about": {
"message": "Acerca de"
},
"unsupportedIframesHandling": {
"message": "Gestión de los iframes no compatibles"
},
"fetchPublicInstances": {
"message": "Recuperar las instancias públicas"
},
"disable": {
"message": "Desactivar"
}
}

View File

@ -99,5 +99,14 @@
},
"about": {
"message": "About"
},
"unsupportedIframesHandling": {
"message": "Sen soporte para a xestión de iframes"
},
"fetchPublicInstances": {
"message": "Obter instancias públicas"
},
"disable": {
"message": "Desactivar"
}
}

View File

@ -90,7 +90,7 @@
"message": "Kopirano"
},
"redirectToOriginal": {
"message": "Preusmjeri prema originalnoj",
"message": "Preusmjeri na original",
"description": "Used in context menus when right clicking on a page/tab"
},
"redirectLink": {
@ -99,5 +99,14 @@
},
"about": {
"message": "O"
},
"unsupportedIframesHandling": {
"message": "Nepodržano rukovanje iframeovima"
},
"fetchPublicInstances": {
"message": "Dohvati javne instance"
},
"disable": {
"message": "Deaktiviraj"
}
}

View File

@ -99,5 +99,14 @@
},
"about": {
"message": "Tentang"
},
"unsupportedIframesHandling": {
"message": "Penanganan iframe tifak didukung"
},
"fetchPublicInstances": {
"message": "Dapatkan server publik"
},
"disable": {
"message": "Nonaktifkan"
}
}

View File

@ -48,7 +48,7 @@
"description": "used in the settings page"
},
"resetSettings": {
"message": "Instellingen herstarten",
"message": "Standaardwaarden",
"description": "used in the settings page"
},
"enable": {
@ -99,5 +99,14 @@
},
"about": {
"message": "Over"
},
"unsupportedIframesHandling": {
"message": "Niet-ondersteunde iframes-afhandeling"
},
"fetchPublicInstances": {
"message": "Openbare instanties ophalen"
},
"disable": {
"message": "Uitschakelen"
}
}

View File

@ -99,5 +99,14 @@
},
"about": {
"message": "Informacje"
},
"unsupportedIframesHandling": {
"message": "Brak obsługi ramek iframe"
},
"fetchPublicInstances": {
"message": "Pobierz instancje publiczne"
},
"disable": {
"message": "Wyłącz"
}
}

View File

@ -90,7 +90,7 @@
"message": "Copiado"
},
"redirectToOriginal": {
"message": "Redirecionar para o original",
"message": "Redirecionar para original",
"description": "Used in context menus when right clicking on a page/tab"
},
"redirectLink": {

View File

@ -99,5 +99,14 @@
},
"about": {
"message": "About"
},
"unsupportedIframesHandling": {
"message": "Manipulare iframe neacceptată"
},
"fetchPublicInstances": {
"message": "Obține instanțe publice"
},
"disable": {
"message": "Dezactivează"
}
}

View File

@ -4,7 +4,7 @@
"description": "name of the extension"
},
"extensionDescription": {
"message": "Браузерное расширение, которое перенаправляет известные сайты на иные интерфейсы и движки, обеспечивающие конфиденциальность",
"message": "Расширение для браузера, перенаправляющее популярные сайты на обеспечивающие конфиденциальность альтернативны",
"description": "description of the extension"
},
"switchInstance": {
@ -40,11 +40,11 @@
"description": "used in the settings page"
},
"importSettings": {
"message": "Импорт настроек",
"message": "Импортировать настройки",
"description": "used in the settings page"
},
"exportSettings": {
"message": "Экспорт настроек",
"message": "Экспортировать настройки",
"description": "used in the settings page"
},
"resetSettings": {
@ -99,5 +99,14 @@
},
"about": {
"message": "О расширении"
},
"unsupportedIframesHandling": {
"message": "Обработка неподдерживаемых iframe"
},
"fetchPublicInstances": {
"message": "Получить общедоступные серверы"
},
"disable": {
"message": "Выключить"
}
}

View File

@ -99,5 +99,14 @@
},
"about": {
"message": "Hakkında"
},
"unsupportedIframesHandling": {
"message": "Desteklenmeyen iframe kullanımı"
},
"fetchPublicInstances": {
"message": "Herkese açık örnekleri getir"
},
"disable": {
"message": "Devre dışı bırak"
}
}

View File

@ -99,5 +99,14 @@
},
"about": {
"message": "Про застосунок"
},
"unsupportedIframesHandling": {
"message": "Непідтримувана обробка iframes"
},
"fetchPublicInstances": {
"message": "Отримати загальнодоступні сервери"
},
"disable": {
"message": "Вимкнути"
}
}

View File

@ -99,5 +99,14 @@
},
"about": {
"message": "关于"
},
"unsupportedIframesHandling": {
"message": "对不支持的 iframe 的处理方式"
},
"fetchPublicInstances": {
"message": "获取公共实例"
},
"disable": {
"message": "禁用"
}
}

View File

@ -179,19 +179,6 @@ function redirect(url, type, initiator, forceRedirection) {
.replace("text", "q")
return `${randomInstance}/${search}`
}
case "lingva": {
let params_arr = url.search.split("&")
params_arr[0] = params_arr[0].substring(1)
let params = {}
for (let i = 0; i < params_arr.length; i++) {
let pair = params_arr[i].split("=")
params[pair[0]] = pair[1]
}
if (params.sl && params.tl && params.text) {
return `${randomInstance}/${params.sl}/${params.tl}/${params.text}`
}
return randomInstance
}
case "osm": {
const dataLatLngRegex = /!3d(-?[0-9]{1,}.[0-9]{1,})!4d(-?[0-9]{1,}.[0-9]{1,})/
const placeRegex = /\/place\/(.*)\//
@ -601,7 +588,6 @@ async function reverse(url) {
let protocolHost = utils.protocolHost(url)
for (const service in config.services) {
let frontend = options[service].frontend
console.log(protocolHost)
if (options[frontend] == undefined) continue
if (!options[frontend].includes(protocolHost) && protocolHost != `http://${frontend}.localhost:8080`) continue
switch (service) {
@ -660,7 +646,6 @@ const defaultInstances = {
'quetre': ['https://quetre.iket.me'],
'libremdb': ['https://libremdb.iket.me'],
'simplyTranslate': ['https://simplytranslate.org'],
'lingva': ['https://lingva.ml'],
'searxng': ['https://search.bus-hit.me'],
'4get': ['https://4get.ca'],
'rimgo': ['https://rimgo.vern.cc'],

View File

@ -32,6 +32,14 @@ function getOptions() {
)
}
function getPingCache() {
return new Promise(resolve =>
browser.storage.local.get("pingCache", r => {
resolve(r.pingCache ?? {})
})
)
}
function getBlacklist(options) {
return new Promise(resolve => {
let url
@ -148,5 +156,6 @@ export default {
camelCase,
getConfig,
getOptions,
getPingCache,
ping,
}

View File

@ -18,6 +18,26 @@
}
},
"services": {
"youtubeMusic": {
"frontends": {
"hyperpipe": {
"name": "Hyperpipe",
"instanceList": true,
"url": "https://codeberg.org/Hyperpipe/Hyperpipe"
}
},
"targets": [
"^https?:\\/{2}music\\.youtube\\.com\\/"
],
"name": "YT Music",
"options": {
"enabled": false,
"frontend": "hyperpipe",
"unsupportedUrls": "bypass"
},
"imageType": "png",
"url": "https://music.youtube.com"
},
"youtube": {
"frontends": {
"invidious": {
@ -106,7 +126,8 @@
"^https?:\\/{2}(i|s)\\.ytimg.com\\/vi\\/.*\\/..*",
"^https?:\\/{2}(www\\.)?youtube.com\\/watch?v=..*",
"^https?:\\/{2}(www\\.)?youtu\\.be\\/..*",
"^https?:\\/{2}(www\\.)?(youtube|youtube-nocookie)\\.com\\/embed\\/..*"
"^https?:\\/{2}(www\\.)?(youtube|youtube-nocookie)\\.com\\/embed\\/..*",
"^https?:\\/{2}music\\.youtube\\.com\\/"
],
"name": "YouTube",
"options": {
@ -120,26 +141,6 @@
"embeddable": true,
"url": "https://youtube.com"
},
"youtubeMusic": {
"frontends": {
"hyperpipe": {
"name": "Hyperpipe",
"instanceList": true,
"url": "https://codeberg.org/Hyperpipe/Hyperpipe"
}
},
"targets": [
"^https?:\\/{2}music\\.youtube\\.com\\/"
],
"name": "YT Music",
"options": {
"enabled": false,
"frontend": "hyperpipe",
"unsupportedUrls": "bypass"
},
"imageType": "png",
"url": "https://music.youtube.com"
},
"twitter": {
"frontends": {
"nitter": {
@ -518,12 +519,6 @@
"url": "https://git.sr.ht/~metalune/simplytranslate_web",
"localhost": true
},
"lingva": {
"name": "Lingva Translate",
"instanceList": true,
"url": "https://github.com/TheDavidDelta/lingva-translate",
"localhost": true
},
"libreTranslate": {
"name": "LibreTranslate",
"instanceList": true,

View File

@ -182,21 +182,30 @@ async function loadPage(path) {
async function calcCustomInstances(frontend) {
let options = await utils.getOptions()
let customInstances = options[frontend]
const pingCache = await utils.getPingCache()
document.getElementById(frontend).getElementsByClassName("custom-checklist")[0].innerHTML = customInstances
.map(
x => `
<div>
<x>
<a href="${x}" target="_blank">${x}</a>
</x>
<button class="add clear-${x}">
<svg xmlns="https://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor">
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
</svg>
</button>
</div>
<hr>`
)
x => {
let time = pingCache[x]
let timeText = ""
if (time) {
const { color, text } = processTime(time)
timeText = `<span class="ping" style="color:${color};">${text}</span>`
}
return `<div>
<x>
<a href="${x}" target="_blank">${x}</a>
${timeText}
</x>
<button class="add clear-${x}">
<svg xmlns="https://www.w3.org/2000/svg" height="20px" viewBox="0 0 24 24" width="20px" fill="currentColor">
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
</svg>
</button>
</div>
<hr>`
})
.join("\n")
for (const item of customInstances) {
document.getElementById(frontend).getElementsByClassName(`clear-${item}`)[0].addEventListener("click", async () => {
@ -243,6 +252,8 @@ async function processCustomInstances(frontend, document) {
}
async function createList(frontend, networks, document, redirects, blacklist) {
const pingCache = await utils.getPingCache()
const options = await utils.getOptions()
for (const network in networks) {
const checklist = document.getElementById(frontend)
.getElementsByClassName(network)[0]
@ -261,7 +272,6 @@ async function createList(frontend, networks, document, redirects, blacklist) {
.placeholder = redirects[frontend].clearnet[0]
const sortedInstances = instances.sort((a, b) => blacklist.cloudflare.includes(a) && !blacklist.cloudflare.includes(b))
const options = await utils.getOptions()
const content = sortedInstances
.map(x => {
@ -270,9 +280,16 @@ async function createList(frontend, networks, document, redirects, blacklist) {
<span style="color:red;">cloudflare</span>
</a>` : ""
let time = pingCache[x]
let timeText = ""
if (time) {
const { color, text } = processTime(time)
timeText = `<span class="ping" style="color:${color};">${text}</span>`
}
const chosen = options[frontend].includes(x) ? `<span style="color:grey;">chosen</span>` : ""
const warnings = [cloudflare, chosen].join(" ")
const warnings = [cloudflare, timeText, chosen].join(" ")
return `<div class="frontend">
<x>
<a href="${x}" target="_blank">${x}</a>
@ -320,6 +337,7 @@ async function ping(frontend) {
...document.getElementById(frontend).getElementsByClassName('clearnet')[0].getElementsByTagName('x')
]
let pingCache = await utils.getPingCache()
for (const element of instanceElements) {
let span = element.getElementsByClassName('ping')[0]
if (!span) span = document.createElement('span')
@ -328,25 +346,32 @@ async function ping(frontend) {
element.appendChild(span)
const href = element.getElementsByTagName('a')[0].href
let time = await utils.ping(href)
let color
let text
if (time < 5000) {
text = `${time}ms`
if (time <= 1000) color = "green"
else if (time <= 2000) color = "orange"
}
else if (time >= 5000) {
color = "red"
if (time == 5000) text = "5000ms+"
if (time > 5000) text = `Error: ${time - 5000}`
}
else {
color = "red"
text = 'Server not found'
}
const time = await utils.ping(href)
const { color, text } = processTime(time)
span.innerHTML = `<span style="color:${color};">${text}</span>`
pingCache[element.getElementsByTagName('a')[0].innerHTML] = time
browser.storage.local.set({ pingCache })
}
}
function processTime(time) {
let text
let color
if (time < 5000) {
text = `${time}ms`
if (time <= 1000) color = "green"
else if (time <= 2000) color = "orange"
}
else if (time >= 5000) {
color = "red"
if (time == 5000) text = "5000ms+"
if (time > 5000) text = `Error: ${time - 5000}`
}
else {
color = "red"
text = 'Server not found'
}
return {
color, text
}
}

View File

@ -7,12 +7,12 @@ each val, service in services
hr
div(class="block block-option")
label(data-localise="__MSG_enable__") Enable
input(id=`${service}-enabled` type="checkbox" aria-label="Enable checkbox")
label(for=`${service}-enabled` data-localise="__MSG_enable__") Enable
input(id=`${service}-enabled` type="checkbox")
div(class="block block-option")
label(for=service data-localise="__MSG_showInPopup__") Show in popup
input(id=service type="checkbox" aria-label="Show in popup toggle")
input(id=service type="checkbox")
div(id=service+"-opacity")

View File

@ -19,19 +19,37 @@ for (const service in config.services) {
divs[service].all = allSites.getElementsByClassName(service)[0]
divs[service].current = currSite.getElementsByClassName(service)[0]
divs[service].all_toggle = allSites.getElementsByClassName(service + "-enabled")[0]
divs[service].current_toggle = currSite.getElementsByClassName(service + "-enabled")[0]
divs[service].all_toggle = allSites.getElementsByClassName(`${service}-enabled`)[0]
divs[service].all_toggle.addEventListener("change", async () => {
const options = await utils.getOptions()
options[service].enabled = divs[service].all_toggle.checked
browser.storage.local.set({ options })
})
allSites.getElementsByClassName(`${service}-change_instance`)[0].addEventListener("click", () => {
browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
if (tabs[0].url) {
const url = new URL(tabs[0].url)
browser.tabs.update({ url: await servicesHelper.switchInstance(url, service) })
}
})
})
divs[service].current_toggle = currSite.getElementsByClassName(`${service}-enabled`)[0]
divs[service].current_toggle.addEventListener("change", async () => {
const options = await utils.getOptions()
options[service].enabled = divs[service].current_toggle.checked
browser.storage.local.set({ options })
})
currSite.getElementsByClassName(`${service}-change_instance`)[0].addEventListener("click", () => {
browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
if (tabs[0].url) {
const url = new URL(tabs[0].url)
browser.tabs.update({ url: await servicesHelper.switchInstance(url, service) })
}
})
})
}
browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
@ -92,13 +110,4 @@ browser.tabs.query({ active: true, currentWindow: true }, async tabs => {
currentSiteDivider.style.display = ""
}
}
})
for (const a of document.getElementsByTagName("a")) {
a.addEventListener("click", e => {
if (!a.classList.contains("prevent")) {
browser.tabs.create({ url: a.getAttribute("href") })
e.preventDefault()
}
})
}
})

View File

@ -17,31 +17,31 @@ html(lang="en")
hr
div(class="block" id="change_instance_div" style="display: none")
button(class="title button prevent" id="change_instance")
button(class="title button bottom-button" id="change_instance")
label(data-localise="__MSG_switchInstance__") Switch Instance
svg(xmlns="http://www.w3.org/2000/svg" height="26px" width="26px" fill="currentColor")
path(d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z")
div(class="block" id="copy_original_div" title="Copy the original redirected link" style="display: none")
button(class="title button prevent" id="copy_original")
label() Copy Origin
button(class="title button bottom-button" id="copy_original")
label() Copy Original
svg(xmlns="http://www.w3.org/2000/svg" height="24px" width="24px" fill="currentColor")
path(d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z")
div(class="block" id="redirect_div" style="display: none")
button(class="title button prevent" id="redirect")
button(class="title button bottom-button" id="redirect")
label Redirect
svg(xmlns="http://www.w3.org/2000/svg" height="24" width="24" fill="currentColor")
path(d="M7 20v-9q0-.825.588-1.413Q8.175 9 9 9h8.2l-1.6-1.6L17 6l4 4-4 4-1.4-1.4 1.6-1.6H9v9Z")
div(class="block" id="redirect_to_original_div" style="display: none")
button(class="title button prevent" id="redirect_to_original")
label Redirect To Origin
button(class="title button bottom-button" id="redirect_to_original")
label Redirect To Original
svg(xmlns="http://www.w3.org/2000/svg" height="24px" width="24px" fill="currentColor")
path(d="M 17,20 V 11 Q 17,10.175 16.412,9.587 15.825,9 15,9 H 6.8 L 8.4,7.4 7,6 3,10 7,14 8.4,12.6 6.8,11 H 15 v 9 z" id="path2")
div(class="block")
button(class="title button prevent" id="more-options")
button(class="title button bottom-button" id="more-options")
label(data-localise="__MSG_settings__") Settings
svg(xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="26px" width="26px" fill="currentColor")
path(d="m9.25 22-.4-3.2q-.325-.125-.612-.3-.288-.175-.563-.375L4.7 19.375l-2.75-4.75 2.575-1.95Q4.5 12.5 4.5 12.337v-.675q0-.162.025-.337L1.95 9.375l2.75-4.75 2.975 1.25q.275-.2.575-.375.3-.175.6-.3l.4-3.2h5.5l.4 3.2q.325.125.613.3.287.175.562.375l2.975-1.25 2.75 4.75-2.575 1.95q.025.175.025.337v.675q0 .163-.05.338l2.575 1.95-2.75 4.75-2.95-1.25q-.275.2-.575.375-.3.175-.6.3l-.4 3.2Zm2.8-6.5q1.45 0 2.475-1.025Q15.55 13.45 15.55 12q0-1.45-1.025-2.475Q13.5 8.5 12.05 8.5q-1.475 0-2.488 1.025Q8.55 10.55 8.55 12q0 1.45 1.012 2.475Q10.575 15.5 12.05 15.5Z")

View File

@ -1,5 +1,5 @@
body {
width: 230px;
width: 270px;
min-height: auto;
}
@ -16,6 +16,14 @@ body {
display: flex;
margin: 0 auto;
justify-content: space-between;
}
.button svg {
width: 26px;
height: 26px;
}
.bottom-button {
width: 100%;
}
@ -33,9 +41,13 @@ div.block label {
margin: 0;
font-size: 18px;
font-weight: bold;
max-width: 160px;
max-width: 180px;
}
div.block label:hover {
cursor: pointer;
}
div.block div {
display: flex;
}

View File

@ -7,4 +7,8 @@ each _, service in services
else
img(src=`/assets/images/${service}-icon.${services[service].imageType}`)
label=services[service].name
input(class=`${service}-enabled` type="checkbox" aria-label=`${services[service].name} toggle`)
div
input(class=`${service}-enabled` type="checkbox" aria-label=`toggle ${services[service].name}`)
button(class=`${service}-change_instance title button` aria-label=`change instance for ${services[service].name}`)
svg(xmlns="http://www.w3.org/2000/svg" height="26px" width="26px" fill="currentColor")
path(d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z")

View File

@ -123,14 +123,14 @@ section.block-option h2 {
body.option {
display: flex;
padding: 40px;
width: 1150px;
width: 1160px;
}
section.links {
display: flex;
flex-wrap: wrap;
flex-direction: column;
width: 300px;
width: 350px;
max-height: 800px;
}