mirror of
https://github.com/styppo/hamstr.git
synced 2024-10-18 05:23:28 +00:00
Implement follow/unfollow
This commit is contained in:
parent
90a2abc7a3
commit
a9f3f79dbf
@ -141,8 +141,7 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const event = this.buildEvent()
|
const event = this.buildEvent()
|
||||||
await this.app.signEvent(event)
|
await this.app.signEvent(event)
|
||||||
//this.nostr.sendEvent(event)
|
this.nostr.publish(event)
|
||||||
console.log('Publishing', event)
|
|
||||||
|
|
||||||
this.reset()
|
this.reset()
|
||||||
this.$emit('publish', event)
|
this.$emit('publish', event)
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="app.isSignedIn" class="following">
|
<div v-if="app.isSignedIn && contacts?.length" class="following">
|
||||||
<div class="following-wrapper">
|
<div class="following-wrapper">
|
||||||
<div class="following-header">
|
<div class="following-header">
|
||||||
<h3>Following</h3>
|
<h3>Following</h3>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="contacts?.length"
|
|
||||||
class="following-body"
|
class="following-body"
|
||||||
>
|
>
|
||||||
<UserCard
|
<UserCard
|
||||||
|
@ -47,7 +47,7 @@ export default {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
await useAppStore().signEvent(event)
|
await useAppStore().signEvent(event)
|
||||||
useNostrStore().sendEvent(event)
|
useNostrStore().publish(event)
|
||||||
|
|
||||||
this.$emit('complete', {
|
this.$emit('complete', {
|
||||||
pubkey: account.pubkey,
|
pubkey: account.pubkey,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
v-if="app.isSignedIn"
|
v-if="app.isSignedIn"
|
||||||
class="btn btn-sm"
|
class="btn btn-sm"
|
||||||
:class="{'btn-primary': !isFollowing}"
|
:class="{'btn-primary': !isFollowing}"
|
||||||
|
@click="toggleFollow"
|
||||||
>
|
>
|
||||||
{{ isFollowing ? 'Unfollow' : 'Follow' }}
|
{{ isFollowing ? 'Unfollow' : 'Follow' }}
|
||||||
</button>
|
</button>
|
||||||
@ -11,6 +12,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import {useNostrStore} from 'src/nostr/NostrStore'
|
import {useNostrStore} from 'src/nostr/NostrStore'
|
||||||
import {useAppStore} from 'stores/App'
|
import {useAppStore} from 'stores/App'
|
||||||
|
import Event, {EventKind, TagType} from 'src/nostr/model/Event'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FollowButton',
|
name: 'FollowButton',
|
||||||
@ -27,12 +29,53 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
contacts() {
|
||||||
|
return this.nostr.getContacts(this.app.myPubkey)
|
||||||
|
},
|
||||||
isFollowing() {
|
isFollowing() {
|
||||||
// TODO improve
|
// TODO improve
|
||||||
const contacts = this.nostr.getContacts(this.app.myPubkey)
|
return this.contacts?.length && this.contacts.find(contact => contact.pubkey === this.pubkey)
|
||||||
return contacts?.length && contacts.find(contact => contact.pubkey === this.pubkey)
|
},
|
||||||
}
|
},
|
||||||
}
|
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)
|
||||||
|
this.nostr.publish(event)
|
||||||
|
},
|
||||||
|
toggleFollow() {
|
||||||
|
return this.isFollowing
|
||||||
|
? this.unfollow()
|
||||||
|
: this.follow()
|
||||||
|
},
|
||||||
|
async follow() {
|
||||||
|
const contacts = [].concat(this.contacts || []) // Clone array
|
||||||
|
contacts.push({pubkey: this.pubkey})
|
||||||
|
await this.updateContacts(contacts)
|
||||||
|
},
|
||||||
|
async unfollow() {
|
||||||
|
const contacts = [].concat(this.contacts || []) // Clone array
|
||||||
|
const idx = contacts.findIndex(contact => contact.pubkey === this.pubkey)
|
||||||
|
contacts.splice(idx, 1)
|
||||||
|
await this.updateContacts(contacts)
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ export default class FetchQueue extends Observable {
|
|||||||
|
|
||||||
if (!filteredIds.length) return
|
if (!filteredIds.length) return
|
||||||
|
|
||||||
console.log(`Fetching ${ids.length}/${Object.keys(this.queue).length} ${this.subId}s`, ids)
|
console.log(`Fetching ${filteredIds.length}/${Object.keys(this.queue).length} ${this.subId}s`, ids)
|
||||||
|
|
||||||
this.fetching = true
|
this.fetching = true
|
||||||
this.retryInterval = setInterval(this.fetch.bind(this), this.retryDelay)
|
this.retryInterval = setInterval(this.fetch.bind(this), this.retryDelay)
|
||||||
|
@ -69,6 +69,7 @@ export const useNostrStore = defineStore('nostr', {
|
|||||||
this.contactQueue = contactQueue(this.client, 'queue')
|
this.contactQueue = contactQueue(this.client, 'queue')
|
||||||
this.contactQueue.on('event', this.addEvent.bind(this))
|
this.contactQueue.on('event', this.addEvent.bind(this))
|
||||||
},
|
},
|
||||||
|
|
||||||
addEvent(event, relay = null) {
|
addEvent(event, relay = null) {
|
||||||
// console.log(`[EVENT] from ${relay}`, event)
|
// console.log(`[EVENT] from ${relay}`, event)
|
||||||
|
|
||||||
@ -119,7 +120,7 @@ export const useNostrStore = defineStore('nostr', {
|
|||||||
return !!this.seenBy[id]
|
return !!this.seenBy[id]
|
||||||
},
|
},
|
||||||
|
|
||||||
sendEvent(event) {
|
publish(event) {
|
||||||
this.addEvent(event)
|
this.addEvent(event)
|
||||||
return this.client.publish(event)
|
return this.client.publish(event)
|
||||||
},
|
},
|
||||||
|
@ -61,7 +61,7 @@ export default class Event {
|
|||||||
this.pubkey = opts.pubkey
|
this.pubkey = opts.pubkey
|
||||||
this.created_at = opts.createdAt || opts.created_at
|
this.created_at = opts.createdAt || opts.created_at
|
||||||
this.kind = opts.kind
|
this.kind = opts.kind
|
||||||
this.tags = Event.parseTags(opts.tags || [])
|
this.tags = opts.tags || []
|
||||||
this.content = opts.content
|
this.content = opts.content
|
||||||
this.sig = opts.sig
|
this.sig = opts.sig
|
||||||
}
|
}
|
||||||
@ -99,11 +99,11 @@ export default class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pubkeyTags() {
|
pubkeyTags() {
|
||||||
return this.tags.filter(tag => tag.type === TagType.PUBKEY)
|
return Event.parseTags(this.tags).filter(tag => tag.type === TagType.PUBKEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
eventTags() {
|
eventTags() {
|
||||||
return this.tags.filter(tag => tag.type === TagType.EVENT)
|
return Event.parseTags(this.tags).filter(tag => tag.type === TagType.EVENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
pubkeyRefs() {
|
pubkeyRefs() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {EventKind, EventRefs, TagType} from 'src/nostr/model/Event'
|
import Event, {EventKind, EventRefs, TagType} from 'src/nostr/model/Event'
|
||||||
import {isEmoji} from 'src/utils/utils'
|
import {isEmoji} from 'src/utils/utils'
|
||||||
|
|
||||||
export default class Note {
|
export default class Note {
|
||||||
@ -21,7 +21,7 @@ export default class Note {
|
|||||||
author: event.pubkey,
|
author: event.pubkey,
|
||||||
createdAt: event.createdAt,
|
createdAt: event.createdAt,
|
||||||
content,
|
content,
|
||||||
tags: event.tags,
|
tags: Event.parseTags(event.tags),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user