refactor: sidebar
This commit is contained in:
parent
21663711f8
commit
057de9595b
13 changed files with 110 additions and 44 deletions
|
|
@ -9,6 +9,7 @@ import {
|
|||
} from '@/components/ui/dropdown-menu'
|
||||
import { toWallet } from '@/lib/link'
|
||||
import { formatPubkey, generateImageByPubkey } from '@/lib/pubkey'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { usePrimaryPage, useSecondaryPage } from '@/PageManager'
|
||||
import { useNostr } from '@/providers/NostrProvider'
|
||||
import { ArrowDownUp, LogIn, LogOut, UserRound, Wallet } from 'lucide-react'
|
||||
|
|
@ -18,17 +19,17 @@ import LoginDialog from '../LoginDialog'
|
|||
import LogoutDialog from '../LogoutDialog'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default function AccountButton() {
|
||||
export default function AccountButton({ collapse }: { collapse: boolean }) {
|
||||
const { pubkey } = useNostr()
|
||||
|
||||
if (pubkey) {
|
||||
return <ProfileButton />
|
||||
return <ProfileButton collapse={collapse} />
|
||||
} else {
|
||||
return <LoginButton />
|
||||
return <LoginButton collapse={collapse} />
|
||||
}
|
||||
}
|
||||
|
||||
function ProfileButton() {
|
||||
function ProfileButton({ collapse }: { collapse: boolean }) {
|
||||
const { t } = useTranslation()
|
||||
const { account, profile } = useNostr()
|
||||
const pubkey = account?.pubkey
|
||||
|
|
@ -46,7 +47,10 @@ function ProfileButton() {
|
|||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="clickable shadow-none p-2 xl:px-2 xl:py-2 w-12 h-12 xl:w-full xl:h-auto flex items-center bg-transparent text-foreground hover:text-accent-foreground rounded-lg justify-start gap-4 text-lg font-semibold"
|
||||
className={cn(
|
||||
'clickable shadow-none p-2 flex items-center bg-transparent text-foreground hover:text-accent-foreground rounded-lg justify-start gap-4 text-lg font-semibold',
|
||||
collapse ? 'w-12 h-12' : 'w-full h-auto'
|
||||
)}
|
||||
>
|
||||
<div className="flex gap-2 items-center flex-1 w-0">
|
||||
<Avatar className="w-8 h-8">
|
||||
|
|
@ -55,7 +59,7 @@ function ProfileButton() {
|
|||
<img src={defaultAvatar} />
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="truncate font-semibold text-lg">{username}</div>
|
||||
{!collapse && <div className="truncate font-semibold text-lg">{username}</div>}
|
||||
</div>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
|
@ -88,12 +92,12 @@ function ProfileButton() {
|
|||
)
|
||||
}
|
||||
|
||||
function LoginButton() {
|
||||
function LoginButton({ collapse }: { collapse: boolean }) {
|
||||
const { checkLogin } = useNostr()
|
||||
|
||||
return (
|
||||
<SidebarItem onClick={() => checkLogin()} title="Login">
|
||||
<LogIn strokeWidth={3} />
|
||||
<SidebarItem onClick={() => checkLogin()} title="Login" collapse={collapse}>
|
||||
<LogIn />
|
||||
</SidebarItem>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Compass } from 'lucide-react'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default function RelaysButton() {
|
||||
export default function RelaysButton({ collapse }: { collapse: boolean }) {
|
||||
const { t } = useTranslation()
|
||||
const { navigate, current } = usePrimaryPage()
|
||||
|
||||
|
|
@ -12,8 +12,9 @@ export default function RelaysButton() {
|
|||
title={t('Explore')}
|
||||
onClick={() => navigate('explore')}
|
||||
active={current === 'explore'}
|
||||
collapse={collapse}
|
||||
>
|
||||
<Compass strokeWidth={3} />
|
||||
<Compass />
|
||||
</SidebarItem>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,17 @@ import { usePrimaryPage } from '@/PageManager'
|
|||
import { Home } from 'lucide-react'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default function HomeButton() {
|
||||
export default function HomeButton({ collapse }: { collapse: boolean }) {
|
||||
const { navigate, current } = usePrimaryPage()
|
||||
|
||||
return (
|
||||
<SidebarItem title="Home" onClick={() => navigate('home')} active={current === 'home'}>
|
||||
<Home strokeWidth={3} />
|
||||
<SidebarItem
|
||||
title="Home"
|
||||
onClick={() => navigate('home')}
|
||||
active={current === 'home'}
|
||||
collapse={collapse}
|
||||
>
|
||||
<Home />
|
||||
</SidebarItem>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { useNotification } from '@/providers/NotificationProvider'
|
|||
import { Bell } from 'lucide-react'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default function NotificationsButton() {
|
||||
export default function NotificationsButton({ collapse }: { collapse: boolean }) {
|
||||
const { checkLogin } = useNostr()
|
||||
const { navigate, current } = usePrimaryPage()
|
||||
const { hasNewNotification } = useNotification()
|
||||
|
|
@ -14,9 +14,10 @@ export default function NotificationsButton() {
|
|||
title="Notifications"
|
||||
onClick={() => checkLogin(() => navigate('notifications'))}
|
||||
active={current === 'notifications'}
|
||||
collapse={collapse}
|
||||
>
|
||||
<div className="relative">
|
||||
<Bell strokeWidth={3} />
|
||||
<Bell />
|
||||
{hasNewNotification && (
|
||||
<div className="absolute -top-1 right-0 w-2 h-2 ring-2 ring-background bg-primary rounded-full" />
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import PostEditor from '@/components/PostEditor'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useNostr } from '@/providers/NostrProvider'
|
||||
import { PencilLine } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default function PostButton() {
|
||||
export default function PostButton({ collapse }: { collapse: boolean }) {
|
||||
const { checkLogin } = useNostr()
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
|
|
@ -20,9 +21,10 @@ export default function PostButton() {
|
|||
})
|
||||
}}
|
||||
variant="default"
|
||||
className="bg-primary xl:justify-center gap-2"
|
||||
className={cn('bg-primary gap-2', !collapse && 'justify-center')}
|
||||
collapse={collapse}
|
||||
>
|
||||
<PencilLine strokeWidth={3} />
|
||||
<PencilLine />
|
||||
</SidebarItem>
|
||||
<PostEditor open={open} setOpen={setOpen} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { useNostr } from '@/providers/NostrProvider'
|
|||
import { UserRound } from 'lucide-react'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default function ProfileButton() {
|
||||
export default function ProfileButton({ collapse }: { collapse: boolean }) {
|
||||
const { navigate, current } = usePrimaryPage()
|
||||
const { checkLogin } = useNostr()
|
||||
|
||||
|
|
@ -12,8 +12,9 @@ export default function ProfileButton() {
|
|||
title="Profile"
|
||||
onClick={() => checkLogin(() => navigate('profile'))}
|
||||
active={current === 'profile'}
|
||||
collapse={collapse}
|
||||
>
|
||||
<UserRound strokeWidth={3} />
|
||||
<UserRound />
|
||||
</SidebarItem>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { usePrimaryPage } from '@/PageManager'
|
|||
import { Search } from 'lucide-react'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default function SearchButton() {
|
||||
export default function SearchButton({ collapse }: { collapse: boolean }) {
|
||||
const { navigate, current, display } = usePrimaryPage()
|
||||
|
||||
return (
|
||||
|
|
@ -10,8 +10,9 @@ export default function SearchButton() {
|
|||
title="Search"
|
||||
onClick={() => navigate('search')}
|
||||
active={current === 'search' && display}
|
||||
collapse={collapse}
|
||||
>
|
||||
<Search strokeWidth={3} />
|
||||
<Search />
|
||||
</SidebarItem>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ import { useSecondaryPage } from '@/PageManager'
|
|||
import { Settings } from 'lucide-react'
|
||||
import SidebarItem from './SidebarItem'
|
||||
|
||||
export default function SettingsButton() {
|
||||
export default function SettingsButton({ collapse }: { collapse: boolean }) {
|
||||
const { push } = useSecondaryPage()
|
||||
|
||||
return (
|
||||
<SidebarItem title="Settings" onClick={() => push(toSettings())}>
|
||||
<Settings strokeWidth={3} />
|
||||
<SidebarItem title="Settings" onClick={() => push(toSettings())} collapse={collapse}>
|
||||
<Settings />
|
||||
</SidebarItem>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,17 @@ import { useTranslation } from 'react-i18next'
|
|||
|
||||
const SidebarItem = forwardRef<
|
||||
HTMLButtonElement,
|
||||
ButtonProps & { title: string; description?: string; active?: boolean }
|
||||
>(({ children, title, description, className, active, ...props }, ref) => {
|
||||
ButtonProps & { title: string; collapse: boolean; description?: string; active?: boolean }
|
||||
>(({ children, title, description, className, active, collapse, ...props }, ref) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Button
|
||||
className={cn(
|
||||
'flex shadow-none items-center transition-colors duration-500 bg-transparent w-12 h-12 xl:w-full xl:h-auto p-3 m-0 xl:py-2 xl:px-3 rounded-lg xl:justify-start gap-4 text-lg font-semibold [&_svg]:size-full xl:[&_svg]:size-4',
|
||||
'flex shadow-none items-center transition-colors duration-500 bg-transparent m-0 rounded-lg gap-4 text-lg font-semibold',
|
||||
collapse
|
||||
? 'w-12 h-12 p-3 [&_svg]:size-full'
|
||||
: 'justify-start w-full h-auto py-2 px-3 [&_svg]:size-5',
|
||||
active && 'text-primary hover:text-primary bg-primary/10 hover:bg-primary/10',
|
||||
className
|
||||
)}
|
||||
|
|
@ -22,7 +25,7 @@ const SidebarItem = forwardRef<
|
|||
{...props}
|
||||
>
|
||||
{children}
|
||||
<div className="max-xl:hidden">{t(description ?? title)}</div>
|
||||
{!collapse && <div>{t(description ?? title)}</div>}
|
||||
</Button>
|
||||
)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import Icon from '@/assets/Icon'
|
||||
import Logo from '@/assets/Logo'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useScreenSize } from '@/providers/ScreenSizeProvider'
|
||||
import { useUserPreferences } from '@/providers/UserPreferencesProvider'
|
||||
import { ChevronsLeft, ChevronsRight } from 'lucide-react'
|
||||
import AccountButton from './AccountButton'
|
||||
import RelaysButton from './ExploreButton'
|
||||
import HomeButton from './HomeButton'
|
||||
|
|
@ -12,24 +15,45 @@ import SettingsButton from './SettingsButton'
|
|||
|
||||
export default function PrimaryPageSidebar() {
|
||||
const { isSmallScreen } = useScreenSize()
|
||||
const { sidebarCollapse, updateSidebarCollapse } = useUserPreferences()
|
||||
|
||||
if (isSmallScreen) return null
|
||||
|
||||
return (
|
||||
<div className="w-16 xl:w-52 flex flex-col pb-2 pt-4 px-2 xl:px-4 justify-between h-full shrink-0">
|
||||
<div
|
||||
className={cn(
|
||||
'relative flex flex-col pb-2 pt-3 justify-between h-full shrink-0',
|
||||
sidebarCollapse ? 'px-2 w-16' : 'px-4 w-52'
|
||||
)}
|
||||
>
|
||||
<div className="space-y-2">
|
||||
<div className="px-3 xl:px-4 mb-6 w-full">
|
||||
<Icon className="xl:hidden" />
|
||||
<Logo className="max-xl:hidden" />
|
||||
</div>
|
||||
<HomeButton />
|
||||
<RelaysButton />
|
||||
<NotificationsButton />
|
||||
<SearchButton />
|
||||
<ProfileButton />
|
||||
<SettingsButton />
|
||||
<PostButton />
|
||||
{sidebarCollapse ? (
|
||||
<div className="px-3 py-1 mb-6 w-full">
|
||||
<Icon />
|
||||
</div>
|
||||
) : (
|
||||
<div className="px-4 mb-6 w-full">
|
||||
<Logo />
|
||||
</div>
|
||||
)}
|
||||
<HomeButton collapse={sidebarCollapse} />
|
||||
<RelaysButton collapse={sidebarCollapse} />
|
||||
<NotificationsButton collapse={sidebarCollapse} />
|
||||
<SearchButton collapse={sidebarCollapse} />
|
||||
<ProfileButton collapse={sidebarCollapse} />
|
||||
<SettingsButton collapse={sidebarCollapse} />
|
||||
<PostButton collapse={sidebarCollapse} />
|
||||
</div>
|
||||
<AccountButton />
|
||||
<AccountButton collapse={sidebarCollapse} />
|
||||
<button
|
||||
className="absolute flex flex-col justify-center items-center top-5 right-0 w-5 h-6 p-0 rounded-l-md hover:shadow-md text-muted-foreground hover:text-foreground hover:bg-background transition-colors [&_svg]:size-4"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
updateSidebarCollapse(!sidebarCollapse)
|
||||
}}
|
||||
>
|
||||
{sidebarCollapse ? <ChevronsRight /> : <ChevronsLeft />}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue