From 5ce2a955879706f4c2bedfa37ecbfde49c179e5b Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Tue, 17 Feb 2026 05:47:54 -0600 Subject: [PATCH] Mobile menu: hide switch accounts when no other accounts, remove domain blocks, add dedicated wallet page - Switch accounts section in MobileDrawer now only renders when otherUsers.length > 0 - Removed "Domain blocks" menu item and its /domain-blocks route - Created WalletPage with full NWC management UI (status cards, wallet list, add/remove/activate connections) - /wallet route now renders the dedicated page instead of a placeholder Co-authored-by: shakespeare.diy --- src/AppRouter.tsx | 5 +- src/components/MobileDrawer.tsx | 86 +++++----- src/pages/WalletPage.tsx | 289 ++++++++++++++++++++++++++++++++ 3 files changed, 334 insertions(+), 46 deletions(-) create mode 100644 src/pages/WalletPage.tsx diff --git a/src/AppRouter.tsx b/src/AppRouter.tsx index 50ce820f..e05e2e4c 100644 --- a/src/AppRouter.tsx +++ b/src/AppRouter.tsx @@ -10,6 +10,7 @@ import { SettingsPage } from "./pages/SettingsPage"; import { HashtagPage } from "./pages/HashtagPage"; import { BookmarksPage } from "./pages/BookmarksPage"; import { PlaceholderPage } from "./pages/PlaceholderPage"; +import { WalletPage } from "./pages/WalletPage"; import { KindFeedPage } from "./pages/KindFeedPage"; import NotFound from "./pages/NotFound"; @@ -30,10 +31,10 @@ export function AppRouter() { } /> } /> } /> - } /> + } /> } /> } /> - } /> + {/* NIP-19 route for npub1, note1, naddr1, nevent1, nprofile1 */} } /> {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} diff --git a/src/components/MobileDrawer.tsx b/src/components/MobileDrawer.tsx index b1384473..73c706be 100644 --- a/src/components/MobileDrawer.tsx +++ b/src/components/MobileDrawer.tsx @@ -1,5 +1,5 @@ import { Link, useNavigate } from 'react-router-dom'; -import { User, Wallet, Bookmark, EyeOff, Settings, ShieldBan, LogOut, ChevronDown, ChevronUp } from 'lucide-react'; +import { User, Wallet, Bookmark, EyeOff, Settings, LogOut, ChevronDown, ChevronUp } from 'lucide-react'; import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { Sheet, SheetContent, SheetTitle } from '@/components/ui/sheet'; import { Separator } from '@/components/ui/separator'; @@ -109,12 +109,6 @@ export function MobileDrawer({ open, onOpenChange }: MobileDrawerProps) { label="Preferences" onClick={handleClose} /> - } - label="Domain blocks" - onClick={handleClose} - /> - + {otherUsers.length > 0 && ( + <> + - {/* Switch accounts section */} -
- + {/* Switch accounts section */} +
+ - {showAccountSwitcher && otherUsers.length > 0 && ( -
- {otherUsers.map((account) => ( - - ))} + {showAccountSwitcher && ( +
+ {otherUsers.map((account) => ( + + ))} +
+ )}
- )} -
+ + )}
) : (
diff --git a/src/pages/WalletPage.tsx b/src/pages/WalletPage.tsx new file mode 100644 index 00000000..204ca7f4 --- /dev/null +++ b/src/pages/WalletPage.tsx @@ -0,0 +1,289 @@ +import { useState } from 'react'; +import { useSeoMeta } from '@unhead/react'; +import { ArrowLeft, Wallet, Plus, Trash2, Zap, Globe, WalletMinimal, CheckCircle } from 'lucide-react'; +import { Link } from 'react-router-dom'; +import { MainLayout } from '@/components/MainLayout'; +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Textarea } from '@/components/ui/textarea'; +import { Badge } from '@/components/ui/badge'; +import { Separator } from '@/components/ui/separator'; +import { Card, CardContent } from '@/components/ui/card'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog'; +import { useNWC } from '@/hooks/useNWCContext'; +import { useWallet } from '@/hooks/useWallet'; +import { useToast } from '@/hooks/useToast'; +import { useCurrentUser } from '@/hooks/useCurrentUser'; + +export function WalletPage() { + const [addDialogOpen, setAddDialogOpen] = useState(false); + const [connectionUri, setConnectionUri] = useState(''); + const [alias, setAlias] = useState(''); + const [isConnecting, setIsConnecting] = useState(false); + + const { user } = useCurrentUser(); + const { + connections, + activeConnection, + connectionInfo, + addConnection, + removeConnection, + setActiveConnection, + } = useNWC(); + const { webln } = useWallet(); + const hasNWC = connections.length > 0 && connections.some(c => c.isConnected); + const { toast } = useToast(); + + useSeoMeta({ + title: 'Wallet | Mew', + description: 'Manage your Lightning wallet connections', + }); + + const handleAddConnection = async () => { + if (!connectionUri.trim()) { + toast({ + title: 'Connection URI required', + description: 'Please enter a valid NWC connection URI.', + variant: 'destructive', + }); + return; + } + + setIsConnecting(true); + try { + const success = await addConnection(connectionUri.trim(), alias.trim() || undefined); + if (success) { + setConnectionUri(''); + setAlias(''); + setAddDialogOpen(false); + } + } finally { + setIsConnecting(false); + } + }; + + const handleRemoveConnection = (connectionString: string) => { + removeConnection(connectionString); + }; + + const handleSetActive = (connectionString: string) => { + setActiveConnection(connectionString); + toast({ + title: 'Active wallet changed', + description: 'The selected wallet is now active for zaps.', + }); + }; + + return ( + +
+ {/* Sticky header */} +
+ + + +
+ +

Wallet

+
+
+ + {!user ? ( +
+ +

Log in to manage your wallet

+

Connect a Lightning wallet to send zaps on Nostr.

+
+ ) : ( +
+ {/* Connection status cards */} +
+

Status

+
+ {/* WebLN */} + + +
+
+ +
+
+

WebLN

+

Browser extension

+
+
+
+ {webln && } + + {webln ? 'Ready' : 'Not Found'} + +
+
+
+ + {/* NWC */} + + +
+
+ +
+
+

Nostr Wallet Connect

+

+ {connections.length > 0 + ? `${connections.length} wallet${connections.length !== 1 ? 's' : ''} connected` + : 'Remote wallet connection'} +

+
+
+
+ {hasNWC && } + + {hasNWC ? 'Ready' : 'None'} + +
+
+
+
+
+ + + + {/* NWC Wallets */} +
+
+

Nostr Wallet Connect

+ +
+ + {connections.length === 0 ? ( + + + +

No wallets connected

+

Add an NWC connection to enable instant zaps.

+
+
+ ) : ( +
+ {connections.map((connection) => { + const info = connectionInfo[connection.connectionString]; + const isActive = activeConnection === connection.connectionString; + return ( + + +
+
+ +
+
+

+ {connection.alias || info?.alias || 'Lightning Wallet'} +

+

+ {isActive ? 'Active' : 'NWC Connection'} +

+
+
+
+ {isActive && } + {!isActive && ( + + )} + +
+
+
+ ); + })} +
+ )} +
+ + {/* Help text */} + {!webln && connections.length === 0 && ( + <> + +
+

+ Install a WebLN browser extension or connect a NWC wallet to send zaps. +

+
+ + )} +
+ )} +
+ + {/* Add wallet dialog */} + + + + Connect NWC Wallet + + Enter your connection string from a compatible wallet. + + +
+
+ + setAlias(e.target.value)} + /> +
+
+ +