Use nanostores for saving instances

This commit is contained in:
Nikita Karamov 2023-03-27 20:26:49 +02:00
parent 56db514d15
commit a5314e5923
No known key found for this signature in database
GPG key ID: 41D6F71EE78E77CD
6 changed files with 57 additions and 27 deletions

View file

@ -25,7 +25,9 @@
"@astrojs/netlify": "^2.2.0", "@astrojs/netlify": "^2.2.0",
"@astrojs/node": "^5.1.0", "@astrojs/node": "^5.1.0",
"@astrojs/vercel": "^3.2.1", "@astrojs/vercel": "^3.2.1",
"astro": "^2.1.7" "@nanostores/persistent": "^0.7.0",
"astro": "^2.1.7",
"nanostores": "^0.7.4"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^18.15.10", "@types/node": "^18.15.10",

View file

@ -5,6 +5,7 @@ specifiers:
'@astrojs/netlify': ^2.2.0 '@astrojs/netlify': ^2.2.0
'@astrojs/node': ^5.1.0 '@astrojs/node': ^5.1.0
'@astrojs/vercel': ^3.2.1 '@astrojs/vercel': ^3.2.1
'@nanostores/persistent': ^0.7.0
'@types/node': ^18.15.10 '@types/node': ^18.15.10
'@typescript-eslint/eslint-plugin': ^5.57.0 '@typescript-eslint/eslint-plugin': ^5.57.0
'@typescript-eslint/parser': ^5.57.0 '@typescript-eslint/parser': ^5.57.0
@ -15,6 +16,7 @@ specifiers:
eslint-config-prettier: ^8.8.0 eslint-config-prettier: ^8.8.0
eslint-plugin-astro: ^0.26.1 eslint-plugin-astro: ^0.26.1
eslint-plugin-unicorn: ^46.0.0 eslint-plugin-unicorn: ^46.0.0
nanostores: ^0.7.4
postcss: ^8.4.21 postcss: ^8.4.21
postcss-csso: ^6.0.1 postcss-csso: ^6.0.1
prettier: ^2.8.7 prettier: ^2.8.7
@ -31,7 +33,9 @@ dependencies:
'@astrojs/netlify': 2.2.0_astro@2.1.7 '@astrojs/netlify': 2.2.0_astro@2.1.7
'@astrojs/node': 5.1.0_astro@2.1.7 '@astrojs/node': 5.1.0_astro@2.1.7
'@astrojs/vercel': 3.2.1_astro@2.1.7 '@astrojs/vercel': 3.2.1_astro@2.1.7
'@nanostores/persistent': 0.7.0_nanostores@0.7.4
astro: 2.1.7_zfwagalafqqey6uoinf67yy4wu astro: 2.1.7_zfwagalafqqey6uoinf67yy4wu
nanostores: 0.7.4
devDependencies: devDependencies:
'@types/node': 18.15.10 '@types/node': 18.15.10
@ -803,6 +807,15 @@ packages:
- supports-color - supports-color
dev: false dev: false
/@nanostores/persistent/0.7.0_nanostores@0.7.4:
resolution: {integrity: sha512-4PAInL/T1hbftZUJ0cmgdFHBMalUoq7BUXFBy7QfyMv/8X3LPTYNh/yxspL7+J+XM3UNvVI7IFRMMs6FBasjhQ==}
engines: {node: ^14.0.0 || ^16.0.0 || >=18.0.0}
peerDependencies:
nanostores: ^0.7.0
dependencies:
nanostores: 0.7.4
dev: false
/@netlify/functions/1.4.0: /@netlify/functions/1.4.0:
resolution: {integrity: sha512-gy7ULTIRroc2/jyFVGx1djCmmBMVisIwrvkqggq5B6iDcInRSy2Tpkm+V5C63hKJVkNRskKWtLQKm9ecCaQTjA==} resolution: {integrity: sha512-gy7ULTIRroc2/jyFVGx1djCmmBMVisIwrvkqggq5B6iDcInRSy2Tpkm+V5C63hKJVkNRskKWtLQKm9ecCaQTjA==}
engines: {node: '>=8.3.0'} engines: {node: '>=8.3.0'}
@ -3668,6 +3681,11 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true hasBin: true
/nanostores/0.7.4:
resolution: {integrity: sha512-MBeUVt7NBcXqh7AGT+KSr3O0X/995CZsvcP2QEMP+PXFwb07qv3Vjyq+EX0yS8f12Vv3Tn2g/BvK/OZoMhJlOQ==}
engines: {node: ^14.0.0 || ^16.0.0 || >=18.0.0}
dev: false
/napi-build-utils/1.0.2: /napi-build-utils/1.0.2:
resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==}

