Move all event creation logic into EventBuilder

This commit is contained in:
styppo 2023-01-20 18:38:29 +00:00
parent c878c92911
commit 285f27c3dd
No known key found for this signature in database
GPG Key ID: 3AAA685C50724C28
5 changed files with 133 additions and 66 deletions

View File

@ -52,7 +52,7 @@ import BaseIcon from 'components/BaseIcon/index.vue'
import EmojiPicker from 'components/CreatePost/EmojiPicker.vue'
import {useAppStore} from 'stores/App'
import {useNostrStore} from 'src/nostr/NostrStore'
import Event, {EventKind} from 'src/nostr/model/Event'
import EventBuilder from 'src/nostr/EventBuilder'
export default {
name: 'PostEditor',
@ -112,35 +112,13 @@ export default {
reset() {
this.content = ''
},
buildEvent() {
return Event.fresh({
pubkey: this.app.myPubkey,
kind: EventKind.NOTE,
tags: this.buildTags(),
content: this.content,
})
},
buildTags() {
// TODO Extract tags from content
const e = []
const p = []
if (this.ancestor) {
if (this.ancestor.hasAncestor()) {
e.push(this.ancestor.root())
}
e.push(this.ancestor.id)
p.push(this.ancestor.author)
}
return e.map(e => ['e', e])
.concat(p.map(p => ['p', p]))
},
async publishPost() {
this.publishing = true
try {
const event = this.buildEvent()
await this.app.signEvent(event)
const event = this.ancestor
? EventBuilder.reply(this.ancestor, this.app.myPubkey, this.content).build()
: EventBuilder.post(this.app.myPubkey, this.content).build()
if (!await this.app.signEvent(event)) return
this.nostr.publish(event)
this.reset()
@ -153,6 +131,7 @@ export default {
color: 'positive',
})
} catch (e) {
console.error('Failed to publish post', e)
this.$q.notify({
message: `Failed to publish post`,
color: 'negative'

View File

@ -25,8 +25,8 @@
<script>
import {useNostrStore} from 'src/nostr/NostrStore'
import {useAppStore} from 'stores/App'
import Event, {EventKind} from 'src/nostr/model/Event'
import Nip05 from 'src/utils/Nip05'
import EventBuilder from 'src/nostr/EventBuilder'
export default {
name: 'ProfileSettings',
@ -70,17 +70,14 @@ export default {
this.verified = this.profile?.nip05.verified
},
async updateProfile() {
const event = Event.fresh({
pubkey: this.pubkey,
kind: EventKind.METADATA,
content: JSON.stringify({
name: this.name || undefined,
about: this.about || undefined,
picture: this.picture || undefined,
nip05: this.nip05 || undefined,
})
})
await this.app.signEvent(event)
const metadata = {
name: this.name || undefined,
about: this.about || undefined,
picture: this.picture || undefined,
nip05: this.nip05 || undefined,
}
const event = EventBuilder.metadata(this.pubkey, metadata).build()
if (!await this.app.signEvent(event)) return
this.nostr.publish(event)
},
},

View File

@ -14,7 +14,7 @@ import {useAppStore} from 'stores/App'
import {useNostrStore} from 'src/nostr/NostrStore'
import {useSettingsStore} from 'stores/Settings'
import {generatePrivateKey} from 'nostr-tools'
import Event, {EventKind} from 'src/nostr/model/Event'
import EventBuilder from 'src/nostr/EventBuilder'
export default {
name: 'SignUpForm',
@ -39,13 +39,7 @@ export default {
const account = settings.addAccount({privkey})
settings.switchAccount(account.pubkey)
const event = Event.fresh({
pubkey: account.pubkey,
kind: EventKind.METADATA,
content: JSON.stringify({
name: this.username
})
})
const event = EventBuilder.metadata(account.pubkey, {name: this.username}).build()
await useAppStore().signEvent(event)
useNostrStore().publish(event)

View File

@ -12,7 +12,7 @@
<script>
import {useNostrStore} from 'src/nostr/NostrStore'
import {useAppStore} from 'stores/App'
import Event, {EventKind, TagType} from 'src/nostr/model/Event'
import EventBuilder from 'src/nostr/EventBuilder'
export default {
name: 'FollowButton',
@ -38,25 +38,9 @@ export default {
},
},
methods: {
// TODO Move this logic somewhere else
buildEvent(contacts) {
return Event.fresh({
pubkey: this.app.myPubkey,
kind: EventKind.CONTACT,
tags: this.buildTags(contacts),
content: '',
})
},
buildTags(contacts) {
const tags = []
for (const contact of contacts) {
tags.push([TagType.PUBKEY, contact.pubkey])
}
return tags
},
async updateContacts(contacts) {
const event = this.buildEvent(contacts)
await this.app.signEvent(event)
const event = EventBuilder.contacts(this.app.myPubkey, contacts.map(c => c.pubkey)).build()
if (!await this.app.signEvent(event)) return
this.nostr.publish(event)
},
toggleFollow() {

113
src/nostr/EventBuilder.js Normal file
View File

@ -0,0 +1,113 @@
import Event, {EventKind, TagType} from 'src/nostr/model/Event'
import DateUtils from 'src/utils/DateUtils'
export default class EventBuilder {
constructor(opts) {
this.event = new Event({
id: opts.id,
pubkey: opts.pubkey || opts.author,
created_at: opts.created_at || opts.createdAt || DateUtils.now(),
kind: opts.kind,
tags: opts.tags || [],
content: opts.content || '',
sig: opts.sig,
})
}
static post(author, content) {
return new EventBuilder({
kind: EventKind.NOTE,
pubkey: author,
content
})
}
static reply(ancestor, author, content) {
const tags = []
// Reference thread root and ancestor
const root = ancestor.eventRefs().root()
if (root) tags.push([TagType.EVENT, root]) // TODO relay, meta
tags.push([TagType.EVENT, ancestor.id]) // TODO relay, meta
// Tag author of ancestor
tags.push([TagType.PUBKEY, ancestor.author])
return new EventBuilder({
kind: EventKind.NOTE,
pubkey: author,
content,
tags,
})
}
static reaction(ancestor, author) {
const tags = []
// Reference ancestor
tags.push([TagType.EVENT, ancestor.id]) // TODO relay, meta
// Tag author of ancestor
tags.push([TagType.PUBKEY, ancestor.author])
return new EventBuilder({
kind: EventKind.REACTION,
pubkey: author,
content: '❤️', // TODO default reaction
tags,
})
}
static metadata(author, metadata) {
return new EventBuilder({
kind: EventKind.METADATA,
pubkey: author,
content: JSON.stringify(metadata),
})
}
static contacts(author, pubkeys) {
const tags = pubkeys.map(pubkey => [TagType.PUBKEY, pubkey])
return new EventBuilder({
kind: EventKind.CONTACT,
pubkey: author,
tags
})
}
static delete(author, ids) {
const tags = ids.map(id => [TagType.EVENT, id])
return new EventBuilder({
kind: EventKind.DELETE,
pubkey: author,
tags
})
}
createdAt(timestamp) {
this.event.created_at = timestamp
return this
}
pubkeyTag(pubkey) {
this.event.tags.push([TagType.PUBKEY, pubkey])
return this
}
eventTag(id, relay = null, meta = null) {
const tag = [TagType.EVENT, id]
if (relay) tag.push(relay)
if (meta) tag.push(meta)
this.event.tags.push(tag)
return this
}
content(content) {
this.event.content = content
return this
}
build() {
return new Event(this.event)
}
}