feat: update layout

This commit is contained in:
codytseng 2025-08-27 21:56:46 +08:00
parent f41536a793
commit 8b1c2ebe3f
30 changed files with 230 additions and 250 deletions

View file

@ -8,7 +8,7 @@ export default function BottomNavigationBar() {
return (
<div
className={cn(
'fixed bottom-0 w-full z-40 bg-background/80 backdrop-blur-xl flex items-center justify-around [&_svg]:size-4 [&_svg]:shrink-0'
'fixed bottom-0 w-full z-40 bg-background border-t flex items-center justify-around [&_svg]:size-4 [&_svg]:shrink-0'
)}
style={{
height: 'calc(3rem + env(safe-area-inset-bottom))',

View file

@ -88,7 +88,7 @@ export default function KindFilter({
key={label}
className={cn(
'cursor-pointer grid gap-1.5 rounded-lg border px-4 py-3',
checked ? 'border-primary bg-primary/20' : 'clickable'
checked ? 'border-primary/60 bg-primary/5' : 'clickable'
)}
onClick={() => {
console.log(checked)
@ -166,7 +166,7 @@ export default function KindFilter({
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>{trigger}</PopoverTrigger>
<PopoverContent className="w-96" collisionPadding={16}>
<PopoverContent className="w-96" collisionPadding={16} sideOffset={0}>
{content}
</PopoverContent>
</Popover>

View file

@ -2,6 +2,7 @@ import { Button } from '@/components/ui/button'
import { SimpleUserAvatar } from '@/components/UserAvatar'
import { cn } from '@/lib/utils'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { ArrowUp } from 'lucide-react'
import { Event } from 'nostr-tools'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
@ -32,34 +33,25 @@ export default function NewNotesButton({
<div
className={cn(
'w-full flex justify-center z-40 pointer-events-none',
isSmallScreen ? 'fixed' : 'absolute bottom-4'
isSmallScreen ? 'fixed' : 'absolute bottom-6'
)}
style={isSmallScreen ? { bottom: 'calc(4rem + env(safe-area-inset-bottom))' } : undefined}
>
<Button
onClick={onClick}
className="group rounded-full h-fit pl-2 pr-3 hover:bg-primary-hover pointer-events-auto"
className="group rounded-full h-fit py-2 pl-2 pr-3 hover:bg-primary-hover pointer-events-auto"
>
{pubkeys.length > 0 && (
<div className="flex items-center">
{pubkeys.map((pubkey, index) => (
<div
key={pubkey}
className="relative -mr-2.5 last:mr-0"
style={{ zIndex: 3 - index }}
>
<SimpleUserAvatar
userId={pubkey}
size="small"
className="border-primary border-2 group-hover:border-primary-hover"
/>
</div>
<div className="*:data-[slot=avatar]:ring-background flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:grayscale">
{pubkeys.map((pubkey) => (
<SimpleUserAvatar userId={pubkey} size="small" />
))}
</div>
)}
<div className="text-md font-medium">
{t('Show n new notes', { n: newEvents.length > 99 ? '99+' : newEvents.length })}
</div>
<ArrowUp />
</Button>
</div>
)}

View file

@ -209,7 +209,7 @@ const NoteList = forwardRef(
setEvents((oldEvents) => [...newEvents, ...oldEvents])
setNewEvents([])
setTimeout(() => {
scrollToTop()
scrollToTop('smooth')
}, 0)
}
@ -218,7 +218,7 @@ const NoteList = forwardRef(
{filteredNewEvents.length > 0 && (
<NewNotesButton newEvents={filteredNewEvents} onClick={showNewEvents} />
)}
<div ref={topRef} className="scroll-mt-24" />
<div ref={topRef} className="scroll-mt-[calc(6rem+1px)]" />
<PullToRefresh
onRefresh={async () => {
setRefreshCount((count) => count + 1)

View file

@ -35,7 +35,7 @@ export default function ProfileList({ pubkeys }: { pubkeys: string[] }) {
}, [visiblePubkeys, pubkeys])
return (
<div className="px-4">
<div className="px-4 pt-2">
{visiblePubkeys.map((pubkey, index) => (
<UserItem key={`${index}-${pubkey}`} pubkey={pubkey} />
))}

View file

@ -12,8 +12,8 @@ const SidebarItem = forwardRef<
return (
<Button
className={cn(
'flex shadow-none items-center bg-transparent w-12 h-12 xl:w-full xl:h-auto p-3 m-0 xl:py-2 xl:px-4 rounded-lg xl:justify-start gap-4 text-lg font-semibold [&_svg]:size-full xl:[&_svg]:size-4',
active && 'text-primary hover:text-primary',
'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',
active && 'text-primary hover:text-primary bg-primary/10 hover:bg-primary/10',
className
)}
variant="ghost"

View file

@ -14,7 +14,7 @@ export default function PrimaryPageSidebar() {
if (isSmallScreen) return null
return (
<div className="w-16 xl:w-52 flex flex-col pb-2 pt-4 px-2 justify-between h-full shrink-0">
<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="space-y-2">
<div className="px-3 xl:px-4 mb-6 w-full">
<Icon className="xl:hidden" />

View file

@ -87,7 +87,7 @@ export default function Tabs({
<div
ref={containerRef}
className={cn(
'sticky flex justify-between top-12 bg-background z-30 px-1 w-full transition-transform',
'sticky flex justify-between top-12 bg-background z-30 px-1 w-full transition-transform border-b',
deepBrowsing && lastScrollTop > threshold ? '-translate-y-[calc(100%+12rem)]' : ''
)}
>

View file

@ -2,15 +2,18 @@ import { cn } from '@/lib/utils'
export function Titlebar({
children,
className
className,
hideBottomBorder = false
}: {
children?: React.ReactNode
className?: string
hideBottomBorder?: boolean
}) {
return (
<div
className={cn(
'sticky top-0 w-full h-12 z-40 bg-background [&_svg]:size-5 [&_svg]:shrink-0 select-none',
!hideBottomBorder && 'border-b',
className
)}
>