View file

@ -66,9 +66,10 @@ const { prefilledInstance } = Astro.props;
<script> <script>
import { extractHost, normalizeURL } from "@scripts/util"; import { extractHost, normalizeURL } from "@scripts/util";
import {
const LOCAL_STORAGE_KEY = "recentInstances"; savedInstances as instanceStore,
const RECENT_INSTANCES_SIZE = 5; saveInstance,
} from "@stores/saved-instances.ts";
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(
@ -76,22 +77,13 @@ const { prefilledInstance } = Astro.props;
) as HTMLLabelElement; ) as HTMLLabelElement;
const $instance = document.querySelector("#instance") as HTMLInputElement; const $instance = document.querySelector("#instance") as HTMLInputElement;
const getSavedInstances = (): Array<string> => { const savedInstances: Set<string> = instanceStore.get();
const storageValue = window.localStorage.getItem(LOCAL_STORAGE_KEY);
if (!storageValue) {
return [];
}
return JSON.parse(storageValue); if (savedInstances.size > 0) {
};
const savedInstances = getSavedInstances();
if (savedInstances.length > 0) {
$instanceContainer.append( $instanceContainer.append(
"Previously used: ", "Previously used: ",
...savedInstances ...[...savedInstances]
.flatMap((instance, index) => { .flatMap((instance: string, index: number) => {
if (!instance) { if (!instance) {
return []; return [];
} }
@ -117,17 +109,8 @@ const { prefilledInstance } = Astro.props;
if (formData.get("remember")) { if (formData.get("remember")) {
const instance = normalizeURL(formData.get("instance") as string); const instance = normalizeURL(formData.get("instance") as string);
const index = savedInstances.indexOf(instance);
if (index >= 0) {
savedInstances.splice(index, 1);
}
savedInstances.unshift(instance);
savedInstances.length = RECENT_INSTANCES_SIZE;
window.localStorage.setItem( saveInstance(instance);
LOCAL_STORAGE_KEY,
JSON.stringify(savedInstances),
);
} }
return true; return true;

View file

@ -0,0 +1,21 @@
import { persistentAtom } from "@nanostores/persistent";
const LOCAL_STORAGE_KEY = "recentInstances";
const RECENT_INSTANCES_SIZE = 5;
export const savedInstances = persistentAtom<Set<string>>(
LOCAL_STORAGE_KEY,
new Set(),
{
encode: (set) => JSON.stringify([...set]),
decode: (value) => new Set(JSON.parse(value)),
},
);
export const saveInstance = (instance: string) => {
savedInstances.set(
new Set(
[instance, ...savedInstances.get()].slice(0, RECENT_INSTANCES_SIZE),
),
);
};

5
svelte.config.js Normal file
View file

@ -0,0 +1,5 @@
import { vitePreprocess } from "@astrojs/svelte";
export default {
preprocess: vitePreprocess(),
};

View file

@ -8,6 +8,7 @@
"@layouts/*": ["src/layouts/*"], "@layouts/*": ["src/layouts/*"],
"@pages/*": ["src/pages/*"], "@pages/*": ["src/pages/*"],
"@scripts/*": ["src/scripts/*"], "@scripts/*": ["src/scripts/*"],
"@stores/*": ["src/stores/*"],
"@styles/*": ["src/styles/*"] "@styles/*": ["src/styles/*"]
} }
} }