mirror of
https://github.com/lumina-rocks/lumina.git
synced 2026-06-04 09:41:32 +02:00
feat: Show number of connected relays in Header Bar (#127)
* feat: add ConnectedRelaysButton component and integrate into TopNavigation fix: improve loading state management in RelaysPage with timeout refactor: sanitize relay URLs in RootLayout * fix: disable debug mode in NostrProvider for production * feat: add AuthButton component and integrate into TopNavigation * fix: update header text in RelaysPage and remove 'Add Relay' button label in AddRelaySheet --------- Co-authored-by: highperfocused <highperfocused@pm.me>
This commit is contained in:
37
components/headerComponents/AuthButton.tsx
Normal file
37
components/headerComponents/AuthButton.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import Link from "next/link";
|
||||
import { UserIcon } from "lucide-react";
|
||||
|
||||
export default function AuthButton() {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" className="flex items-center gap-2">
|
||||
<UserIcon className="h-[1.2rem] w-[1.2rem]" />
|
||||
<span className="hidden sm:inline">Account</span>
|
||||
<span className="sr-only">Account options</span>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem asChild>
|
||||
<Link href="/login" className="w-full cursor-pointer">
|
||||
Sign In
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem asChild>
|
||||
<Link href="/onboarding" className="w-full cursor-pointer">
|
||||
Register
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
}
|
||||
43
components/headerComponents/ConnectedRelaysButton.tsx
Normal file
43
components/headerComponents/ConnectedRelaysButton.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import Link from "next/link";
|
||||
import { useNostr } from "nostr-react";
|
||||
import { Wifi } from "lucide-react";
|
||||
|
||||
export default function ConnectedRelaysButton() {
|
||||
const { connectedRelays } = useNostr();
|
||||
const [relayCount, setRelayCount] = useState<number>(0);
|
||||
const [isConnecting, setIsConnecting] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
// Update relay count when connectedRelays changes
|
||||
if (connectedRelays && connectedRelays.length > 0) {
|
||||
// Count only connected relays (status === 1)
|
||||
const activeRelays = connectedRelays.filter(relay => relay.status === 1).length;
|
||||
setRelayCount(activeRelays);
|
||||
|
||||
// If at least one relay is connected, we're no longer in connecting state
|
||||
if (activeRelays > 0) {
|
||||
setIsConnecting(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Set a timeout to stop showing "Connecting..." after a reasonable time
|
||||
const timer = setTimeout(() => {
|
||||
setIsConnecting(false);
|
||||
}, 5000);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}, [connectedRelays]);
|
||||
|
||||
return (
|
||||
<Link href={"/relays"}>
|
||||
<Button variant={"outline"} className="gap-2">
|
||||
<Wifi className={`h-4 w-4 ${isConnecting ? 'animate-pulse' : ''}`} />
|
||||
{isConnecting && relayCount === 0 ? 'Connecting...' : `${relayCount}`}
|
||||
</Button>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
@@ -4,10 +4,11 @@ import { siteConfig } from "@/config/site"
|
||||
import { useEffect, useState } from "react"
|
||||
import { TopNavigationItems } from "./TopNavigationItems"
|
||||
import { DropdownThemeMode } from "./DropdownThemeMode"
|
||||
import LoginButton from "./LoginButton"
|
||||
import { AvatarDropdown } from "./AvatarDropdown"
|
||||
import RegisterButton from "./RegisterButton"
|
||||
import GitHubButton from "@/components/headerComponents/GitHubButton"
|
||||
import ConnectedRelaysButton from "@/components/headerComponents/ConnectedRelaysButton"
|
||||
import AuthButton from "./AuthButton"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { UserIcon } from "lucide-react"
|
||||
|
||||
export function TopNavigation() {
|
||||
const [pubkey, setPubkey] = useState<string | null>(null)
|
||||
@@ -26,8 +27,13 @@ export function TopNavigation() {
|
||||
<TopNavigationItems items={siteConfig.mainNav} />
|
||||
<div className="flex flex-1 items-center justify-end space-x-4">
|
||||
<nav className="flex items-center space-x-2">
|
||||
<GitHubButton />
|
||||
<ConnectedRelaysButton />
|
||||
<DropdownThemeMode />
|
||||
{/* Placeholder for auth button to prevent layout shift */}
|
||||
<Button variant="outline" className="flex items-center gap-2" disabled>
|
||||
<UserIcon className="h-[1.2rem] w-[1.2rem]" />
|
||||
<span className="hidden sm:inline">Account</span>
|
||||
</Button>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
@@ -41,11 +47,9 @@ export function TopNavigation() {
|
||||
<TopNavigationItems items={siteConfig.mainNav} />
|
||||
<div className="flex flex-1 items-center justify-end space-x-4">
|
||||
<nav className="flex items-center space-x-2">
|
||||
<GitHubButton />
|
||||
<ConnectedRelaysButton />
|
||||
<DropdownThemeMode />
|
||||
{pubkey === null ? <RegisterButton /> : null}
|
||||
{pubkey === null ? <LoginButton /> : null}
|
||||
{pubkey !== null ? <AvatarDropdown /> : null}
|
||||
{pubkey !== null ? <AvatarDropdown /> : <AuthButton />}
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user