mirror of
https://github.com/lumina-rocks/lumina.git
synced 2026-04-10 23:47:05 +02:00
Revert "Revert "Fix: hydration errors (#45)""
This reverts commit a737463115.
This commit is contained in:
@@ -3,38 +3,42 @@
|
||||
import { BellIcon, GlobeIcon, HomeIcon, RowsIcon, UploadIcon } from "@radix-ui/react-icons"
|
||||
import Link from "next/link"
|
||||
import { FormEvent, JSX, SVGProps, useEffect, useState } from "react"
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar"
|
||||
import { useRouter, usePathname } from 'next/navigation'
|
||||
import { SearchIcon, Upload } from "lucide-react";
|
||||
import {
|
||||
Drawer,
|
||||
DrawerClose,
|
||||
DrawerContent,
|
||||
DrawerDescription,
|
||||
DrawerFooter,
|
||||
DrawerHeader,
|
||||
DrawerTitle,
|
||||
DrawerTrigger,
|
||||
} from "@/components/ui/drawer"
|
||||
import { Button } from "./ui/button";
|
||||
import { Textarea } from "./ui/textarea";
|
||||
import { useNostr } from "nostr-react";
|
||||
import { SearchIcon } from "lucide-react";
|
||||
|
||||
export default function BottomBar() {
|
||||
const router = useRouter();
|
||||
const [pubkey, setPubkey] = useState<null | string>(null);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const pathname = usePathname();
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
setPubkey(window.localStorage.getItem('pubkey') ?? null);
|
||||
}
|
||||
setMounted(true);
|
||||
setPubkey(window.localStorage.getItem('pubkey'));
|
||||
}, []);
|
||||
|
||||
if (typeof window === 'undefined') return null;
|
||||
|
||||
const isActive = (path: string, currentPath: string) => currentPath === path ? 'text-purple-500' : '';
|
||||
|
||||
// Render minimal navigation during SSR and hydration
|
||||
if (!mounted) {
|
||||
return (
|
||||
<nav className="fixed inset-x-0 bottom-0 h-14 flex flex-row shrink-0 items-center justify-between border-t bg-background/90 shadow-up-4 z-50 backdrop-blur">
|
||||
<Link className={`flex flex-col items-center justify-center w-full text-xs gap-1 px-4 ${isActive('/', pathname)}`} href="/">
|
||||
<HomeIcon className={`h-6 w-6`} />
|
||||
<span className="sr-only">Home</span>
|
||||
</Link>
|
||||
<Link className={`flex flex-col items-center justify-center w-full text-xs gap-1 px-4 ${isActive('/global', pathname)}`} href="/global">
|
||||
<GlobeIcon className={`h-6 w-6`} />
|
||||
<span className="sr-only">Global</span>
|
||||
</Link>
|
||||
<Link className={`flex flex-col items-center justify-center w-full text-xs gap-1 px-4 ${isActive('/search', pathname)}`} href="/search">
|
||||
<SearchIcon className={`h-6 w-6`} />
|
||||
<span className="sr-only">Search</span>
|
||||
</Link>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<nav className="fixed inset-x-0 bottom-0 h-14 flex flex-row shrink-0 items-center justify-between border-t bg-background/90 shadow-up-4 z-50 backdrop-blur">
|
||||
<Link className={`flex flex-col items-center justify-center w-full text-xs gap-1 px-4 ${isActive('/', pathname)}`} href="/">
|
||||
|
||||
@@ -97,7 +97,6 @@ const ProfileInfoCard: React.FC<ProfileInfoCardProps> = React.memo(({ pubkey })
|
||||
<div>
|
||||
<NIP05 nip05={nip05?.toString() ?? ''} pubkey={pubkey} />
|
||||
<div className='py-6 grid grid-cols-5 gap-4'>
|
||||
{/* <Button className='w-full'>Follow</Button> */}
|
||||
<div className='col-span-2'>
|
||||
<FollowButton pubkey={pubkey} userPubkey={userPubkey}></FollowButton>
|
||||
</div>
|
||||
@@ -105,7 +104,7 @@ const ProfileInfoCard: React.FC<ProfileInfoCardProps> = React.memo(({ pubkey })
|
||||
<Button className='w-full' variant="outline">View Statistics</Button>
|
||||
</Link>
|
||||
<Drawer>
|
||||
<DrawerTrigger>
|
||||
<DrawerTrigger asChild>
|
||||
<Button className='w-full' variant="outline"><Share1Icon /></Button>
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
@@ -114,7 +113,6 @@ const ProfileInfoCard: React.FC<ProfileInfoCardProps> = React.memo(({ pubkey })
|
||||
<DrawerDescription>Share this Profile with others.</DrawerDescription>
|
||||
</DrawerHeader>
|
||||
<div className="px-2">
|
||||
{/* <h1>URL</h1> */}
|
||||
<div className="flex items-center mb-4">
|
||||
<Input value={host+"/profile/"+nip19.npubEncode(pubkey)} disabled className="mr-2" />
|
||||
<Button variant="outline" onClick={handleCopyLink}>Copy Link</Button>
|
||||
@@ -125,8 +123,10 @@ const ProfileInfoCard: React.FC<ProfileInfoCardProps> = React.memo(({ pubkey })
|
||||
</div>
|
||||
</div>
|
||||
<DrawerFooter>
|
||||
<DrawerClose>
|
||||
<Button variant="outline">Close</Button>
|
||||
<DrawerClose asChild>
|
||||
<div>
|
||||
<Button variant="outline">Close</Button>
|
||||
</div>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
|
||||
@@ -82,7 +82,7 @@ export default function ReactionButton({ event }: { event: any }) {
|
||||
|
||||
return (
|
||||
<Drawer>
|
||||
<DrawerTrigger>
|
||||
<DrawerTrigger asChild>
|
||||
<Button variant={liked ? "default" : "outline"}>
|
||||
{isLoading ? (
|
||||
<>
|
||||
@@ -125,8 +125,10 @@ export default function ReactionButton({ event }: { event: any }) {
|
||||
<hr className="my-4" />
|
||||
<ReactionButtonReactionList filteredEvents={filteredEvents} />
|
||||
<DrawerFooter>
|
||||
<DrawerClose>
|
||||
<Button variant={"secondary"}>Close</Button>
|
||||
<DrawerClose asChild>
|
||||
<div>
|
||||
<Button variant={"secondary"}>Close</Button>
|
||||
</div>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
|
||||
@@ -60,7 +60,7 @@ export default function ViewCopyButton({ event }: ViewCopyButtonProps) {
|
||||
|
||||
return (
|
||||
<Drawer>
|
||||
<DrawerTrigger>
|
||||
<DrawerTrigger asChild>
|
||||
<Button variant="outline"><Share1Icon /></Button>
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
@@ -80,12 +80,13 @@ export default function ViewCopyButton({ event }: ViewCopyButtonProps) {
|
||||
</div>
|
||||
</div>
|
||||
<DrawerFooter>
|
||||
<DrawerClose>
|
||||
<Button variant="outline">Close</Button>
|
||||
<DrawerClose asChild>
|
||||
<div>
|
||||
<Button variant="outline">Close</Button>
|
||||
</div>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
|
||||
);
|
||||
}
|
||||
@@ -20,7 +20,7 @@ interface ViewRawButtonProps {
|
||||
export default function ViewRawButton({ event }: ViewRawButtonProps) {
|
||||
return (
|
||||
<Drawer>
|
||||
<DrawerTrigger>
|
||||
<DrawerTrigger asChild>
|
||||
<Button variant="outline"><CodeIcon /></Button>
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
@@ -30,8 +30,10 @@ export default function ViewRawButton({ event }: ViewRawButtonProps) {
|
||||
</DrawerHeader>
|
||||
<Textarea rows={20} disabled>{JSON.stringify(event, null, 2)}</Textarea>
|
||||
<DrawerFooter>
|
||||
<DrawerClose>
|
||||
<Button variant="outline">Close</Button>
|
||||
<DrawerClose asChild>
|
||||
<div>
|
||||
<Button variant="outline">Close</Button>
|
||||
</div>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
|
||||
@@ -85,12 +85,10 @@ export default function ZapButton({ event }: { event: any }) {
|
||||
|
||||
return (
|
||||
<Drawer>
|
||||
<DrawerTrigger>
|
||||
{/* <Button variant="default" onClick={onPost}>{events.length} Reactions</Button> */}
|
||||
<DrawerTrigger asChild>
|
||||
{isLoading ? (
|
||||
<Button variant="outline"><ReloadIcon className="mr-2 h-4 w-4 animate-spin" /> ⚡️</Button>
|
||||
) : (
|
||||
// <Button variant="outline">{events.length} ⚡️ ({sats} sats)</Button>
|
||||
<Button variant="outline">{sats} sats ⚡️</Button>
|
||||
)}
|
||||
</DrawerTrigger>
|
||||
@@ -110,8 +108,10 @@ export default function ZapButton({ event }: { event: any }) {
|
||||
<hr className="my-4" />
|
||||
<ZapButtonList events={events} />
|
||||
<DrawerFooter>
|
||||
<DrawerClose>
|
||||
<Button variant={"outline"}>Close</Button>
|
||||
<DrawerClose asChild>
|
||||
<div>
|
||||
<Button variant={"outline"}>Close</Button>
|
||||
</div>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
|
||||
@@ -11,27 +11,46 @@ import RegisterButton from "./RegisterButton";
|
||||
|
||||
export function TopNavigation() {
|
||||
const [pubkey, setPubkey] = useState<string | null>(null);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
setPubkey(window.localStorage.getItem('pubkey'));
|
||||
}
|
||||
setMounted(true);
|
||||
setPubkey(window.localStorage.getItem('pubkey'));
|
||||
}, []);
|
||||
|
||||
// Prevent hydration mismatch by not rendering auth-dependent content until mounted
|
||||
if (!mounted) {
|
||||
return (
|
||||
<nav>
|
||||
<header className="bg-background/80 sticky top-0 z-40 w-full border-b backdrop-blur">
|
||||
<div className="container flex h-16 items-center space-x-4 sm:justify-between sm:space-x-0">
|
||||
<TopNavigationItems items={siteConfig.mainNav} />
|
||||
<div className="flex flex-1 items-center justify-end space-x-4">
|
||||
<nav className="flex items-center space-x-2">
|
||||
<DropdownThemeMode />
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<header className="bg-background/80 sticky top-0 z-40 w-full border-b backdrop-blur">
|
||||
<div className="container flex h-16 items-center space-x-4 sm:justify-between sm:space-x-0">
|
||||
<TopNavigationItems items={siteConfig.mainNav} />
|
||||
<div className="flex flex-1 items-center justify-end space-x-4">
|
||||
<nav className="flex items-center space-x-2">
|
||||
<DropdownThemeMode />
|
||||
{pubkey === null ? <RegisterButton /> : null}
|
||||
{pubkey === null ? <LoginButton /> : null}
|
||||
{/* {pubkey !== null ? <Button variant="secondary" onClick={() => { localStorage.removeItem('pubkey'); window.location.reload(); }}>Logout</Button> : null} */}
|
||||
{pubkey !== null ? <AvatarDropdown /> : null}
|
||||
</nav>
|
||||
<nav>
|
||||
<header className="bg-background/80 sticky top-0 z-40 w-full border-b backdrop-blur">
|
||||
<div className="container flex h-16 items-center space-x-4 sm:justify-between sm:space-x-0">
|
||||
<TopNavigationItems items={siteConfig.mainNav} />
|
||||
<div className="flex flex-1 items-center justify-end space-x-4">
|
||||
<nav className="flex items-center space-x-2">
|
||||
<DropdownThemeMode />
|
||||
{pubkey === null ? <RegisterButton /> : null}
|
||||
{pubkey === null ? <LoginButton /> : null}
|
||||
{pubkey !== null ? <AvatarDropdown /> : null}
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</header>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user