mirror of
https://github.com/block/buzz.git
synced 2026-11-12 20:31:12 +00:00
A workflow message names its owner in a marked p tag, ["p", owner, "", "owner"], for attribution. #p live, history and push matching, operator listeners, desktop, mobile and the iOS NSE treat that tag as attribution rather than a mention. A workflow that mentions its owner adds a plain p, so the owner is notified only when actually mentioned. NOSTR.md records the #p exception. Co-authored-by: studio <dc2fc481343672df31a689840c09299972e704dac592e0da6f18486646a7ee3e@buzz.block.builderlab.xyz> Signed-off-by: Tom Brow <tomb@squareup.com>
101 lines
2.2 KiB
TypeScript
101 lines
2.2 KiB
TypeScript
import type { RelayEvent } from "@/shared/api/types";
|
|
import {
|
|
getThreadReference,
|
|
isBroadcastReply,
|
|
} from "@/features/messages/lib/threading";
|
|
|
|
/**
|
|
* Whether the event's `p` tags address `currentPubkey`. A workflow message
|
|
* names its owner in `["p", owner, "", "owner"]` for attribution only; that
|
|
* tag is not a mention. A workflow that mentions its owner adds a plain `p`.
|
|
*/
|
|
export function hasMentionForEvent(
|
|
event: RelayEvent,
|
|
currentPubkey: string,
|
|
): boolean {
|
|
if (currentPubkey.length === 0) {
|
|
return false;
|
|
}
|
|
const workflow = event.tags.some(
|
|
(tag) => tag[0] === "buzz:workflow" && tag[1] === "true",
|
|
);
|
|
return event.tags.some(
|
|
(tag) =>
|
|
tag[0] === "p" &&
|
|
tag[1]?.toLowerCase() === currentPubkey &&
|
|
!(workflow && tag[3] === "owner"),
|
|
);
|
|
}
|
|
|
|
export type NotifyOptions = {
|
|
participatedRootIds: ReadonlySet<string>;
|
|
followedRootIds: ReadonlySet<string>;
|
|
authoredRootIds: ReadonlySet<string>;
|
|
mutedRootIds?: ReadonlySet<string>;
|
|
mutedChannelIds?: ReadonlySet<string>;
|
|
channelId?: string | null;
|
|
};
|
|
|
|
export function shouldNotifyForEvent(
|
|
event: RelayEvent,
|
|
currentPubkey: string,
|
|
options: NotifyOptions,
|
|
): boolean {
|
|
const {
|
|
participatedRootIds,
|
|
followedRootIds,
|
|
authoredRootIds,
|
|
mutedRootIds = new Set(),
|
|
mutedChannelIds = new Set(),
|
|
channelId = null,
|
|
} = options;
|
|
const { parentId, rootId } = getThreadReference(event.tags);
|
|
|
|
if (isBroadcastReply(event.tags)) {
|
|
return true;
|
|
}
|
|
|
|
if (hasMentionForEvent(event, currentPubkey)) {
|
|
return true;
|
|
}
|
|
|
|
if (channelId !== null && mutedChannelIds.has(channelId)) {
|
|
return false;
|
|
}
|
|
|
|
if (parentId === null) {
|
|
return true;
|
|
}
|
|
|
|
if (rootId !== null && mutedRootIds.has(rootId)) {
|
|
return false;
|
|
}
|
|
|
|
if (rootId !== null && participatedRootIds.has(rootId)) {
|
|
return true;
|
|
}
|
|
|
|
if (rootId !== null && followedRootIds.has(rootId)) {
|
|
return true;
|
|
}
|
|
|
|
if (rootId !== null && authoredRootIds.has(rootId)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
export function isHighPriorityEventForUser(
|
|
event: RelayEvent,
|
|
currentPubkey: string,
|
|
): boolean {
|
|
if (hasMentionForEvent(event, currentPubkey)) {
|
|
return true;
|
|
}
|
|
if (isBroadcastReply(event.tags)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|