notis done

This commit is contained in:
smolgrrr 2023-12-19 16:16:38 +11:00
parent d320c6c389
commit 00db487605
2 changed files with 113 additions and 104 deletions

View File

@ -32,21 +32,38 @@ const useUniqEvents = () => {
const Notifications = () => { const Notifications = () => {
const [sortByTime, setSortByTime] = useState<boolean>(localStorage.getItem('sortBy') !== 'false'); const [sortByTime, setSortByTime] = useState<boolean>(localStorage.getItem('sortBy') !== 'false');
const [setAnon, setSetAnon] = useState<boolean>(localStorage.getItem('anonMode') !== 'false'); const [setAnon, setSetAnon] = useState<boolean>(localStorage.getItem('anonMode') !== 'false');
const [notifsView, setNotifsView] = useState(false);
const { noteEvents, metadataEvents } = useUniqEvents(); const { noteEvents, metadataEvents } = useUniqEvents();
const storedKeys = JSON.parse(localStorage.getItem('usedKeys') || '[]');
const storedPubkeys = storedKeys.map((key: any[]) => key[1]);
const postEvents = noteEvents const postEvents = noteEvents
.filter((event) => .filter((event) =>
event.kind !== 0 && event.kind !== 0 &&
(event.kind !== 1) storedPubkeys.includes(event.pubkey)
) )
const sortedEvents = [...postEvents] const sortedEvents = [...postEvents]
.sort((a, b) => .sort((a, b) =>
sortByTime ? b.created_at - a.created_at : verifyPow(b) - verifyPow(a) sortByTime ? b.created_at - a.created_at : verifyPow(b) - verifyPow(a)
) )
.filter( .filter(
!setAnon ? (e) => !metadataEvents.some((metadataEvent) => metadataEvent.pubkey === e.pubkey) : () => true !setAnon ? (e) => !metadataEvents.some((metadataEvent) => metadataEvent.pubkey === e.pubkey) : () => true
); );
const mentions = noteEvents
.filter((event) =>
event.kind !== 0 &&
event.tags.some((tag) => tag[0] === "p" && storedPubkeys.includes(tag[1]))
)
const sortedMentions = [...mentions]
.sort((a, b) =>
sortByTime ? b.created_at - a.created_at : verifyPow(b) - verifyPow(a)
)
.filter(
!setAnon ? (e) => !metadataEvents.some((metadataEvent) => metadataEvent.pubkey === e.pubkey) : () => true
);
const toggleSort = useCallback(() => { const toggleSort = useCallback(() => {
setSortByTime(prev => { setSortByTime(prev => {
@ -64,6 +81,10 @@ const Notifications = () => {
}); });
}, []); }, []);
const toggleNotifs = useCallback(() => {
setNotifsView(prev => !prev);
}, []);
const countReplies = (event: Event) => { const countReplies = (event: Event) => {
return noteEvents.filter((e) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id)).length; return noteEvents.filter((e) => e.tags.some((tag) => tag[0] === "e" && tag[1] === event.id)).length;
}; };
@ -72,19 +93,55 @@ const Notifications = () => {
return ( return (
<main className="text-white mb-20"> <main className="text-white mb-20">
<OptionsBar sortByTime={sortByTime} setAnon={setAnon} toggleSort={toggleSort} toggleAnon={toggleAnon} /> <OptionsBar sortByTime={sortByTime} setAnon={setAnon} toggleSort={toggleSort} toggleAnon={toggleAnon} />
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-4 p-4"> <div className="block sm:hidden">
{sortedEvents.map((event) => ( <label htmlFor="toggleC" className="p-4 flex items-center cursor-pointer">
event.kind === 1 ? <div className="relative">
<PostCard <input
event={event} id="toggleC"
metadata={metadataEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null} type="checkbox"
replyCount={countReplies(event)} className="sr-only"
checked={notifsView}
onChange={toggleNotifs}
/> />
: <div className="block bg-gray-600 w-8 h-4 rounded-full"></div>
<RepostCard <div className={`dot absolute left-1 top-0.5 bg-white w-3 h-3 rounded-full transition ${notifsView ? 'transform translate-x-full bg-blue-400' : ''}`} ></div>
event={event} </div>
/> <div className={`ml-2 text-neutral-500 text-sm ${notifsView ? 'text-neutral-500' : ''}`}>
))} {notifsView ? 'Mentions' : 'Prev Posts'}
</div>
</label>
</div>
<div className="flex">
<div className={`grid grid-cols-1 gap-4 px-4 flex-grow ${notifsView ? 'hidden sm:block' : ''}`}>
<span>Your Recent Posts</span>
{sortedEvents.map((event) => (
event.kind === 1 ?
<PostCard
event={event}
metadata={metadataEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null}
replyCount={countReplies(event)}
/>
:
<RepostCard
event={event}
/>
))}
</div>
<div className={`grid grid-cols-1 gap-4 px-4 flex-grow ${notifsView ? '' : 'hidden sm:block'}`}>
<span>Mentions</span>
{sortedMentions.map((event) => (
event.kind === 1 ?
<PostCard
event={event}
metadata={metadataEvents.find((e) => e.pubkey === event.pubkey && e.kind === 0) || null}
replyCount={countReplies(event)}
/>
:
<RepostCard
event={event}
/>
))}
</div>
</div> </div>
</main> </main>
); );

View File

@ -247,99 +247,51 @@ export const subNotesOnce = (
// }, 2000); // }, 2000);
// }; // };
/** quick subscribe to a note id (nip-19) */ const hasEventTag = (tag: string[]) => tag[0] === 'e';
const isReply = ([tag, , , marker]: string[]) => tag === 'e' && marker !== 'mention';
export const getReplyTo = (evt: Event): string | null => {
const eventTags = evt.tags.filter(isReply);
const withReplyMarker = eventTags.filter(([, , , marker]) => marker === 'reply');
if (withReplyMarker.length === 1) {
return withReplyMarker[0][1];
}
const withRootMarker = eventTags.filter(([, , , marker]) => marker === 'root');
if (withReplyMarker.length === 0 && withRootMarker.length === 1) {
return withRootMarker[0][1];
}
// fallback to deprecated positional 'e' tags (nip-10)
const lastTag = eventTags.at(-1);
return lastTag ? lastTag[1] : null;
};
export const subNotifications = ( export const subNotifications = (
pubkeys: string[], pubkeys: string[],
onEvent: SubCallback, onEvent: SubCallback,
) => { ) => {
const replyPubkeys = new Set<string>(); unsubAll();
sub({ sub({
cb: onEvent, cb: (evt, relay) => {
onEvent(evt, relay);
},
filter: { filter: {
authors: Array.from(pubkeys), authors: pubkeys,
kinds: [1, 7],
limit: 25,
},
unsub: true,
});
sub({
cb: (evt, relay) => {
onEvent(evt, relay);
},
filter: {
'#p': pubkeys,
kinds: [1], kinds: [1],
limit: 50, limit: 50,
}, },
unsub: true, unsub: true,
}); });
setTimeout(() => {
// get profile info
sub({
cb: onEvent,
filter: {
authors: Array.from(replyPubkeys),
kinds: [0],
limit: replyPubkeys.size,
},
unsub: true,
});
replyPubkeys.clear();
}, 2000);
}; };
// const hasEventTag = (tag: string[]) => tag[0] === 'e';
// const isReply = ([tag, , , marker]: string[]) => tag === 'e' && marker !== 'mention';
// export const getReplyTo = (evt: Event): string | null => {
// const eventTags = evt.tags.filter(isReply);
// const withReplyMarker = eventTags.filter(([, , , marker]) => marker === 'reply');
// if (withReplyMarker.length === 1) {
// return withReplyMarker[0][1];
// }
// const withRootMarker = eventTags.filter(([, , , marker]) => marker === 'root');
// if (withReplyMarker.length === 0 && withRootMarker.length === 1) {
// return withRootMarker[0][1];
// }
// // fallback to deprecated positional 'e' tags (nip-10)
// const lastTag = eventTags.at(-1);
// return lastTag ? lastTag[1] : null;
// };
// export const subNotifications = (
// pubkeys: string[],
// onEvent: SubCallback,
// ) => {
// const authorsPrefixes = pubkeys.map(pubkey => pubkey.slice(0, 32));
// console.info(`subscribe to homefeed ${authorsPrefixes}`);
// unsubAll();
// const repliesTo = new Set<string>();
// sub({
// cb: (evt, relay) => {
// if (
// evt.tags.some(hasEventTag)
// ) {
// const note = getReplyTo(evt); // get all reply to events instead?
// if (note && !repliesTo.has(note)) {
// repliesTo.add(note);
// subOnce({
// cb: onEvent,
// filter: {
// ids: [note],
// kinds: [1],
// limit: 1,
// },
// relay,
// });
// }
// }
// onEvent(evt, relay);
// },
// filter: {
// authors: authorsPrefixes,
// kinds: [1],
// limit: 20,
// },
// });
// // get metadata
// sub({
// cb: onEvent,
// filter: {
// authors: pubkeys,
// kinds: [0],
// limit: pubkeys.length,
// },
// unsub: true,
// });
// };