fix: remove fediverse node autocomplete (CORS blocked)
nodes.fediverse.party doesn't send CORS headers, so the fetch fails from the browser. Remove autocomplete entirely — users type their instance once and localStorage remembers it.
This commit is contained in:
@@ -126,24 +126,12 @@ withBlogSidebar: true
|
|||||||
@click.outside="showModal = false">
|
@click.outside="showModal = false">
|
||||||
<h3 class="text-lg font-semibold text-surface-900 dark:text-surface-100 mb-1">Fediverse Interaction</h3>
|
<h3 class="text-lg font-semibold text-surface-900 dark:text-surface-100 mb-1">Fediverse Interaction</h3>
|
||||||
<p class="text-sm text-surface-500 dark:text-surface-400 mb-4">Enter your instance to like, boost, or reply.</p>
|
<p class="text-sm text-surface-500 dark:text-surface-400 mb-4">Enter your instance to like, boost, or reply.</p>
|
||||||
<div class="relative">
|
|
||||||
<input x-ref="instanceInput"
|
<input x-ref="instanceInput"
|
||||||
x-model="instance"
|
x-model="instance"
|
||||||
@input="filterSuggestions()"
|
|
||||||
@keydown.enter.prevent="confirm()"
|
@keydown.enter.prevent="confirm()"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="mastodon.social"
|
placeholder="mastodon.social"
|
||||||
class="w-full px-3 py-2 border border-surface-300 dark:border-surface-600 rounded-lg bg-white dark:bg-surface-700 text-surface-900 dark:text-surface-100 placeholder-surface-400 focus:outline-none focus:ring-2 focus:ring-[#a730b8] focus:border-transparent text-sm">
|
class="w-full px-3 py-2 border border-surface-300 dark:border-surface-600 rounded-lg bg-white dark:bg-surface-700 text-surface-900 dark:text-surface-100 placeholder-surface-400 focus:outline-none focus:ring-2 focus:ring-[#a730b8] focus:border-transparent text-sm">
|
||||||
{# Autocomplete suggestions #}
|
|
||||||
<ul x-show="suggestions.length > 0"
|
|
||||||
class="absolute z-10 left-0 right-0 mt-1 bg-white dark:bg-surface-700 border border-surface-200 dark:border-surface-600 rounded-lg shadow-lg max-h-48 overflow-y-auto">
|
|
||||||
<template x-for="domain in suggestions" :key="domain">
|
|
||||||
<li @click="selectSuggestion(domain)"
|
|
||||||
x-text="domain"
|
|
||||||
class="px-3 py-2 text-sm text-surface-700 dark:text-surface-200 hover:bg-surface-100 dark:hover:bg-surface-600 cursor-pointer"></li>
|
|
||||||
</template>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="flex gap-3 mt-4">
|
<div class="flex gap-3 mt-4">
|
||||||
<button @click="showModal = false"
|
<button @click="showModal = false"
|
||||||
class="flex-1 px-4 py-2 text-sm font-medium text-surface-600 dark:text-surface-300 bg-surface-100 dark:bg-surface-700 hover:bg-surface-200 dark:hover:bg-surface-600 rounded-lg transition-colors">
|
class="flex-1 px-4 py-2 text-sm font-medium text-surface-600 dark:text-surface-300 bg-surface-100 dark:bg-surface-700 hover:bg-surface-200 dark:hover:bg-surface-600 rounded-lg transition-colors">
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ document.addEventListener("alpine:init", () => {
|
|||||||
postUrl,
|
postUrl,
|
||||||
showModal: false,
|
showModal: false,
|
||||||
instance: "",
|
instance: "",
|
||||||
suggestions: [],
|
|
||||||
allNodes: null,
|
|
||||||
loading: false,
|
|
||||||
|
|
||||||
handleClick(event) {
|
handleClick(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -28,67 +25,13 @@ document.addEventListener("alpine:init", () => {
|
|||||||
|
|
||||||
openModal(prefill) {
|
openModal(prefill) {
|
||||||
this.instance = prefill || "";
|
this.instance = prefill || "";
|
||||||
this.suggestions = [];
|
|
||||||
this.showModal = true;
|
this.showModal = true;
|
||||||
this.fetchNodes();
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
const input = this.$refs.instanceInput;
|
const input = this.$refs.instanceInput;
|
||||||
if (input) input.focus();
|
if (input) input.focus();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async fetchNodes() {
|
|
||||||
const cached = sessionStorage.getItem("fediverse_nodes");
|
|
||||||
if (cached) {
|
|
||||||
try {
|
|
||||||
this.allNodes = JSON.parse(cached);
|
|
||||||
this.filterSuggestions();
|
|
||||||
return;
|
|
||||||
} catch {
|
|
||||||
// Corrupted cache, refetch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loading = true;
|
|
||||||
const controller = new AbortController();
|
|
||||||
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await fetch("https://nodes.fediverse.party/nodes.json", {
|
|
||||||
signal: controller.signal,
|
|
||||||
});
|
|
||||||
clearTimeout(timeout);
|
|
||||||
if (res.ok) {
|
|
||||||
this.allNodes = await res.json();
|
|
||||||
sessionStorage.setItem(
|
|
||||||
"fediverse_nodes",
|
|
||||||
JSON.stringify(this.allNodes),
|
|
||||||
);
|
|
||||||
this.filterSuggestions();
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// Network error or timeout — autocomplete unavailable
|
|
||||||
} finally {
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
filterSuggestions() {
|
|
||||||
const query = this.instance.trim().toLowerCase();
|
|
||||||
if (!query || !this.allNodes) {
|
|
||||||
this.suggestions = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.suggestions = this.allNodes
|
|
||||||
.filter((node) => node.toLowerCase().includes(query))
|
|
||||||
.slice(0, 8);
|
|
||||||
},
|
|
||||||
|
|
||||||
selectSuggestion(domain) {
|
|
||||||
this.instance = domain;
|
|
||||||
this.suggestions = [];
|
|
||||||
},
|
|
||||||
|
|
||||||
confirm() {
|
confirm() {
|
||||||
let domain = this.instance.trim();
|
let domain = this.instance.trim();
|
||||||
if (!domain) return;
|
if (!domain) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user