mirror of
https://github.com/coracle-social/coracle.git
synced 2024-09-18 19:23:40 +00:00
Fix nip 65, remove relays from people, pulling stats from routes table only
This commit is contained in:
parent
12506c015b
commit
130773a90c
@ -7,10 +7,12 @@
|
||||
- [ ] Separate user info and relays so we can still select/figure out relays for anons
|
||||
- [ ] Separate petnames out as well so anons can follow people
|
||||
- [ ] Initial user load doesn't have any relays, cache user or wait for people db to be loaded
|
||||
- nip07.getRelays, nip05, relay.nostr.band
|
||||
- [ ] Fix bugs on bugsnag
|
||||
|
||||
# Snacks
|
||||
|
||||
- [ ] DM/chat read status in encrypted note
|
||||
- [ ] Relay recommendations based on follows/followers
|
||||
- [ ] Pinned posts ala snort
|
||||
- [ ] Likes list on note detail. Maybe a sidebar or header for note detail page?
|
||||
|
@ -13,7 +13,7 @@
|
||||
import {displayPerson, isLike} from 'src/util/nostr'
|
||||
import {timedelta, shuffle, now, sleep} from 'src/util/misc'
|
||||
import cmd from 'src/agent/cmd'
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import {getUserRelays} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import keys from 'src/agent/keys'
|
||||
|
@ -13,7 +13,17 @@ const updateUser = (relays, updates) =>
|
||||
publishEvent(relays, 0, {content: JSON.stringify(updates)})
|
||||
|
||||
const setRelays = (relays, newRelays) =>
|
||||
publishEvent(relays, 10001, {tags: newRelays.map(r => [r.url, r.read || "", r.write || ""])})
|
||||
publishEvent(relays, 10002, {
|
||||
tags: newRelays.map(r => {
|
||||
const t = ["r", r.url]
|
||||
|
||||
if (!r.write) {
|
||||
t.push('read')
|
||||
}
|
||||
|
||||
return t
|
||||
}),
|
||||
})
|
||||
|
||||
const setPetnames = (relays, petnames) =>
|
||||
publishEvent(relays, 3, {tags: petnames})
|
||||
|
@ -1,47 +0,0 @@
|
||||
import type {Person} from 'src/util/types'
|
||||
import type {Readable} from 'svelte/store'
|
||||
import {uniq, last} from 'ramda'
|
||||
import {derived, get} from 'svelte/store'
|
||||
import {Tags} from 'src/util/nostr'
|
||||
import {now, timedelta} from 'src/util/misc'
|
||||
import database from 'src/agent/database'
|
||||
import keys from 'src/agent/keys'
|
||||
|
||||
export const user = derived(
|
||||
[keys.pubkey, database.people as Readable<any>],
|
||||
([pubkey, $people]) => {
|
||||
if (!pubkey) {
|
||||
return null
|
||||
}
|
||||
|
||||
return ($people[pubkey] || {pubkey})
|
||||
}
|
||||
) as Readable<Person>
|
||||
|
||||
export const getMuffle = () => {
|
||||
const $user = get(user) as Person
|
||||
|
||||
if (!$user?.muffle) {
|
||||
return []
|
||||
}
|
||||
|
||||
const shouldMuffle = t => Math.random() > parseFloat(last(t))
|
||||
|
||||
return Tags.wrap($user.muffle.filter(shouldMuffle)).values().all()
|
||||
}
|
||||
|
||||
export const getFollows = pubkey =>
|
||||
Tags.wrap(database.getPersonWithFallback(pubkey).petnames).type("p").values().all()
|
||||
|
||||
export const getNetwork = pubkey =>
|
||||
uniq(getFollows(pubkey).flatMap(getFollows))
|
||||
|
||||
export const getStalePubkeys = pubkeys => {
|
||||
// If we're not reloading, only get pubkeys we don't already know about
|
||||
return uniq(pubkeys).filter(pubkey => {
|
||||
const p = database.people.get(pubkey)
|
||||
|
||||
return !p || p.updated_at < now() - timedelta(1, 'days')
|
||||
})
|
||||
}
|
||||
|
@ -3,12 +3,12 @@
|
||||
*
|
||||
* cmd
|
||||
* -> network
|
||||
* -> helpers, pool
|
||||
* -> user, pool
|
||||
* -> keys
|
||||
* -> sync
|
||||
* -> database
|
||||
*
|
||||
* In other words, command/network depend on utility functions and the network to
|
||||
* do their job. The database sits at the bottom since it's shared between helpers
|
||||
* do their job. The database sits at the bottom since it's shared between user
|
||||
* which query the database, and network which both queries and updates it.
|
||||
*/
|
||||
|
@ -1,16 +1,25 @@
|
||||
import {uniq, uniqBy, prop, map, propEq, indexBy, pluck} from 'ramda'
|
||||
import {personKinds, findReplyId} from 'src/util/nostr'
|
||||
import {chunk} from 'hurdak/lib/hurdak'
|
||||
import {batch} from 'src/util/misc'
|
||||
import {getStalePubkeys} from 'src/agent/helpers'
|
||||
import {batch, timedelta, now} from 'src/util/misc'
|
||||
import {
|
||||
getRelaysForEventParent, getAllPubkeyWriteRelays, aggregateScores,
|
||||
getUserNetworkWriteRelays,
|
||||
} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import pool from 'src/agent/pool'
|
||||
import keys from 'src/agent/keys'
|
||||
import sync from 'src/agent/sync'
|
||||
|
||||
const getStalePubkeys = pubkeys => {
|
||||
// If we're not reloading, only get pubkeys we don't already know about
|
||||
return uniq(pubkeys).filter(pubkey => {
|
||||
const p = database.people.get(pubkey)
|
||||
|
||||
return !p || p.updated_at < now() - timedelta(1, 'days')
|
||||
})
|
||||
}
|
||||
|
||||
const publish = async (relays, event) => {
|
||||
const signedEvent = await keys.sign(event)
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
import {get} from 'svelte/store'
|
||||
import {sortBy, uniq, uniqBy, prop, pluck} from 'ramda'
|
||||
import {createMapOf, first} from 'hurdak/lib/hurdak'
|
||||
import type {Relay} from 'src/util/types'
|
||||
import {writable, get} from 'svelte/store'
|
||||
import {pick, map, assoc, sortBy, uniq, uniqBy, prop} from 'ramda'
|
||||
import {first} from 'hurdak/lib/hurdak'
|
||||
import {Tags} from 'src/util/nostr'
|
||||
import {getFollows} from 'src/agent/helpers'
|
||||
import {getFollows} from 'src/agent/social'
|
||||
import database from 'src/agent/database'
|
||||
import keys from 'src/agent/keys'
|
||||
|
||||
@ -18,25 +19,24 @@ import keys from 'src/agent/keys'
|
||||
// doesn't need to see.
|
||||
// 5) Advertise relays — write and read back your own relay list
|
||||
|
||||
export const relays = writable([])
|
||||
|
||||
// Pubkey relays
|
||||
|
||||
export const getPubkeyRelays = pubkey => {
|
||||
const person = database.getPersonWithFallback(pubkey)
|
||||
export const getPubkeyRelays = (pubkey, mode = null) => {
|
||||
const filter = mode ? {pubkey, mode} : {pubkey}
|
||||
|
||||
return scoreRelays(pubkey, person.relays || [])
|
||||
return sortByScore(map(pick(['url', 'score']), database.routes.all(filter)))
|
||||
}
|
||||
|
||||
export const getPubkeyReadRelays = pubkey =>
|
||||
getPubkeyRelays(pubkey).filter(r => r.read !== '!')
|
||||
export const getPubkeyReadRelays = pubkey => getPubkeyRelays(pubkey, 'read')
|
||||
|
||||
export const getPubkeyWriteRelays = pubkey =>
|
||||
getPubkeyRelays(pubkey).filter(r => r.write !== '!')
|
||||
export const getPubkeyWriteRelays = pubkey => getPubkeyRelays(pubkey, 'write')
|
||||
|
||||
// Multiple pubkeys
|
||||
|
||||
export const getAllPubkeyRelays = pubkeys =>
|
||||
aggregateScores(pubkeys.map(getPubkeyRelays))
|
||||
export const getAllPubkeyRelays = (pubkeys, mode = null) =>
|
||||
aggregateScores(pubkeys.map(pubkey => getPubkeyRelays(pubkey, mode)))
|
||||
|
||||
export const getAllPubkeyReadRelays = pubkeys =>
|
||||
aggregateScores(pubkeys.map(getPubkeyReadRelays))
|
||||
@ -46,9 +46,9 @@ export const getAllPubkeyWriteRelays = pubkeys =>
|
||||
|
||||
// Current user
|
||||
|
||||
export const getUserRelays = () => getPubkeyRelays(get(keys.pubkey))
|
||||
export const getUserReadRelays = () => getPubkeyReadRelays(get(keys.pubkey))
|
||||
export const getUserWriteRelays = () => getPubkeyWriteRelays(get(keys.pubkey))
|
||||
export const getUserRelays = (): Array<Relay> => get(relays).map(assoc('score', 1))
|
||||
export const getUserReadRelays = () => getUserRelays().filter(prop('read'))
|
||||
export const getUserWriteRelays = () => getUserRelays().filter(prop('write'))
|
||||
|
||||
// Network relays
|
||||
|
||||
@ -111,13 +111,6 @@ export const getEventPublishRelays = event => {
|
||||
const uniqByUrl = uniqBy(prop('url'))
|
||||
const sortByScore = sortBy(r => -r.score)
|
||||
|
||||
const scoreRelays = (pubkey, relays) => {
|
||||
const routes = database.routes.all({pubkey, url: pluck('url', relays)})
|
||||
const scores = createMapOf('url', 'score', routes)
|
||||
|
||||
return uniqByUrl(sortByScore(relays.map(r => ({...r, score: scores[r.url] || 0}))))
|
||||
}
|
||||
|
||||
export const aggregateScores = relayGroups => {
|
||||
const scores = {} as Record<string, {
|
||||
score: number,
|
||||
|
9
src/agent/social.ts
Normal file
9
src/agent/social.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import {uniq} from 'ramda'
|
||||
import {Tags} from 'src/util/nostr'
|
||||
import database from 'src/agent/database'
|
||||
|
||||
export const getFollows = pubkey =>
|
||||
Tags.wrap(database.getPersonWithFallback(pubkey).petnames).type("p").values().all()
|
||||
|
||||
export const getNetwork = pubkey =>
|
||||
uniq(getFollows(pubkey).flatMap(getFollows))
|
@ -41,49 +41,8 @@ const processProfileEvents = async events => {
|
||||
return content
|
||||
})
|
||||
},
|
||||
2: () => {
|
||||
if (e.created_at > (person.relays_updated_at || 0)) {
|
||||
const {relays = []} = database.getPersonWithFallback(e.pubkey)
|
||||
|
||||
return {
|
||||
relays: relays.concat({url: e.content}),
|
||||
relays_updated_at: e.created_at,
|
||||
}
|
||||
}
|
||||
},
|
||||
3: () => {
|
||||
const data = {petnames: e.tags}
|
||||
|
||||
if (e.created_at > (person.relays_updated_at || 0)) {
|
||||
tryJson(() => {
|
||||
Object.assign(data, {
|
||||
relays_updated_at: e.created_at,
|
||||
relays: Object.entries(JSON.parse(e.content))
|
||||
.map(([url, conditions]) => {
|
||||
const {write, read} = conditions as Record<string, boolean|string>
|
||||
|
||||
return {
|
||||
url,
|
||||
write: [false, '!'].includes(write) ? '!' : '',
|
||||
read: [false, '!'].includes(read) ? '!' : '',
|
||||
}
|
||||
})
|
||||
.filter(r => isRelay(r.url)),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return data
|
||||
},
|
||||
3: () => ({petnames: e.tags}),
|
||||
12165: () => ({muffle: e.tags}),
|
||||
10001: () => {
|
||||
if (e.created_at > (person.relays_updated_at || 0)) {
|
||||
return {
|
||||
relays: e.tags.map(([url, read, write]) => ({url, read, write})),
|
||||
relays_updated_at: e.created_at,
|
||||
}
|
||||
}
|
||||
},
|
||||
default: () => {
|
||||
log(`Received unsupported event type ${e.kind}`)
|
||||
},
|
||||
@ -153,7 +112,7 @@ const processMessages = async events => {
|
||||
|
||||
const getWeight = type => {
|
||||
if (type === 'nip05') return 1
|
||||
if (type === 'kind:10001') return 1
|
||||
if (type === 'kind:10002') return 1
|
||||
if (type === 'kind:3') return 0.8
|
||||
if (type === 'kind:2') return 0.5
|
||||
if (type === 'seen') return 0.2
|
||||
@ -216,19 +175,14 @@ const processRoutes = async events => {
|
||||
})
|
||||
})
|
||||
},
|
||||
10001: () => {
|
||||
10002: () => {
|
||||
e.tags
|
||||
.forEach(([url, read, write]) => {
|
||||
if (![false, '!'].includes(write)) {
|
||||
updates.push(
|
||||
calculateRoute(e.pubkey, url, 'kind:100001', 'write', e.created_at)
|
||||
)
|
||||
}
|
||||
|
||||
if (![false, '!'].includes(read)) {
|
||||
updates.push(
|
||||
calculateRoute(e.pubkey, url, 'kind:100001', 'read', e.created_at)
|
||||
)
|
||||
.forEach(([url, read, mode]) => {
|
||||
if (mode) {
|
||||
calculateRoute(e.pubkey, url, 'kind:10002', mode, e.created_at)
|
||||
} else {
|
||||
calculateRoute(e.pubkey, url, 'kind:10002', 'read', e.created_at)
|
||||
calculateRoute(e.pubkey, url, 'kind:10002', 'write', e.created_at)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
16
src/agent/user.ts
Normal file
16
src/agent/user.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import type {Person} from 'src/util/types'
|
||||
import type {Readable} from 'svelte/store'
|
||||
import {derived} from 'svelte/store'
|
||||
import database from 'src/agent/database'
|
||||
import keys from 'src/agent/keys'
|
||||
|
||||
export const user = derived(
|
||||
[keys.pubkey, database.people as Readable<any>],
|
||||
([pubkey, $people]) => {
|
||||
if (!pubkey) {
|
||||
return null
|
||||
}
|
||||
|
||||
return ($people[pubkey] || {pubkey})
|
||||
}
|
||||
) as Readable<Person>
|
@ -5,9 +5,9 @@ import {createMap, ellipsize} from 'hurdak/lib/hurdak'
|
||||
import {get} from 'svelte/store'
|
||||
import {renderContent} from 'src/util/html'
|
||||
import {Tags, displayPerson, findReplyId} from 'src/util/nostr'
|
||||
import {user, getNetwork} from 'src/agent/helpers'
|
||||
import {getUserWriteRelays} from 'src/agent/relays'
|
||||
import defaults from 'src/agent/defaults'
|
||||
import {user} from 'src/agent/user'
|
||||
import {getNetwork} from 'src/agent/social'
|
||||
import {relays} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import network from 'src/agent/network'
|
||||
import keys from 'src/agent/keys'
|
||||
@ -49,44 +49,50 @@ export const login = async ({privkey, pubkey}: {privkey?: string, pubkey?: strin
|
||||
|
||||
export const addRelay = async url => {
|
||||
const person = get(user) as Person
|
||||
const modify = relays => relays.concat({url, write: '!'})
|
||||
|
||||
// Set to defaults to support anonymous usage
|
||||
defaults.relays = modify(defaults.relays)
|
||||
relays.update($relays => {
|
||||
$relays.push({url, write: false, read: true})
|
||||
|
||||
if (person) {
|
||||
const relays = modify(person.relays || [])
|
||||
if (person) {
|
||||
(async () => {
|
||||
// Publish to the new set of relays
|
||||
await cmd.setRelays($relays, $relays)
|
||||
|
||||
// Publish to the new set of relays
|
||||
await cmd.setRelays(relays, relays)
|
||||
// Reload alerts, messages, etc
|
||||
await loadAppData(person.pubkey)
|
||||
})()
|
||||
}
|
||||
|
||||
// Reload alerts, messages, etc
|
||||
await loadAppData(person.pubkey)
|
||||
}
|
||||
return $relays
|
||||
})
|
||||
}
|
||||
|
||||
export const removeRelay = async url => {
|
||||
const person = get(user) as Person
|
||||
const modify = relays => reject(whereEq({url}), relays)
|
||||
|
||||
// Set to defaults to support anonymous usage
|
||||
defaults.relays = modify(defaults.relays)
|
||||
relays.update($relays => {
|
||||
$relays = reject(whereEq({url}), $relays)
|
||||
|
||||
if (person) {
|
||||
await cmd.setRelays(getUserWriteRelays(), modify(person.relays || []))
|
||||
}
|
||||
if (person && $relays.length > 0) {
|
||||
cmd.setRelays($relays, $relays)
|
||||
}
|
||||
|
||||
return $relays
|
||||
})
|
||||
}
|
||||
|
||||
export const setRelayWriteCondition = async (url, write) => {
|
||||
const person = get(user) as Person
|
||||
const modify = relays => relays.map(when(whereEq({url}), assoc('write', write)))
|
||||
|
||||
// Set to defaults to support anonymous usage
|
||||
defaults.relays = modify(defaults.relays)
|
||||
relays.update($relays => {
|
||||
$relays = $relays.map(when(whereEq({url}), assoc('write', write)))
|
||||
|
||||
if (person) {
|
||||
await cmd.setRelays(getUserWriteRelays(), modify(person.relays || []))
|
||||
}
|
||||
if (person && $relays.length > 0) {
|
||||
cmd.setRelays($relays, $relays)
|
||||
}
|
||||
|
||||
return $relays
|
||||
})
|
||||
}
|
||||
|
||||
export const renderNote = (note, {showEntire = false}) => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {pluck, reject} from 'ramda'
|
||||
import {get} from 'svelte/store'
|
||||
import {synced, now, timedelta} from 'src/util/misc'
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import {getUserReadRelays} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import network from 'src/agent/network'
|
||||
|
@ -8,7 +8,7 @@
|
||||
import Badge from 'src/partials/Badge.svelte'
|
||||
import Anchor from 'src/partials/Anchor.svelte'
|
||||
import Spinner from 'src/partials/Spinner.svelte'
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import database from 'src/agent/database'
|
||||
import {renderNote} from 'src/app'
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
import {formatTimestamp, stringToColor} from 'src/util/misc'
|
||||
import Compose from "src/partials/Compose.svelte"
|
||||
import Card from "src/partials/Card.svelte"
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import {getEventPublishRelays, getRelaysForEventParent} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import cmd from 'src/agent/cmd'
|
||||
@ -217,7 +217,7 @@
|
||||
{/if}
|
||||
</Anchor>
|
||||
<Anchor
|
||||
href={"/" + nip19.neventEncode({id: note.id, relays: [note.seen_on.url]})}
|
||||
href={"/" + nip19.neventEncode({id: note.id, relays: [note.seen_on]})}
|
||||
class="text-sm text-light"
|
||||
type="unstyled">
|
||||
{formatTimestamp(note.created_at)}
|
||||
|
@ -1,13 +1,14 @@
|
||||
<script lang="ts">
|
||||
import {onMount} from 'svelte'
|
||||
import {partition, propEq, always, mergeRight, uniqBy, sortBy, prop} from 'ramda'
|
||||
import {partition, last, propEq, always, mergeRight, uniqBy, sortBy, prop} from 'ramda'
|
||||
import {slide} from 'svelte/transition'
|
||||
import {quantify} from 'hurdak/lib/hurdak'
|
||||
import {createScroller, now, Cursor} from 'src/util/misc'
|
||||
import {Tags} from 'src/util/nostr'
|
||||
import Spinner from 'src/partials/Spinner.svelte'
|
||||
import Content from 'src/partials/Content.svelte'
|
||||
import Note from "src/partials/Note.svelte"
|
||||
import {getMuffle} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import network from 'src/agent/network'
|
||||
import {modal, mergeParents} from "src/app"
|
||||
|
||||
@ -20,8 +21,10 @@
|
||||
|
||||
const since = now()
|
||||
const maxNotes = 300
|
||||
const muffle = getMuffle()
|
||||
const cursor = new Cursor()
|
||||
const muffle = Tags
|
||||
.wrap(($user?.muffle || []).filter(t => Math.random() > parseFloat(last(t))))
|
||||
.values().all()
|
||||
|
||||
const processNewNotes = async newNotes => {
|
||||
// Remove people we're not interested in hearing about, sort by created date
|
||||
|
@ -6,7 +6,7 @@
|
||||
import {between} from 'hurdak/lib/hurdak'
|
||||
import {fly} from 'svelte/transition'
|
||||
import Toggle from "src/partials/Toggle.svelte"
|
||||
import {user} from "src/agent/helpers"
|
||||
import {relays} from "src/agent/relays"
|
||||
import pool from 'src/agent/pool'
|
||||
import {addRelay, removeRelay, setRelayWriteCondition} from "src/app"
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
let showStatus = false
|
||||
let joined = false
|
||||
|
||||
$: joined = find(propEq('url', relay.url), $user?.relays || [])
|
||||
$: joined = find(propEq('url', relay.url), $relays)
|
||||
|
||||
onMount(() => {
|
||||
return poll(10_000, async () => {
|
||||
|
@ -4,7 +4,7 @@
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {navigate} from "svelte-routing"
|
||||
import {fuzzy} from "src/util/misc"
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import network from 'src/agent/network'
|
||||
import database from 'src/agent/database'
|
||||
import {getUserReadRelays} from 'src/agent/relays'
|
||||
|
@ -3,7 +3,7 @@
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {now} from 'src/util/misc'
|
||||
import Channel from 'src/partials/Channel.svelte'
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import {getRelaysForEventChildren} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import network from 'src/agent/network'
|
||||
|
@ -4,7 +4,7 @@
|
||||
import {personKinds} from 'src/util/nostr'
|
||||
import {now} from 'src/util/misc'
|
||||
import Channel from 'src/partials/Channel.svelte'
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import {getAllPubkeyRelays} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import network from 'src/agent/network'
|
||||
|
@ -6,7 +6,7 @@
|
||||
import Tabs from "src/partials/Tabs.svelte"
|
||||
import Network from "src/views/notes/Network.svelte"
|
||||
import Popular from "src/views/notes/Popular.svelte"
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
|
||||
export let activeTab
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
import Notes from "src/views/person/Notes.svelte"
|
||||
import Likes from "src/views/person/Likes.svelte"
|
||||
import Relays from "src/views/person/Relays.svelte"
|
||||
import {user} from "src/agent/helpers"
|
||||
import {user} from "src/agent/user"
|
||||
import {getPubkeyWriteRelays, getUserWriteRelays} from "src/agent/relays"
|
||||
import network from "src/agent/network"
|
||||
import keys from "src/agent/keys"
|
||||
|
@ -11,7 +11,7 @@
|
||||
import Button from "src/partials/Button.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import Heading from "src/partials/Heading.svelte"
|
||||
import {user} from "src/agent/helpers"
|
||||
import {user} from "src/agent/user"
|
||||
import {getUserWriteRelays} from 'src/agent/relays'
|
||||
import cmd from "src/agent/cmd"
|
||||
import {toast} from "src/app"
|
||||
|
@ -8,14 +8,14 @@
|
||||
import Anchor from "src/partials/Anchor.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import RelayCard from "src/partials/RelayCard.svelte"
|
||||
import {user} from "src/agent/helpers"
|
||||
import {relays} from "src/agent/relays"
|
||||
import database from 'src/agent/database'
|
||||
import {modal, settings} from "src/app"
|
||||
import defaults from "src/agent/defaults"
|
||||
|
||||
let q = ""
|
||||
let search
|
||||
let relays = []
|
||||
let knownRelays = database.watch('relays', t => t.all())
|
||||
|
||||
fetch(get(settings).dufflepudUrl + '/relay')
|
||||
.then(async res => {
|
||||
@ -26,15 +26,13 @@
|
||||
|
||||
database.relays.bulkPatch(createMap('url', defaults.relays))
|
||||
|
||||
const knownRelays = database.watch('relays', relays => relays.all())
|
||||
|
||||
$: {
|
||||
relays = $user?.relays || []
|
||||
const joined = new Set(pluck('url', $relays))
|
||||
|
||||
const joined = new Set(pluck('url', relays))
|
||||
const data = ($knownRelays || []).filter(r => !joined.has(r.url))
|
||||
|
||||
search = fuzzy(data, {keys: ["name", "description", "url"]})
|
||||
search = fuzzy(
|
||||
$knownRelays.filter(r => !joined.has(r.url)),
|
||||
{keys: ["name", "description", "url"]}
|
||||
)
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -52,11 +50,11 @@
|
||||
Relays are hubs for your content and connections. At least one is required to
|
||||
interact with the network, but you can join as many as you like.
|
||||
</p>
|
||||
{#if relays.length === 0}
|
||||
{#if $relays.length === 0}
|
||||
<div class="text-center">No relays connected</div>
|
||||
{/if}
|
||||
<div class="grid grid-cols-1 gap-4">
|
||||
{#each relays as relay (relay.url)}
|
||||
{#each $relays as relay (relay.url)}
|
||||
<RelayCard showControls {relay} />
|
||||
{/each}
|
||||
</div>
|
||||
@ -79,8 +77,8 @@
|
||||
<RelayCard {relay} />
|
||||
{/each}
|
||||
<small class="text-center">
|
||||
Showing {Math.min(($knownRelays || []).length - relays.length, 50)}
|
||||
of {($knownRelays || []).length - relays.length} known relays
|
||||
Showing {Math.min(($knownRelays || []).length - $relays.length, 50)}
|
||||
of {($knownRelays || []).length - $relays.length} known relays
|
||||
</small>
|
||||
</div>
|
||||
</Content>
|
||||
|
@ -7,7 +7,7 @@
|
||||
import Button from "src/partials/Button.svelte"
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import Heading from "src/partials/Heading.svelte"
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import {toast, settings} from "src/app"
|
||||
|
||||
let values = {...$settings}
|
||||
|
@ -2,7 +2,7 @@ import {last, identity, objOf, prop, flatten, uniq} from 'ramda'
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {ensurePlural, ellipsize, first} from 'hurdak/lib/hurdak'
|
||||
|
||||
export const personKinds = [0, 2, 3, 10001, 12165]
|
||||
export const personKinds = [0, 2, 3, 10002, 12165]
|
||||
|
||||
export class Tags {
|
||||
constructor(tags) {
|
||||
|
@ -2,6 +2,9 @@ import type {Event} from 'nostr-tools'
|
||||
|
||||
export type Relay = {
|
||||
url: string
|
||||
score?: number
|
||||
write?: boolean
|
||||
read?: boolean
|
||||
}
|
||||
|
||||
export type Person = {
|
||||
|
@ -2,7 +2,7 @@
|
||||
import {onMount} from "svelte"
|
||||
import {nip19} from 'nostr-tools'
|
||||
import {quantify} from 'hurdak/lib/hurdak'
|
||||
import {last, whereEq, find, reject, pluck, propEq} from 'ramda'
|
||||
import {last, reject, pluck, propEq} from 'ramda'
|
||||
import {fly} from 'svelte/transition'
|
||||
import {navigate} from "svelte-routing"
|
||||
import {fuzzy} from "src/util/misc"
|
||||
@ -13,7 +13,7 @@
|
||||
import Content from "src/partials/Content.svelte"
|
||||
import Modal from "src/partials/Modal.svelte"
|
||||
import Heading from 'src/partials/Heading.svelte'
|
||||
import {user} from "src/agent/helpers"
|
||||
import {user} from "src/agent/user"
|
||||
import {getUserWriteRelays} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import cmd from "src/agent/cmd"
|
||||
@ -27,12 +27,15 @@
|
||||
let q = ''
|
||||
let search
|
||||
|
||||
const knownRelays = database.watch('relays', relays => relays.all())
|
||||
const knownRelays = database.watch('relays', t => t.all())
|
||||
|
||||
$: {
|
||||
const data = reject(({url}) => find(whereEq({url}), relays), $knownRelays || [])
|
||||
const joined = new Set(pluck('url', relays))
|
||||
|
||||
search = fuzzy(data, {keys: ["name", "description", "url"]})
|
||||
search = fuzzy(
|
||||
$knownRelays.filter(r => !joined.has(r.url)),
|
||||
{keys: ["name", "description", "url"]}
|
||||
)
|
||||
}
|
||||
|
||||
const onSubmit = async () => {
|
||||
|
@ -5,7 +5,7 @@
|
||||
import Button from "src/partials/Button.svelte"
|
||||
import Content from 'src/partials/Content.svelte'
|
||||
import SelectButton from "src/partials/SelectButton.svelte"
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import {getUserWriteRelays} from 'src/agent/relays'
|
||||
import cmd from 'src/agent/cmd'
|
||||
import {modal} from 'src/app'
|
||||
|
@ -3,7 +3,7 @@
|
||||
import {personKinds} from "src/util/nostr"
|
||||
import Input from "src/partials/Input.svelte"
|
||||
import PersonInfo from 'src/partials/PersonInfo.svelte'
|
||||
import {user} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import {getUserReadRelays} from 'src/agent/relays'
|
||||
import database from 'src/agent/database'
|
||||
import network from 'src/agent/network'
|
||||
|
@ -1,7 +1,8 @@
|
||||
<script>
|
||||
import {uniq} from 'ramda'
|
||||
import Notes from "src/partials/Notes.svelte"
|
||||
import {user, getFollows, getNetwork} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import {getFollows, getNetwork} from 'src/agent/social'
|
||||
import {getAllPubkeyWriteRelays} from 'src/agent/relays'
|
||||
|
||||
// Get first- and second-order follows. shuffle and slice network so we're not
|
||||
|
@ -2,7 +2,8 @@
|
||||
import {uniq} from 'ramda'
|
||||
import Notes from "src/partials/Notes.svelte"
|
||||
import {isLike} from 'src/util/nostr'
|
||||
import {user, getFollows, getNetwork} from 'src/agent/helpers'
|
||||
import {user} from 'src/agent/user'
|
||||
import {getFollows, getNetwork} from 'src/agent/social'
|
||||
import {getAllPubkeyWriteRelays} from 'src/agent/relays'
|
||||
|
||||
// Get first- and second-order follows. shuffle and slice network so we're not
|
||||
|
Loading…
Reference in New Issue
Block a user