make event store class award of replaceable events

This commit is contained in:
hzrd149
2023-10-12 11:44:36 -05:00
parent 5b8ff3eab7
commit bfc28c097b
4 changed files with 39 additions and 11 deletions

View File

@@ -1,5 +1,6 @@
import { getEventUID } from "../helpers/nostr/events";
import { NostrEvent } from "../types/nostr-event";
import { getEventUID, isReplaceable } from "../helpers/nostr/events";
import replaceableEventLoaderService from "../services/replaceable-event-requester";
import { NostrEvent, isDTag } from "../types/nostr-event";
import Subject from "./subject";
export type EventFilter = (event: NostrEvent, store: EventStore) => boolean;
@@ -20,7 +21,8 @@ export default class EventStore {
onDelete = new Subject<string>(undefined, false);
onClear = new Subject(undefined, false);
addEvent(event: NostrEvent) {
private replaceableEventSubs = new Map<string, Subject<NostrEvent>>();
private handleEvent(event: NostrEvent) {
const id = getEventUID(event);
const existing = this.events.get(id);
if (!existing || event.created_at > existing.created_at) {
@@ -28,6 +30,21 @@ export default class EventStore {
this.onEvent.next(event);
}
}
addEvent(event: NostrEvent) {
const id = getEventUID(event);
this.handleEvent(event);
if (isReplaceable(event.kind)) {
// pass the event on
replaceableEventLoaderService.handleEvent(event);
// subscribe to any future changes
const sub = replaceableEventLoaderService.getEvent(event.kind, event.pubkey, event.tags.find(isDTag)?.[1]);
sub.subscribe(this.handleEvent, this);
this.replaceableEventSubs.set(id, sub);
}
}
getEvent(id: string) {
return this.events.get(id);
}
@@ -36,11 +53,23 @@ export default class EventStore {
this.events.delete(id);
this.onDelete.next(id);
}
if (this.replaceableEventSubs.has(id)) {
this.replaceableEventSubs.get(id)?.unsubscribe(this.handleEvent, this);
this.replaceableEventSubs.delete(id);
}
}
clear() {
this.events.clear();
this.onClear.next(undefined);
for (const [_, sub] of this.replaceableEventSubs) {
sub.unsubscribe(this.handleEvent, this);
}
}
cleanup() {
this.clear();
}
connect(other: EventStore) {

View File

@@ -278,6 +278,7 @@ export default class TimelineLoader {
cleanup() {
this.close();
this.removeLoaders();
this.events.cleanup();
deleteEventService.stream.unsubscribe(this.handleDeleteEvent, this);
}

View File

@@ -37,7 +37,7 @@ export default function NoteZapButton({ event, allowComment, showEventPreview, .
<>
{total > 0 ? (
<Button
leftIcon={<LightningIcon />}
leftIcon={<LightningIcon verticalAlign="sub" />}
aria-label="Zap Note"
title="Zap Note"
colorScheme={hasZapped ? "primary" : undefined}
@@ -49,7 +49,7 @@ export default function NoteZapButton({ event, allowComment, showEventPreview, .
</Button>
) : (
<IconButton
icon={<LightningIcon />}
icon={<LightningIcon verticalAlign="sub" />}
aria-label="Zap Note"
title="Zap Note"
{...props}

View File

@@ -1,12 +1,10 @@
import dayjs from "dayjs";
import { Kind, nip19 } from "nostr-tools";
import { nip19 } from "nostr-tools";
import { getEventRelays } from "../../services/event-relays";
import { ATag, DraftNostrEvent, ETag, isETag, isPTag, NostrEvent, RTag, Tag } from "../../types/nostr-event";
import { ATag, DraftNostrEvent, isDTag, isETag, isPTag, NostrEvent, RTag, Tag } from "../../types/nostr-event";
import { RelayConfig, RelayMode } from "../../classes/relay";
import { getMatchNostrLink } from "../regexp";
import relayScoreboardService from "../../services/relay-scoreboard";
import type { AddressPointer, EventPointer } from "nostr-tools/lib/nip19";
import type { AddressPointer } from "nostr-tools/lib/nip19";
export function truncatedId(str: string, keep = 6) {
if (str.length < keep * 2 + 3) return str;
@@ -150,7 +148,7 @@ export function parseRTag(tag: RTag): RelayConfig {
}
export function getEventCoordinate(event: NostrEvent) {
const d = event.tags.find((t) => t[0] === "d")?.[1];
const d = event.tags.find(isDTag)?.[1];
return d ? `${event.kind}:${event.pubkey}:${d}` : `${event.kind}:${event.pubkey}`;
}
export function pointerToATag(pointer: AddressPointer): ATag {