mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-09-28 04:27:35 +02:00
small fixes for reaction popover and notifications
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { Subject } from "./subject";
|
import { Subject } from "./subject";
|
||||||
import { NostrEvent } from "../types/nostr-event";
|
import { NostrEvent } from "../types/nostr-event";
|
||||||
import { NostrOutgoingMessage, NostrRequestFilter } from "../types/nostr-query";
|
import { NostrOutgoingMessage, NostrOutgoingRequest, NostrRequestFilter } from "../types/nostr-query";
|
||||||
import Relay, { IncomingEvent } from "./relay";
|
import Relay, { IncomingEvent } from "./relay";
|
||||||
import relayPoolService from "../services/relay-pool";
|
import relayPoolService from "../services/relay-pool";
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ export default class NostrMultiSubscription {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.relayUrls = relayUrls;
|
this.relayUrls = relayUrls;
|
||||||
|
|
||||||
this.relays = relayUrls.map((url) => relayPoolService.requestRelay(url));
|
this.relays = this.relayUrls.map((url) => relayPoolService.requestRelay(url));
|
||||||
}
|
}
|
||||||
private handleEvent(event: IncomingEvent) {
|
private handleEvent(event: IncomingEvent) {
|
||||||
if (this.state === NostrMultiSubscription.OPEN && event.subId === this.id && !this.seenEvents.has(event.body.id)) {
|
if (this.state === NostrMultiSubscription.OPEN && event.subId === this.id && !this.seenEvents.has(event.body.id)) {
|
||||||
@@ -33,58 +33,70 @@ export default class NostrMultiSubscription {
|
|||||||
this.seenEvents.add(event.body.id);
|
this.seenEvents.add(event.body.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
send(message: NostrOutgoingMessage) {
|
|
||||||
|
private relayQueries = new WeakMap<Relay, NostrRequestFilter>();
|
||||||
|
private updateRelayQueries() {
|
||||||
|
if (!this.query || this.state !== NostrMultiSubscription.OPEN) return;
|
||||||
|
|
||||||
|
const message: NostrOutgoingRequest = Array.isArray(this.query)
|
||||||
|
? ["REQ", this.id, ...this.query]
|
||||||
|
: ["REQ", this.id, this.query];
|
||||||
|
|
||||||
|
for (const relay of this.relays) {
|
||||||
|
if (this.relayQueries.get(relay) !== this.query) {
|
||||||
|
relay.send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private handleRelayConnect(relay: Relay) {
|
||||||
|
this.updateRelayQueries();
|
||||||
|
}
|
||||||
|
private handleRelayDisconnect(relay: Relay) {
|
||||||
|
this.relayQueries.delete(relay);
|
||||||
|
}
|
||||||
|
sendToAll(message: NostrOutgoingMessage) {
|
||||||
for (const relay of this.relays) {
|
for (const relay of this.relays) {
|
||||||
relay.send(message);
|
relay.send(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** listen for event and open events from relays */
|
/** listen for event and open events from relays */
|
||||||
private subscribeToRelays() {
|
private connectToRelays() {
|
||||||
for (const relay of this.relays) {
|
for (const relay of this.relays) {
|
||||||
relay.onEvent.subscribe(this.handleEvent, this);
|
relay.onEvent.subscribe(this.handleEvent, this);
|
||||||
}
|
relay.onOpen.subscribe(this.handleRelayConnect, this);
|
||||||
|
relay.onClose.subscribe(this.handleRelayDisconnect, this);
|
||||||
for (const url of this.relayUrls) {
|
relayPoolService.addClaim(relay.url, this);
|
||||||
relayPoolService.addClaim(url, this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** listen for event and open events from relays */
|
/** stop listing to events from relays */
|
||||||
private unsubscribeFromRelays() {
|
private disconnectFromRelays() {
|
||||||
for (const relay of this.relays) {
|
for (const relay of this.relays) {
|
||||||
relay.onEvent.unsubscribe(this.handleEvent, this);
|
relay.onEvent.unsubscribe(this.handleEvent, this);
|
||||||
}
|
relay.onOpen.unsubscribe(this.handleRelayConnect, this);
|
||||||
|
relay.onClose.unsubscribe(this.handleRelayDisconnect, this);
|
||||||
for (const url of this.relayUrls) {
|
relayPoolService.removeClaim(relay.url, this);
|
||||||
relayPoolService.removeClaim(url, this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open() {
|
open() {
|
||||||
if (!this.query) throw new Error("cant open without a query");
|
if (!this.query) throw new Error("Cant open without a query");
|
||||||
if (this.state === NostrMultiSubscription.OPEN) return this;
|
if (this.state === NostrMultiSubscription.OPEN) return this;
|
||||||
|
|
||||||
this.state = NostrMultiSubscription.OPEN;
|
this.state = NostrMultiSubscription.OPEN;
|
||||||
if (Array.isArray(this.query)) {
|
this.connectToRelays();
|
||||||
this.send(["REQ", this.id, ...this.query]);
|
this.updateRelayQueries();
|
||||||
} else this.send(["REQ", this.id, this.query]);
|
|
||||||
|
|
||||||
this.subscribeToRelays();
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
setQuery(query: NostrRequestFilter) {
|
setQuery(query: NostrRequestFilter) {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
if (this.state === NostrMultiSubscription.OPEN) {
|
this.updateRelayQueries();
|
||||||
if (Array.isArray(this.query)) {
|
|
||||||
this.send(["REQ", this.id, ...this.query]);
|
|
||||||
} else this.send(["REQ", this.id, this.query]);
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
setRelays(relays: string[]) {
|
setRelays(relayUrls: string[]) {
|
||||||
this.unsubscribeFromRelays();
|
this.disconnectFromRelays();
|
||||||
const newRelays = relays.map((url) => relayPoolService.requestRelay(url));
|
const newRelays = relayUrls.map((url) => relayPoolService.requestRelay(url));
|
||||||
|
|
||||||
for (const relay of this.relays) {
|
for (const relay of this.relays) {
|
||||||
if (!newRelays.includes(relay)) {
|
if (!newRelays.includes(relay)) {
|
||||||
@@ -95,24 +107,14 @@ export default class NostrMultiSubscription {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const relay of newRelays) {
|
|
||||||
if (!this.relays.includes(relay)) {
|
|
||||||
// if the subscription is open and it has a query
|
|
||||||
if (this.state === NostrMultiSubscription.OPEN && this.query) {
|
|
||||||
// open a connection to this relay
|
|
||||||
if (Array.isArray(this.query)) {
|
|
||||||
relay.send(["REQ", this.id, ...this.query]);
|
|
||||||
} else relay.send(["REQ", this.id, this.query]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set new relays
|
// set new relays
|
||||||
this.relayUrls = relays;
|
this.relayUrls = relayUrls;
|
||||||
this.relays = newRelays;
|
this.relays = newRelays;
|
||||||
|
|
||||||
if (this.state === NostrMultiSubscription.OPEN) {
|
if (this.state === NostrMultiSubscription.OPEN) {
|
||||||
this.subscribeToRelays();
|
this.connectToRelays();
|
||||||
|
this.updateRelayQueries();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close() {
|
close() {
|
||||||
@@ -121,11 +123,11 @@ export default class NostrMultiSubscription {
|
|||||||
// set state
|
// set state
|
||||||
this.state = NostrMultiSubscription.CLOSED;
|
this.state = NostrMultiSubscription.CLOSED;
|
||||||
// send close message
|
// send close message
|
||||||
this.send(["CLOSE", this.id]);
|
this.sendToAll(["CLOSE", this.id]);
|
||||||
// forget all seen events
|
// forget all seen events
|
||||||
this.seenEvents.clear();
|
this.seenEvents.clear();
|
||||||
// unsubscribe from relay messages
|
// unsubscribe from relay messages
|
||||||
this.unsubscribeFromRelays();
|
this.disconnectFromRelays();
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@@ -6,6 +6,7 @@ import {
|
|||||||
PopoverBody,
|
PopoverBody,
|
||||||
PopoverContent,
|
PopoverContent,
|
||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
|
useBoolean,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
|
|
||||||
import useEventReactions from "../../../hooks/use-event-reactions";
|
import useEventReactions from "../../../hooks/use-event-reactions";
|
||||||
@@ -22,6 +23,7 @@ import { getEventUID } from "../../../helpers/nostr/events";
|
|||||||
export default function ReactionButton({ event, ...props }: { event: NostrEvent } & Omit<ButtonProps, "children">) {
|
export default function ReactionButton({ event, ...props }: { event: NostrEvent } & Omit<ButtonProps, "children">) {
|
||||||
const { requestSignature } = useSigningContext();
|
const { requestSignature } = useSigningContext();
|
||||||
const reactions = useEventReactions(getEventUID(event)) ?? [];
|
const reactions = useEventReactions(getEventUID(event)) ?? [];
|
||||||
|
const [popover, setPopover] = useBoolean();
|
||||||
|
|
||||||
const addReaction = async (emoji = "+", url?: string) => {
|
const addReaction = async (emoji = "+", url?: string) => {
|
||||||
const draft = draftEventReaction(event, emoji, url);
|
const draft = draftEventReaction(event, emoji, url);
|
||||||
@@ -31,11 +33,12 @@ export default function ReactionButton({ event, ...props }: { event: NostrEvent
|
|||||||
const writeRelays = clientRelaysService.getWriteUrls();
|
const writeRelays = clientRelaysService.getWriteUrls();
|
||||||
new NostrPublishAction("Reaction", writeRelays, signed);
|
new NostrPublishAction("Reaction", writeRelays, signed);
|
||||||
eventReactionsService.handleEvent(signed);
|
eventReactionsService.handleEvent(signed);
|
||||||
|
setPopover.off();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover isLazy>
|
<Popover isLazy isOpen={popover} onOpen={setPopover.on} onClose={setPopover.off}>
|
||||||
<PopoverTrigger>
|
<PopoverTrigger>
|
||||||
<IconButton icon={<AddReactionIcon />} aria-label="Add Reaction" {...props}>
|
<IconButton icon={<AddReactionIcon />} aria-label="Add Reaction" {...props}>
|
||||||
{reactions?.length ?? 0}
|
{reactions?.length ?? 0}
|
||||||
|
@@ -65,7 +65,7 @@ export default function ContentDiscoveryView() {
|
|||||||
Back
|
Back
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
<SimpleGrid columns={{ base: 1, md: 2, lg: 3, xl: 4 }}>
|
<SimpleGrid columns={{ base: 1, md: 2, lg: 3, xl: 4 }} spacing="2">
|
||||||
{DMVs.map((appData) => (
|
{DMVs.map((appData) => (
|
||||||
<DVMCard key={appData.id} appData={appData} maxW="lg" />
|
<DVMCard key={appData.id} appData={appData} maxW="lg" />
|
||||||
))}
|
))}
|
||||||
|
Reference in New Issue
Block a user