diff options
| author | Adam Soltys <[email protected]> | 2026-02-28 14:14:53 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-02-28 14:14:53 -0800 |
| commit | dc92cf377f52e5f165020ea5a8407a14d279264c (patch) | |
| tree | db2f11aa25c4cc0ec721ef048a4157d9512d2b55 /src | |
| parent | e6de3a1b76104790a216533db9077c35bcd104b1 (diff) | |
| download | coinos-ui-dc92cf377f52e5f165020ea5a8407a14d279264c.tar.gz coinos-ui-dc92cf377f52e5f165020ea5a8407a14d279264c.zip | |
store ark state
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/LocationsMap.svelte | 47 | ||||
| -rw-r--r-- | src/hooks.server.ts | 13 | ||||
| -rw-r--r-- | src/lib/ark.ts | 111 | ||||
| -rw-r--r-- | src/locales/ar.json | 17 | ||||
| -rw-r--r-- | src/locales/bn.json | 17 | ||||
| -rw-r--r-- | src/locales/de.json | 17 | ||||
| -rw-r--r-- | src/locales/el.json | 17 | ||||
| -rw-r--r-- | src/locales/en.json | 17 | ||||
| -rw-r--r-- | src/locales/es.json | 17 | ||||
| -rw-r--r-- | src/locales/fa.json | 17 | ||||
| -rw-r--r-- | src/locales/fr.json | 17 | ||||
| -rw-r--r-- | src/locales/hi.json | 17 | ||||
| -rw-r--r-- | src/locales/it.json | 17 | ||||
| -rw-r--r-- | src/locales/ja.json | 17 | ||||
| -rw-r--r-- | src/locales/ko.json | 17 | ||||
| -rw-r--r-- | src/locales/nl.json | 17 | ||||
| -rw-r--r-- | src/locales/pl.json | 17 | ||||
| -rw-r--r-- | src/locales/pt.json | 17 | ||||
| -rw-r--r-- | src/locales/ru.json | 17 | ||||
| -rw-r--r-- | src/locales/th.json | 17 | ||||
| -rw-r--r-- | src/locales/tr.json | 17 | ||||
| -rw-r--r-- | src/locales/zh.json | 17 | ||||
| -rw-r--r-- | src/routes/(static)/login/+page.svelte | 6 | ||||
| -rw-r--r-- | src/routes/(static)/register/auth/+page.svelte | 6 |
24 files changed, 483 insertions, 23 deletions
diff --git a/src/components/LocationsMap.svelte b/src/components/LocationsMap.svelte index cd6bd69f..7529edcb 100644 --- a/src/components/LocationsMap.svelte +++ b/src/components/LocationsMap.svelte @@ -102,22 +102,31 @@ if (showFilters) showList = false; }; - const categoryLabels: { slug: string; name: string }[] = [ - { slug: "restaurant", name: "Restaurant" }, - { slug: "cafe", name: "Café" }, - { slug: "bar", name: "Bar" }, - { slug: "fast-food", name: "Fast Food" }, - { slug: "grocery", name: "Grocery" }, - { slug: "hairdresser", name: "Hairdresser" }, - { slug: "hotel", name: "Hotel" }, - { slug: "shop", name: "Shop" }, - { slug: "atm", name: "ATM" }, - { slug: "health", name: "Health" }, - { slug: "office", name: "Office" }, - { slug: "default", name: "Other" }, + const categorySlugs = [ + "restaurant", "cafe", "bar", "fast-food", "grocery", "hairdresser", + "hotel", "shop", "atm", "health", "office", "default", ]; - let activeFilters: Set<string> = $state(new Set(categoryLabels.map((c) => c.slug))); + const categoryTranslationKeys: Record<string, string> = { + "restaurant": "map.restaurant", + "cafe": "map.cafe", + "bar": "map.bar", + "fast-food": "map.fastFood", + "grocery": "map.grocery", + "hairdresser": "map.hairdresser", + "hotel": "map.hotel", + "shop": "map.shop", + "atm": "map.atm", + "health": "map.health", + "office": "map.office", + "default": "map.other", + }; + + let categoryLabels = $derived( + categorySlugs.map((slug) => ({ slug, name: $t(categoryTranslationKeys[slug]) })) + ); + + let activeFilters: Set<string> = $state(new Set(categorySlugs)); let lastToggledOn: string | undefined = $state(); @@ -141,7 +150,7 @@ } function setAllFilters() { - activeFilters = new Set(categoryLabels.map((c) => c.slug)); + activeFilters = new Set(categorySlugs); } function clearAllFilters() { @@ -565,7 +574,7 @@ : inview, ); - let categoryLabelMap = Object.fromEntries(categoryLabels.map((c) => [c.slug, c.name])); + let categoryLabelMap = $derived(Object.fromEntries(categoryLabels.map((c) => [c.slug, c.name]))); let presentCategories = $derived( categoryLabels.filter((c) => inview.some((m) => m.category === c.slug)), @@ -609,7 +618,7 @@ <div class="flex flex-col w-[300px] max-w-[calc(100vw*0.5)] absolute right-4 bottom-8 bg-base-100/90 rounded-2xl shadow overflow-hidden"> <div class="flex items-center gap-2 p-3"> <div class="relative flex-1"> - <input bind:value={search} placeholder="Search locations..." class="w-full border border-base-300 rounded-lg pl-3 pr-8 py-2 text-sm" /> + <input bind:value={search} placeholder={$t("map.searchLocations")} class="w-full border border-base-300 rounded-lg pl-3 pr-8 py-2 text-sm" /> <div class="flex items-center absolute right-2 top-1/2 -translate-y-1/2"> {#if search} <button type="button" onclick={clearSearch} aria-label="Clear"> @@ -664,11 +673,11 @@ <button onclick={setAllFilters} class="text-xs px-3 py-1 rounded-full border border-primary bg-primary text-white" - >All</button> + >{$t("map.all")}</button> <button onclick={clearAllFilters} class="text-xs px-3 py-1 rounded-full border border-primary" - >None</button> + >{$t("map.none")}</button> <button onclick={() => showFilters = false} aria-label="Close" class="ml-auto opacity-40 hover:opacity-100"> <iconify-icon noobserver icon="ph:x-bold" width="18"></iconify-icon> </button> diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 780e62ad..1bb8e132 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -5,10 +5,17 @@ import type { Handle } from "@sveltejs/kit"; setIpGetter(() => ipStore.getStore()); export const handle: Handle = async ({ event, resolve }) => { - const ip = + let ip = event.request.headers.get("cf-connecting-ip") || - event.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || - event.getClientAddress(); + event.request.headers.get("x-forwarded-for")?.split(",")[0]?.trim(); + + if (!ip) { + try { + ip = event.getClientAddress(); + } catch { + ip = "127.0.0.1"; + } + } return ipStore.run(ip, () => resolve(event)); }; diff --git a/src/lib/ark.ts b/src/lib/ark.ts index 2f1595a1..1a779f32 100644 --- a/src/lib/ark.ts +++ b/src/lib/ark.ts @@ -10,6 +10,34 @@ export const arkServerUrl = { export const arkkey = persistLocal("arkkey", ""); export const arkaid = persistLocal("arkaid", ""); +interface SerializedVtxo { + txid: string; + vout: number; + value: number; + status: { confirmed: boolean; isLeaf?: boolean }; + virtualStatus: { + state: "preconfirmed" | "settled" | "swept" | "spent"; + commitmentTxIds?: string[]; + batchExpiry?: number; + }; + spentBy?: string; + settledBy?: string; + arkTxId?: string; + createdAt: string; + isUnrolled: boolean; + isSpent?: boolean; +} + +interface ArkVaultSnapshot { + version: 1; + cachedAt: string; + arkServerUrl: string; + arkInfoRaw: Record<string, any>; + vtxos: SerializedVtxo[]; + vtxoChains: Record<string, { chain: any[] }>; + virtualTxs: Record<string, string>; +} + let arkSdkPromise: Promise<typeof import("@arkade-os/sdk")> | undefined; const loadArkSdk = () => (arkSdkPromise ||= import("@arkade-os/sdk")); @@ -41,6 +69,85 @@ const toHex = (bytes: Uint8Array) => .map((b) => b.toString(16).padStart(2, "0")) .join(""); +export async function cacheVaultSnapshot() { + try { + const wallet = await getWallet(); + if (!wallet) return; + + const infoRes = await fetch(`${arkServerUrl}/v1/info`); + if (!infoRes.ok) return; + const arkInfoRaw = await infoRes.json(); + + const script = toHex(wallet.offchainTapscript.pkScript); + const vtxosResponse = await wallet.indexerProvider.getVtxos({ scripts: [script] }); + const vtxos = vtxosResponse.vtxos; + + const spendable = vtxos.filter( + (v: any) => !v.isSpent && v.virtualStatus.state !== "spent", + ); + + const vtxoChains: Record<string, { chain: any[] }> = {}; + const allNonCommitmentTxids = new Set<string>(); + + for (const vtxo of spendable) { + const key = `${vtxo.txid}:${vtxo.vout}`; + const chainData = await wallet.indexerProvider.getVtxoChain({ + txid: vtxo.txid, + vout: vtxo.vout, + }); + vtxoChains[key] = { chain: chainData.chain }; + + for (const tx of chainData.chain) { + if ( + tx.type !== "INDEXER_CHAINED_TX_TYPE_COMMITMENT" && + tx.type !== "INDEXER_CHAINED_TX_TYPE_UNSPECIFIED" + ) { + allNonCommitmentTxids.add(tx.txid); + } + } + } + + const virtualTxs: Record<string, string> = {}; + const txidArray = Array.from(allNonCommitmentTxids); + if (txidArray.length > 0) { + const result = await wallet.indexerProvider.getVirtualTxs(txidArray); + for (let i = 0; i < txidArray.length; i++) { + virtualTxs[txidArray[i]] = result.txs[i]; + } + } + + const serializedVtxos: SerializedVtxo[] = vtxos.map((v: any) => ({ + txid: v.txid, + vout: v.vout, + value: v.value, + status: v.status, + virtualStatus: v.virtualStatus, + spentBy: v.spentBy, + settledBy: v.settledBy, + arkTxId: v.arkTxId, + createdAt: v.createdAt instanceof Date ? v.createdAt.toISOString() : String(v.createdAt), + isUnrolled: v.isUnrolled, + isSpent: v.isSpent, + })); + + const snapshot: ArkVaultSnapshot = { + version: 1, + cachedAt: new Date().toISOString(), + arkServerUrl: arkServerUrl!, + arkInfoRaw, + vtxos: serializedVtxos, + vtxoChains, + virtualTxs, + }; + + const uid = localStorage.getItem("arkkey:uid"); + const key = uid ? `arkVaultSnapshot:${uid}` : "arkVaultSnapshot"; + localStorage.setItem(key, JSON.stringify(snapshot)); + } catch (e) { + console.error("[ark] snapshot cache failed:", e); + } +} + export const subscribeToAsp = (onEvent: () => void) => { let es: EventSource | null = null; let subId: string | null = null; @@ -171,7 +278,9 @@ const _syncTransactions = async (aid: string) => { const bal = await wallet.getBalance(); const balance = (bal.available || 0) + (bal.preconfirmed || 0); - return post("/post/ark/sync", { transactions, aid, balance }); + const result = await post("/post/ark/sync", { transactions, aid, balance }); + cacheVaultSnapshot(); // fire-and-forget + return result; }; export const syncTransactions = async (aid: string) => { diff --git a/src/locales/ar.json b/src/locales/ar.json index 8d7dfb57..70452c10 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -671,5 +671,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "البحث عن مواقع...", + "all": "الكل", + "none": "لا شيء", + "restaurant": "مطعم", + "cafe": "مقهى", + "bar": "بار", + "fastFood": "وجبات سريعة", + "grocery": "بقالة", + "hairdresser": "حلاق", + "hotel": "فندق", + "shop": "متجر", + "atm": "صراف آلي", + "health": "صحة", + "office": "مكتب", + "other": "أخرى" } } diff --git a/src/locales/bn.json b/src/locales/bn.json index c28d34a0..dde42680 100644 --- a/src/locales/bn.json +++ b/src/locales/bn.json @@ -671,5 +671,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "অবস্থান অনুসন্ধান করুন...", + "all": "সব", + "none": "কিছুই না", + "restaurant": "রেস্তোরাঁ", + "cafe": "ক্যাফে", + "bar": "বার", + "fastFood": "ফাস্ট ফুড", + "grocery": "মুদি দোকান", + "hairdresser": "নাপিত", + "hotel": "হোটেল", + "shop": "দোকান", + "atm": "এটিএম", + "health": "স্বাস্থ্য", + "office": "অফিস", + "other": "অন্যান্য" } } diff --git a/src/locales/de.json b/src/locales/de.json index e99b8130..84c7dcc6 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -700,5 +700,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "Standorte suchen...", + "all": "Alle", + "none": "Keine", + "restaurant": "Restaurant", + "cafe": "Café", + "bar": "Bar", + "fastFood": "Schnellimbiss", + "grocery": "Lebensmittel", + "hairdresser": "Friseur", + "hotel": "Hotel", + "shop": "Geschäft", + "atm": "Geldautomat", + "health": "Gesundheit", + "office": "Büro", + "other": "Sonstiges" } } diff --git a/src/locales/el.json b/src/locales/el.json index bc17abc0..4e4580d6 100644 --- a/src/locales/el.json +++ b/src/locales/el.json @@ -691,5 +691,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "Αναζήτηση τοποθεσιών...", + "all": "Όλα", + "none": "Κανένα", + "restaurant": "Εστιατόριο", + "cafe": "Καφετέρια", + "bar": "Μπαρ", + "fastFood": "Φαστ Φουντ", + "grocery": "Παντοπωλείο", + "hairdresser": "Κομμωτήριο", + "hotel": "Ξενοδοχείο", + "shop": "Κατάστημα", + "atm": "ATM", + "health": "Υγεία", + "office": "Γραφείο", + "other": "Άλλο" } } diff --git a/src/locales/en.json b/src/locales/en.json index ae5a56f0..d4feb73e 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -135,6 +135,23 @@ "description": "Over 500 businesses worldwide are accepting bitcoin with Coinos. We hope that yours will be next!" } }, + "map": { + "searchLocations": "Search locations...", + "all": "All", + "none": "None", + "restaurant": "Restaurant", + "cafe": "Café", + "bar": "Bar", + "fastFood": "Fast Food", + "grocery": "Grocery", + "hairdresser": "Hairdresser", + "hotel": "Hotel", + "shop": "Shop", + "atm": "ATM", + "health": "Health", + "office": "Office", + "other": "Other" + }, "mapAdd": { "header": "Add your location", "description": "Coinos pulls merchant locations from OpenStreetMap. To add your business to our map, follow these steps:", diff --git a/src/locales/es.json b/src/locales/es.json index dba0385a..252e42b1 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -673,5 +673,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "Buscar ubicaciones...", + "all": "Todos", + "none": "Ninguno", + "restaurant": "Restaurante", + "cafe": "Café", + "bar": "Bar", + "fastFood": "Comida rápida", + "grocery": "Supermercado", + "hairdresser": "Peluquería", + "hotel": "Hotel", + "shop": "Tienda", + "atm": "Cajero", + "health": "Salud", + "office": "Oficina", + "other": "Otro" } } diff --git a/src/locales/fa.json b/src/locales/fa.json index 9e13cdc2..f3493c6e 100644 --- a/src/locales/fa.json +++ b/src/locales/fa.json @@ -673,5 +673,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "جستجوی مکانها...", + "all": "همه", + "none": "هیچ", + "restaurant": "رستوران", + "cafe": "کافه", + "bar": "بار", + "fastFood": "فست فود", + "grocery": "سوپرمارکت", + "hairdresser": "آرایشگاه", + "hotel": "هتل", + "shop": "فروشگاه", + "atm": "خودپرداز", + "health": "سلامت", + "office": "دفتر", + "other": "سایر" } } diff --git a/src/locales/fr.json b/src/locales/fr.json index b84c48db..c781d212 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -673,5 +673,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "Rechercher des lieux...", + "all": "Tous", + "none": "Aucun", + "restaurant": "Restaurant", + "cafe": "Café", + "bar": "Bar", + "fastFood": "Restauration rapide", + "grocery": "Épicerie", + "hairdresser": "Coiffeur", + "hotel": "Hôtel", + "shop": "Boutique", + "atm": "Distributeur", + "health": "Santé", + "office": "Bureau", + "other": "Autre" } } diff --git a/src/locales/hi.json b/src/locales/hi.json index 8f24ab9c..84b3876e 100644 --- a/src/locales/hi.json +++ b/src/locales/hi.json @@ -671,5 +671,22 @@ "noRelaysSet": "चेतावनी: आपने कोई पसंदीदा रिले निर्धारित नहीं किया है। आप किसी भी संदेश प्राप्त करने में सक्षम नहीं होंगे या आपके द्वारा भेजे गए संदेशों को देखने में सक्षम होंगे।.", "nostrSettingsLink": "अपने रिले सेट करने के लिए अपने नोस्ट्र सेटिंग पर जाएं।.", "anonymous": "अनाम" + }, + "map": { + "searchLocations": "स्थान खोजें...", + "all": "सभी", + "none": "कोई नहीं", + "restaurant": "रेस्तरां", + "cafe": "कैफ़े", + "bar": "बार", + "fastFood": "फ़ास्ट फ़ूड", + "grocery": "किराना", + "hairdresser": "नाई", + "hotel": "होटल", + "shop": "दुकान", + "atm": "एटीएम", + "health": "स्वास्थ्य", + "office": "कार्यालय", + "other": "अन्य" } } diff --git a/src/locales/it.json b/src/locales/it.json index ba332eeb..514b4e56 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -671,5 +671,22 @@ "noRelaysSet": "ATTENZIONE: Non hai impostato alcun relè preferito. Non potrai ricevere messaggi o vedere i messaggi che hai inviato.", "nostrSettingsLink": "Vai alle impostazioni Nostr per impostare i relè.", "anonymous": "Anonimo" + }, + "map": { + "searchLocations": "Cerca luoghi...", + "all": "Tutti", + "none": "Nessuno", + "restaurant": "Ristorante", + "cafe": "Caffè", + "bar": "Bar", + "fastFood": "Fast Food", + "grocery": "Alimentari", + "hairdresser": "Parrucchiere", + "hotel": "Hotel", + "shop": "Negozio", + "atm": "Bancomat", + "health": "Salute", + "office": "Ufficio", + "other": "Altro" } } diff --git a/src/locales/ja.json b/src/locales/ja.json index d80ace25..25724bbb 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -673,5 +673,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "場所を検索...", + "all": "すべて", + "none": "なし", + "restaurant": "レストラン", + "cafe": "カフェ", + "bar": "バー", + "fastFood": "ファストフード", + "grocery": "食料品店", + "hairdresser": "美容院", + "hotel": "ホテル", + "shop": "ショップ", + "atm": "ATM", + "health": "医療", + "office": "オフィス", + "other": "その他" } } diff --git a/src/locales/ko.json b/src/locales/ko.json index 6dcd594e..443e936e 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -671,5 +671,22 @@ "noRelaysSet": "경고: 당신은 어떤 선호한 릴레이를 놓지 않았습니다. 당신은 어떤 메시지를 수신 할 수 없습니다 또는 전송 된 메시지를 볼 수 없습니다.", "nostrSettingsLink": "릴레이를 설정하려면 Nostr 설정을 이동합니다.", "anonymous": "이름 *" + }, + "map": { + "searchLocations": "장소 검색...", + "all": "전체", + "none": "없음", + "restaurant": "레스토랑", + "cafe": "카페", + "bar": "바", + "fastFood": "패스트푸드", + "grocery": "식료품점", + "hairdresser": "미용실", + "hotel": "호텔", + "shop": "상점", + "atm": "ATM", + "health": "건강", + "office": "사무실", + "other": "기타" } } diff --git a/src/locales/nl.json b/src/locales/nl.json index fb475bab..f5e294bc 100644 --- a/src/locales/nl.json +++ b/src/locales/nl.json @@ -671,5 +671,22 @@ "noRelaysSet": "WAARSCHUWING: U heeft geen voorkeursrelais ingesteld. U kunt geen berichten ontvangen of de berichten zien die u hebt verzonden.", "nostrSettingsLink": "Ga naar uw Nostr instellingen om uw relais in te stellen.", "anonymous": "Anoniem" + }, + "map": { + "searchLocations": "Locaties zoeken...", + "all": "Alle", + "none": "Geen", + "restaurant": "Restaurant", + "cafe": "Café", + "bar": "Bar", + "fastFood": "Fastfood", + "grocery": "Supermarkt", + "hairdresser": "Kapper", + "hotel": "Hotel", + "shop": "Winkel", + "atm": "Geldautomaat", + "health": "Gezondheid", + "office": "Kantoor", + "other": "Overig" } } diff --git a/src/locales/pl.json b/src/locales/pl.json index d03c068d..d142dd0e 100644 --- a/src/locales/pl.json +++ b/src/locales/pl.json @@ -671,5 +671,22 @@ "noRelaysSet": "UWAGA: Nie ustawiłeś żadnych preferowanych przekaźników. Nie będziesz w stanie odbierać wiadomości ani widzieć wiadomości, które wysłałeś.", "nostrSettingsLink": "Przejdź do ustawień Nostr, aby ustawić przekaźniki.", "anonymous": "Anonimowy" + }, + "map": { + "searchLocations": "Szukaj lokalizacji...", + "all": "Wszystkie", + "none": "Żadne", + "restaurant": "Restauracja", + "cafe": "Kawiarnia", + "bar": "Bar", + "fastFood": "Fast food", + "grocery": "Sklep spożywczy", + "hairdresser": "Fryzjer", + "hotel": "Hotel", + "shop": "Sklep", + "atm": "Bankomat", + "health": "Zdrowie", + "office": "Biuro", + "other": "Inne" } } diff --git a/src/locales/pt.json b/src/locales/pt.json index bdb94c30..ff38cf3e 100644 --- a/src/locales/pt.json +++ b/src/locales/pt.json @@ -695,5 +695,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "Pesquisar locais...", + "all": "Todos", + "none": "Nenhum", + "restaurant": "Restaurante", + "cafe": "Café", + "bar": "Bar", + "fastFood": "Fast Food", + "grocery": "Mercearia", + "hairdresser": "Cabeleireiro", + "hotel": "Hotel", + "shop": "Loja", + "atm": "Multibanco", + "health": "Saúde", + "office": "Escritório", + "other": "Outro" } } diff --git a/src/locales/ru.json b/src/locales/ru.json index 0b0dcee6..333e5110 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -673,5 +673,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "Поиск мест...", + "all": "Все", + "none": "Ничего", + "restaurant": "Ресторан", + "cafe": "Кафе", + "bar": "Бар", + "fastFood": "Фастфуд", + "grocery": "Продукты", + "hairdresser": "Парикмахерская", + "hotel": "Отель", + "shop": "Магазин", + "atm": "Банкомат", + "health": "Здоровье", + "office": "Офис", + "other": "Другое" } } diff --git a/src/locales/th.json b/src/locales/th.json index f5c2ce0e..db080c03 100644 --- a/src/locales/th.json +++ b/src/locales/th.json @@ -671,5 +671,22 @@ "noRelaysSet": "คุณยังไม่ได้ตั้งเครื่องส่งใด ๆ ที่ชื่นชอบ คุณจะไม่ได้รับข้อความใด ๆ หรือเห็นข้อความที่คุณส่งไป.", "nostrSettingsLink": "ไปที่กองจมูกของคุณเพื่อตั้งค่าเครื่องส่งของคุณ.", "anonymous": "นิรนาม" + }, + "map": { + "searchLocations": "ค้นหาสถานที่...", + "all": "ทั้งหมด", + "none": "ไม่มี", + "restaurant": "ร้านอาหาร", + "cafe": "คาเฟ่", + "bar": "บาร์", + "fastFood": "ฟาสต์ฟู้ด", + "grocery": "ร้านขายของชำ", + "hairdresser": "ร้านทำผม", + "hotel": "โรงแรม", + "shop": "ร้านค้า", + "atm": "ตู้เอทีเอ็ม", + "health": "สุขภาพ", + "office": "สำนักงาน", + "other": "อื่นๆ" } } diff --git a/src/locales/tr.json b/src/locales/tr.json index 893fc6f7..e104eaab 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -671,5 +671,22 @@ "noRelaysSet": "WARNING: Herhangi bir tercih edilen röle ayarlamadın. Herhangi bir mesaj alabilir veya gönderdiğiniz mesajları göremezsiniz.", "nostrSettingsLink": "Rölelerinizi ayarlamak için Nostr ayarlarınıza gidin.", "anonymous": "Anonim" + }, + "map": { + "searchLocations": "Konum ara...", + "all": "Tümü", + "none": "Hiçbiri", + "restaurant": "Restoran", + "cafe": "Kafe", + "bar": "Bar", + "fastFood": "Fast Food", + "grocery": "Market", + "hairdresser": "Kuaför", + "hotel": "Otel", + "shop": "Mağaza", + "atm": "ATM", + "health": "Sağlık", + "office": "Ofis", + "other": "Diğer" } } diff --git a/src/locales/zh.json b/src/locales/zh.json index 95b4d38d..6a7aa18f 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -673,5 +673,22 @@ "nl": "Nederlands", "th": "ไทย", "pl": "Polski" + }, + "map": { + "searchLocations": "搜索位置...", + "all": "全部", + "none": "无", + "restaurant": "餐厅", + "cafe": "咖啡馆", + "bar": "酒吧", + "fastFood": "快餐", + "grocery": "杂货店", + "hairdresser": "理发店", + "hotel": "酒店", + "shop": "商店", + "atm": "ATM", + "health": "医疗", + "office": "办公室", + "other": "其他" } } diff --git a/src/routes/(static)/login/+page.svelte b/src/routes/(static)/login/+page.svelte index 7a7b06ed..c23acc8b 100644 --- a/src/routes/(static)/login/+page.svelte +++ b/src/routes/(static)/login/+page.svelte @@ -31,8 +31,14 @@ pin?.set(undefined); signer.set(undefined); const installDismissed = localStorage.getItem("installDismissed"); + const snapshots: [string, string][] = []; + for (let i = 0; i < localStorage.length; i++) { + const k = localStorage.key(i)!; + if (k.startsWith("arkVaultSnapshot:")) snapshots.push([k, localStorage.getItem(k)!]); + } localStorage.clear(); if (installDismissed) localStorage.setItem("installDismissed", installDismissed); + for (const [k, v] of snapshots) localStorage.setItem(k, v); sessionStorage.clear(); }, 50); } diff --git a/src/routes/(static)/register/auth/+page.svelte b/src/routes/(static)/register/auth/+page.svelte index 80915108..32539079 100644 --- a/src/routes/(static)/register/auth/+page.svelte +++ b/src/routes/(static)/register/auth/+page.svelte @@ -51,8 +51,14 @@ pin.set(undefined); signer.set(undefined); const installDismissed = localStorage.getItem("installDismissed"); + const snapshots: [string, string][] = []; + for (let i = 0; i < localStorage.length; i++) { + const k = localStorage.key(i)!; + if (k.startsWith("arkVaultSnapshot:")) snapshots.push([k, localStorage.getItem(k)!]); + } localStorage.clear(); if (installDismissed) localStorage.setItem("installDismissed", installDismissed); + for (const [k, v] of snapshots) localStorage.setItem(k, v); sessionStorage.clear(); }, 50); } |
