mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-06-06 02:31:13 +02:00
refactor: open GroupListViewer via chat command with kind 10009 naddr
Instead of a separate 'chats' command, open the multi-room group list interface by passing a kind 10009 naddr to the chat command. Changes: - Fix TypeScript error in GroupListViewer (replaceable returns single event) - Add GroupListIdentifier type for kind 10009 addresses - Update chat parser to detect kind 10009 naddr and route to GroupListViewer - Update WindowRenderer to check identifier type and render GroupListViewer - Remove 'chats' command and appId (consolidated into chat command) - Update chat command documentation to include kind 10009 example Usage: chat naddr1...10009... Open multi-room group list interface
This commit is contained in:
@@ -113,11 +113,13 @@ export function GroupListViewer() {
|
||||
() =>
|
||||
activePubkey
|
||||
? eventStore.replaceable(10009, activePubkey).pipe(
|
||||
map((events) => {
|
||||
console.log(
|
||||
`[GroupListViewer] Loaded ${events.length} group list events`,
|
||||
);
|
||||
return events[0]; // replaceable() returns array, take most recent
|
||||
map((event) => {
|
||||
if (event) {
|
||||
console.log(
|
||||
`[GroupListViewer] Loaded group list event: ${event.id.slice(0, 8)}...`,
|
||||
);
|
||||
}
|
||||
return event;
|
||||
}),
|
||||
)
|
||||
: undefined,
|
||||
|
||||
@@ -176,16 +176,18 @@ export function WindowRenderer({ window, onClose }: WindowRendererProps) {
|
||||
content = <ConnViewer />;
|
||||
break;
|
||||
case "chat":
|
||||
content = (
|
||||
<ChatViewer
|
||||
protocol={window.props.protocol}
|
||||
identifier={window.props.identifier}
|
||||
customTitle={window.customTitle}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
case "chats":
|
||||
content = <GroupListViewer />;
|
||||
// Check if this is a group list (kind 10009) - render multi-room interface
|
||||
if (window.props.identifier?.type === "group-list") {
|
||||
content = <GroupListViewer />;
|
||||
} else {
|
||||
content = (
|
||||
<ChatViewer
|
||||
protocol={window.props.protocol}
|
||||
identifier={window.props.identifier}
|
||||
customTitle={window.customTitle}
|
||||
/>
|
||||
);
|
||||
}
|
||||
break;
|
||||
case "spells":
|
||||
content = <SpellsViewer />;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { ChatCommandResult } from "@/types/chat";
|
||||
import type { ChatCommandResult, GroupListIdentifier } from "@/types/chat";
|
||||
// import { NipC7Adapter } from "./chat/adapters/nip-c7-adapter";
|
||||
import { Nip29Adapter } from "./chat/adapters/nip-29-adapter";
|
||||
import { Nip53Adapter } from "./chat/adapters/nip-53-adapter";
|
||||
import { nip19 } from "nostr-tools";
|
||||
// Import other adapters as they're implemented
|
||||
// import { Nip17Adapter } from "./chat/adapters/nip-17-adapter";
|
||||
// import { Nip28Adapter } from "./chat/adapters/nip-28-adapter";
|
||||
@@ -34,6 +35,31 @@ export function parseChatCommand(args: string[]): ChatCommandResult {
|
||||
identifier = `${args[0]}'${args[1]}`;
|
||||
}
|
||||
|
||||
// Check for kind 10009 (group list) naddr - open multi-room interface
|
||||
if (identifier.startsWith("naddr1")) {
|
||||
try {
|
||||
const decoded = nip19.decode(identifier);
|
||||
if (decoded.type === "naddr" && decoded.data.kind === 10009) {
|
||||
const groupListIdentifier: GroupListIdentifier = {
|
||||
type: "group-list",
|
||||
value: {
|
||||
kind: 10009,
|
||||
pubkey: decoded.data.pubkey,
|
||||
identifier: decoded.data.identifier,
|
||||
},
|
||||
relays: decoded.data.relays,
|
||||
};
|
||||
return {
|
||||
protocol: "nip-29", // Use nip-29 as the protocol designation
|
||||
identifier: groupListIdentifier,
|
||||
adapter: null, // No adapter needed for group list view
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
// Not a valid naddr, continue to adapter parsing
|
||||
}
|
||||
}
|
||||
|
||||
// Try each adapter in priority order
|
||||
const adapters = [
|
||||
// new Nip17Adapter(), // Phase 2
|
||||
@@ -68,6 +94,9 @@ Currently supported formats:
|
||||
- naddr1... (NIP-53 live activity chat, kind 30311)
|
||||
Example:
|
||||
chat naddr1... (live stream address)
|
||||
- naddr1... (Multi-room group list, kind 10009)
|
||||
Example:
|
||||
chat naddr1... (group list address)
|
||||
|
||||
More formats coming soon:
|
||||
- npub/nprofile/hex pubkey (NIP-C7/NIP-17 direct messages)
|
||||
|
||||
@@ -17,7 +17,6 @@ export type AppId =
|
||||
| "debug"
|
||||
| "conn"
|
||||
| "chat"
|
||||
| "chats"
|
||||
| "spells"
|
||||
| "spellbooks"
|
||||
| "win";
|
||||
|
||||
@@ -178,6 +178,22 @@ export interface ChannelIdentifier {
|
||||
relays?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Group list identifier (kind 10009)
|
||||
* Used to open multi-room chat interface
|
||||
*/
|
||||
export interface GroupListIdentifier {
|
||||
type: "group-list";
|
||||
/** Address pointer for the group list (kind 10009) */
|
||||
value: {
|
||||
kind: 10009;
|
||||
pubkey: string;
|
||||
identifier: string;
|
||||
};
|
||||
/** Relay hints from naddr encoding */
|
||||
relays?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Protocol-specific identifier - discriminated union
|
||||
* Returned by adapter parseIdentifier()
|
||||
@@ -187,7 +203,8 @@ export type ProtocolIdentifier =
|
||||
| LiveActivityIdentifier
|
||||
| DMIdentifier
|
||||
| NIP05Identifier
|
||||
| ChannelIdentifier;
|
||||
| ChannelIdentifier
|
||||
| GroupListIdentifier;
|
||||
|
||||
/**
|
||||
* Chat command parsing result
|
||||
|
||||
@@ -350,20 +350,21 @@ export const manPages: Record<string, ManPageEntry> = {
|
||||
section: "1",
|
||||
synopsis: "chat <identifier>",
|
||||
description:
|
||||
"Join and participate in Nostr chat conversations. Supports NIP-29 relay-based groups and NIP-53 live activity chat. For NIP-29 groups, use format 'relay'group-id' where relay is the WebSocket URL (wss:// prefix optional). For NIP-53 live activities, pass the naddr of a kind 30311 live event to join its chat.",
|
||||
"Join and participate in Nostr chat conversations. Supports NIP-29 relay-based groups, NIP-53 live activity chat, and multi-room group list interface. For NIP-29 groups, use format 'relay'group-id' where relay is the WebSocket URL (wss:// prefix optional). For NIP-53 live activities, pass the naddr of a kind 30311 live event. For multi-room interface, pass the naddr of a kind 10009 group list event.",
|
||||
options: [
|
||||
{
|
||||
flag: "<identifier>",
|
||||
description:
|
||||
"NIP-29 group (relay'group-id) or NIP-53 live activity (naddr1...)",
|
||||
"NIP-29 group (relay'group-id), NIP-53 live activity (naddr1... kind 30311), or group list (naddr1... kind 10009)",
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
"chat relay.example.com'bitcoin-dev Join NIP-29 relay group",
|
||||
"chat wss://nos.lol'welcome Join NIP-29 group with explicit protocol",
|
||||
"chat naddr1... Join NIP-53 live activity chat",
|
||||
"chat naddr1...30311... Join NIP-53 live activity chat",
|
||||
"chat naddr1...10009... Open multi-room group list interface",
|
||||
],
|
||||
seeAlso: ["chats", "profile", "open", "req", "live"],
|
||||
seeAlso: ["profile", "open", "req", "live"],
|
||||
appId: "chat",
|
||||
category: "Nostr",
|
||||
argParser: async (args: string[]) => {
|
||||
@@ -374,18 +375,6 @@ export const manPages: Record<string, ManPageEntry> = {
|
||||
};
|
||||
},
|
||||
},
|
||||
chats: {
|
||||
name: "chats",
|
||||
section: "1",
|
||||
synopsis: "chats",
|
||||
description:
|
||||
"Open a multi-room chat interface showing all your NIP-29 groups. Displays groups from your kind 10009 (User Group List) event, sorted by most recent activity. Click any group to view its chat. Provides an overview of all your group conversations in one place.",
|
||||
examples: ["chats Open multi-room chat interface"],
|
||||
seeAlso: ["chat", "profile"],
|
||||
appId: "chats",
|
||||
category: "Nostr",
|
||||
defaultProps: {},
|
||||
},
|
||||
profile: {
|
||||
name: "profile",
|
||||
section: "1",
|
||||
|
||||
Reference in New Issue
Block a user