@@ -6,38 +6,45 @@ import { useBlueskyStore } from '../lib/bluesky/store';
66import { BellIcon , HomeIcon , LogInIcon , MailIcon , SearchIcon , SettingsIcon , UserIcon } from 'lucide-react' ;
77import { CreatePost } from './CreatePost' ;
88import { cn } from '@/lib/utils' ;
9- import { appName } from '@/config' ;
109import { useQueryClient } from '@tanstack/react-query' ;
1110import { useUnreadCount } from '@/lib/bluesky/hooks/useUnreadCount' ;
1211import { useConversations } from '@/lib/bluesky/hooks/useConversations' ;
12+ import { useScollVisible } from '@/hooks/useScrollVisible' ;
13+ import { Avatar } from './ui/avatar' ;
14+ import { useProfile } from '@/lib/bluesky/hooks/useProfile' ;
1315
1416const HomeLink = ( ) => {
17+ const { t } = useTranslation ( 'app' ) ;
1518 const location = useLocation ( ) ;
1619 const queryClient = useQueryClient ( ) ;
1720 return (
1821 < Link
1922 to = "/"
20- onClick = { ( ) => {
23+ onClick = { async ( ) => {
2124 // if we're on the homepage already we need to invalidate the associated query
2225 if ( location . pathname === '/' ) {
2326 // @TODO : we should really be invalidating the query for the current feed not all feeds
24- queryClient . invalidateQueries ( {
27+ await queryClient . invalidateQueries ( {
2528 queryKey : [ 'feed' ] ,
2629 } ) ;
2730 }
2831 } }
32+ className = "flex flex-row items-center gap-2 p-3 rounded-sm hover:no-underline hover:bg-gray-200 dark:hover:bg-gray-700"
2933 >
30- < HomeIcon className = "size-7 xl:hidden " />
31- < h1 className = "text-2xl font-bold hidden xl:block" > { appName } </ h1 >
34+ < HomeIcon className = "size-7 xl:size-6 active:scale-90 " />
35+ < span className = "hidden xl:block" > { t ( 'home' ) } </ span >
3236 </ Link >
3337 ) ;
3438} ;
3539
3640const SearchLink = ( ) => {
3741 const { t } = useTranslation ( 'search' ) ;
3842 return (
39- < Link to = "/search" >
40- < SearchIcon className = "size-7 xl:hidden" />
43+ < Link
44+ to = "/search"
45+ className = "flex flex-row items-center gap-2 p-3 rounded-sm hover:no-underline hover:bg-gray-200 dark:hover:bg-gray-700"
46+ >
47+ < SearchIcon className = "size-7 xl:size-6 active:scale-90" />
4148 < span className = "hidden xl:block" > { t ( 'search' ) } </ span >
4249 </ Link >
4350 ) ;
@@ -48,9 +55,12 @@ const MessagesLink = () => {
4855 const { data : convos } = useConversations ( ) ;
4956 const unreadCount = convos ?. map ( ( convo ) => convo . unreadCount ) . reduce ( ( a , b ) => a + b , 0 ) ?? 0 ;
5057 return (
51- < Link to = "/messages" >
52- < div className = "relative" >
53- < MailIcon className = "size-7 xl:hidden" />
58+ < Link
59+ to = "/messages"
60+ className = "flex flex-row items-center gap-2 p-3 rounded-sm hover:no-underline hover:bg-gray-200 dark:hover:bg-gray-700"
61+ >
62+ < div className = "relative active:scale-90" >
63+ < MailIcon className = "size-7 xl:size-6" />
5464 { unreadCount > 0 && (
5565 < span className = "absolute top-0 right-0 inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-red-100 bg-blue-500 rounded-full transform translate-x-1/2 -translate-y-1/2" >
5666 { unreadCount }
@@ -66,9 +76,12 @@ const NotificationsLink = () => {
6676 const { t } = useTranslation ( 'notifications' ) ;
6777 const { data : unreadCount } = useUnreadCount ( ) ;
6878 return (
69- < Link to = "/notifications" >
79+ < Link
80+ to = "/notifications"
81+ className = "flex flex-row items-center gap-2 p-3 rounded-sm hover:no-underline hover:bg-gray-200 dark:hover:bg-gray-700"
82+ >
7083 < div className = "relative" >
71- < BellIcon className = "size-7 xl:hidden " />
84+ < BellIcon className = "size-7 xl:size-6 active:scale-90 " />
7285 { unreadCount > 0 && (
7386 < span className = "absolute top-0 right-0 inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-red-100 bg-blue-500 rounded-full transform translate-x-1/2 -translate-y-1/2" >
7487 { unreadCount }
@@ -92,8 +105,9 @@ const ProfileLink = () => {
92105 params = { {
93106 handle : session ?. handle ,
94107 } }
108+ className = "flex flex-row items-center gap-2 p-3 rounded-sm hover:no-underline hover:bg-gray-200 dark:hover:bg-gray-700"
95109 >
96- < UserIcon className = "size-7 xl:hidden " />
110+ < UserIcon className = "size-7 xl:size-6 active:scale-90 " />
97111 < span className = "hidden xl:block" > { t ( 'profile' ) } </ span >
98112 </ Link >
99113 ) ;
@@ -102,8 +116,11 @@ const ProfileLink = () => {
102116const SettingsLink = ( ) => {
103117 const { t } = useTranslation ( 'app' ) ;
104118 return (
105- < Link to = "/settings" >
106- < SettingsIcon className = "size-7 xl:hidden" />
119+ < Link
120+ to = "/settings"
121+ className = "flex flex-row items-center gap-2 p-3 rounded-sm hover:no-underline hover:bg-gray-200 dark:hover:bg-gray-700"
122+ >
123+ < SettingsIcon className = "size-7 xl:size-6 active:scale-90" />
107124 < span className = "hidden xl:block" > { t ( 'settings' ) } </ span >
108125 </ Link >
109126 ) ;
@@ -113,7 +130,7 @@ const LoginButton = () => {
113130 const { t } = useTranslation ( 'auth' ) ;
114131 return (
115132 < Link to = "/login" >
116- < LogInIcon className = "size-7 xl:hidden" />
133+ < LogInIcon className = "size-7 xl:hidden active:scale-90 " />
117134 < span className = "hidden xl:block" > { t ( 'login.default' ) } </ span >
118135 </ Link >
119136 ) ;
@@ -122,19 +139,26 @@ const LoginButton = () => {
122139export const Navbar = ( ) => {
123140 const { isAuthenticated } = useAuth ( ) ;
124141 const location = useLocation ( ) ;
142+ const isVisible = useScollVisible ( ) ;
143+ const handle = useBlueskyStore ( ( state ) => state . session ?. handle ) ;
144+ const { data : profile } = useProfile ( { handle } ) ;
125145
126146 return (
127147 < div
128148 className = { cn (
129- 'bg-background text-foreground' ,
149+ 'bg-background text-foreground sticky ' ,
130150 // base
131- 'px-4 pt-1 z-50 ' ,
151+ 'px-4 pt-1 z-40 ' ,
132152 // mobile
133153 'fixed bottom-0 left-0 right-0 pb-safe border-t border-gray-200 dark:border-gray-800' ,
134154 // tablet
135155 'md:top-0 md:right-auto md:border-r md:border-gray-200 md:dark:border-gray-800' ,
136156 // desktop
137157 'xl:bg-inherit xl:sticky xl:h-screen xl:border-none xl:top-0' ,
158+ // transition
159+ 'transform transition-transform duration-200 ease-in-out' ,
160+ isVisible ? 'translate-y-0' : 'translate-y-full' ,
161+ 'md:translate-y-0' ,
138162 ) }
139163 >
140164 < div
@@ -147,6 +171,9 @@ export const Navbar = () => {
147171 'xl:space-y-0' ,
148172 ) }
149173 >
174+ < div className = "flex flex-row items-center gap-2 p-3" >
175+ { handle && < Avatar handle = { handle } avatar = { profile ?. avatar } hover = { false } /> }
176+ </ div >
150177 < HomeLink />
151178 < SearchLink />
152179 { isAuthenticated && < MessagesLink /> }
0 commit comments