mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-06-15 09:08:43 +02:00
Revert "feat: Add Badge Awards to chat"
This reverts commits: -1686a94feat: Add Badge Awards (kind 8) to NIP-53 live chat -909359ffeat: Add Badge Awards (kind 8) to chat as system messages Badge award rendering in chat will be implemented later. This keeps the PR focused on Profile Badges (kind 30008) implementation.
This commit is contained in:
@@ -35,12 +35,6 @@ import { UserName } from "./nostr/UserName";
|
||||
import { RichText } from "./nostr/RichText";
|
||||
import Timestamp from "./Timestamp";
|
||||
import { ReplyPreview } from "./chat/ReplyPreview";
|
||||
import { Award } from "lucide-react";
|
||||
import {
|
||||
getBadgeName,
|
||||
getBadgeIdentifier,
|
||||
getBadgeImageUrl,
|
||||
} from "@/lib/nip58-helpers";
|
||||
import { MembersDropdown } from "./chat/MembersDropdown";
|
||||
import { RelaysDropdown } from "./chat/RelaysDropdown";
|
||||
import { MessageReactions } from "./chat/MessageReactions";
|
||||
@@ -204,106 +198,6 @@ type ConversationResult =
|
||||
| { status: "success"; conversation: Conversation }
|
||||
| { status: "error"; error: string };
|
||||
|
||||
/**
|
||||
* Parse badge address to extract pubkey and identifier
|
||||
*/
|
||||
function parseBadgeAddress(address: string): {
|
||||
kind: number;
|
||||
pubkey: string;
|
||||
identifier: string;
|
||||
} | null {
|
||||
const parts = address.split(":");
|
||||
if (parts.length !== 3) return null;
|
||||
|
||||
const kind = parseInt(parts[0], 10);
|
||||
const pubkey = parts[1];
|
||||
const identifier = parts[2];
|
||||
|
||||
if (isNaN(kind) || !pubkey || identifier === undefined) return null;
|
||||
|
||||
return { kind, pubkey, identifier };
|
||||
}
|
||||
|
||||
/**
|
||||
* BadgeAwardSystemMessage - Renders badge award as system message
|
||||
* Format: "🏆 username awarded 🏅 badge-name to username(s)"
|
||||
*/
|
||||
const BadgeAwardSystemMessage = memo(function BadgeAwardSystemMessage({
|
||||
message,
|
||||
badgeAddress,
|
||||
awardedPubkeys,
|
||||
}: {
|
||||
message: Message;
|
||||
badgeAddress: string;
|
||||
awardedPubkeys: string[];
|
||||
}) {
|
||||
const coordinate = parseBadgeAddress(badgeAddress);
|
||||
|
||||
// Fetch the badge definition event
|
||||
const badgeEvent = use$(
|
||||
() =>
|
||||
coordinate
|
||||
? eventStore.replaceable(
|
||||
coordinate.kind,
|
||||
coordinate.pubkey,
|
||||
coordinate.identifier,
|
||||
)
|
||||
: undefined,
|
||||
[coordinate?.kind, coordinate?.pubkey, coordinate?.identifier],
|
||||
);
|
||||
|
||||
const badgeName = badgeEvent ? getBadgeName(badgeEvent) : null;
|
||||
const badgeIdentifier = badgeEvent ? getBadgeIdentifier(badgeEvent) : null;
|
||||
const badgeImageUrl = badgeEvent ? getBadgeImageUrl(badgeEvent) : null;
|
||||
|
||||
const displayBadgeName = badgeName || badgeIdentifier || "a badge";
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-1.5 px-3 py-1 flex-wrap">
|
||||
<span className="text-xs text-muted-foreground">*</span>
|
||||
|
||||
{/* Issuer */}
|
||||
<UserName
|
||||
pubkey={message.author}
|
||||
className="text-xs text-muted-foreground"
|
||||
/>
|
||||
|
||||
<span className="text-xs text-muted-foreground">awarded</span>
|
||||
|
||||
{/* Badge Icon */}
|
||||
{badgeImageUrl ? (
|
||||
<img
|
||||
src={badgeImageUrl}
|
||||
alt={displayBadgeName}
|
||||
className="size-4 rounded object-cover flex-shrink-0"
|
||||
loading="lazy"
|
||||
/>
|
||||
) : (
|
||||
<Award className="size-4 text-muted-foreground flex-shrink-0" />
|
||||
)}
|
||||
|
||||
{/* Badge Name */}
|
||||
<span className="text-xs font-semibold text-muted-foreground">
|
||||
{displayBadgeName}
|
||||
</span>
|
||||
|
||||
<span className="text-xs text-muted-foreground">to</span>
|
||||
|
||||
{/* Recipients */}
|
||||
{awardedPubkeys.length === 1 ? (
|
||||
<UserName
|
||||
pubkey={awardedPubkeys[0]}
|
||||
className="text-xs text-muted-foreground"
|
||||
/>
|
||||
) : (
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{awardedPubkeys.length} people
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* ComposerReplyPreview - Shows who is being replied to in the composer
|
||||
*/
|
||||
@@ -379,20 +273,8 @@ const MessageItem = memo(function MessageItem({
|
||||
[conversation],
|
||||
);
|
||||
|
||||
// System messages (join/leave/badge-award) have special styling
|
||||
// System messages (join/leave) have special styling
|
||||
if (message.type === "system") {
|
||||
// Badge awards get special rendering
|
||||
if (message.content === "badge-award" && message.metadata?.badgeAddress) {
|
||||
return (
|
||||
<BadgeAwardSystemMessage
|
||||
message={message}
|
||||
badgeAddress={message.metadata.badgeAddress}
|
||||
awardedPubkeys={message.metadata.awardedPubkeys || []}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Default system message rendering (join/leave)
|
||||
return (
|
||||
<div className="flex items-center px-3 py-1">
|
||||
<span className="text-xs text-muted-foreground">
|
||||
|
||||
@@ -21,7 +21,6 @@ import accountManager from "@/services/accounts";
|
||||
import { getTagValues } from "@/lib/nostr-utils";
|
||||
import { normalizeRelayURL } from "@/lib/relay-url";
|
||||
import { EventFactory } from "applesauce-core/event-factory";
|
||||
import { getAwardedPubkeys } from "@/lib/nip58-helpers";
|
||||
|
||||
/**
|
||||
* NIP-29 Adapter - Relay-Based Groups
|
||||
@@ -322,13 +321,12 @@ export class Nip29Adapter extends ChatProtocolAdapter {
|
||||
console.log(`[NIP-29] Loading messages for ${groupId} from ${relayUrl}`);
|
||||
|
||||
// Single filter for all group events:
|
||||
// kind 8: badge awards (NIP-58)
|
||||
// kind 9: chat messages
|
||||
// kind 9000: put-user (admin adds user)
|
||||
// kind 9001: remove-user (admin removes user)
|
||||
// kind 9321: nutzaps (NIP-61)
|
||||
const filter: Filter = {
|
||||
kinds: [8, 9, 9000, 9001, 9321],
|
||||
kinds: [9, 9000, 9001, 9321],
|
||||
"#h": [groupId],
|
||||
limit: options?.limit || 50,
|
||||
};
|
||||
@@ -405,7 +403,7 @@ export class Nip29Adapter extends ChatProtocolAdapter {
|
||||
|
||||
// Same filter as loadMessages but with until for pagination
|
||||
const filter: Filter = {
|
||||
kinds: [8, 9, 9000, 9001, 9321],
|
||||
kinds: [9, 9000, 9001, 9321],
|
||||
"#h": [groupId],
|
||||
until: before,
|
||||
limit: 50,
|
||||
@@ -1058,30 +1056,6 @@ export class Nip29Adapter extends ChatProtocolAdapter {
|
||||
* Helper: Convert Nostr event to Message
|
||||
*/
|
||||
private eventToMessage(event: NostrEvent, conversationId: string): Message {
|
||||
// Handle badge awards (kind 8) as system messages
|
||||
if (event.kind === 8) {
|
||||
const awardedPubkeys = getAwardedPubkeys(event);
|
||||
const badgeAddress = getTagValues(event, "a")[0]; // Badge definition address
|
||||
|
||||
// Content will be set to "badge-award" to trigger special rendering
|
||||
return {
|
||||
id: event.id,
|
||||
conversationId,
|
||||
author: event.pubkey, // Issuer
|
||||
content: "badge-award",
|
||||
timestamp: event.created_at,
|
||||
type: "system",
|
||||
protocol: "nip-29",
|
||||
metadata: {
|
||||
encrypted: false,
|
||||
// Store badge info for rendering
|
||||
badgeAddress,
|
||||
awardedPubkeys,
|
||||
},
|
||||
event,
|
||||
};
|
||||
}
|
||||
|
||||
// Handle admin events (join/leave) as system messages
|
||||
if (event.kind === 9000 || event.kind === 9001) {
|
||||
// Extract the affected user's pubkey from p-tag
|
||||
|
||||
@@ -29,8 +29,6 @@ import {
|
||||
isValidZap,
|
||||
} from "applesauce-common/helpers/zap";
|
||||
import { EventFactory } from "applesauce-core/event-factory";
|
||||
import { getAwardedPubkeys } from "@/lib/nip58-helpers";
|
||||
import { getTagValues } from "@/lib/nostr-utils";
|
||||
|
||||
/**
|
||||
* NIP-53 Adapter - Live Activity Chat
|
||||
@@ -261,9 +259,9 @@ export class Nip53Adapter extends ChatProtocolAdapter {
|
||||
`[NIP-53] Loading messages for ${aTagValue} from ${relays.length} relays`,
|
||||
);
|
||||
|
||||
// Single filter for live chat messages (kind 1311), badge awards (kind 8), and zaps (kind 9735)
|
||||
// Single filter for live chat messages (kind 1311) and zaps (kind 9735)
|
||||
const filter: Filter = {
|
||||
kinds: [8, 1311, 9735],
|
||||
kinds: [1311, 9735],
|
||||
"#a": [aTagValue],
|
||||
limit: options?.limit || 50,
|
||||
};
|
||||
@@ -363,7 +361,7 @@ export class Nip53Adapter extends ChatProtocolAdapter {
|
||||
|
||||
// Same filter as loadMessages but with until for pagination
|
||||
const filter: Filter = {
|
||||
kinds: [8, 1311, 9735],
|
||||
kinds: [1311, 9735],
|
||||
"#a": [aTagValue],
|
||||
until: before,
|
||||
limit: 50,
|
||||
@@ -675,30 +673,6 @@ export class Nip53Adapter extends ChatProtocolAdapter {
|
||||
* Helper: Convert Nostr event to Message
|
||||
*/
|
||||
private eventToMessage(event: NostrEvent, conversationId: string): Message {
|
||||
// Handle badge awards (kind 8) as system messages
|
||||
if (event.kind === 8) {
|
||||
const awardedPubkeys = getAwardedPubkeys(event);
|
||||
const badgeAddress = getTagValues(event, "a")[0]; // Badge definition address
|
||||
|
||||
// Content will be set to "badge-award" to trigger special rendering
|
||||
return {
|
||||
id: event.id,
|
||||
conversationId,
|
||||
author: event.pubkey, // Issuer
|
||||
content: "badge-award",
|
||||
timestamp: event.created_at,
|
||||
type: "system",
|
||||
protocol: "nip-53",
|
||||
metadata: {
|
||||
encrypted: false,
|
||||
// Store badge info for rendering
|
||||
badgeAddress,
|
||||
awardedPubkeys,
|
||||
},
|
||||
event,
|
||||
};
|
||||
}
|
||||
|
||||
// Look for reply e-tags (NIP-10 style)
|
||||
const eTags = event.tags.filter((t) => t[0] === "e");
|
||||
// Find the reply tag (has "reply" marker or is the last e-tag without marker)
|
||||
|
||||
@@ -5,7 +5,6 @@ import type { NostrEvent } from "./nostr";
|
||||
* Used for filtering and validating chat-related events
|
||||
*/
|
||||
export const CHAT_KINDS = [
|
||||
8, // NIP-58: Badge awards (system messages)
|
||||
9, // NIP-29: Group chat messages
|
||||
9321, // NIP-61: Nutzaps (ecash zaps in groups/live chats)
|
||||
1311, // NIP-53: Live chat messages
|
||||
@@ -107,9 +106,6 @@ export interface MessageMetadata {
|
||||
zapRecipient?: string; // Pubkey of zap recipient
|
||||
// NIP-61 nutzap-specific metadata
|
||||
nutzapUnit?: string; // Unit for nutzap amount (sat, usd, eur, etc.)
|
||||
// Badge award metadata (for type: "system" with content: "badge-award")
|
||||
badgeAddress?: string; // Badge definition address (30009:pubkey:identifier)
|
||||
awardedPubkeys?: string[]; // Pubkeys of recipients
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user