Merge pull request #314 from kphrx/feat/kind1-reposts
feat: render kind 1 reposts
This commit is contained in:
commit
1161c69e36
@ -11,7 +11,15 @@ import Pin from "Icons/Pin";
|
|||||||
import { parseZap } from "Element/Zap";
|
import { parseZap } from "Element/Zap";
|
||||||
import ProfileImage from "Element/ProfileImage";
|
import ProfileImage from "Element/ProfileImage";
|
||||||
import Text from "Element/Text";
|
import Text from "Element/Text";
|
||||||
import { eventLink, getReactions, dedupeByPubkey, hexToBech32, normalizeReaction, Reaction } from "Util";
|
import {
|
||||||
|
eventLink,
|
||||||
|
getReactions,
|
||||||
|
dedupeByPubkey,
|
||||||
|
tagFilterOfTextRepost,
|
||||||
|
hexToBech32,
|
||||||
|
normalizeReaction,
|
||||||
|
Reaction,
|
||||||
|
} from "Util";
|
||||||
import NoteFooter, { Translation } from "Element/NoteFooter";
|
import NoteFooter, { Translation } from "Element/NoteFooter";
|
||||||
import NoteTime from "Element/NoteTime";
|
import NoteTime from "Element/NoteTime";
|
||||||
import { useUserProfiles } from "Feed/ProfileFeed";
|
import { useUserProfiles } from "Feed/ProfileFeed";
|
||||||
@ -98,7 +106,14 @@ export default function Note(props: NoteProps) {
|
|||||||
}, [reactions]);
|
}, [reactions]);
|
||||||
const positive = groupReactions[Reaction.Positive];
|
const positive = groupReactions[Reaction.Positive];
|
||||||
const negative = groupReactions[Reaction.Negative];
|
const negative = groupReactions[Reaction.Negative];
|
||||||
const reposts = useMemo(() => dedupeByPubkey(getReactions(related, ev.Id, EventKind.Repost)), [related, ev]);
|
const reposts = useMemo(
|
||||||
|
() =>
|
||||||
|
dedupeByPubkey([
|
||||||
|
...getReactions(related, ev.Id, EventKind.TextNote).filter(e => e.tags.some(tagFilterOfTextRepost(e, ev.Id))),
|
||||||
|
...getReactions(related, ev.Id, EventKind.Repost),
|
||||||
|
]),
|
||||||
|
[related, ev]
|
||||||
|
);
|
||||||
const zaps = useMemo(() => {
|
const zaps = useMemo(() => {
|
||||||
const sortedZaps = getReactions(related, ev.Id, EventKind.ZapReceipt)
|
const sortedZaps = getReactions(related, ev.Id, EventKind.ZapReceipt)
|
||||||
.map(parseZap)
|
.map(parseZap)
|
||||||
|
@ -30,7 +30,12 @@ export default function NoteReaction(props: NoteReactionProps) {
|
|||||||
return null;
|
return null;
|
||||||
}, [ev]);
|
}, [ev]);
|
||||||
|
|
||||||
if (ev.Kind !== EventKind.Reaction && ev.Kind !== EventKind.Repost) {
|
if (
|
||||||
|
ev.Kind !== EventKind.Reaction &&
|
||||||
|
ev.Kind !== EventKind.Repost &&
|
||||||
|
(ev.Kind !== EventKind.TextNote ||
|
||||||
|
ev.Tags.every((a, i) => a.Event !== refEvent || a.Marker !== "mention" || ev.Content !== `#[${i}]`))
|
||||||
|
) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +57,7 @@ export default function NoteReaction(props: NoteReactionProps) {
|
|||||||
const root = extractRoot();
|
const root = extractRoot();
|
||||||
const isOpMuted = root && isMuted(root.pubkey);
|
const isOpMuted = root && isMuted(root.pubkey);
|
||||||
const opt = {
|
const opt = {
|
||||||
showHeader: ev?.Kind === EventKind.Repost,
|
showHeader: ev?.Kind === EventKind.Repost || ev?.Kind === EventKind.TextNote,
|
||||||
showFooter: false,
|
showFooter: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import { useCallback, useMemo } from "react";
|
|||||||
import { useInView } from "react-intersection-observer";
|
import { useInView } from "react-intersection-observer";
|
||||||
|
|
||||||
import ArrowUp from "Icons/ArrowUp";
|
import ArrowUp from "Icons/ArrowUp";
|
||||||
import { dedupeByPubkey } from "Util";
|
import { dedupeByPubkey, tagFilterOfTextRepost } from "Util";
|
||||||
import ProfileImage from "Element/ProfileImage";
|
import ProfileImage from "Element/ProfileImage";
|
||||||
import useTimelineFeed, { TimelineSubject } from "Feed/TimelineFeed";
|
import useTimelineFeed, { TimelineSubject } from "Feed/TimelineFeed";
|
||||||
import { TaggedRawEvent } from "@snort/nostr";
|
import { TaggedRawEvent } from "@snort/nostr";
|
||||||
@ -72,6 +72,10 @@ export default function Timeline({
|
|||||||
return <ProfilePreview actions={<></>} pubkey={e.pubkey} className="card" />;
|
return <ProfilePreview actions={<></>} pubkey={e.pubkey} className="card" />;
|
||||||
}
|
}
|
||||||
case EventKind.TextNote: {
|
case EventKind.TextNote: {
|
||||||
|
const eRef = e.tags.find(tagFilterOfTextRepost(e))?.at(1);
|
||||||
|
if (eRef) {
|
||||||
|
return <NoteReaction data={e} key={e.id} root={parent.notes.find(a => a.id === eRef)} />;
|
||||||
|
}
|
||||||
return <Note key={e.id} data={e} related={related.notes} ignoreModeration={ignoreModeration} />;
|
return <Note key={e.id} data={e} related={related.notes} ignoreModeration={ignoreModeration} />;
|
||||||
}
|
}
|
||||||
case EventKind.ZapReceipt: {
|
case EventKind.ZapReceipt: {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { u256 } from "@snort/nostr";
|
import { u256 } from "@snort/nostr";
|
||||||
import { EventKind, Subscriptions } from "@snort/nostr";
|
import { EventKind, Subscriptions } from "@snort/nostr";
|
||||||
import { unixNow, unwrap } from "Util";
|
import { unixNow, unwrap, tagFilterOfTextRepost } from "Util";
|
||||||
import useSubscription from "Feed/Subscription";
|
import useSubscription from "Feed/Subscription";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { RootState } from "State/Store";
|
import { RootState } from "State/Store";
|
||||||
@ -147,11 +147,19 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
|
|||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
const reposts = main.store.notes
|
const repostsByKind6 = main.store.notes
|
||||||
.filter(a => a.kind === EventKind.Repost && a.content === "")
|
.filter(a => a.kind === EventKind.Repost && a.content === "")
|
||||||
.map(a => a.tags.find(b => b[0] === "e"))
|
.map(a => a.tags.find(b => b[0] === "e"))
|
||||||
.filter(a => a)
|
.filter(a => a)
|
||||||
.map(a => unwrap(a)[1]);
|
.map(a => unwrap(a)[1]);
|
||||||
|
const repostsByKind1 = main.store.notes
|
||||||
|
.filter(
|
||||||
|
a => (a.kind === EventKind.Repost || a.kind === EventKind.TextNote) && a.tags.some(tagFilterOfTextRepost(a))
|
||||||
|
)
|
||||||
|
.map(a => a.tags.find(tagFilterOfTextRepost(a)))
|
||||||
|
.filter(a => a)
|
||||||
|
.map(a => unwrap(a)[1]);
|
||||||
|
const reposts = [...repostsByKind6, ...repostsByKind1];
|
||||||
if (reposts.length > 0) {
|
if (reposts.length > 0) {
|
||||||
setTrackingParentEvents(s => {
|
setTrackingParentEvents(s => {
|
||||||
if (reposts.some(a => !s.includes(a))) {
|
if (reposts.some(a => !s.includes(a))) {
|
||||||
|
@ -6,10 +6,14 @@ import type { NotificationRequest } from "State/Login";
|
|||||||
import { MetadataCache, UsersDb } from "State/Users";
|
import { MetadataCache, UsersDb } from "State/Users";
|
||||||
import { getDisplayName } from "Element/ProfileImage";
|
import { getDisplayName } from "Element/ProfileImage";
|
||||||
import { MentionRegex } from "Const";
|
import { MentionRegex } from "Const";
|
||||||
|
import { tagFilterOfTextRepost } from "Util";
|
||||||
|
|
||||||
export async function makeNotification(db: UsersDb, ev: TaggedRawEvent): Promise<NotificationRequest | null> {
|
export async function makeNotification(db: UsersDb, ev: TaggedRawEvent): Promise<NotificationRequest | null> {
|
||||||
switch (ev.kind) {
|
switch (ev.kind) {
|
||||||
case EventKind.TextNote: {
|
case EventKind.TextNote: {
|
||||||
|
if (ev.tags.some(tagFilterOfTextRepost(ev))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const pubkeys = new Set([ev.pubkey, ...ev.tags.filter(a => a[0] === "p").map(a => a[1])]);
|
const pubkeys = new Set([ev.pubkey, ...ev.tags.filter(a => a[0] === "p").map(a => a[1])]);
|
||||||
const users = await db.bulkGet(Array.from(pubkeys));
|
const users = await db.bulkGet(Array.from(pubkeys));
|
||||||
const fromUser = users.find(a => a?.pubkey === ev.pubkey);
|
const fromUser = users.find(a => a?.pubkey === ev.pubkey);
|
||||||
|
@ -191,3 +191,8 @@ export function getNewest(rawNotes: TaggedRawEvent[]) {
|
|||||||
return notes[0];
|
return notes[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function tagFilterOfTextRepost(note: TaggedRawEvent, id?: u256): (tag: string[], i: number) => boolean {
|
||||||
|
return (tag, i) =>
|
||||||
|
tag[0] === "e" && tag[3] === "mention" && note.content === `#[${i}]` && (id ? tag[1] === id : true);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user