Skip to content

Commit

Permalink
feat: better notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
ImLunaHey committed Jan 4, 2025
1 parent c92218f commit 0d26edd
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 170 deletions.
15 changes: 15 additions & 0 deletions src/lib/bluesky/hooks/usePost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useQuery } from '@tanstack/react-query';
import { useBlueskyStore } from '../store';

export function usePost({ handle, rkey }: { handle: string; rkey: string }) {
const agent = useBlueskyStore((store) => store.agent);

return useQuery({
queryKey: ['post', { handle, rkey }],
queryFn: async () => {
const response = await agent.getPost({ repo: handle, rkey });
return response.value;
},
enabled: !!agent && !!handle,
});
}
2 changes: 1 addition & 1 deletion src/lib/bluesky/types/BSkyNotification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export const BSkyReplyNotification = Type.Object({
author: BSkyAuthor,
reason: Type.Literal('reply'),
reasonSubject: Type.Optional(Type.String()),
record: BSkyPost['record'],
record: BSkyPost.properties.record,
isRead: Type.Boolean(),
indexedAt: Type.String(),
labels: Type.Optional(Type.Array(Type.Any())),
Expand Down
114 changes: 1 addition & 113 deletions src/lib/bluesky/types/BSkyPost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,119 +13,7 @@ export const BSkyPost = Type.Object({
record: Type.Object({
$type: Type.Literal('app.bsky.feed.post'),
createdAt: Type.String(),
embed: Type.Optional(
Type.Union([
Type.Object({
$type: Type.Literal('app.bsky.embed.record'),
record: Type.Object({
cid: Type.String(),
uri: Type.String(),
}),
}),
Type.Object({
$type: Type.Literal('app.bsky.embed.recordWithMedia'),
media: Type.Union([
Type.Object({
$type: Type.Literal('app.bsky.embed.external'),
external: Type.Object({
description: Type.String(),
thumb: Type.Object({
$type: Type.Literal('blob'),
ref: Type.Object({
$link: Type.String(),
}),
mimeType: Type.String(),
size: Type.Number(),
}),
title: Type.String(),
uri: Type.String(),
}),
}),
Type.Object({
$type: Type.Literal('app.bsky.embed.images'),
images: Type.Array(
Type.Object({
alt: Type.String(),
aspectRatio: Type.Object({
height: Type.Number(),
width: Type.Number(),
}),
image: Type.Object({
$type: Type.Literal('blob'),
ref: Type.Object({
$link: Type.String(),
}),
mimeType: Type.String(),
size: Type.Number(),
}),
}),
),
}),
]),

record: Type.Object({
$type: Type.Literal('app.bsky.embed.record'),
record: Type.Object({
cid: Type.String(),
uri: Type.String(),
}),
}),
}),
Type.Object({
$type: Type.Literal('app.bsky.embed.images'),
images: Type.Array(
Type.Object({
alt: Type.String(),
aspectRatio: Type.Object({
height: Type.Number(),
width: Type.Number(),
}),
image: Type.Object({
$type: Type.Literal('blob'),
ref: Type.Object({
$link: Type.String(),
}),
mimeType: Type.String(),
size: Type.Number(),
}),
}),
),
}),
Type.Object({
$type: Type.Literal('app.bsky.embed.video'),
alt: Type.Optional(Type.String()),
aspectRatio: Type.Object({
height: Type.Number(),
width: Type.Number(),
}),
video: Type.Object({
$type: Type.Literal('blob'),
ref: Type.Object({
$link: Type.String(),
}),
mimeType: Type.String(),
size: Type.Number(),
}),
}),
Type.Object({
$type: Type.Literal('app.bsky.embed.external'),
external: Type.Object({
description: Type.String(),
thumb: Type.Object({
$type: Type.Literal('blob'),
ref: Type.Object({
$link: Type.String(),
}),
mimeType: Type.String(),
size: Type.Number(),
}),

title: Type.String(),
uri: Type.String(),
}),
}),
]),
),
embed: Type.Optional(BSkyPostEmbed),
facets: Type.Optional(Type.Array(BSkyFacet)),
langs: Type.Optional(Type.Array(Type.String())),
reply: Type.Optional(
Expand Down
112 changes: 112 additions & 0 deletions src/lib/bluesky/types/BSkyPostEmbed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,116 @@ export const BSkyPostEmbed = Type.Recursive((Self) => {
]);
});

// Type.Union([
// Type.Object({
// $type: Type.Literal('app.bsky.embed.record'),
// record: Type.Object({
// cid: Type.String(),
// uri: Type.String(),
// }),
// }),
// Type.Object({
// $type: Type.Literal('app.bsky.embed.recordWithMedia'),
// media: Type.Union([
// Type.Object({
// $type: Type.Literal('app.bsky.embed.external'),
// external: Type.Object({
// description: Type.String(),
// thumb: Type.Object({
// $type: Type.Literal('blob'),
// ref: Type.Object({
// $link: Type.String(),
// }),
// mimeType: Type.String(),
// size: Type.Number(),
// }),
// title: Type.String(),
// uri: Type.String(),
// }),
// }),
// Type.Object({
// $type: Type.Literal('app.bsky.embed.images'),
// images: Type.Array(
// Type.Object({
// alt: Type.String(),
// aspectRatio: Type.Object({
// height: Type.Number(),
// width: Type.Number(),
// }),
// image: Type.Object({
// $type: Type.Literal('blob'),
// ref: Type.Object({
// $link: Type.String(),
// }),
// mimeType: Type.String(),
// size: Type.Number(),
// }),
// }),
// ),
// }),
// ]),

// record: Type.Object({
// $type: Type.Literal('app.bsky.embed.record'),
// record: Type.Object({
// cid: Type.String(),
// uri: Type.String(),
// }),
// }),
// }),
// Type.Object({
// $type: Type.Literal('app.bsky.embed.images'),
// images: Type.Array(
// Type.Object({
// alt: Type.String(),
// aspectRatio: Type.Object({
// height: Type.Number(),
// width: Type.Number(),
// }),
// image: Type.Object({
// $type: Type.Literal('blob'),
// ref: Type.Object({
// $link: Type.String(),
// }),
// mimeType: Type.String(),
// size: Type.Number(),
// }),
// }),
// ),
// }),
// Type.Object({
// $type: Type.Literal('app.bsky.embed.video'),
// alt: Type.Optional(Type.String()),
// aspectRatio: Type.Object({
// height: Type.Number(),
// width: Type.Number(),
// }),
// video: Type.Object({
// $type: Type.Literal('blob'),
// ref: Type.Object({
// $link: Type.String(),
// }),
// mimeType: Type.String(),
// size: Type.Number(),
// }),
// }),
// Type.Object({
// $type: Type.Literal('app.bsky.embed.external'),
// external: Type.Object({
// description: Type.String(),
// thumb: Type.Object({
// $type: Type.Literal('blob'),
// ref: Type.Object({
// $link: Type.String(),
// }),
// mimeType: Type.String(),
// size: Type.Number(),
// }),

// title: Type.String(),
// uri: Type.String(),
// }),
// }),
// ]),

export type BSkyPostEmbed = Static<typeof BSkyPostEmbed>;
34 changes: 22 additions & 12 deletions src/routes/notifications/components/FollowNotification.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
import { Avatar } from '@/components/ui/avatar';
import { Link } from '@/components/ui/Link';
import { BSkyFollowNotification } from '@/lib/bluesky/types/BSkyNotification';
import { UserPlus2 } from 'lucide-react';
import { useTranslation } from 'react-i18next';

export function FollowNotification({ notification }: { notification: BSkyFollowNotification }) {
const { t } = useTranslation('notifications');
return (
<Link
to="/profile/$handle"
params={{
handle: notification.author.handle,
}}
className="hover:no-underline"
>
<div className="p-2">
<div className="flex flex-row gap-1 overflow-hidden max-h-16">
<Avatar handle={notification.author.handle} avatar={notification.author.avatar} className="size-8 " />
<div className="p-2">
<div className="flex flex-row gap-2 p-2">
<div className="flex flex-shrink-0 w-12 justify-end aspect-square">
<UserPlus2 className="stroke-blue-400 size-6" />
</div>
<div>
{notification.author.displayName} {t('followedYou')}
<Link
to="/profile/$handle"
params={{
handle: notification.author.handle,
}}
className="hover:no-underline"
>
<div className="flex flex-row gap-2">
<div className="flex flex-row gap-1 overflow-hidden max-h-16">
<Avatar handle={notification.author.handle} avatar={notification.author.avatar} className="size-8" />
</div>
<div>
{notification.author.displayName} {t('followedYou')}
</div>
</div>
</Link>
</div>
</div>
</Link>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { forwardRef, HtmlHTMLAttributes, Ref } from 'react';
import { useTranslation } from 'react-i18next';
import { Virtuoso } from 'react-virtuoso';
import { GroupNotification } from './GroupNotification';
import { HeartIcon } from 'lucide-react';

Check failure on line 9 in src/routes/notifications/components/GroupedNotifications.tsx

View workflow job for this annotation

GitHub Actions / lint (22.x)

'HeartIcon' is defined but never used

// group notifications by uri
export function GroupedNotifications() {
Expand Down
Loading

0 comments on commit 0d26edd

Please sign in to comment.