feat: improve mobile experience

This commit is contained in:
codytseng
2025-01-02 21:57:14 +08:00
parent 8ec0d46d58
commit 3946e603b3
98 changed files with 2508 additions and 1058 deletions

View File

@@ -0,0 +1,29 @@
import { usePrimaryPage } from '@/PageManager'
import { useNostr } from '@/providers/NostrProvider'
import { UserRound } from 'lucide-react'
import { SimpleUserAvatar } from '../UserAvatar'
import BottomNavigationBarItem from './BottomNavigationBarItem'
export default function AccountButton() {
const { navigate, current } = usePrimaryPage()
const { pubkey } = useNostr()
return (
<BottomNavigationBarItem
onClick={() => {
navigate('me')
}}
active={current === 'me'}
>
{pubkey ? (
<SimpleUserAvatar
userId={pubkey}
size="small"
className={current === 'me' ? 'ring-primary ring-1' : ''}
/>
) : (
<UserRound />
)}
</BottomNavigationBarItem>
)
}

View File

@@ -0,0 +1,27 @@
import { cn } from '@/lib/utils'
import { Button } from '../ui/button'
import { MouseEventHandler } from 'react'
export default function BottomNavigationBarItem({
children,
active = false,
onClick
}: {
children: React.ReactNode
active?: boolean
onClick: MouseEventHandler
}) {
return (
<Button
className={cn(
'flex shadow-none items-center bg-transparent w-full h-12 xl:w-full xl:h-auto p-3 m-0 xl:py-2 xl:px-4 rounded-lg xl:justify-start text-lg font-semibold [&_svg]:size-full xl:[&_svg]:size-4',
active && 'text-primary disabled:opacity-100'
)}
disabled={active}
variant="ghost"
onClick={onClick}
>
{children}
</Button>
)
}

View File

@@ -0,0 +1,13 @@
import { usePrimaryPage } from '@/PageManager'
import { Home } from 'lucide-react'
import BottomNavigationBarItem from './BottomNavigationBarItem'
export default function HomeButton() {
const { navigate, current } = usePrimaryPage()
return (
<BottomNavigationBarItem active={current === 'home'} onClick={() => navigate('home')}>
<Home />
</BottomNavigationBarItem>
)
}

View File

@@ -0,0 +1,16 @@
import { usePrimaryPage } from '@/PageManager'
import { Bell } from 'lucide-react'
import BottomNavigationBarItem from './BottomNavigationBarItem'
export default function NotificationsButton() {
const { navigate, current } = usePrimaryPage()
return (
<BottomNavigationBarItem
active={current === 'notifications'}
onClick={() => navigate('notifications')}
>
<Bell />
</BottomNavigationBarItem>
)
}

View File

@@ -0,0 +1,22 @@
import PostEditor from '@/components/PostEditor'
import { PencilLine } from 'lucide-react'
import { useState } from 'react'
import BottomNavigationBarItem from './BottomNavigationBarItem'
export default function PostButton() {
const [open, setOpen] = useState(false)
return (
<>
<BottomNavigationBarItem
onClick={(e) => {
e.stopPropagation()
setOpen(true)
}}
>
<PencilLine />
</BottomNavigationBarItem>
<PostEditor open={open} setOpen={setOpen} />
</>
)
}

View File

@@ -0,0 +1,25 @@
import { cn } from '@/lib/utils'
import HomeButton from './HomeButton'
import NotificationsButton from './NotificationsButton'
import PostButton from './PostButton'
import AccountButton from './AccountButton'
export default function BottomNavigationBar({ visible = true }: { visible?: boolean }) {
return (
<div
className={cn(
'fixed bottom-0 w-full z-20 bg-background/90 backdrop-blur-xl duration-700 transition-transform flex items-center justify-around [&_svg]:size-4 [&_svg]:shrink-0',
visible ? '' : 'translate-y-full'
)}
style={{
height: 'calc(3rem + env(safe-area-inset-bottom))',
paddingBottom: 'env(safe-area-inset-bottom)'
}}
>
<HomeButton />
<PostButton />
<NotificationsButton />
<AccountButton />
</div>
)
}