From d3fb510bbbae212c0a419730f1ad42f6e5f0a3cb Mon Sep 17 00:00:00 2001 From: Nikita Karamov Date: Fri, 17 Mar 2023 22:53:25 +0100 Subject: [PATCH] Rewrite the instance selector This commit adds a new '/api/instances' endpoint that returns the domains of the available Mastodon instances. This also changes the input field, making it accept a host rather than the full domain. --- lib/main.js | 40 ------------------ src/components/instance-select.astro | 61 ++++++++++++++++++++++++++++ src/pages/api/instances.ts | 16 ++++++++ src/pages/api/share.ts | 6 +-- src/pages/index.astro | 29 ++----------- src/styles/main.scss | 4 +- 6 files changed, 87 insertions(+), 69 deletions(-) create mode 100644 src/components/instance-select.astro create mode 100644 src/pages/api/instances.ts diff --git a/lib/main.js b/lib/main.js index 3a543e1..b3b46ed 100644 --- a/lib/main.js +++ b/lib/main.js @@ -26,13 +26,11 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -const INSTANCE_LIST_URL = "https://api.joinmastodon.org/servers"; const LOCAL_STORAGE_KEY = "recentInstances"; const RECENT_INSTANCES_SIZE = 5; const $form = document.querySelector("#js-s2f-form"); const $instance = document.querySelector("#instance"); -const $instanceDatalist = document.querySelector("#instanceDatalist"); /** * Adds missing "https://" and ending slash to the URL @@ -50,43 +48,6 @@ function normalizeUrl(url) { return url; } -function onLoadInstancesError() { - console.error("Couldn't load instance list"); -} - -function onLoadInstancesSuccess() { - if (this.status >= 400) { - return onLoadInstancesError(); - } - - const currentInstance = $instance.value; - const instanceDomains = JSON.parse(this.responseText).map( - (index) => index.domain, - ); - if (currentInstance && !instanceDomains.includes(currentInstance)) { - instanceDomains.push(currentInstance); - } - instanceDomains.sort(); - - for (const instanceDomain of instanceDomains) { - const $option = document.createElement("option"); - $option.value = normalizeUrl(instanceDomain); - $instanceDatalist.append($option); - } -} - -function loadInstances() { - if ($instanceDatalist.children.length === 0) { - const request = new XMLHttpRequest(); - - request.addEventListener("load", onLoadInstancesSuccess); - request.addEventListener("error", onLoadInstancesError); - - request.open("GET", INSTANCE_LIST_URL); - request.send(); - } -} - function getRecentInstances() { const storedValue = window.localStorage.getItem(LOCAL_STORAGE_KEY); if (!storedValue) return []; @@ -136,5 +97,4 @@ if (prefillInstance != undefined) { $instance.value = normalizeUrl(prefillInstance); } -$instance.addEventListener("focus", loadInstances); $form.addEventListener("submit", onFormSubmit); diff --git a/src/components/instance-select.astro b/src/components/instance-select.astro new file mode 100644 index 0000000..33a3089 --- /dev/null +++ b/src/components/instance-select.astro @@ -0,0 +1,61 @@ +--- +let instances; +try { + const response = await fetch(new URL("/api/instances", Astro.url)); + instances = await response.json(); +} catch { + console.error("Couln't fetch instances"); + instances = []; +} +--- + + + {instances.map((instance) => + + + + + diff --git a/src/pages/api/instances.ts b/src/pages/api/instances.ts new file mode 100644 index 0000000..0ac8d9c --- /dev/null +++ b/src/pages/api/instances.ts @@ -0,0 +1,16 @@ +import { APIRoute } from "astro"; + +export const get: APIRoute = async () => { + const response = await fetch("https://api.joinmastodon.org/servers"); + const instances = await response.json(); + + return new Response( + JSON.stringify(instances.map((instance) => instance.domain)), + { + headers: { + "Cache-Control": "s-maxage=86400, max-age=86400, public", + "Content-Type": "application/json", + }, + }, + ); +}; diff --git a/src/pages/api/share.ts b/src/pages/api/share.ts index 5a1cbfc..813a0ae 100644 --- a/src/pages/api/share.ts +++ b/src/pages/api/share.ts @@ -4,10 +4,10 @@ export const post: APIRoute = async ({ redirect, request }) => { const formData = await request.formData(); const text = (formData.get("text") as string) || ""; - const instanceURL = - (formData.get("instance") as string) || "https://mastodon.social"; + const instanceDomain = + (formData.get("instance") as string) || "mastodon.social"; - const publishUrl = new URL("/share", instanceURL); + const publishUrl = new URL("/share", `https://${instanceDomain}/`); publishUrl.search = new URLSearchParams({ text, }).toString(); diff --git a/src/pages/index.astro b/src/pages/index.astro index b608e4a..51358ac 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,4 +1,5 @@ --- +import InstanceSelect from "../components/instance-select.astro"; import "../styles/main.scss"; --- @@ -22,9 +23,7 @@ import "../styles/main.scss"; along with this program. If not, see . SPDX-License-Identifier: AGPL-3.0-or-later ---> - - +--> @@ -37,7 +36,7 @@ import "../styles/main.scss"; - - - - +