Skip to content

Commit

Permalink
fix: add sticky header to posts
Browse files Browse the repository at this point in the history
  • Loading branch information
ImLunaHey committed Jan 7, 2025
1 parent 06335d8 commit b71ffff
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/components/PostCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export function PostCard({ post, context, className, onClick }: PostCardProps) {
params={{ handle: post.author.handle, postId: post.uri.split('/').pop()! }}
className="absolute inset-0"
/>
<div className="flex flex-col border-b border-gray-200 dark:border-gray-800">
<div className="flex flex-col">
<div className={cn('p-3 w-full max-w-[550px] gap-2 flex flex-row', className)} onClick={onClick} id={post.uri}>
<div className="flex-shrink-0">
<Avatar handle={post.author.handle} avatar={post.author.avatar} />
Expand Down
2 changes: 1 addition & 1 deletion src/components/Timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export function Timeline({ columnNumber = 1 }: { columnNumber: number }) {
endReached={() => fetchNextPage()}
components={{
List: forwardRef(function List(props, ref) {
return <div ref={ref} {...props} className="flex flex-col" />;
return <div ref={ref} {...props} className="flex flex-col divide-y" />;
}),
}}
itemContent={(index: number) => (
Expand Down
1 change: 1 addition & 0 deletions src/i18n/lang/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const en = {
blueskyHandle: 'bluesky handle e.g. @alice.bsky.social',
following: 'following',
followers: 'followers',
post: 'post',
posts: 'posts',
replies: 'replies',
reposts: 'reposts',
Expand Down
2 changes: 1 addition & 1 deletion src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function Root() {
<Navbar />
<div className="flex justify-center mx-auto">
<ErrorBoundary>
<div className={cn('flex flex-col gap-2 sm:border-x', pathname !== '/' && 'w-screen sm:w-[550px]')}>
<div className={cn('flex flex-col sm:border-x', pathname !== '/' && 'w-screen sm:w-[550px]')}>
<Outlet key="app" />
</div>
</ErrorBoundary>
Expand Down
58 changes: 31 additions & 27 deletions src/routes/profile/$handle/index.lazy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const Route = createLazyFileRoute('/profile/$handle/')({
});

const List = forwardRef(function List(props: HtmlHTMLAttributes<HTMLDivElement>, ref: Ref<HTMLDivElement>) {
return <div ref={ref} {...props} className="flex flex-col gap-2" />;
return <div ref={ref} {...props} className="flex flex-col divide-y" />;
});

function All() {
Expand Down Expand Up @@ -146,7 +146,9 @@ function Media() {

const filteredPosts = feed
// Filter to only media
?.filter(({ post }) => (post.record as BSkyPost['record']).embed?.$type === 'app.bsky.embed.images');
// TODO: fix this
// eslint-disable-next-line @typescript-eslint/no-explicit-any
?.filter(({ post }) => (post.record as any).embed?.$type === 'app.bsky.embed.images');

return (
<Virtuoso
Expand Down Expand Up @@ -183,35 +185,37 @@ function Profile() {
{profile.displayName} (@{handle})
</title>
</Helmet>
<div className="flex flex-col gap-2">
<Banner banner={profile?.banner} />
<div className="px-4 -mt-12">
<Avatar avatar={profile?.avatar} handle={profile.handle} className="size-24" />
<div>
<div className="flex gap-2">
<h2 className="text-xl font-bold">{profile?.displayName || profile.handle}</h2>
<Badge title={profile.viewer?.following && profile.viewer?.followedBy ? 'You both follow each other' : ''}>
{profile.viewer?.following && profile.viewer?.followedBy && 'Mutuals'}
</Badge>
{handle !== session?.handle && <FollowButton handle={handle} following={!!profile.viewer?.following} />}
</div>
<Handle handle={profile.handle} />
{!experiments.zenMode && (
<div className="flex flex-col">
<div className="flex flex-col gap-2">
<Banner banner={profile?.banner} />
<div className="px-4 -mt-12">
<Avatar avatar={profile?.avatar} handle={profile.handle} className="size-24" />
<div>
<div className="flex gap-2">
<FormattedNumber value={profile?.followersCount} unit={t('followers')} />
<FormattedNumber value={profile?.followsCount} unit={t('following')} />
<FormattedNumber value={profile?.postsCount} unit={t('posts')} />
<h2 className="text-xl font-bold">{profile?.displayName || profile.handle}</h2>
<Badge title={profile.viewer?.following && profile.viewer?.followedBy ? 'You both follow each other' : ''}>
{profile.viewer?.following && profile.viewer?.followedBy && 'Mutuals'}
</Badge>
{handle !== session?.handle && <FollowButton handle={handle} following={!!profile.viewer?.following} />}
</div>
)}
<FormattedText text={profile?.description ?? ''} linkify key="profile-description" />
<Handle handle={profile.handle} />
{!experiments.zenMode && (
<div className="flex gap-2">
<FormattedNumber value={profile?.followersCount} unit={t('followers')} />
<FormattedNumber value={profile?.followsCount} unit={t('following')} />
<FormattedNumber value={profile?.postsCount} unit={t('posts')} />
</div>
)}
<FormattedText text={profile?.description ?? ''} linkify key="profile-description" />

{profile.viewer?.blockingByList && (
<div className="p-2 border mt-2">
<span>{t('profile:blockedBy', { name: profile.viewer.blockingByList.name })}</span>
</div>
)}
{profile.viewer?.blockingByList && (
<div className="p-2 border mt-2">
<span>{t('profile:blockedBy', { name: profile.viewer.blockingByList.name })}</span>
</div>
)}

<Debug value={profile} />
<Debug value={profile} />
</div>
</div>
</div>
{!profile.viewer?.blockingByList && (
Expand Down
12 changes: 8 additions & 4 deletions src/routes/profile/$handle/post.$postId.lazy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import { Helmet } from 'react-helmet';
import { Loading } from '@/components/ui/loading';
import { Virtuoso } from 'react-virtuoso';
import { forwardRef, HtmlHTMLAttributes, Ref } from 'react';
import { StickyHeader } from '@/components/sticky-header';

export const Route = createLazyFileRoute('/profile/$handle/post/$postId')({
component: Post,
});

const List = forwardRef(function List(props: HtmlHTMLAttributes<HTMLDivElement>, ref: Ref<HTMLDivElement>) {
return <div ref={ref} {...props} className="flex flex-col gap-2" />;
return <div ref={ref} {...props} className="flex flex-col divide-y" />;
});

function Post() {
Expand All @@ -37,20 +38,23 @@ function Post() {
<Helmet>
<link rel="canonical" href={`https://bsky.app/profile/${handle}/post/${params.postId}`} />
</Helmet>
<div className="border-x h-screen">
<StickyHeader>
<h1 className="text-xl font-bold">{t('post')}</h1>
</StickyHeader>
<div className="border-x h-full">
<Virtuoso
useWindowScroll
// we need the [&>*]: since we're targeting the window scroll div
// and the div is inside of the Virtuoso component
className="[&>*]:flex [&>*]:flex-col [&>*]:gap-2"
className="[&>*]:flex [&>*]:flex-col"
totalCount={replies.length}
itemContent={(index) => {
const reply = replies?.[index];
if (!reply) return null;
return reply.post && <PostCard post={reply.post} key={reply.post.uri} />;
}}
components={{
Header: () => <PostCard post={postThread?.post as BSkyPost} />,
Header: () => <PostCard post={postThread?.post as BSkyPost} className="border-b" />,
List,
}}
/>
Expand Down

0 comments on commit b71ffff

Please sign in to comment.