mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-30 00:41:12 +00:00
Count followers using rbr.bio
This commit is contained in:
parent
1939725ac6
commit
755d6cfa7f
@ -199,8 +199,8 @@ const applyContext = (notes, context) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
listen,
|
|
||||||
load,
|
load,
|
||||||
|
listen,
|
||||||
loadPeople,
|
loadPeople,
|
||||||
loadParents,
|
loadParents,
|
||||||
streamContext,
|
streamContext,
|
||||||
|
@ -38,7 +38,7 @@ class Connection {
|
|||||||
url: string
|
url: string
|
||||||
promise?: Deferred<void>
|
promise?: Deferred<void>
|
||||||
queue: string[]
|
queue: string[]
|
||||||
error: {code: string; occurredAt: number}
|
error: {code: string; message: string, occurredAt: number}
|
||||||
status: {code: string; message: string}
|
status: {code: string; message: string}
|
||||||
timeout?: number
|
timeout?: number
|
||||||
stats: Record<string, number>
|
stats: Record<string, number>
|
||||||
@ -72,8 +72,8 @@ class Connection {
|
|||||||
setStatus(code, message) {
|
setStatus(code, message) {
|
||||||
this.status = {code, message}
|
this.status = {code, message}
|
||||||
}
|
}
|
||||||
setError(code) {
|
setError(code, message) {
|
||||||
this.error = {code, occurredAt: Date.now()}
|
this.error = {code, message, occurredAt: Date.now()}
|
||||||
}
|
}
|
||||||
connect() {
|
connect() {
|
||||||
if (this.ws) {
|
if (this.ws) {
|
||||||
@ -100,11 +100,11 @@ class Connection {
|
|||||||
})
|
})
|
||||||
|
|
||||||
this.ws.addEventListener("error", e => {
|
this.ws.addEventListener("error", e => {
|
||||||
log(`Error on connection to ${this.url}`, e)
|
log(`Error on connection to ${this.url}`)
|
||||||
|
|
||||||
this.disconnect()
|
this.disconnect()
|
||||||
this.promise.reject()
|
this.promise.reject()
|
||||||
this.setError(ERROR.CONNECTION)
|
this.setError(ERROR.CONNECTION, "Disconnected")
|
||||||
this.setStatus(STATUS.CLOSED, "Closed")
|
this.setStatus(STATUS.CLOSED, "Closed")
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ class Connection {
|
|||||||
conn: this,
|
conn: this,
|
||||||
unsub: () => {
|
unsub: () => {
|
||||||
if (this.status.code === STATUS.READY) {
|
if (this.status.code === STATUS.READY) {
|
||||||
this.send("CLOSE", id, ...filters)
|
this.send("CLOSE", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.bus.off("EVENT", eventChannel)
|
this.bus.off("EVENT", eventChannel)
|
||||||
@ -196,12 +196,23 @@ class Connection {
|
|||||||
|
|
||||||
this.send("EVENT", event)
|
this.send("EVENT", event)
|
||||||
}
|
}
|
||||||
|
count(filter, id, {onCount}) {
|
||||||
|
const channel = this.bus.on("COUNT", (subid, ...payload) => {
|
||||||
|
if (subid === id) {
|
||||||
|
onCount(...payload)
|
||||||
|
|
||||||
|
this.bus.off("COUNT", channel)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.send("COUNT", id, ...filter)
|
||||||
|
}
|
||||||
listenForAuth() {
|
listenForAuth() {
|
||||||
// Propagate auth to global handler
|
// Propagate auth to global handler
|
||||||
this.bus.on("AUTH", challenge => {
|
this.bus.on("AUTH", challenge => {
|
||||||
if (!this.error) {
|
if (!this.error) {
|
||||||
this.setStatus(STATUS.ERROR, "Logging in")
|
this.setStatus(STATUS.ERROR, "Logging in")
|
||||||
this.setError(ERROR.UNAUTHORIZED)
|
this.setError(ERROR.UNAUTHORIZED, "Logging in")
|
||||||
|
|
||||||
eventBus.handle("AUTH", challenge, this)
|
eventBus.handle("AUTH", challenge, this)
|
||||||
}
|
}
|
||||||
@ -214,7 +225,7 @@ class Connection {
|
|||||||
this.setStatus(STATUS.READY, "Connected")
|
this.setStatus(STATUS.READY, "Connected")
|
||||||
} else {
|
} else {
|
||||||
this.disconnect()
|
this.disconnect()
|
||||||
this.setError(ERROR.FORBIDDEN)
|
this.setError(ERROR.FORBIDDEN, "Access restricted")
|
||||||
}
|
}
|
||||||
|
|
||||||
this.bus.off("OK", channel)
|
this.bus.off("OK", channel)
|
||||||
@ -225,8 +236,8 @@ class Connection {
|
|||||||
return this.error && Date.now() - 30_000 < this.error.occurredAt
|
return this.error && Date.now() - 30_000 < this.error.occurredAt
|
||||||
}
|
}
|
||||||
getQuality() {
|
getQuality() {
|
||||||
if (this.status.code === STATUS.ERROR) {
|
if (this.error) {
|
||||||
return [0, this.status.message]
|
return [0, this.error.message]
|
||||||
}
|
}
|
||||||
|
|
||||||
const {timeouts, subsCount, eoseTimer, eoseCount} = this.stats
|
const {timeouts, subsCount, eoseTimer, eoseCount} = this.stats
|
||||||
@ -474,6 +485,22 @@ const subscribe = async ({relays, filter, onEvent, onEose, onError}: SubscribeOp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const count = async filter => {
|
||||||
|
const conn = await connect("wss://rbr.bio")
|
||||||
|
|
||||||
|
if (!conn || conn.status.code !== STATUS.READY) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
filter = ensurePlural(filter)
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
conn.count(filter, createFilterId(filter), {
|
||||||
|
onCount: res => resolve(res?.count),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
|
|
||||||
const createFilterId = filters =>
|
const createFilterId = filters =>
|
||||||
@ -504,4 +531,5 @@ export default {
|
|||||||
disconnect,
|
disconnect,
|
||||||
publish,
|
publish,
|
||||||
subscribe,
|
subscribe,
|
||||||
|
count,
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
import {navigate} from "svelte-routing"
|
import {navigate} from "svelte-routing"
|
||||||
import {log} from "src/util/logger"
|
import {log} from "src/util/logger"
|
||||||
import {renderContent, parseHex} from "src/util/html"
|
import {renderContent, parseHex} from "src/util/html"
|
||||||
|
import {numberFmt} from "src/util/misc"
|
||||||
import {displayPerson, Tags, toHex} from "src/util/nostr"
|
import {displayPerson, Tags, toHex} from "src/util/nostr"
|
||||||
import Tabs from "src/partials/Tabs.svelte"
|
import Tabs from "src/partials/Tabs.svelte"
|
||||||
import Content from "src/partials/Content.svelte"
|
import Content from "src/partials/Content.svelte"
|
||||||
@ -19,7 +20,7 @@
|
|||||||
import pool from "src/agent/pool"
|
import pool from "src/agent/pool"
|
||||||
import {sampleRelays, getPubkeyWriteRelays} from "src/agent/relays"
|
import {sampleRelays, getPubkeyWriteRelays} from "src/agent/relays"
|
||||||
import network from "src/agent/network"
|
import network from "src/agent/network"
|
||||||
import {getPersonWithFallback, people} from "src/agent/tables"
|
import {getPersonWithFallback} from "src/agent/tables"
|
||||||
import {routes, modal, theme, getThemeColor} from "src/app/ui"
|
import {routes, modal, theme, getThemeColor} from "src/app/ui"
|
||||||
import PersonCircle from "src/partials/PersonCircle.svelte"
|
import PersonCircle from "src/partials/PersonCircle.svelte"
|
||||||
|
|
||||||
@ -104,27 +105,25 @@
|
|||||||
loading = false
|
loading = false
|
||||||
})
|
})
|
||||||
|
|
||||||
// Prime our followers count
|
// Get our followers count
|
||||||
people.all().forEach(p => {
|
const count = await pool.count({kinds: [3], "#p": [pubkey]})
|
||||||
if (Tags.wrap(p.petnames).type("p").values().all().includes(pubkey)) {
|
|
||||||
followers.add(p.pubkey)
|
|
||||||
followersCount.set(followers.size)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Round out our followers count
|
if (count) {
|
||||||
await network.load({
|
followersCount.set(count)
|
||||||
shouldProcess: false,
|
} else {
|
||||||
relays: getRelays(),
|
await network.load({
|
||||||
filter: [{kinds: [3], "#p": [pubkey]}],
|
shouldProcess: false,
|
||||||
onChunk: events => {
|
relays: getRelays(),
|
||||||
for (const e of events) {
|
filter: [{kinds: [3], "#p": [pubkey]}],
|
||||||
followers.add(e.pubkey)
|
onChunk: events => {
|
||||||
}
|
for (const e of events) {
|
||||||
|
followers.add(e.pubkey)
|
||||||
|
}
|
||||||
|
|
||||||
followersCount.set(followers.size)
|
followersCount.set(followers.size)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const toggleActions = () => {
|
const toggleActions = () => {
|
||||||
@ -231,7 +230,7 @@
|
|||||||
<strong>{person.petnames.length}</strong> following
|
<strong>{person.petnames.length}</strong> following
|
||||||
</button>
|
</button>
|
||||||
<button on:click={showFollowers}>
|
<button on:click={showFollowers}>
|
||||||
<strong>{$followersCount}</strong> followers
|
<strong>{numberFmt.format($followersCount)}</strong> followers
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
@ -388,13 +388,13 @@ export const hexToBech32 = (prefix, url) =>
|
|||||||
|
|
||||||
export const bech32ToHex = b32 => utf8.encode(bech32.fromWords(bech32.decode(b32, false).words))
|
export const bech32ToHex = b32 => utf8.encode(bech32.fromWords(bech32.decode(b32, false).words))
|
||||||
|
|
||||||
export const formatSats = sats => {
|
export const numberFmt = new Intl.NumberFormat
|
||||||
const formatter = new Intl.NumberFormat()
|
|
||||||
|
|
||||||
if (sats < 1_000) return formatter.format(sats)
|
export const formatSats = sats => {
|
||||||
if (sats < 1_000_000) return formatter.format(round(1, sats / 1000)) + "K"
|
if (sats < 1_000) return numberFmt.format(sats)
|
||||||
if (sats < 100_000_000) return formatter.format(round(1, sats / 1_000_000)) + "MM"
|
if (sats < 1_000_000) return numberFmt.format(round(1, sats / 1000)) + "K"
|
||||||
return formatter.format(round(2, sats / 100_000_000)) + "BTC"
|
if (sats < 100_000_000) return numberFmt.format(round(1, sats / 1_000_000)) + "MM"
|
||||||
|
return numberFmt.format(round(2, sats / 100_000_000)) + "BTC"
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventBusListener = {
|
type EventBusListener = {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import * as path from 'path'
|
import * as path from "path"
|
||||||
import {defineConfig} from 'vite'
|
import {defineConfig} from "vite"
|
||||||
import {VitePWA} from 'vite-plugin-pwa'
|
import {VitePWA} from "vite-plugin-pwa"
|
||||||
import mkcert from 'vite-plugin-mkcert'
|
import mkcert from "vite-plugin-mkcert"
|
||||||
import sveltePreprocess from 'svelte-preprocess'
|
import sveltePreprocess from "svelte-preprocess"
|
||||||
import {svelte} from '@sveltejs/vite-plugin-svelte'
|
import {svelte} from "@sveltejs/vite-plugin-svelte"
|
||||||
import {nodePolyfills} from 'vite-plugin-node-polyfills'
|
import {nodePolyfills} from "vite-plugin-node-polyfills"
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
server: {
|
server: {
|
||||||
@ -15,8 +15,8 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
src: path.resolve(__dirname, 'src'),
|
src: path.resolve(__dirname, "src"),
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
mkcert(),
|
mkcert(),
|
||||||
@ -24,13 +24,13 @@ export default defineConfig({
|
|||||||
protocolImports: true,
|
protocolImports: true,
|
||||||
}),
|
}),
|
||||||
VitePWA({
|
VitePWA({
|
||||||
registerType: 'autoUpdate',
|
registerType: "autoUpdate",
|
||||||
injectRegister: 'auto',
|
injectRegister: "auto",
|
||||||
manifest: {
|
manifest: {
|
||||||
name: 'Coracle',
|
name: "Coracle",
|
||||||
short_name: 'Coracle',
|
short_name: "Coracle",
|
||||||
description: 'Nostr, your way.',
|
description: "Nostr, your way.",
|
||||||
theme_color: '#EB5E28',
|
theme_color: "#EB5E28",
|
||||||
icons: [
|
icons: [
|
||||||
{type: "image/png", sizes: "192x192", src: "/images/favicon/android-icon-192x192.png"},
|
{type: "image/png", sizes: "192x192", src: "/images/favicon/android-icon-192x192.png"},
|
||||||
{type: "image/png", sizes: "512x512", src: "/images/favicon/android-icon-512x512.png"},
|
{type: "image/png", sizes: "512x512", src: "/images/favicon/android-icon-512x512.png"},
|
||||||
@ -40,8 +40,7 @@ export default defineConfig({
|
|||||||
svelte({
|
svelte({
|
||||||
preprocess: sveltePreprocess(),
|
preprocess: sveltePreprocess(),
|
||||||
onwarn: (warning, handler) => {
|
onwarn: (warning, handler) => {
|
||||||
|
if (warning.code.startsWith("a11y-")) return
|
||||||
if (warning.code.startsWith('a11y-')) return
|
|
||||||
if (warning.filename.includes("node_modules")) return
|
if (warning.filename.includes("node_modules")) return
|
||||||
|
|
||||||
handler(warning)
|
handler(warning)
|
||||||
|
Loading…
Reference in New Issue
Block a user