Made Select Services searchable and with iconsk

This commit is contained in:
ManeraKai 2024-07-24 16:37:15 +03:00
parent 96a11b3270
commit 1f6859e4e6
No known key found for this signature in database
GPG Key ID: 5ABC31FFD562E337
8 changed files with 152 additions and 62 deletions

View File

@ -25,16 +25,16 @@
}, },
"homepage": "https://libredirect.github.io", "homepage": "https://libredirect.github.io",
"devDependencies": { "devDependencies": {
"prettier": "3.3.3",
"pug-cli": "^1.0.0-alpha6",
"web-ext": "^7.2.0",
"@rollup/plugin-commonjs": "^24.0.0", "@rollup/plugin-commonjs": "^24.0.0",
"@rollup/plugin-node-resolve": "^15.0.0", "@rollup/plugin-node-resolve": "^15.0.0",
"@rollup/plugin-terser": "^0.4.0", "@rollup/plugin-terser": "^0.4.0",
"prettier": "3.3.3",
"pug-cli": "^1.0.0-alpha6",
"rollup": "^3.15.0", "rollup": "^3.15.0",
"rollup-plugin-css-only": "^4.3.0", "rollup-plugin-css-only": "^4.3.0",
"rollup-plugin-svelte": "^7.1.2", "rollup-plugin-svelte": "^7.1.2",
"svelte": "^3.55.0" "svelte": "^3.55.0",
"web-ext": "^7.2.0"
}, },
"webExt": { "webExt": {
"sourceDir": "./src/", "sourceDir": "./src/",
@ -44,5 +44,8 @@
"build": { "build": {
"overwriteDest": true "overwriteDest": true
} }
},
"dependencies": {
"svelte-select": "^5.8.3"
} }
} }

View File

