feat(nostr): publish notes with per-relay status (M11.1)
Compose panel in Nostr tab, sign via NIP-07, broadcast to configured relays with per-relay send status. Character counter (soft 280 limit). Removed isDark conditionals from NostrGrid (dark-only app). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
869db87fd5
commit
9b4980b669
@@ -175,6 +175,57 @@ function disconnect() {
|
||||
initialized = false
|
||||
}
|
||||
|
||||
export interface PublishResult {
|
||||
url: string
|
||||
success: boolean
|
||||
message: string
|
||||
}
|
||||
|
||||
function publishEvent(signedEvent: NostrEvent): Promise<PublishResult[]> {
|
||||
const connectedRelays = relays.filter(r => r.connected && r.ws)
|
||||
if (connectedRelays.length === 0) {
|
||||
return Promise.resolve([])
|
||||
}
|
||||
|
||||
const results = connectedRelays.map(relay => {
|
||||
return new Promise<PublishResult>((resolve) => {
|
||||
const timer = setTimeout(() => {
|
||||
resolve({ url: relay.url, success: false, message: 'Timeout' })
|
||||
}, 5000)
|
||||
|
||||
const handler = (msg: MessageEvent) => {
|
||||
try {
|
||||
const data = JSON.parse(msg.data)
|
||||
// NIP-01: ["OK", <event_id>, <accepted>, <message>]
|
||||
if (Array.isArray(data) && data[0] === 'OK' && data[1] === signedEvent.id) {
|
||||
clearTimeout(timer)
|
||||
relay.ws?.removeEventListener('message', handler)
|
||||
resolve({
|
||||
url: relay.url,
|
||||
success: !!data[2],
|
||||
message: data[3] ?? (data[2] ? 'Published' : 'Rejected'),
|
||||
})
|
||||
}
|
||||
} catch { /* skip */ }
|
||||
}
|
||||
|
||||
relay.ws!.addEventListener('message', handler)
|
||||
try {
|
||||
relay.ws!.send(JSON.stringify(['EVENT', signedEvent]))
|
||||
} catch {
|
||||
clearTimeout(timer)
|
||||
relay.ws?.removeEventListener('message', handler)
|
||||
resolve({ url: relay.url, success: false, message: 'Send failed' })
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// Also add to our local feed
|
||||
addEvent(signedEvent)
|
||||
|
||||
return Promise.all(results)
|
||||
}
|
||||
|
||||
function fetchNote(hexId: string, timeoutMs = 5000): Promise<NostrNote | null> {
|
||||
// Check if already cached
|
||||
const cached = events.value.find(e => e.id === hexId)
|
||||
@@ -237,5 +288,6 @@ export function useNostr() {
|
||||
connect,
|
||||
disconnect,
|
||||
fetchNote,
|
||||
publishEvent,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user