diff --git a/src/lib/components/preconnect/main.svelte b/src/lib/components/preconnect/main.svelte new file mode 100644 index 00000000..58045bc5 --- /dev/null +++ b/src/lib/components/preconnect/main.svelte @@ -0,0 +1,10 @@ + + + + + + diff --git a/src/lib/components/searchbox/main.svelte b/src/lib/components/searchbox/main.svelte index 0f16420d..f213f866 100644 --- a/src/lib/components/searchbox/main.svelte +++ b/src/lib/components/searchbox/main.svelte @@ -22,7 +22,7 @@ function handleSubmit(e) { if (query === '') { e.preventDefault(); - } else { + } else if (!loading) { loading = true; } } diff --git a/src/lib/functions/api/createurl.js b/src/lib/functions/api/createurl.js index 73f162ff..1229d97f 100644 --- a/src/lib/functions/api/createurl.js +++ b/src/lib/functions/api/createurl.js @@ -3,7 +3,7 @@ import { env } from '$env/dynamic/public'; /** * Create an API URL - * @param {string} path + * @param {string} [path] * @param {URLSearchParams} [params] * @returns {URL} */ @@ -14,7 +14,7 @@ export function createApiUrl(path, params) { throw error(500, 'PUBLIC_API_URI env is not defined'); } - const apiUrl = (apiUri.endsWith('/') ? apiUri : apiUri + '/') + path; + const apiUrl = (apiUri.endsWith('/') ? apiUri : apiUri + '/') + (path ?? ''); const urll = new URL(apiUrl); if (params) { diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 2d72037f..ae311a17 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,9 +1,12 @@ + +
diff --git a/src/routes/opensearch.xml/+server.js b/src/routes/opensearch.xml/+server.js index 94403f26..ca96f035 100644 --- a/src/routes/opensearch.xml/+server.js +++ b/src/routes/opensearch.xml/+server.js @@ -1,54 +1,72 @@ import { error } from '@sveltejs/kit'; import { env } from '$env/dynamic/public'; -/** @returns {string} */ -function getInstanceUrl() { - const instanceUri = env.PUBLIC_URI; - if (!instanceUri) { - error(500, 'PUBLIC_URI is not set'); - } +const opensearchType = 'application/opensearchdescription+xml'; - const instanceUrl = `${instanceUri}${instanceUri.endsWith('/') ? '' : '/'}`; - return instanceUrl; +/** @type {import('./$types').RequestHandler} */ +export async function GET() { + const body = getOpensearchXml('GET'); + return new Response(body, { + headers: { + 'Content-Type': opensearchType + } + }); } -/** @returns {string} */ -function getSearchUrl() { - const instanceUrl = getInstanceUrl(); - return `${instanceUrl}search`; +/** @type {import('./$types').RequestHandler} */ +export async function POST() { + const body = getOpensearchXml('POST'); + return new Response(body, { + headers: { + 'Content-Type': opensearchType + } + }); } -// function getSuggestionsUrl() { -// const instanceUrl = getInstanceUrl(); -// return `${instanceUrl}suggestions`; -// } - /** * @param {'GET' | 'POST'} opensearchMethod - The method to use for searching * @returns {string} - The OpenSearch XML body */ -function getOpenSearchXml(opensearchMethod) { +function getOpensearchXml(opensearchMethod) { const instanceName = env.PUBLIC_INSTANCE_NAME ?? 'Hearchco'; + const instanceNameShort = instanceName.slice( + 0, + instanceName.length > 16 ? 16 : instanceName.length + ); + + const description = + env.PUBLIC_DESCRIPTION ?? + 'Hearchco is a distributed and fast metasearch engine that respects your privacy.'; + const descriptionShort = description.slice( + 0, + description.length > 1024 ? 1024 : description.length + ); + + const faviconType = 'image/x-icon'; + const faviconSize = 16; + const instanceUrl = getInstanceUrl(); const searchUrl = getSearchUrl(); + const faviconUrl = getFaviconUrl(); // TODO: const suggestionsUrl = getSuggestionsUrl(); const searchUrlTag = opensearchMethod === 'GET' - ? `` - : ` + ? `` + : ` + - `; + + `; // TODO: const body = ` - ${instanceName} - Hearchco metasearch engine - Hearchco is a distributed and fast metasearch engine that respects your privacy. + ${instanceNameShort} + ${descriptionShort} UTF-8 - /favicon.svg + ${faviconUrl} ${searchUrlTag} @@ -59,24 +77,30 @@ function getOpenSearchXml(opensearchMethod) { return body; } -/** @type {import('./$types').RequestHandler} */ -export async function GET() { - const opensearchMethod = 'GET'; - const body = getOpenSearchXml(opensearchMethod); - return new Response(body, { - headers: { - 'Content-Type': 'application/opensearchdescription+xml' - } - }); +/** @returns {string} */ +function getInstanceUrl() { + const instanceUri = env.PUBLIC_URI; + if (!instanceUri) { + error(500, 'PUBLIC_URI is not set'); + } + + const instanceUrl = `${instanceUri}${instanceUri.endsWith('/') ? '' : '/'}`; + return instanceUrl; } -/** @type {import('./$types').RequestHandler} */ -export async function POST() { - const opensearchMethod = 'POST'; - const body = getOpenSearchXml(opensearchMethod); - return new Response(body, { - headers: { - 'Content-Type': 'application/opensearchdescription+xml' - } - }); +/** @returns {string} */ +function getSearchUrl() { + const instanceUrl = getInstanceUrl(); + return `${instanceUrl}search`; +} + +/** @returns {string} */ +function getFaviconUrl() { + const instanceUrl = getInstanceUrl(); + return `${instanceUrl}favicon.ico`; } + +// function getSuggestionsUrl() { +// const instanceUrl = getInstanceUrl(); +// return `${instanceUrl}suggestions`; +// }