mirror of
https://github.com/styppo/hamstr.git
synced 2024-10-18 05:23:28 +00:00
* Hide reactions, reposts, bots from feed
* Improve feed performance
This commit is contained in:
parent
ecbb2f98e3
commit
2e78bdd51e
@ -44,7 +44,6 @@ export default defineComponent({
|
||||
methods: {
|
||||
async load() {
|
||||
if (this.loading) return
|
||||
console.log('loading')
|
||||
|
||||
this.loading = true
|
||||
this.$emit('loading')
|
||||
|
@ -41,21 +41,28 @@ export default class Note {
|
||||
return this.eventRefs().ancestor()
|
||||
}
|
||||
|
||||
pubkeyTags() {
|
||||
return this.tags.filter(tag => tag.type === TagType.PUBKEY)
|
||||
}
|
||||
|
||||
eventTags() {
|
||||
return this.tags.filter(tag => tag.type === TagType.EVENT)
|
||||
}
|
||||
|
||||
pubkeyRefs() {
|
||||
return this.tags
|
||||
.filter(tag => tag.type === TagType.PUBKEY)
|
||||
.map(tag => tag.ref)
|
||||
return this.pubkeyTags().map(tag => tag.ref)
|
||||
}
|
||||
|
||||
eventRefs() {
|
||||
const refs = this.tags
|
||||
.filter(tag => tag.type === TagType.EVENT)
|
||||
.map(tag => tag.ref)
|
||||
return new EventRefs(refs)
|
||||
return new EventRefs(this.eventTags().map(tag => tag.ref))
|
||||
}
|
||||
|
||||
relatedPubkeys() {
|
||||
return [this.author].concat(this.pubkeyRefs())
|
||||
}
|
||||
|
||||
contentTagRefs() {
|
||||
const regex = /#\[([0-9]+)]/ig
|
||||
const regex = /#\[([0-9]+)]/g
|
||||
let refs = []
|
||||
let match
|
||||
while ((match = regex.exec(this.content))) {
|
||||
@ -64,9 +71,16 @@ export default class Note {
|
||||
return refs
|
||||
}
|
||||
|
||||
isRepostOrTag() {
|
||||
return Note.isRepostOrTag(this)
|
||||
}
|
||||
|
||||
static isRepostOrTag(event) {
|
||||
return /#\[([0-9]+)]/.test(event.content)
|
||||
}
|
||||
|
||||
isReaction() {
|
||||
return this.kind === EventKind.REACTION
|
||||
|| (this.hasAncestor() && Note.isReactionContent(this.content))
|
||||
return Note.isReaction(this)
|
||||
}
|
||||
|
||||
static isReaction(event) {
|
||||
|
@ -22,6 +22,9 @@ export const useStatStore = defineStore('stat', {
|
||||
if (Note.isReaction(event)) {
|
||||
const stats = this.getOrInit(event.eventRefs().ancestor())
|
||||
stats.reactions++
|
||||
} else if (Note.isRepostOrTag(event)) {
|
||||
const stats = this.getOrInit(event.eventRefs().ancestor())
|
||||
stats.shares++
|
||||
} else {
|
||||
for (const eventId of event.eventRefs()) {
|
||||
const stats = this.getOrInit(eventId)
|
||||
|
@ -33,13 +33,13 @@
|
||||
<div class="load-more-container" :class="{'more-available': numUnreads}">
|
||||
<AsyncLoadButton
|
||||
v-if="numUnreads"
|
||||
:load-fn="loadUnreads"
|
||||
:load-fn="loadNewer"
|
||||
:label="`Load ${numUnreads} unreads`"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<template v-for="(thread, i) in feedItems">
|
||||
<Thread v-if="defer(i)" :key="thread[0].id" :thread="thread" class="full-width" />
|
||||
<Thread v-if="true || defer(i)" :key="thread[0].id" :thread="thread" class="full-width" />
|
||||
</template>
|
||||
|
||||
<ListPlaceholder :count="feedItems?.length" :loading="loading" />
|
||||
@ -66,6 +66,7 @@ import {useNostrStore} from 'src/nostr/NostrStore'
|
||||
import Defer from 'src/utils/Defer'
|
||||
import {EventKind} from 'src/nostr/model/Event'
|
||||
import DateUtils from 'src/utils/DateUtils'
|
||||
import Bots from 'src/utils/bots'
|
||||
|
||||
const Feeds = {
|
||||
global: {
|
||||
@ -79,6 +80,8 @@ const Feeds = {
|
||||
|
||||
const feedOrder = (a, b) => b[0].createdAt - a[0].createdAt
|
||||
|
||||
const MAX_ITEMS_VISIBLE = 50
|
||||
|
||||
export default defineComponent({
|
||||
name: 'Feed',
|
||||
components: {
|
||||
@ -110,14 +113,11 @@ export default defineComponent({
|
||||
return this.feeds[this.selectedFeed]
|
||||
},
|
||||
feedItems() {
|
||||
return this.activeFeed?.items
|
||||
},
|
||||
feedUnreads() {
|
||||
return this.activeFeed?.unreads
|
||||
return this.activeFeed?.visible
|
||||
},
|
||||
numUnreads() {
|
||||
if (this.recentlyLoaded) return 0
|
||||
return this.activeFeed?.unreads.length
|
||||
return this.activeFeed?.newer.length
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
@ -129,22 +129,27 @@ export default defineComponent({
|
||||
filters,
|
||||
{subId: `feed:${feedId}`}
|
||||
)
|
||||
stream.on('init', events => {
|
||||
const items = events.map(event => [event]) // TODO Single element thread
|
||||
stream.on('init', notes => {
|
||||
const items = notes
|
||||
.filter(this.filterNote.bind(this))
|
||||
.map(note => [note]) // TODO Single element thread
|
||||
items.sort(feedOrder)
|
||||
this.feeds[feedId].items = items.slice(0, filters.limit)
|
||||
this.feeds[feedId].visible = items.slice(0, filters.limit)
|
||||
this.loading = false
|
||||
|
||||
// Wait a bit before showing the first unreads
|
||||
setTimeout(() => this.recentlyLoaded = false, 5000)
|
||||
})
|
||||
stream.on('update', event => {
|
||||
this.feeds[feedId].unreads.push([event]) // TODO Single element thread
|
||||
stream.on('update', note => {
|
||||
if (this.filterNote(note)) {
|
||||
this.feeds[feedId].newer.push([note]) // TODO Single element thread
|
||||
}
|
||||
})
|
||||
|
||||
this.feeds[feedId] = {
|
||||
items: [],
|
||||
unreads: [],
|
||||
visible: [],
|
||||
newer: [],
|
||||
older: [],
|
||||
stream,
|
||||
}
|
||||
},
|
||||
@ -152,12 +157,18 @@ export default defineComponent({
|
||||
this.initFeed(feedId)
|
||||
this.selectedFeed = feedId
|
||||
},
|
||||
loadUnreads() {
|
||||
loadNewer() {
|
||||
// TODO Deduplicate feed items
|
||||
const items = this.feedUnreads.concat(this.feedItems)
|
||||
this.activeFeed.newer.sort(feedOrder)
|
||||
const items = this.activeFeed.newer.concat(this.feedItems)
|
||||
if (items.length > MAX_ITEMS_VISIBLE) {
|
||||
const older = items.splice(MAX_ITEMS_VISIBLE)
|
||||
this.activeFeed.older = older.concat(this.activeFeed.older)
|
||||
}
|
||||
//items.sort(feedOrder)
|
||||
this.activeFeed.items = items
|
||||
this.activeFeed.unreads = []
|
||||
|
||||
this.activeFeed.visible = items
|
||||
this.activeFeed.newer = []
|
||||
|
||||
// Wait a bit before showing unreads again
|
||||
this.recentlyLoaded = true
|
||||
@ -167,22 +178,35 @@ export default defineComponent({
|
||||
},
|
||||
async loadOlder() {
|
||||
const until = this.feedItems[this.feedItems.length - 1]?.[0]?.createdAt || DateUtils.now()
|
||||
console.log('until', new Date(until * 1000))
|
||||
const filters = Object.assign({}, Feeds[this.selectedFeed].filters, {until})
|
||||
|
||||
if (this.activeFeed.older.length >= filters.limit) {
|
||||
const chunk = this.activeFeed.older.splice(0, filters.limit)
|
||||
this.activeFeed.visible = this.feedItems.concat(chunk)
|
||||
return chunk
|
||||
}
|
||||
|
||||
// Remove any residual older items
|
||||
this.activeFeed.older = []
|
||||
|
||||
const older = await this.nostr.fetch(filters, {subId: `feed:${this.selectedFeed}-older`})
|
||||
const items = older.map(event => [event]).sort(feedOrder)
|
||||
const items = older
|
||||
.filter(note => note.createdAt <= until)
|
||||
.filter(this.filterNote.bind(this))
|
||||
.map(note => [note]) // TODO Single element thread
|
||||
.sort(feedOrder)
|
||||
|
||||
console.log('got items', older)
|
||||
|
||||
console.log('length before', this.activeFeed.items.length)
|
||||
// TODO Deduplicate feed items
|
||||
this.activeFeed.items = this.feedItems.concat(items)
|
||||
|
||||
console.log('length after', this.activeFeed.items.length)
|
||||
this.activeFeed.visible = this.feedItems.concat(items)
|
||||
|
||||
return older
|
||||
},
|
||||
filterNote(note) {
|
||||
if (note.isReaction()) return false
|
||||
if (note.isRepostOrTag()) return false
|
||||
if (note.relatedPubkeys().some(Bots.isBot)) return false
|
||||
return true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initFeed(this.selectedFeed)
|
||||
|
10
src/utils/bots.js
Normal file
10
src/utils/bots.js
Normal file
@ -0,0 +1,10 @@
|
||||
import {bech32ToHex} from 'src/utils/utils'
|
||||
|
||||
const Bots = new Set()
|
||||
export default Bots
|
||||
Bots.isBot = Bots.has.bind(Bots)
|
||||
Bots.add = pubkey => Set.prototype.add.call(Bots, bech32ToHex(pubkey))
|
||||
|
||||
Bots.add('npub1tsgw6pncspg4d5u778hk63s3pls70evs4czfsmx0fzap9xwt203qtkhtk4') // gpt3
|
||||
Bots.add('npub17stpezz4suqdywh33k9x8pht04l76a5sfrsjj7q3mnp5ap5937eqdt58d7') // bitcoin_bot
|
||||
Bots.add('npub1xe59lfgsdvduqwh8h65zahkc2hv02mzpmdxghhhcpx0puret9taqheapxc') // moe_bot
|
Loading…
Reference in New Issue
Block a user