@ -29,7 +29,6 @@
onMount(async () => { onMount(async () => {
let opts = await utils.getOptions() let opts = await utils.getOptions()
if (!opts) { if (!opts) {
console.log("init defulats")
await servicesHelper.initDefaults() await servicesHelper.initDefaults()
opts = await utils.getOptions() opts = await utils.getOptions()
} }

View File

@ -13,6 +13,7 @@
import utils from "../../../assets/javascripts/utils" import utils from "../../../assets/javascripts/utils"
export let selectedService export let selectedService
export let selectedFrontend
let _options let _options
let _config let _config
@ -34,10 +35,10 @@
$: { $: {
allInstances = [] allInstances = []
if (_options[serviceOptions.frontend]) allInstances.push(..._options[serviceOptions.frontend]) if (_options[selectedFrontend]) allInstances.push(..._options[selectedFrontend])
if (redirects && redirects[serviceOptions.frontend]) { if (redirects && redirects[selectedFrontend]) {
for (const network in redirects[serviceOptions.frontend]) { for (const network in redirects[selectedFrontend]) {
allInstances.push(...redirects[serviceOptions.frontend][network]) allInstances.push(...redirects[selectedFrontend][network])
} }
} }
} }
@ -48,12 +49,12 @@
} }
function isCustomInstance(instance) { function isCustomInstance(instance) {
if (redirects[serviceOptions.frontend]) { if (redirects[selectedFrontend]) {
for (const network in redirects[serviceOptions.frontend]) { for (const network in redirects[selectedFrontend]) {
if (redirects[serviceOptions.frontend][network].includes(instance)) return true if (redirects[selectedFrontend][network].includes(instance)) return false
} }
} }
return false return true
} }
async function pingInstances() { async function pingInstances() {
@ -92,15 +93,15 @@
let addInstanceValue let addInstanceValue
function addInstance() { function addInstance() {
const instance = utils.protocolHost(new URL(addInstanceValue)) const instance = utils.protocolHost(new URL(addInstanceValue))
if (!_options[serviceOptions.frontend].includes(instance)) { if (!_options[selectedFrontend].includes(instance)) {
_options[serviceOptions.frontend].push(instance) _options[selectedFrontend].push(instance)
addInstanceValue = "" addInstanceValue = ""
options.set(_options) options.set(_options)
} }
} }
</script> </script>
{#if serviceConf.frontends[serviceOptions.frontend].instanceList && redirects && blacklist} {#if serviceConf.frontends[selectedFrontend].instanceList && redirects && blacklist}
<hr /> <hr />
<div dir="ltr"> <div dir="ltr">
<div class="ping"> <div class="ping">
@ -120,16 +121,14 @@
type="url" type="url"
placeholder="https://instance.com" placeholder="https://instance.com"
aria-label="Add instance input" aria-label="Add instance input"
on:keydown={e => { on:keydown={e => e.key === "Enter" && addInstance()}
if (e.key === "Enter") addInstance()
}}
/> />
<button on:click={addInstance} class="add" aria-label="Add the instance"> <button on:click={addInstance} class="add" aria-label="Add the instance">
<AddIcon /> <AddIcon />
</button> </button>
</Row> </Row>
{#each _options[serviceOptions.frontend] as instance} {#each _options[selectedFrontend] as instance}
<Row> <Row>
<span> <span>
<a href={instance} target="_blank" rel="noopener noreferrer">{instance}</a> <a href={instance} target="_blank" rel="noopener noreferrer">{instance}</a>
@ -144,9 +143,9 @@
class="add" class="add"
aria-label="Remove Instance" aria-label="Remove Instance"
on:click={() => { on:click={() => {
const index = _options[serviceOptions.frontend].indexOf(instance) const index = _options[selectedFrontend].indexOf(instance)
if (index > -1) { if (index > -1) {
_options[serviceOptions.frontend].splice(index, 1) _options[selectedFrontend].splice(index, 1)
options.set(_options) options.set(_options)
} }
}} }}
@ -156,15 +155,15 @@
</Row> </Row>
<hr /> <hr />
{/each} {/each}
<Row></Row>
{#if redirects !== "disabled" && blacklist !== "disabled"} {#if redirects !== "disabled" && blacklist !== "disabled"}
{#if redirects[serviceOptions.frontend] && redirects[serviceOptions.frontend]["clearnet"]} {#if redirects[selectedFrontend] && redirects[selectedFrontend]["clearnet"]}
{#each Object.entries(_config.networks) as [networkName, network]} {#each Object.entries(_config.networks) as [networkName, network]}
{#if redirects[serviceOptions.frontend] && redirects[serviceOptions.frontend][networkName]} {#if redirects[selectedFrontend] && redirects[selectedFrontend][networkName] && redirects[selectedFrontend][networkName].length > 0}
<Row></Row>
<Row><Label>{network.name}</Label></Row> <Row><Label>{network.name}</Label></Row>
<hr /> <hr />
{#each redirects[serviceOptions.frontend][networkName] as instance} {#each redirects[selectedFrontend][networkName] as instance}
<Row> <Row>
<span> <span>
<a href={instance} target="_blank" rel="noopener noreferrer">{instance}</a> <a href={instance} target="_blank" rel="noopener noreferrer">{instance}</a>
@ -178,7 +177,7 @@
cloudflare cloudflare
</a> </a>
{/if} {/if}
{#if _options[serviceOptions.frontend].includes(instance)} {#if _options[selectedFrontend].includes(instance)}
<span style="color:grey">chosen</span> <span style="color:grey">chosen</span>
{/if} {/if}
{#if pingCache && pingCache[instance]} {#if pingCache && pingCache[instance]}
@ -189,9 +188,9 @@
class="add" class="add"
aria-label="Add instance" aria-label="Add instance"
on:click={() => { on:click={() => {
if (_options[serviceOptions.frontend]) { if (_options[selectedFrontend]) {
if (!_options[serviceOptions.frontend].includes(instance)) { if (!_options[selectedFrontend].includes(instance)) {
_options[serviceOptions.frontend].push(instance) _options[selectedFrontend].push(instance)
options.set(_options) options.set(_options)
} }
} }

View File

@ -46,19 +46,17 @@
} }
let embeddableFrontends = [] let embeddableFrontends = []
$: (() => { $: if (serviceConf) {
if (serviceConf) { embeddableFrontends = []
embeddableFrontends = [] for (const [frontendId, frontendConf] of Object.entries(serviceConf.frontends)) {
for (const [frontendId, frontendConf] of Object.entries(serviceConf.frontends)) { if (frontendConf.embeddable && frontendConf.instanceList) {
if (frontendConf.embeddable && frontendConf.instanceList) { embeddableFrontends.push({
embeddableFrontends.push({ value: frontendId,
value: frontendId, name: frontendConf.name,
name: frontendConf.name, })
})
}
} }
} }
})() }
</script> </script>
<RowSelect <RowSelect

View File

@ -0,0 +1,37 @@
<script>
import { onDestroy } from "svelte"
export let details
import { config, options } from "../stores"
let _options
let _config
const unsubscribeOptions = options.subscribe(val => (_options = val))
const unsubscribeConfig = config.subscribe(val => (_config = val))
onDestroy(() => {
unsubscribeOptions()
unsubscribeConfig()
})
let theme
$: if (_options) {
if (_options.theme == "dark") {
theme = "dark"
} else if (_options.theme == "light") {
theme = "light"
} else if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
theme = "dark"
} else {
theme = "light"
}
}
</script>
{#if _config.services[details.value].imageType == "svgMono"}
{#if theme == "dark"}
<img src={`/assets/images/${details.value}-icon-light.svg`} alt={details.label} />
{:else}
<img src={`/assets/images/${details.value}-icon.svg`} alt={details.label} />
{/if}
{:else}
<img src={`/assets/images/${details.value}-icon.${_config.services[details.value].imageType}`} alt={details.label} />
{/if}

View File

@ -1,6 +1,4 @@
<script> <script>
let browser = window.browser || window.chrome
import Checkbox from "../components/RowCheckbox.svelte" import Checkbox from "../components/RowCheckbox.svelte"
import RowSelect from "../components/RowSelect.svelte" import RowSelect from "../components/RowSelect.svelte"
import Row from "../components/Row.svelte" import Row from "../components/Row.svelte"
@ -8,8 +6,10 @@
import Select from "../components/Select.svelte" import Select from "../components/Select.svelte"
import { options, config } from "../stores" import { options, config } from "../stores"
import RedirectType from "./RedirectType.svelte" import RedirectType from "./RedirectType.svelte"
import { onDestroy, onMount } from "svelte" import { onDestroy } from "svelte"
import Instances from "./Instances.svelte" import Instances from "./Instances.svelte"
import SvelteSelect from "svelte-select"
import ServiceIcon from "./ServiceIcon.svelte"
let _options let _options
let _config let _config
@ -22,9 +22,9 @@
}) })
let selectedService = "youtube" let selectedService = "youtube"
$: serviceConf = _config.services[selectedService] $: serviceConf = _config.services[selectedService]
$: serviceOptions = _options[selectedService] $: serviceOptions = _options[selectedService]
$: frontendWebsite = serviceConf.frontends[serviceOptions.frontend].url
</script> </script>
<div> <div>
@ -33,15 +33,26 @@
Service: Service:
<a href={serviceConf.url} target="_blank" rel="noopener noreferrer">{serviceConf.url}</a> <a href={serviceConf.url} target="_blank" rel="noopener noreferrer">{serviceConf.url}</a>
</Label> </Label>
<Select <SvelteSelect
clearable={false}
class="svelte_select"
value={selectedService} value={selectedService}
values={[ on:change={e => (selectedService = e.detail.value)}
...Object.entries(_config.services).map(([serviceId, service]) => { items={[
return { value: serviceId, name: service.name } ...Object.entries(_config.services).map(([serviceKey, service]) => {
return { value: serviceKey, label: service.name }
}), }),
]} ]}
onChange={e => (selectedService = e.target.options[e.target.options.selectedIndex].value)} >
/> <div class="slot" slot="item" let:item>
<ServiceIcon details={item} />
{item.label}
</div>
<div class="slot" slot="selection" let:selection>
<ServiceIcon details={selection} />
{selection.label}
</div>
</SvelteSelect>
</Row> </Row>
<hr /> <hr />
@ -73,9 +84,9 @@
<Row> <Row>
<Label> <Label>
Frontend: Frontend:
<a href={serviceConf.frontends[serviceOptions.frontend].url} target="_blank" rel="noopener noreferrer" <a href={frontendWebsite} target="_blank" rel="noopener noreferrer">
>{serviceConf.frontends[serviceOptions.frontend].url}</a {frontendWebsite}
> </a>
</Label> </Label>
<Select <Select
value={serviceOptions.frontend} value={serviceOptions.frontend}
@ -95,7 +106,7 @@
<RedirectType {selectedService} /> <RedirectType {selectedService} />
<RowSelect <RowSelect
label="Unsupported iframes handling" label="Unsupported embeds handling"
value={serviceOptions.unsupportedUrls} value={serviceOptions.unsupportedUrls}
onChange={e => { onChange={e => {
serviceOptions.unsupportedUrls = e.target.options[e.target.options.selectedIndex].value serviceOptions.unsupportedUrls = e.target.options[e.target.options.selectedIndex].value
@ -108,12 +119,55 @@
/> />
{#if selectedService == "search"} {#if selectedService == "search"}
<div> <Row>
Set LibRedirect as Default Search Engine. For how to do in chromium browsers, click <Label>
<a href="https://libredirect.github.io/docs.html#search_engine_chromium">here</a>. Set LibRedirect as Default Search Engine. For how to do in chromium browsers, click
</div> <a
href="https://libredirect.github.io/docs.html#search_engine_chromium"
target="_blank"
rel="noopener noreferrer"
>here
</a>.
</Label>
</Row>
{/if} {/if}
<Instances {selectedService} /> <Instances
{selectedService}
selectedFrontend={!serviceConf.frontends[serviceOptions.frontend].desktopApp ||
serviceOptions.redirectType == "main_frame"
? serviceOptions.frontend
: serviceOptions.embedFrontend}
/>
<Row></Row>
</div> </div>
</div> </div>
<style>
:global(.svelte_select) {
font-weight: bold;
--item-padding: 0 10px;
--border: none;
--border-hover: none;
--width: 210px;
--background: var(--bg-secondary);
--list-background: var(--bg-secondary);
--item-active-background: red;
--item-is-active-bg: grey;
--item-hover-bg: grey;
--item-color: var(--text); /*text color*/
}
:global(.svelte_select .slot) {
display: flex;
justify-content: start;
align-items: center;
}
:global(.svelte_select img, .svelte_select svg) {
margin-right: 10px;
height: 26px;
width: 26px;
color: var(--text);
}
</style>

View File

@ -12,7 +12,7 @@
</a> </a>
<a href="#services" on:click={() => page.set("services")} style={$page == "services" && "color: var(--active);"}> <a href="#services" on:click={() => page.set("services")} style={$page == "services" && "color: var(--active);"}>
<ServicesIcon style="margin-right: 5px" /> <ServicesIcon style="margin-right: 5px" />
<span data-localise="__MSG_general__">Services</span> <span data-localise="__MSG_services__">Services</span>
</a> </a>
<a href="https://libredirect.github.io" target="_blank" rel="noopener noreferrer"> <a href="https://libredirect.github.io" target="_blank" rel="noopener noreferrer">
<AboutIcon style="margin-right: 5px" /> <AboutIcon style="margin-right: 5px" />

View File

@ -5,7 +5,7 @@
export let ariaLabel export let ariaLabel
</script> </script>
<select bind:value={value} on:change={onChange} aria-label={ariaLabel} on:change on:contextmenu on:input> <select bind:value on:change={onChange} aria-label={ariaLabel} on:change on:contextmenu on:input>
{#each values as option} {#each values as option}
<option value={option.value}>{option.name}</option> <option value={option.value}>{option.name}</option>
{/each} {/each}