fix: more robust storage

This commit is contained in:
Alejandro Gómez
2025-12-11 00:18:28 +01:00
parent 86114eef8c
commit 9c9d04c947
2 changed files with 48 additions and 8 deletions

View File

@@ -1,4 +1,4 @@
import { Copy, Check, Server } from "lucide-react";
import { Copy, Check } from "lucide-react";
import { useRelayInfo } from "../hooks/useRelayInfo";
import { useCopy } from "../hooks/useCopy";
import { Button } from "./ui/button";
@@ -46,7 +46,7 @@ export function RelayViewer({ url }: RelayViewerProps) {
{(info?.contact || info?.pubkey) && (
<div>
<h3 className="mb-2 font-semibold text-sm">Operator</h3>
<div className="space-y-2 text-sm">
<div className="space-y-2 text-sm text-accent">
{info.contact && info.contact.length == 64 && (
<UserName pubkey={info.contact} />
)}

View File

@@ -1,5 +1,6 @@
import { useEffect } from "react";
import { useAtom } from "jotai";
import { atomWithStorage } from "jotai/utils";
import { atomWithStorage, createJSONStorage } from "jotai/utils";
import { GrimoireState, AppId } from "@/types/app";
import { useLocale } from "@/hooks/useLocale";
import * as Logic from "./logic";
@@ -18,10 +19,47 @@ const initialState: GrimoireState = {
},
};
// Persistence Atom
// Custom storage with error handling
const storage = createJSONStorage<GrimoireState>(() => ({
getItem: (key: string) => {
try {
const value = localStorage.getItem(key);
return value;
} catch (error) {
console.warn("Failed to read from localStorage:", error);
return null;
}
},
setItem: (key: string, value: string) => {
try {
localStorage.setItem(key, value);
} catch (error) {
console.error("Failed to write to localStorage:", error);
// Handle quota exceeded or other errors
if (
error instanceof DOMException &&
error.name === "QuotaExceededError"
) {
console.error(
"localStorage quota exceeded. State will not be persisted.",
);
}
}
},
removeItem: (key: string) => {
try {
localStorage.removeItem(key);
} catch (error) {
console.warn("Failed to remove from localStorage:", error);
}
},
}));
// Persistence Atom with custom storage
export const grimoireStateAtom = atomWithStorage<GrimoireState>(
"grimoire_v6",
initialState,
storage,
);
// The Hook
@@ -29,10 +67,12 @@ export const useGrimoire = () => {
const [state, setState] = useAtom(grimoireStateAtom);
const browserLocale = useLocale();
// Initialize locale from browser if not set
if (!state.locale) {
setState((prev) => ({ ...prev, locale: browserLocale }));
}
// Initialize locale from browser if not set (moved to useEffect to avoid race condition)
useEffect(() => {
if (!state.locale) {
setState((prev) => ({ ...prev, locale: browserLocale }));
}
}, [state.locale, browserLocale, setState]);
return {
state,