update notification

This commit is contained in:
Ren Amamiya 2023-07-23 15:54:34 +07:00
parent f0fb1bee1e
commit 13ca8a2c54
10 changed files with 116 additions and 48 deletions

View File

@ -33,6 +33,10 @@ button {
@apply outline-fuchsia-500;
}
iframe {
height: auto !important;
}
/* For Webkit-based browsers (Chrome, Safari and Opera) */
.scrollbar-hide::-webkit-scrollbar {
display: none;

View File

@ -56,8 +56,8 @@ export const MentionNote = memo(function MentionNote({ id }: { id: string }) {
},
}}
>
{data?.content?.parsed?.length > 200
? data.content.parsed.substring(0, 200) + '...'
{data?.content?.parsed?.length > 160
? data.content.parsed.substring(0, 160) + '...'
: data.content.parsed}
</ReactMarkdown>
</div>

View File

@ -2,7 +2,7 @@ import ReactPlayer from 'react-player/es6';
export function VideoPreview({ urls }: { urls: string[] }) {
return (
<div className="relative mb-2 mt-3 flex w-full max-w-[420px] flex-col gap-2">
<div className="relative mb-2 mt-3 flex w-full flex-col gap-2">
{urls.map((url) => (
<ReactPlayer
key={url}

View File

@ -0,0 +1,5 @@
export * from './user';
export * from './modal';
export * from './types/reaction';
export * from './types/repost';
export * from './types/mention';

View File

@ -6,8 +6,7 @@ import { useCallback } from 'react';
import { useNDK } from '@libs/ndk/provider';
import { BellIcon, CancelIcon, LoaderIcon } from '@shared/icons';
import { NotificationUser } from '@shared/notification/user';
import { User } from '@shared/user';
import { NotiMention, NotiReaction, NotiRepost } from '@shared/notification';
import { nHoursAgo } from '@utils/date';
import { LumeEvent } from '@utils/types';
@ -22,7 +21,9 @@ export function NotificationModal({ pubkey }: { pubkey: string }) {
{ '#p': [pubkey], kinds: [1, 6, 7, 9735] },
{ since: nHoursAgo(24) }
);
return events as unknown as LumeEvent[];
const filterSelf = events.filter((el) => el.pubkey !== pubkey);
const sorted = filterSelf.sort((a, b) => a.created_at - b.created_at);
return sorted as unknown as LumeEvent[];
},
{
refetchOnWindowFocus: false,
@ -33,36 +34,13 @@ export function NotificationModal({ pubkey }: { pubkey: string }) {
(event: NDKEvent) => {
switch (event.kind) {
case 1:
return (
<div key={event.id} className="flex flex-col px-5 py-2">
<User pubkey={event.pubkey} time={event.created_at} isChat={true} />
<div className="-mt-[20px] pl-[49px]">
<p className="select-text whitespace-pre-line break-words text-base text-zinc-100">
{event.content}
</p>
</div>
</div>
);
return <NotiMention key={event.id} event={event} />;
case 6:
return (
<div key={event.id} className="flex flex-col px-5 py-2">
<NotificationUser pubkey={event.pubkey} desc="repost your post" />
</div>
);
return <NotiRepost key={event.id} event={event} />;
case 7:
return (
<div key={event.id} className="flex flex-col px-5 py-2">
<NotificationUser pubkey={event.pubkey} desc="liked your post" />
</div>
);
case 9735:
return (
<div key={event.id} className="flex flex-col px-5 py-2">
<NotificationUser pubkey={event.pubkey} desc="zapped your post" />
</div>
);
return <NotiReaction key={event.id} event={event} />;
default:
return <div className="flex flex-col px-5 py-2">{event.content}</div>;
return null;
}
},
[data]

View File

@ -0,0 +1,34 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { useMemo } from 'react';
import { MentionNote, NoteContent } from '@shared/notes';
import { NotiUser } from '@shared/notification';
import { formatCreatedAt } from '@utils/createdAt';
import { parser } from '@utils/parser';
export function NotiMention({ event }: { event: NDKEvent }) {
const replyTo = event.tags.find((e) => e[0] === 'e')?.[1];
const createdAt = formatCreatedAt(event.created_at);
const content = useMemo(() => parser(event), [event]);
return (
<div className="flex h-min flex-col px-5 py-2">
<div className="flex items-start justify-between">
<div className="flex items-start gap-1">
<NotiUser pubkey={event.pubkey} />
<p className="leading-none text-zinc-400">reply your post</p>
</div>
<div>
<span className="leading-none text-zinc-500">{createdAt}</span>
</div>
</div>
<div className="-mt-4 pl-[35px]">
<div>
<NoteContent content={content} />
</div>
{replyTo && <MentionNote id={replyTo} />}
</div>
</div>
);
}

View File

@ -0,0 +1,26 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { MentionNote } from '@shared/notes';
import { NotiUser } from '@shared/notification';
import { formatCreatedAt } from '@utils/createdAt';
export function NotiReaction({ event }: { event: NDKEvent }) {
const root = event.tags.find((e) => e[0] === 'e')?.[1];
const createdAt = formatCreatedAt(event.created_at);
return (
<div className="flex h-min flex-col px-5 py-2">
<div className="flex items-start justify-between">
<div className="flex items-start gap-1">
<NotiUser pubkey={event.pubkey} />
<p className="leading-none text-zinc-400">reacted {event.content}</p>
</div>
<div>
<span className="leading-none text-zinc-500">{createdAt}</span>
</div>
</div>
<div className="-mt-4 pl-[35px]">{root && <MentionNote id={root} />}</div>
</div>
);
}

View File

@ -0,0 +1,26 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { MentionNote } from '@shared/notes';
import { NotiUser } from '@shared/notification';
import { formatCreatedAt } from '@utils/createdAt';
export function NotiRepost({ event }: { event: NDKEvent }) {
const root = event.tags.find((e) => e[0] === 'e')?.[1];
const createdAt = formatCreatedAt(event.created_at);
return (
<div className="flex h-min flex-col px-5 py-2">
<div className="flex items-start justify-between">
<div className="flex items-start gap-1">
<NotiUser pubkey={event.pubkey} />
<p className="leading-none text-zinc-400">repost your post</p>
</div>
<div>
<span className="leading-none text-zinc-500">{createdAt}</span>
</div>
</div>
<div className="-mt-4 pl-[35px]">{root && <MentionNote id={root} />}</div>
</div>
);
}

View File

@ -3,39 +3,35 @@ import { Image } from '@shared/image';
import { DEFAULT_AVATAR } from '@stores/constants';
import { useProfile } from '@utils/hooks/useProfile';
import { shortenKey } from '@utils/shortenKey';
import { displayNpub } from '@utils/shortenKey';
export function NotificationUser({ pubkey, desc }: { pubkey: string; desc: string }) {
export function NotiUser({ pubkey }: { pubkey: string }) {
const { status, user } = useProfile(pubkey);
if (status === 'loading') {
return (
<div className="flex items-center gap-2">
<div className="relative h-11 w-11 shrink-0 animate-pulse rounded-md bg-zinc-800" />
<div className="flex items-start gap-2">
<div className="relative h-8 w-8 shrink-0 animate-pulse rounded-md bg-zinc-800" />
<div className="flex w-full flex-1 flex-col items-start gap-1 text-start">
<span className="h-4 w-1/2 animate-pulse rounded bg-zinc-800" />
<span className="h-3 w-1/3 animate-pulse rounded bg-zinc-800" />
</div>
</div>
);
}
return (
<div className="flex items-center justify-start gap-2">
<div className="relative h-11 w-11 shrink rounded-md">
<div className="flex shrink-0 items-start justify-start gap-2">
<div className="w-88 relative h-8 shrink rounded-md">
<Image
src={user.image}
fallback={DEFAULT_AVATAR}
alt={pubkey}
className="h-11 w-11 rounded-md object-cover"
className="w-88 h-8 rounded-md object-cover"
/>
</div>
<div className="inline-flex flex-1 items-center justify-start gap-1 text-start">
<span className="leading-none text-zinc-400">
{user.nip05 || user.name || user.displayName || shortenKey(pubkey)}
</span>
<span className="leading-none text-zinc-400">{desc}</span>
</div>
<span className="max-w-[10rem] truncate leading-none text-zinc-200">
{user.nip05 || user.name || user.displayName || displayNpub(pubkey, 16)}
</span>
</div>
);
}

View File

@ -18,7 +18,6 @@ export function useProfile(pubkey: string, fallback?: string) {
const current = Math.floor(Date.now() / 1000);
const cache = await getUserMetadata(pubkey);
if (cache && parseInt(cache.created_at) + 86400 >= current) {
console.log('cache hit:', cache);
return JSON.parse(cache.content);
} else {
const filter: NDKFilter = { kinds: [0], authors: [pubkey] };