added network select feature

This commit is contained in:
Siavash Sameni
2025-08-28 15:16:02 +04:00
parent f60e4ca3a5
commit 62653437b5
4 changed files with 93 additions and 22 deletions

View File

@@ -36,6 +36,10 @@ const defaultSettings: NotificationSettings = {
export default function SettingsModal({ open, initial, onClose, onSave }: SettingsModalProps) {
const [form, setForm] = useState<NotificationSettings>(initial || defaultSettings);
const [testStatus, setTestStatus] = useState<string>("");
// RPC runtime overrides (stored in localStorage)
const [rpcBase, setRpcBase] = useState<string>("");
const [rpcArbitrum, setRpcArbitrum] = useState<string>("");
const [rpcMainnet, setRpcMainnet] = useState<string>("");
useEffect(() => {
if (open) {
@@ -45,6 +49,16 @@ export default function SettingsModal({ open, initial, onClose, onSave }: Settin
if (!merged.ntfyServer) merged.ntfyServer = ENV_NTFY;
if (!merged.schedyBaseUrl) merged.schedyBaseUrl = ENV_SCHEDY;
setForm(merged);
// Load RPC overrides from localStorage
try {
const ls = typeof window !== 'undefined' ? window.localStorage : undefined;
const b = ls?.getItem('rpc:base') || '';
const a = ls?.getItem('rpc:arbitrum') || '';
const m = ls?.getItem('rpc:mainnet') || '';
setRpcBase(b || 'https://base.llamarpc.com');
setRpcArbitrum(a || '');
setRpcMainnet(m || '');
} catch {}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [open, initial]);
@@ -284,6 +298,41 @@ export default function SettingsModal({ open, initial, onClose, onSave }: Settin
</div>
</>
)}
{/* RPC settings */}
<div className="col-span-2 mt-2 border-t border-gray-700 pt-2">
<div className="text-sm font-semibold text-gray-200 mb-1">RPC endpoints (per network)</div>
<div className="grid grid-cols-2 gap-3">
<label>
<span className="text-gray-300">Base RPC (default https://base.llamarpc.com)</span>
<input
className="mt-1 w-full rounded border border-gray-700 bg-gray-800 px-2 py-1 text-gray-100"
placeholder="https://base.llamarpc.com"
value={rpcBase}
onChange={(e) => setRpcBase(e.target.value)}
/>
</label>
<label>
<span className="text-gray-300">Arbitrum RPC (optional)</span>
<input
className="mt-1 w-full rounded border border-gray-700 bg-gray-800 px-2 py-1 text-gray-100"
placeholder="https://arb.yourrpc.example"
value={rpcArbitrum}
onChange={(e) => setRpcArbitrum(e.target.value)}
/>
</label>
<label className="col-span-2">
<span className="text-gray-300">Mainnet RPC (optional)</span>
<input
className="mt-1 w-full rounded border border-gray-700 bg-gray-800 px-2 py-1 text-gray-100"
placeholder="https://mainnet.yourrpc.example"
value={rpcMainnet}
onChange={(e) => setRpcMainnet(e.target.value)}
/>
</label>
<div className="col-span-2 text-xs text-gray-400">Changes apply immediately after Save without rebuild.</div>
</div>
</div>
</div>
<div className="mt-4 flex justify-end gap-2">
@@ -307,7 +356,27 @@ export default function SettingsModal({ open, initial, onClose, onSave }: Settin
<button
className="rounded bg-indigo-600 px-3 py-1.5 disabled:opacity-50"
disabled={saveDisabled}
onClick={() => onSave(form)}
onClick={() => {
// Persist RPC overrides
try {
if (typeof window !== 'undefined' && window.localStorage) {
const ls = window.localStorage;
const b = (rpcBase || '').trim();
const a = (rpcArbitrum || '').trim();
const m = (rpcMainnet || '').trim();
if (b) ls.setItem('rpc:base', b); else ls.removeItem('rpc:base');
if (a) ls.setItem('rpc:arbitrum', a); else ls.removeItem('rpc:arbitrum');
if (m) ls.setItem('rpc:mainnet', m); else ls.removeItem('rpc:mainnet');
}
} catch {}
onSave(form);
try {
if (typeof window !== 'undefined') {
// Ensure new RPCs are applied by reloading the app
setTimeout(() => window.location.reload(), 150);
}
} catch {}
}}
>
Save
</button>