Load and cache popular instances
This commit is contained in:
parent
870406209e
commit
e84fed7952
2 changed files with 54 additions and 3 deletions
|
@ -7,7 +7,7 @@
|
||||||
const { prefilledInstance } = Astro.props;
|
const { prefilledInstance } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<datalist id="instance-list"></datalist>
|
<datalist id="instances"></datalist>
|
||||||
<label id="s2f-instanceContainer">
|
<label id="s2f-instanceContainer">
|
||||||
Fediverse instance
|
Fediverse instance
|
||||||
<div class="instance-input">
|
<div class="instance-input">
|
||||||
|
@ -17,7 +17,7 @@ const { prefilledInstance } = Astro.props;
|
||||||
name="instance"
|
name="instance"
|
||||||
id="instance"
|
id="instance"
|
||||||
placeholder="mastodon.social"
|
placeholder="mastodon.social"
|
||||||
list="instance-list"
|
list="instances"
|
||||||
required
|
required
|
||||||
aria-describedby="https-label"
|
aria-describedby="https-label"
|
||||||
value={prefilledInstance}
|
value={prefilledInstance}
|
||||||
|
@ -67,6 +67,7 @@ const { prefilledInstance } = Astro.props;
|
||||||
<script>
|
<script>
|
||||||
import { getUrlDomain, normalizeURL } from "@scripts/util";
|
import { getUrlDomain, normalizeURL } from "@scripts/util";
|
||||||
import { $savedInstances, save } from "@stores/saved-instances";
|
import { $savedInstances, save } from "@stores/saved-instances";
|
||||||
|
import { $popularInstances } from "@stores/popular-instances";
|
||||||
|
|
||||||
const $form = document.querySelector("#js-s2f-form") as HTMLFormElement;
|
const $form = document.querySelector("#js-s2f-form") as HTMLFormElement;
|
||||||
const $instanceContainer = document.querySelector(
|
const $instanceContainer = document.querySelector(
|
||||||
|
@ -112,5 +113,17 @@ const { prefilledInstance } = Astro.props;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const instancesElement = document.querySelector("#instances");
|
||||||
|
if (instancesElement != undefined) {
|
||||||
|
$popularInstances.subscribe((instances) => {
|
||||||
|
instancesElement.replaceChildren(
|
||||||
|
...instances.map((domain) => {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = domain;
|
||||||
|
return option;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<script src="../scripts/fetch-instances.ts"></script>
|
|
||||||
|
|
38
src/stores/popular-instances.ts
Normal file
38
src/stores/popular-instances.ts
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import { persistentAtom } from "@nanostores/persistent";
|
||||||
|
import { onMount, task } from "nanostores";
|
||||||
|
|
||||||
|
const UPDATE_INTERVAL_MS = 1000 * 60 * 60 * 24; // one day
|
||||||
|
|
||||||
|
export const $popularInstances = persistentAtom<string[]>(
|
||||||
|
"popularInstances",
|
||||||
|
[],
|
||||||
|
{
|
||||||
|
encode: JSON.stringify,
|
||||||
|
decode: JSON.parse,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
export const $lastFetched = persistentAtom<Date>(
|
||||||
|
"popularInstancesLastFetched",
|
||||||
|
new Date(0),
|
||||||
|
{
|
||||||
|
encode: (date) => date.toISOString(),
|
||||||
|
decode: (encoded) => new Date(encoded),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMount($popularInstances, () => {
|
||||||
|
task(async () => {
|
||||||
|
if (Date.now() - $lastFetched.get().getTime() < UPDATE_INTERVAL_MS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch("/api/instances");
|
||||||
|
$popularInstances.set(await response.json());
|
||||||
|
$lastFetched.set(new Date());
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Could not fetch popular instances:", error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
Reference in a new issue